UNPKG

extra-markdown-text

Version:
95 lines (93 loc) 3.42 kB
const RCODEBLOCK = /^ {0,3}```(\w*)\s*\n([\s\S]*?)^ {0,3}```[ \t]*\n|((?:^(?: {4}|\t)[\s\S]*?\n)+)/gm; function unindentCodeBlock(txt) { return txt.replace(/^( {4}|\t)/gm, ''); } function forEachCodeBlock(txt, fn) { var m = null; while ((m = RCODEBLOCK.exec(txt)) != null) fn(m[0], m[1] || '', m[2] != null ? m[2] : unindentCodeBlock(m[3])); } function codeBlocks(txt) { var a = []; forEachCodeBlock(txt, (full, language, body) => a.push({ full, language, body })); return a; } function replaceCodeBlocks(txt, fn) { return txt.replace(RCODEBLOCK, (m, p1, p2, p3) => { return fn(m, p1 || '', p2 != null ? p2 : unindentCodeBlock(p3)); }); } function tagCodeBlocks(txt) { var tags = new Map(), i = -1; var txt = replaceCodeBlocks(txt, full => { var k = `AUTO_CODE_BLOCK_${++i}`; tags.set(k, full); return '```\n' + `${k}\n` + '```\n'; }); return [txt, tags]; } function untagCodeBlocks(txt, tags) { for (var [tag, full] of tags) txt = txt.replace('```\n' + `${tag}\n` + '```\n', full); return txt; } const RLINK = /!?\[(.*?)\](?:\((.*?)\)| ?\[(.*?)\]|(?!:))/gm; function forEachLink(txt, fn) { var txt = replaceCodeBlocks(txt, () => ''), m = null; while ((m = RLINK.exec(txt)) != null) if (!m[0].startsWith('!')) fn(m[0], m[1], m[3] || '', m[2] || ''); } function links(txt) { var a = []; forEachLink(txt, (full, name, reference, url) => a.push({ full, name, reference, url })); return a; } function replaceLinks(txt, fn) { var [txt, tags] = tagCodeBlocks(txt); txt = txt.replace(RLINK, (m, p1, p2, p3) => { return m.startsWith('!') ? m : fn(m, p1, p3 || '', p2 || ''); }); return untagCodeBlocks(txt, tags); } const RLINKREFERENCE = /^[ \t]*\[(.*?)\]:[ \t]*<?([>\S]*?)>?(?:[ \t]*['"(](.*?)['")])?[ \t]*$/gm; function forEachLinkReference(txt, fn) { var txt = replaceCodeBlocks(txt, () => ''), m = null; while ((m = RLINKREFERENCE.exec(txt)) != null) fn(m[0], m[1], m[2], m[3] || ''); } function linkReferences(txt) { var a = []; forEachLinkReference(txt, (full, name, url, title) => a.push({ full, name, url, title })); return a; } function replaceLinkReferences(txt, fn) { var [txt, tags] = tagCodeBlocks(txt); txt = txt.replace(RLINKREFERENCE, (m, p1, p2, p3) => fn(m, p1, p2, p3 || '')); return untagCodeBlocks(txt, tags); } const RTABLE = /.*?\n.*?(?:\|[ \t]*---|---[ \t]*\|)[\s\S]*?(?:\n(?=[ \t]*\n)|$)/g; function tableRows(full) { var rows = []; var ls = full.trim().split('\n'); ls.splice(1, 1); for (var l of ls) rows.push(l.replace(/(^\s*\|)|(\|\s*$)/g, '').split('|')); return rows; } function forEachTable(txt, fn) { var txt = replaceCodeBlocks(txt, () => ''), m = null; while ((m = RTABLE.exec(txt)) != null) fn(m[0], tableRows(m[0])); } function tables(txt) { var a = []; forEachTable(txt, (full, rows) => a.push({ full, rows })); return a; } function replaceTables(txt, fn) { var [txt, tags] = tagCodeBlocks(txt); txt = txt.replace(RTABLE, m => fn(m, tableRows(m))); return untagCodeBlocks(txt, tags); } export { codeBlocks, forEachCodeBlock, forEachLink, forEachLinkReference, forEachTable, linkReferences, links, replaceCodeBlocks, replaceLinkReferences, replaceLinks, replaceTables, tables, tagCodeBlocks, untagCodeBlocks };