A live markdown editor in a bookmarklet. Preview is updated on every key press. I should implement a delay.
It's a lot of code, but I like the nature of bookmarklets where nothing is retained after you close it.
I often find myself just wanting to see what the markdown looks like, which is why I built this.
I used Snarkdown, a 1kb markdown parser. I did try to make my own parser but I gave up.
Also, I changed the line-breaks from <br/> to <p></p> since they need a margin below each line.
data:text/html,<title>md-editor</title><p id=c style=position:absolute;top:0;right:4></p><textarea id=d spellcheck=false style=resize:none;filter:invert(1)hue-rotate(180deg)></textarea><div id=f></div><script>d.onkeyup=e=>f.innerHTML=k(d.value);var e={"":["<em>","</em>"],_:["<strong>","</strong>"],"*":["<strong>","</strong>"],"~":["<s>","</s>"],"\n":["<p>","</p>"]," ":["<br>"],"-":["<hr>"]};function n(e){return e.replace(RegExp("^"+(e.match(/^(\t| )+/)||"")[0],"gm"),"")}function r(e){return(e+"").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}k=function t(a,o){var c,l,s,g,p,u=/((?:^|\n+)(?:\n---+|\* \*(?: \*)+)\n)|(?:^``` *(\w*)\n([\s\S]*?)\n```$)|((?:(?:^|\n+)(?:\t|%20 {2,}).+)+\n*)|((?:(?:^|\n)([>*+-]|\d+\.)\s+.*)+)|(?:!\[([^\]]*?)\]\(([^)]+?)\))|(\[)|(\](?:\(([^)]+?)\))?)|(?:(?:^|\n+)([^\s].*)\n(-{3,}|={3,})(?:\n+|$))|(?:(?:^|\n+)(%23{1,6})\s*(.+)(?:\n+|$))|(?:`([^`].*?)`)|(%20 \n\n*|\n{2,}|__|\*\*|[_*]|~~)/gm,m=[],h="",i=o||{},d=0;function $(n){var r=e[n[1]||""],t=m[m.length-1]==n;return r?r[1]?(t?m.pop():m.push(n),r[0|t]):r[0]:n}function f(){for(var e="";m.length;)e+=$(m[m.length-1]);return e}for(a=a.replace(/^\[(.+?)\]:\s*(.+)$/gm,function(e,n,r){return i[n.toLowerCase()]=r,""}).replace(/^\n+|\n+$/g,"");s=u.exec(a);)l=a.substring(d,s.index),d=u.lastIndex,c=s[0],l.match(/[^\\](\\\\)*\\$/)||((p=s[3]||s[4])?c='<pre class="code '+(s[4]?"poetry":s[2].toLowerCase())+'"><code'+(s[2]?' class="language-'+s[2].toLowerCase()+'"':"")+">"+n(r(p).replace(/^\n+|\n+$/g,""))+"</code></pre>":(p=s[6])?(p.match(/\./)&&(s[5]=s[5].replace(/^\d+/gm,"")),g=t(n(s[5].replace(/^\s*[>*+.-]/gm,""))),">"==p?p="blockquote":(p=p.match(/\./)?"ol":"ul",g=g.replace(/^(.*)(\n|$)/gm,"<li>$1</li>")),c="<"+p+">"+g+"</"+p+">"):s[8]?c='<img src="'+r(s[8])+'" alt="'+r(s[7])+'">':s[10]?(h=h.replace("<a>",'<a href="'+r(s[11]||i[l.toLowerCase()])+'">'),c=f()+"</a>"):s[9]?c="<a>":s[12]||s[14]?c="<"+(p="h"+(s[14]?s[14].length:s[13]>"="?1:2))+">"+t(s[12]||s[15],i)+"</"+p+">":s[16]?c="<code>"+r(s[16])+"</code>":(s[17]||s[1])&&(c=$(s[17]||"--"))),h+=l,h+=c;return(h+a.substring(d)+f()).replace(/^\n+|\n+$/g,"")};</script><style>body,%23f,%23d{box-sizing:border-box;margin:0}%23d,%23f{display:inline-block;width:50%;height:100%;vertical-align:top;padding:1rem}%23f,.code{overflow:auto;padding:1rem}.code,code{scrollbar-width:thin;background-color:%23EEE;border-radius:.2rem}%23f{font-family:Arial}
More features but uses a CDN link to get the library
data:text/html,<meta charset=utf8><title>%E2%9C%8D MD</title><p id=c style=position:absolute;top:0;right:4></p><textarea id=d spellcheck=false style=resize:none;filter:invert(1)hue-rotate(180deg)></textarea><div id=f></div><script src="https://cdnjs.cloudflare.com/ajax/libs/marked/11.1.0/marked.min.js" integrity="sha512-49xmrP3uviO3RLWud0G4giZPhidSGQMjdsX3AkGH0tW4q1FN1nzTa4WGhyKIl+sggfI2q9rB78y/HvVK2HbVnA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script><script>d.onkeyup=e=>f.innerHTML=marked.parse(d.value);</script><style>body,%23f,%23d{box-sizing:border-box;margin:0}%23d,%23f{display:inline-block;width:50%;height:100%;vertical-align:top;padding:1rem}%23f,.code{overflow:auto;padding:1rem}.code,pre,code{scrollbar-width:thin;background-color:%23EEE;border-radius:.2rem}%23f{font-family:Arial}