(md, prevLinks)
| 24 | |
| 25 | /** Parse Markdown into an HTML String. */ |
| 26 | export default function parse(md, prevLinks) { |
| 27 | let tokenizer = /((?:^|\n+)(?:\n---+|\* \*(?: \*)+)\n)|(?:^``` *(\w*)\n([\s\S]*?)\n```$)|((?:(?:^|\n+)(?:\t| {2,}).+)+\n*)|((?:(?:^|\n)([>*+-]|\d+\.)\s+.*)+)|(?:!\[([^\]]*?)\]\(([^)]+?)\))|(\[)|(\](?:\(([^)]+?)\))?)|(?:(?:^|\n+)([^\s].*)\n(-{3,}|={3,})(?:\n+|$))|(?:(?:^|\n+)(#{1,6})\s*(.+)(?:\n+|$))|(?:`([^`].*?)`)|( \n\n*|\n{2,}|__|\*\*|[_*]|~~)/gm, |
| 28 | context = [], |
| 29 | out = '', |
| 30 | links = prevLinks || {}, |
| 31 | last = 0, |
| 32 | chunk, prev, token, inner, t; |
| 33 | |
| 34 | function tag(token) { |
| 35 | let desc = TAGS[token[1] || '']; |
| 36 | let end = context[context.length-1] == token; |
| 37 | if (!desc) return token; |
| 38 | if (!desc[1]) return desc[0]; |
| 39 | if (end) context.pop(); |
| 40 | else context.push(token); |
| 41 | return desc[end|0]; |
| 42 | } |
| 43 | |
| 44 | function flush() { |
| 45 | let str = ''; |
| 46 | while (context.length) str += tag(context[context.length-1]); |
| 47 | return str; |
| 48 | } |
| 49 | |
| 50 | md = md.replace(/^\[(.+?)\]:\s*(.+)$/gm, (s, name, url) => { |
| 51 | links[name.toLowerCase()] = url; |
| 52 | return ''; |
| 53 | }).replace(/^\n+|\n+$/g, ''); |
| 54 | |
| 55 | while ( (token=tokenizer.exec(md)) ) { |
| 56 | prev = md.substring(last, token.index); |
| 57 | last = tokenizer.lastIndex; |
| 58 | chunk = token[0]; |
| 59 | if (prev.match(/[^\\](\\\\)*\\$/)) { |
| 60 | // escaped |
| 61 | } |
| 62 | // Code/Indent blocks: |
| 63 | else if (t = (token[3] || token[4])) { |
| 64 | chunk = '<pre class="code '+(token[4]?'poetry':token[2].toLowerCase())+'"><code'+(token[2] ? ` class="language-${token[2].toLowerCase()}"` : '')+'>'+outdent(encodeAttr(t).replace(/^\n+|\n+$/g, ''))+'</code></pre>'; |
| 65 | } |
| 66 | // > Quotes, -* lists: |
| 67 | else if (t = token[6]) { |
| 68 | if (t.match(/\./)) { |
| 69 | token[5] = token[5].replace(/^\d+/gm, ''); |
| 70 | } |
| 71 | inner = parse(outdent(token[5].replace(/^\s*[>*+.-]/gm, ''))); |
| 72 | if (t=='>') t = 'blockquote'; |
| 73 | else { |
| 74 | t = t.match(/\./) ? 'ol' : 'ul'; |
| 75 | inner = inner.replace(/^(.*)(\n|$)/gm, '<li>$1</li>'); |
| 76 | } |
| 77 | chunk = '<'+t+'>' + inner + '</'+t+'>'; |
| 78 | } |
| 79 | // Images: |
| 80 | else if (token[8]) { |
| 81 | chunk = `<img src="${encodeAttr(token[8])}" alt="${encodeAttr(token[7])}">`; |
| 82 | } |
| 83 | // Links: |
nothing calls this directly
no test coverage detected
searching dependent graphs…