quikdown 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,8 @@
1
+ /**
2
+ * quikdown_bd - Bidirectional Markdown Parser
3
+ * @version 1.0.4
4
+ * @license BSD-2-Clause
5
+ * @copyright DeftIO 2025
6
+ */
7
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).quikdown_bd=t()}(this,function(){"use strict";const e={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};function t(t){return t.replace(/[&<>"']/g,t=>e[t])}function n(e,n={}){if(!e||"string"!=typeof e)return"";const{fence_plugin:o,inline_styles:a=!1,bidirectional:i=!0}=n;i||(n.bidirectional=!1);const l=function(e,n){return function(r,o="",a=""){let i="";if(a&&(i+=` data-qd="${t(a)}"`),e){const e=n[r];(e||o)&&(i+=` style="${o?e?`${e};${o}`:o:e}"`)}else i+=` class="quikdown-${r}"`;return i}}(a,{h1:"font-size:2em;font-weight:600;margin:.67em 0;text-align:left",h2:"font-size:1.5em;font-weight:600;margin:.83em 0",h3:"font-size:1.25em;font-weight:600;margin:1em 0",h4:"font-size:1em;font-weight:600;margin:1.33em 0",h5:"font-size:.875em;font-weight:600;margin:1.67em 0",h6:"font-size:.85em;font-weight:600;margin:2em 0",pre:"background:#f4f4f4;padding:10px;border-radius:4px;overflow-x:auto;margin:1em 0",code:"background:#f0f0f0;padding:2px 4px;border-radius:3px;font-family:monospace",blockquote:"border-left:4px solid #ddd;margin-left:0;padding-left:1em",table:"border-collapse:collapse;width:100%;margin:1em 0",th:"border:1px solid #ddd;padding:8px;background-color:#f2f2f2;font-weight:bold;text-align:left",td:"border:1px solid #ddd;padding:8px;text-align:left",hr:"border:none;border-top:1px solid #ddd;margin:1em 0",img:"max-width:100%;height:auto",a:"color:#06c;text-decoration:underline",strong:"font-weight:bold",em:"font-style:italic",del:"text-decoration:line-through",ul:"margin:.5em 0;padding-left:2em",ol:"margin:.5em 0;padding-left:2em",li:"margin:.25em 0","task-item":"list-style:none","task-checkbox":"margin-right:.5em"});let c=e;const s=[],d=[];return c=c.replace(/^(```|~~~)([^\n]*)\n([\s\S]*?)^\1$/gm,(e,n,r,o)=>{const a=`§CB${s.length}§`;return s.push({fence:n,lang:r.trim(),code:t(o.trimEnd()),original:e}),a}),c=c.replace(/`([^`]+)`/g,(e,n)=>{const r=`§IC${d.length}§`;return d.push({code:t(n),original:e}),r}),c=t(c),c=c.replace(/^(#{1,6})\s+(.+?)\s*#*$/gm,(e,t,n)=>{const r=t.length;return`<h${r}${l("h"+r,"",t)}>${n}</h${r}>`}),c=c.replace(/\*\*(.+?)\*\*/g,`<strong${l("strong","","**")}>$1</strong>`),c=c.replace(/__(.+?)__/g,`<strong${l("strong","","__")}>$1</strong>`),c=c.replace(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,`<em${l("em","","*")}>$1</em>`),c=c.replace(/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g,`<em${l("em","","_")}>$1</em>`),c=c.replace(/~~(.+?)~~/g,`<del${l("del","","~~")}>$1</del>`),c=c.replace(/^&gt;\s+(.+)$/gm,`<blockquote${l("blockquote","",">")}>$1</blockquote>`),c=c.replace(/<\/blockquote>\n<blockquote[^>]*>/g,"\n"),c=c.replace(/^---+$/gm,`<hr${l("hr","","---")}>`),c=function(e,t){const n=e.split("\n"),r=[];let o=[];for(let e=0;e<n.length;e++){const a=n[e],i=a.match(/^(\s*)([*\-+]|\d+\.)\s+(.+)$/);if(i){const[,e,n,a]=i,l=Math.floor(e.length/2),c=/^\d+\./.test(n),s=c?"ol":"ul",d=c?"1.":n;let u=a,g="";const p=a.match(/^\[([x ])\]\s+(.*)$/i);if(p&&!c){const[,e,n]=p,r="x"===e.toLowerCase();u=`<input type="checkbox"${t("task-checkbox","","[")}${r?" checked":""}> ${n}`,g=t("task-item","","- [ ]")}for(;o.length>l+1;){const e=o.pop();r.push(`</${e.type}>`)}o.length===l&&(o.push({type:s,level:l,marker:d}),r.push(`<${s}${t(s,"",d)}>`));const f=g||t("li","",d);r.push(`<li${f}>${u}</li>`)}else{for(;o.length>0;){const e=o.pop();r.push(`</${e.type}>`)}r.push(a)}}for(;o.length>0;){const e=o.pop();r.push(`</${e.type}>`)}return r.join("\n")}(c,l),c=c.replace(/!\[([^\]]*)\]\(([^)]+)\)/g,(e,n,r)=>`<img${l("img","","!")} src="${r}" alt="${n}" data-qd-alt="${t(n)}" data-qd-src="${t(r)}">`),c=c.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(e,n,r)=>`<a${l("a","","[")} href="${r}" data-qd-text="${t(n)}">${n}</a>`),c=function(e,t){const n=e.split("\n"),o=[];let a=!1,i=[];for(let e=0;e<n.length;e++){const l=n[e].trim();if(l.includes("|"))a||(a=!0,i=[]),i.push(l);else{if(a){const e=r(i,t);e?o.push(e):o.push(...i),a=!1,i=[]}o.push(n[e])}}if(a&&i.length>0){const e=r(i,t);e?o.push(e):o.push(...i)}return o.join("\n")}(c,l),c=c.replace(/ $/gm,'<br data-qd=" ">'),c=c.replace(/\n\n+/g,"</p><p>"),c="<p>"+c+"</p>",c=c.replace(/<p><\/p>/g,""),c=c.replace(/<p>(<h[1-6][^>]*>)/g,"$1"),c=c.replace(/(<\/h[1-6]>)<\/p>/g,"$1"),c=c.replace(/<p>(<blockquote[^>]*>)/g,"$1"),c=c.replace(/(<\/blockquote>)<\/p>/g,"$1"),c=c.replace(/<p>(<ul[^>]*>|<ol[^>]*>)/g,"$1"),c=c.replace(/(<\/ul>|<\/ol>)<\/p>/g,"$1"),c=c.replace(/<p>(<hr[^>]*>)<\/p>/g,"$1"),c=c.replace(/<p>(<table[^>]*>)/g,"$1"),c=c.replace(/(<\/table>)<\/p>/g,"$1"),s.forEach((e,t)=>{const n=`§CB${t}§`;let r;o&&"function"==typeof o?(r=o(e.code,e.lang),void 0===r&&(r=`<pre${l("pre","",e.fence)}><code data-qd-lang="${e.lang}">${e.code}</code></pre>`)):r=`<pre${l("pre","",e.fence)} data-qd-fence="${e.fence}" data-qd-lang="${e.lang}"><code>${e.code}</code></pre>`,c=c.replace(n,r)}),d.forEach((e,t)=>{const n=`§IC${t}§`;c=c.replace(n,`<code${l("code","","`")}>${e.code}</code>`)}),c.trim()}function r(e,n){if(e.length<2)return null;let r=-1,o=[];for(let t=1;t<e.length;t++)if(/^\|?[\s\-:|]+\|?$/.test(e[t])&&e[t].includes("-")){r=t;const n=e[t].replace(/^\|/,"").replace(/\|$/,"").split("|");o=n.map(e=>{const t=e.trim();return t.startsWith(":")&&t.endsWith(":")?"center":t.endsWith(":")?"right":"left"});break}if(-1===r)return null;let a=`<table${n("table","","|")} data-qd-align="${o.join(",")}">\n`;if(r>0){a+=`<thead${n("thead","","|")}>\n<tr${n("tr","","|")}>\n`;e[0].replace(/^\|/,"").replace(/\|$/,"").split("|").forEach((e,r)=>{const i=o[r]&&"left"!==o[r]?`text-align:${o[r]}`:"";a+=`<th${n("th",i,"|")} data-qd-align="${o[r]||"left"}">${t(e.trim())}</th>\n`}),a+="</tr>\n</thead>\n"}const i=e.slice(r+1);return i.length>0&&(a+=`<tbody${n("tbody","","|")}>\n`,i.forEach(e=>{a+=`<tr${n("tr","","|")}>\n`;e.replace(/^\|/,"").replace(/\|$/,"").split("|").forEach((e,r)=>{const i=o[r]&&"left"!==o[r]?`text-align:${o[r]}`:"";a+=`<td${n("td",i,"|")} data-qd-align="${o[r]||"left"}">${t(e.trim())}</td>\n`}),a+="</tr>\n"}),a+="</tbody>\n"),a+="</table>",a}return n.toMarkdown=function(e){let t;if("string"==typeof e)t=document.createElement("div"),t.innerHTML=e;else{if(!(e instanceof Element))return"";t=e}function n(e,t={}){if(e.nodeType===Node.TEXT_NODE)return e.textContent;if(e.nodeType!==Node.ELEMENT_NODE)return"";const o=e.tagName.toLowerCase(),a=e.getAttribute("data-qd"),i=window.getComputedStyle?window.getComputedStyle(e):{};let l="";for(let r of e.childNodes)l+=n(r,{parentTag:o,...t});switch(o){case"h1":case"h2":case"h3":case"h4":case"h5":case"h6":const n=parseInt(o[1]);return`${a||"#".repeat(n)} ${l.trim()}\n\n`;case"strong":case"b":if("bold"===i.fontWeight||i.fontWeight>=700||"strong"===o||"b"===o){const e=a||"**";return`${e}${l}${e}`}return l;case"em":case"i":if("italic"===i.fontStyle||"em"===o||"i"===o){const e=a||"*";return`${e}${l}${e}`}return l;case"del":case"s":case"strike":const c=a||"~~";return`${c}${l}${c}`;case"code":if("pre"===t.parentTag)return l;const s=a||"`";return`${s}${l}${s}`;case"pre":const d=e.getAttribute("data-qd-fence")||a||"```",u=e.getAttribute("data-qd-lang")||"",g=e.querySelector("code");return`${d}${u}\n${(g?g.textContent:l).trimEnd()}\n${d}\n\n`;case"blockquote":const p=a||">";return l.trim().split("\n").map(e=>`${p} ${e}`).join("\n")+"\n\n";case"hr":return`${a||"---"}\n\n`;case"br":return`${a||" "}\n`;case"a":const f=e.getAttribute("data-qd-text")||l.trim(),$=e.getAttribute("href")||"";return f!==$||a?`[${f}](${$})`:`<${$}>`;case"img":return`${a||"!"}[${e.getAttribute("data-qd-alt")||e.getAttribute("alt")||""}](${e.getAttribute("data-qd-src")||e.getAttribute("src")||""})`;case"ul":case"ol":return r(e,"ol"===o)+"\n";case"li":case"span":default:return l;case"table":return function(e){let t="";const n=e.getAttribute("data-qd-align"),r=n?n.split(","):[],o=e.querySelector("thead");if(o){const e=o.querySelector("tr");if(e){const n=[];for(let t of e.querySelectorAll("th"))n.push(t.textContent.trim());t+="| "+n.join(" | ")+" |\n";t+="| "+n.map((e,t)=>{const n=r[t]||th.getAttribute("data-qd-align")||"left";return"center"===n?":---:":"right"===n?"---:":"---"}).join(" | ")+" |\n"}}const a=e.querySelector("tbody");if(a)for(let e of a.querySelectorAll("tr")){const n=[];for(let t of e.querySelectorAll("td"))n.push(t.textContent.trim());n.length>0&&(t+="| "+n.join(" | ")+" |\n")}return t.trim()}(e)+"\n\n";case"p":return l.trim()?l.trim()+"\n\n":"";case"div":if(e.classList&&e.classList.contains("mermaid-container")){const t=e.getAttribute("data-qd-fence")||"```",n=e.getAttribute("data-qd-lang")||"mermaid",r=e.querySelector(".mermaid-source");if(r){const e=document.createElement("div");e.innerHTML=r.innerHTML;return`${t}${n}\n${e.textContent}\n${t}\n\n`}const o=e.querySelector(".mermaid");if(o&&o.textContent.includes("graph"))return`${t}${n}\n${o.textContent.trim()}\n${t}\n\n`}if(e.classList&&e.classList.contains("mermaid")){const t=e.getAttribute("data-qd-fence")||"```";return`${t}${e.getAttribute("data-qd-lang")||"mermaid"}\n${e.textContent.trim()}\n${t}\n\n`}return l}}function r(e,t,o=0){let a="",i=1;const l=" ".repeat(o);for(let c of e.children){if("LI"!==c.tagName)continue;let e=c.getAttribute("data-qd")||(t?`${i}.`:"-");const s=c.querySelector('input[type="checkbox"]');if(s){const t=s.checked?"x":" ";e="-";let r="";for(let e of c.childNodes)e.nodeType===Node.TEXT_NODE?r+=e.textContent:e.tagName&&"INPUT"!==e.tagName&&(r+=n(e));a+=`${l}${e} [${t}] ${r.trim()}\n`}else{let t="";for(let e of c.childNodes)"UL"===e.tagName||"OL"===e.tagName?t+=r(e,"OL"===e.tagName,o+1):t+=n(e);a+=`${l}${e} ${t.trim()}\n`}i++}return a}let o=n(t);return o=o.replace(/\n{3,}/g,"\n\n"),o=o.trim(),o},n.emitStyles=function(e="quikdown-",t="light"){return""},n.configure=function(e){return function(t){return n(t,e)}},n.version="1.0.4","undefined"!=typeof module&&module.exports&&(module.exports=n),"undefined"!=typeof window&&(window.quikdown_bd=n),n});
8
+ //# sourceMappingURL=quikdown_bd.umd.min.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quikdown_bd.umd.min.js","sources":["../src/quikdown_bd.js"],"sourcesContent":["/**\n * quikdown_bd - Bidirectional markdown/HTML converter\n * Standalone version with round-trip conversion support\n * \n * Uses data-qd attributes to preserve original markdown syntax\n * Enables HTML→Markdown conversion for quikdown-generated HTML\n */\n\n// Version - uses same version as core quikdown\nconst VERSION = '__QUIKDOWN_VERSION__';\n\n// Helper to escape HTML (same as core)\nconst ESC_MAP = {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'};\nfunction escapeHtml(text) {\n return text.replace(/[&<>\"']/g, m => ESC_MAP[m]);\n}\n\n// Modified getAttr that adds data-qd attributes\nfunction createGetAttrBD(inline_styles, styles) {\n return function(tag, additionalStyle = '', sourceMarker = '') {\n let attrs = '';\n \n // Add data-qd attribute if source marker provided\n if (sourceMarker) {\n attrs += ` data-qd=\"${escapeHtml(sourceMarker)}\"`;\n }\n \n // Add style or class\n if (inline_styles) {\n const style = styles[tag];\n if (style || additionalStyle) {\n const fullStyle = additionalStyle ? (style ? `${style};${additionalStyle}` : additionalStyle) : style;\n attrs += ` style=\"${fullStyle}\"`;\n }\n } else {\n attrs += ` class=\"quikdown-${tag}\"`;\n }\n \n return attrs;\n };\n}\n\n/**\n * Enhanced markdown parser with bidirectional support\n * Wraps the core parser and adds data-qd attributes\n */\nfunction quikdown_bd(markdown, options = {}) {\n if (!markdown || typeof markdown !== 'string') {\n return '';\n }\n \n const { fence_plugin, inline_styles = false, bidirectional = true } = options;\n \n // If not bidirectional mode, process without data-qd attributes\n if (!bidirectional) {\n // Process without bidirectional tracking\n options.bidirectional = false;\n }\n \n // For bidirectional, we need to manually process with source tracking\n // This is a custom implementation that adds data-qd attributes\n \n const QUIKDOWN_STYLES = {\n h1: 'font-size:2em;font-weight:600;margin:.67em 0;text-align:left',\n h2: 'font-size:1.5em;font-weight:600;margin:.83em 0',\n h3: 'font-size:1.25em;font-weight:600;margin:1em 0',\n h4: 'font-size:1em;font-weight:600;margin:1.33em 0',\n h5: 'font-size:.875em;font-weight:600;margin:1.67em 0',\n h6: 'font-size:.85em;font-weight:600;margin:2em 0',\n pre: 'background:#f4f4f4;padding:10px;border-radius:4px;overflow-x:auto;margin:1em 0',\n code: 'background:#f0f0f0;padding:2px 4px;border-radius:3px;font-family:monospace',\n blockquote: 'border-left:4px solid #ddd;margin-left:0;padding-left:1em',\n table: 'border-collapse:collapse;width:100%;margin:1em 0',\n th: 'border:1px solid #ddd;padding:8px;background-color:#f2f2f2;font-weight:bold;text-align:left',\n td: 'border:1px solid #ddd;padding:8px;text-align:left',\n hr: 'border:none;border-top:1px solid #ddd;margin:1em 0',\n img: 'max-width:100%;height:auto',\n a: 'color:#06c;text-decoration:underline',\n strong: 'font-weight:bold',\n em: 'font-style:italic',\n del: 'text-decoration:line-through',\n ul: 'margin:.5em 0;padding-left:2em',\n ol: 'margin:.5em 0;padding-left:2em',\n li: 'margin:.25em 0',\n 'task-item': 'list-style:none',\n 'task-checkbox': 'margin-right:.5em'\n };\n \n const getAttr = createGetAttrBD(inline_styles, QUIKDOWN_STYLES);\n \n // Process markdown with source tracking\n let html = markdown;\n \n // Phase 1: Extract and protect code blocks\n const codeBlocks = [];\n const inlineCodes = [];\n \n // Extract fenced code blocks\n html = html.replace(/^(```|~~~)([^\\n]*)\\n([\\s\\S]*?)^\\1$/gm, (match, fence, lang, code) => {\n const placeholder = `§CB${codeBlocks.length}§`;\n codeBlocks.push({\n fence,\n lang: lang.trim(),\n code: escapeHtml(code.trimEnd()),\n original: match\n });\n return placeholder;\n });\n \n // Extract inline code\n html = html.replace(/`([^`]+)`/g, (match, code) => {\n const placeholder = `§IC${inlineCodes.length}§`;\n inlineCodes.push({\n code: escapeHtml(code),\n original: match\n });\n return placeholder;\n });\n \n // Escape HTML\n html = escapeHtml(html);\n \n // Process headings with source tracking\n html = html.replace(/^(#{1,6})\\s+(.+?)\\s*#*$/gm, (match, hashes, content) => {\n const level = hashes.length;\n const sourceMarker = hashes;\n return `<h${level}${getAttr('h' + level, '', sourceMarker)}>${content}</h${level}>`;\n });\n \n // Process bold/italic/strikethrough with source tracking\n html = html.replace(/\\*\\*(.+?)\\*\\*/g, `<strong${getAttr('strong', '', '**')}>$1</strong>`);\n html = html.replace(/__(.+?)__/g, `<strong${getAttr('strong', '', '__')}>$1</strong>`);\n html = html.replace(/(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)/g, `<em${getAttr('em', '', '*')}>$1</em>`);\n html = html.replace(/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g, `<em${getAttr('em', '', '_')}>$1</em>`);\n html = html.replace(/~~(.+?)~~/g, `<del${getAttr('del', '', '~~')}>$1</del>`);\n \n // Process blockquotes\n html = html.replace(/^&gt;\\s+(.+)$/gm, `<blockquote${getAttr('blockquote', '', '>')}>$1</blockquote>`);\n html = html.replace(/<\\/blockquote>\\n<blockquote[^>]*>/g, '\\n');\n \n // Process horizontal rules\n html = html.replace(/^---+$/gm, `<hr${getAttr('hr', '', '---')}>`);\n \n // Process lists (simplified for now)\n html = processListsBD(html, getAttr, inline_styles);\n \n // Process links and images\n html = html.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, (match, alt, src) => {\n return `<img${getAttr('img', '', '!')} src=\"${src}\" alt=\"${alt}\" data-qd-alt=\"${escapeHtml(alt)}\" data-qd-src=\"${escapeHtml(src)}\">`;\n });\n \n html = html.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, (match, text, href) => {\n return `<a${getAttr('a', '', '[')} href=\"${href}\" data-qd-text=\"${escapeHtml(text)}\">${text}</a>`;\n });\n \n // Process tables\n html = processTablesBD(html, getAttr);\n \n // Line breaks\n html = html.replace(/ $/gm, '<br data-qd=\" \">');\n \n // Paragraphs\n html = html.replace(/\\n\\n+/g, '</p><p>');\n html = '<p>' + html + '</p>';\n \n // Clean up empty paragraphs and unwrap block elements\n html = html.replace(/<p><\\/p>/g, '');\n html = html.replace(/<p>(<h[1-6][^>]*>)/g, '$1');\n html = html.replace(/(<\\/h[1-6]>)<\\/p>/g, '$1');\n html = html.replace(/<p>(<blockquote[^>]*>)/g, '$1');\n html = html.replace(/(<\\/blockquote>)<\\/p>/g, '$1');\n html = html.replace(/<p>(<ul[^>]*>|<ol[^>]*>)/g, '$1');\n html = html.replace(/(<\\/ul>|<\\/ol>)<\\/p>/g, '$1');\n html = html.replace(/<p>(<hr[^>]*>)<\\/p>/g, '$1');\n html = html.replace(/<p>(<table[^>]*>)/g, '$1');\n html = html.replace(/(<\\/table>)<\\/p>/g, '$1');\n \n // Restore code blocks\n codeBlocks.forEach((block, i) => {\n const placeholder = `§CB${i}§`;\n let replacement;\n \n if (fence_plugin && typeof fence_plugin === 'function') {\n replacement = fence_plugin(block.code, block.lang);\n if (replacement === undefined) {\n replacement = `<pre${getAttr('pre', '', block.fence)}><code data-qd-lang=\"${block.lang}\">${block.code}</code></pre>`;\n }\n } else {\n replacement = `<pre${getAttr('pre', '', block.fence)} data-qd-fence=\"${block.fence}\" data-qd-lang=\"${block.lang}\"><code>${block.code}</code></pre>`;\n }\n \n html = html.replace(placeholder, replacement);\n });\n \n // Restore inline codes\n inlineCodes.forEach((item, i) => {\n const placeholder = `§IC${i}§`;\n html = html.replace(placeholder, `<code${getAttr('code', '', '`')}>${item.code}</code>`);\n });\n \n return html.trim();\n}\n\n// Process lists with source tracking\nfunction processListsBD(text, getAttr, inline_styles) {\n const lines = text.split('\\n');\n const result = [];\n let listStack = [];\n \n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const match = line.match(/^(\\s*)([*\\-+]|\\d+\\.)\\s+(.+)$/);\n \n if (match) {\n const [, indent, marker, content] = match;\n const level = Math.floor(indent.length / 2);\n const isOrdered = /^\\d+\\./.test(marker);\n const listType = isOrdered ? 'ol' : 'ul';\n const sourceMarker = isOrdered ? '1.' : marker;\n \n // Handle task lists\n let listItemContent = content;\n let taskAttrs = '';\n const taskMatch = content.match(/^\\[([x ])\\]\\s+(.*)$/i);\n if (taskMatch && !isOrdered) {\n const [, checked, taskContent] = taskMatch;\n const isChecked = checked.toLowerCase() === 'x';\n listItemContent = `<input type=\"checkbox\"${getAttr('task-checkbox', '', '[')}${isChecked ? ' checked' : ''}> ${taskContent}`;\n taskAttrs = getAttr('task-item', '', '- [ ]');\n }\n \n // Close deeper levels\n while (listStack.length > level + 1) {\n const list = listStack.pop();\n result.push(`</${list.type}>`);\n }\n \n // Open new level if needed\n if (listStack.length === level) {\n listStack.push({ type: listType, level, marker: sourceMarker });\n result.push(`<${listType}${getAttr(listType, '', sourceMarker)}>`);\n }\n \n const liAttr = taskAttrs || getAttr('li', '', sourceMarker);\n result.push(`<li${liAttr}>${listItemContent}</li>`);\n } else {\n // Close all lists\n while (listStack.length > 0) {\n const list = listStack.pop();\n result.push(`</${list.type}>`);\n }\n result.push(line);\n }\n }\n \n // Close remaining lists\n while (listStack.length > 0) {\n const list = listStack.pop();\n result.push(`</${list.type}>`);\n }\n \n return result.join('\\n');\n}\n\n// Process tables with source tracking\nfunction processTablesBD(text, getAttr) {\n const lines = text.split('\\n');\n const result = [];\n let inTable = false;\n let tableLines = [];\n \n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n \n if (line.includes('|')) {\n if (!inTable) {\n inTable = true;\n tableLines = [];\n }\n tableLines.push(line);\n } else {\n if (inTable) {\n const tableHtml = buildTableBD(tableLines, getAttr);\n if (tableHtml) {\n result.push(tableHtml);\n } else {\n result.push(...tableLines);\n }\n inTable = false;\n tableLines = [];\n }\n result.push(lines[i]);\n }\n }\n \n if (inTable && tableLines.length > 0) {\n const tableHtml = buildTableBD(tableLines, getAttr);\n if (tableHtml) {\n result.push(tableHtml);\n } else {\n result.push(...tableLines);\n }\n }\n \n return result.join('\\n');\n}\n\n// Build table with source tracking\nfunction buildTableBD(lines, getAttr) {\n if (lines.length < 2) return null;\n \n // Find separator\n let separatorIndex = -1;\n let alignments = [];\n \n for (let i = 1; i < lines.length; i++) {\n if (/^\\|?[\\s\\-:|]+\\|?$/.test(lines[i]) && lines[i].includes('-')) {\n separatorIndex = i;\n const cells = lines[i].replace(/^\\|/, '').replace(/\\|$/, '').split('|');\n alignments = cells.map(cell => {\n const trimmed = cell.trim();\n if (trimmed.startsWith(':') && trimmed.endsWith(':')) return 'center';\n if (trimmed.endsWith(':')) return 'right';\n return 'left';\n });\n break;\n }\n }\n \n if (separatorIndex === -1) return null;\n \n let html = `<table${getAttr('table', '', '|')} data-qd-align=\"${alignments.join(',')}\">\\n`;\n \n // Headers\n if (separatorIndex > 0) {\n html += `<thead${getAttr('thead', '', '|')}>\\n<tr${getAttr('tr', '', '|')}>\\n`;\n const cells = lines[0].replace(/^\\|/, '').replace(/\\|$/, '').split('|');\n cells.forEach((cell, i) => {\n const align = alignments[i] && alignments[i] !== 'left' ? `text-align:${alignments[i]}` : '';\n html += `<th${getAttr('th', align, '|')} data-qd-align=\"${alignments[i] || 'left'}\">${escapeHtml(cell.trim())}</th>\\n`;\n });\n html += '</tr>\\n</thead>\\n';\n }\n \n // Body\n const bodyLines = lines.slice(separatorIndex + 1);\n if (bodyLines.length > 0) {\n html += `<tbody${getAttr('tbody', '', '|')}>\\n`;\n bodyLines.forEach(line => {\n html += `<tr${getAttr('tr', '', '|')}>\\n`;\n const cells = line.replace(/^\\|/, '').replace(/\\|$/, '').split('|');\n cells.forEach((cell, i) => {\n const align = alignments[i] && alignments[i] !== 'left' ? `text-align:${alignments[i]}` : '';\n html += `<td${getAttr('td', align, '|')} data-qd-align=\"${alignments[i] || 'left'}\">${escapeHtml(cell.trim())}</td>\\n`;\n });\n html += '</tr>\\n';\n });\n html += '</tbody>\\n';\n }\n \n html += '</table>';\n return html;\n}\n\n/**\n * Convert HTML back to Markdown by walking the DOM tree\n * Uses data-qd attributes when available, falls back to canonical forms\n * Assumes browser environment with DOM API available\n */\nquikdown_bd.toMarkdown = function(htmlOrElement) {\n // Accept either HTML string or DOM element\n let container;\n if (typeof htmlOrElement === 'string') {\n container = document.createElement('div');\n container.innerHTML = htmlOrElement;\n } else if (htmlOrElement instanceof Element) {\n container = htmlOrElement;\n } else {\n return '';\n }\n \n // Walk the DOM tree and reconstruct markdown\n function walkNode(node, parentContext = {}) {\n if (node.nodeType === Node.TEXT_NODE) {\n // Return text content, preserving whitespace where needed\n return node.textContent;\n }\n \n if (node.nodeType !== Node.ELEMENT_NODE) {\n return '';\n }\n \n const tag = node.tagName.toLowerCase();\n const dataQd = node.getAttribute('data-qd');\n const styles = window.getComputedStyle ? window.getComputedStyle(node) : {};\n \n // Process children with context\n let childContent = '';\n for (let child of node.childNodes) {\n childContent += walkNode(child, { parentTag: tag, ...parentContext });\n }\n \n // Determine markdown based on element and attributes\n switch (tag) {\n case 'h1':\n case 'h2':\n case 'h3':\n case 'h4':\n case 'h5':\n case 'h6':\n const level = parseInt(tag[1]);\n const prefix = dataQd || '#'.repeat(level);\n return `${prefix} ${childContent.trim()}\\n\\n`;\n \n case 'strong':\n case 'b':\n // Check if it's bold through style too\n if (styles.fontWeight === 'bold' || styles.fontWeight >= 700 || tag === 'strong' || tag === 'b') {\n const boldMarker = dataQd || '**';\n return `${boldMarker}${childContent}${boldMarker}`;\n }\n return childContent;\n \n case 'em':\n case 'i':\n // Check for italic through style\n if (styles.fontStyle === 'italic' || tag === 'em' || tag === 'i') {\n const emMarker = dataQd || '*';\n return `${emMarker}${childContent}${emMarker}`;\n }\n return childContent;\n \n case 'del':\n case 's':\n case 'strike':\n const delMarker = dataQd || '~~';\n return `${delMarker}${childContent}${delMarker}`;\n \n case 'code':\n // Skip if inside pre (handled by pre)\n if (parentContext.parentTag === 'pre') {\n return childContent;\n }\n const codeMarker = dataQd || '`';\n return `${codeMarker}${childContent}${codeMarker}`;\n \n case 'pre':\n const fence = node.getAttribute('data-qd-fence') || dataQd || '```';\n const lang = node.getAttribute('data-qd-lang') || '';\n // Look for code element child\n const codeEl = node.querySelector('code');\n const codeContent = codeEl ? codeEl.textContent : childContent;\n return `${fence}${lang}\\n${codeContent.trimEnd()}\\n${fence}\\n\\n`;\n \n case 'blockquote':\n const quoteMarker = dataQd || '>';\n const lines = childContent.trim().split('\\n');\n return lines.map(line => `${quoteMarker} ${line}`).join('\\n') + '\\n\\n';\n \n case 'hr':\n const hrMarker = dataQd || '---';\n return `${hrMarker}\\n\\n`;\n \n case 'br':\n const brMarker = dataQd || ' ';\n return `${brMarker}\\n`;\n \n case 'a':\n const linkText = node.getAttribute('data-qd-text') || childContent.trim();\n const href = node.getAttribute('href') || '';\n // Check for autolinks\n if (linkText === href && !dataQd) {\n return `<${href}>`;\n }\n return `[${linkText}](${href})`;\n \n case 'img':\n const alt = node.getAttribute('data-qd-alt') || node.getAttribute('alt') || '';\n const src = node.getAttribute('data-qd-src') || node.getAttribute('src') || '';\n const imgMarker = dataQd || '!';\n return `${imgMarker}[${alt}](${src})`;\n \n case 'ul':\n case 'ol':\n return walkList(node, tag === 'ol') + '\\n';\n \n case 'li':\n // Handled by list processor\n return childContent;\n \n case 'table':\n return walkTable(node) + '\\n\\n';\n \n case 'p':\n // Check if it's actually a paragraph or just a wrapper\n if (childContent.trim()) {\n return childContent.trim() + '\\n\\n';\n }\n return '';\n \n case 'div':\n // Check if it's a mermaid container\n if (node.classList && node.classList.contains('mermaid-container')) {\n const fence = node.getAttribute('data-qd-fence') || '```';\n const lang = node.getAttribute('data-qd-lang') || 'mermaid';\n // Look for the source element\n const sourceElement = node.querySelector('.mermaid-source');\n if (sourceElement) {\n // Decode HTML entities\n const temp = document.createElement('div');\n temp.innerHTML = sourceElement.innerHTML;\n const code = temp.textContent;\n return `${fence}${lang}\\n${code}\\n${fence}\\n\\n`;\n }\n // Fallback: try to extract from the mermaid element\n const mermaidElement = node.querySelector('.mermaid');\n if (mermaidElement && mermaidElement.textContent.includes('graph')) {\n return `${fence}${lang}\\n${mermaidElement.textContent.trim()}\\n${fence}\\n\\n`;\n }\n }\n // Check if it's a standalone mermaid diagram (legacy)\n if (node.classList && node.classList.contains('mermaid')) {\n const fence = node.getAttribute('data-qd-fence') || '```';\n const lang = node.getAttribute('data-qd-lang') || 'mermaid';\n const code = node.textContent.trim();\n return `${fence}${lang}\\n${code}\\n${fence}\\n\\n`;\n }\n // Pass through other divs\n return childContent;\n \n case 'span':\n // Pass through container elements\n return childContent;\n \n default:\n return childContent;\n }\n }\n \n // Walk list elements\n function walkList(listNode, isOrdered, depth = 0) {\n let result = '';\n let index = 1;\n const indent = ' '.repeat(depth);\n \n for (let child of listNode.children) {\n if (child.tagName !== 'LI') continue;\n \n const dataQd = child.getAttribute('data-qd');\n let marker = dataQd || (isOrdered ? `${index}.` : '-');\n \n // Check for task list checkbox\n const checkbox = child.querySelector('input[type=\"checkbox\"]');\n if (checkbox) {\n const checked = checkbox.checked ? 'x' : ' ';\n marker = '-';\n // Get text without the checkbox\n let text = '';\n for (let node of child.childNodes) {\n if (node.nodeType === Node.TEXT_NODE) {\n text += node.textContent;\n } else if (node.tagName && node.tagName !== 'INPUT') {\n text += walkNode(node);\n }\n }\n result += `${indent}${marker} [${checked}] ${text.trim()}\\n`;\n } else {\n // Check for nested lists\n let hasNestedList = false;\n let itemContent = '';\n \n for (let node of child.childNodes) {\n if (node.tagName === 'UL' || node.tagName === 'OL') {\n hasNestedList = true;\n itemContent += walkList(node, node.tagName === 'OL', depth + 1);\n } else {\n itemContent += walkNode(node);\n }\n }\n \n result += `${indent}${marker} ${itemContent.trim()}\\n`;\n }\n \n index++;\n }\n \n return result;\n }\n \n // Walk table elements\n function walkTable(table) {\n let result = '';\n const alignData = table.getAttribute('data-qd-align');\n const alignments = alignData ? alignData.split(',') : [];\n \n // Process header\n const thead = table.querySelector('thead');\n if (thead) {\n const headerRow = thead.querySelector('tr');\n if (headerRow) {\n const headers = [];\n for (let th of headerRow.querySelectorAll('th')) {\n headers.push(th.textContent.trim());\n }\n result += '| ' + headers.join(' | ') + ' |\\n';\n \n // Add separator with alignment\n const separators = headers.map((_, i) => {\n const align = alignments[i] || th.getAttribute('data-qd-align') || 'left';\n if (align === 'center') return ':---:';\n if (align === 'right') return '---:';\n return '---';\n });\n result += '| ' + separators.join(' | ') + ' |\\n';\n }\n }\n \n // Process body\n const tbody = table.querySelector('tbody');\n if (tbody) {\n for (let row of tbody.querySelectorAll('tr')) {\n const cells = [];\n for (let td of row.querySelectorAll('td')) {\n cells.push(td.textContent.trim());\n }\n if (cells.length > 0) {\n result += '| ' + cells.join(' | ') + ' |\\n';\n }\n }\n }\n \n return result.trim();\n }\n \n // Process the DOM tree\n let markdown = walkNode(container);\n \n // Clean up\n markdown = markdown.replace(/\\n{3,}/g, '\\n\\n'); // Remove excessive newlines\n markdown = markdown.trim();\n \n return markdown;\n};\n\n// Add emitStyles method (same as core)\nquikdown_bd.emitStyles = function(prefix = 'quikdown-', theme = 'light') {\n // This would generate CSS based on the styles\n // For now, returning empty string as placeholder\n // In production, this would generate the full CSS\n return '';\n};\n\n// Configure method\nquikdown_bd.configure = function(options) {\n return function(markdown) {\n return quikdown_bd(markdown, options);\n };\n};\n\n// Version property\nquikdown_bd.version = VERSION;\n\n// Export for both module and browser\nif (typeof module !== 'undefined' && module.exports) {\n module.exports = quikdown_bd;\n}\n\nif (typeof window !== 'undefined') {\n window.quikdown_bd = quikdown_bd;\n}\n\nexport default quikdown_bd;"],"names":["ESC_MAP","escapeHtml","text","replace","m","quikdown_bd","markdown","options","fence_plugin","inline_styles","bidirectional","getAttr","styles","tag","additionalStyle","sourceMarker","attrs","style","createGetAttrBD","h1","h2","h3","h4","h5","h6","pre","code","blockquote","table","th","td","hr","img","a","strong","em","del","ul","ol","li","html","codeBlocks","inlineCodes","match","fence","lang","placeholder","length","push","trim","trimEnd","original","hashes","content","level","lines","split","result","listStack","i","line","indent","marker","Math","floor","isOrdered","test","listType","listItemContent","taskAttrs","taskMatch","checked","taskContent","isChecked","toLowerCase","list","pop","type","liAttr","join","processListsBD","alt","src","href","inTable","tableLines","includes","tableHtml","buildTableBD","processTablesBD","forEach","block","replacement","undefined","item","separatorIndex","alignments","cells","map","cell","trimmed","startsWith","endsWith","align","bodyLines","slice","toMarkdown","htmlOrElement","container","document","createElement","innerHTML","Element","walkNode","node","parentContext","nodeType","Node","TEXT_NODE","textContent","ELEMENT_NODE","tagName","dataQd","getAttribute","window","getComputedStyle","childContent","child","childNodes","parentTag","parseInt","repeat","fontWeight","boldMarker","fontStyle","emMarker","delMarker","codeMarker","codeEl","querySelector","quoteMarker","linkText","walkList","alignData","thead","headerRow","headers","querySelectorAll","_","tbody","row","walkTable","classList","contains","sourceElement","temp","mermaidElement","listNode","depth","index","children","checkbox","itemContent","emitStyles","prefix","theme","configure","version","module","exports"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quikdown",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "quikdown is a simple markdown to HTML parser that supports fences",
5
5
  "author": "deftio (https://github.com/deftio",
6
6
  "license": "BSD-2-Clause",
@@ -17,6 +17,21 @@
17
17
  "unpkg": "dist/quikdown.umd.min.js",
18
18
  "browser": "dist/quikdown.umd.min.js",
19
19
  "types": "dist/quikdown.d.ts",
20
+ "exports": {
21
+ ".": {
22
+ "import": "./dist/quikdown.esm.js",
23
+ "require": "./dist/quikdown.cjs",
24
+ "browser": "./dist/quikdown.umd.min.js",
25
+ "types": "./dist/quikdown.d.ts"
26
+ },
27
+ "./bd": {
28
+ "import": "./dist/quikdown_bd.esm.js",
29
+ "require": "./dist/quikdown_bd.cjs",
30
+ "browser": "./dist/quikdown_bd.umd.min.js",
31
+ "types": "./dist/quikdown_bd.d.ts"
32
+ },
33
+ "./package.json": "./package.json"
34
+ },
20
35
  "files": [
21
36
  "dist"
22
37
  ],
@@ -25,7 +40,7 @@
25
40
  "examples": "examples"
26
41
  },
27
42
  "scripts": {
28
- "test": "jest --coverage",
43
+ "test": "NODE_NO_WARNINGS=1 jest --coverage",
29
44
  "test:quikdown": "jest tests/quikdown.test.js",
30
45
  "test:unit": "jest --coverage",
31
46
  "test:e2e": "npx playwright test --config=playwright.config.cjs",
@@ -40,7 +55,14 @@
40
55
  "buildDocs": "node ./tools/buildDocs.js",
41
56
  "docs:api": "npx jsdoc src/quikchat.js -d docs/api",
42
57
  "updateExampleCopies": "cp dist/quikchat.umd.min.js examples/fastapi_llm/static && cp dist/quikchat.min.css examples/fastapi_llm/static && cp dist/quikchat.umd.min.js examples/npm_express/static && cp dist/quikchat.min.css examples/npm_express/static",
43
- "build": "npm run updateVersion && rollup -c"
58
+ "build": "npm run updateVersion && rollup -c && npm run css",
59
+ "build:all": "npm run build && npm run buildDocs",
60
+ "build:lex": "rollup -c rollup.config.lex.js",
61
+ "build:css": "node tools/generateThemeCSS.js",
62
+ "build:docs": "node ./tools/buildDocs.js",
63
+ "minify:css": "node tools/minifyThemeCSS.js",
64
+ "css": "npm run build:css && npm run minify:css",
65
+ "test:perf": "node tests/performance-benchmark.js"
44
66
  },
45
67
  "jest": {
46
68
  "testEnvironment": "jsdom",
@@ -49,7 +71,7 @@
49
71
  },
50
72
  "collectCoverage": true,
51
73
  "collectCoverageFrom": [
52
- "src/quikdown.js"
74
+ "dist/quikdown.esm.js"
53
75
  ],
54
76
  "coverageDirectory": "coverage",
55
77
  "coverageReporters": [
@@ -106,6 +128,7 @@
106
128
  "docbat": "^0.9.3",
107
129
  "jest": "^29.7.0",
108
130
  "jest-environment-jsdom": "^29.7.0",
131
+ "jsdom": "^26.1.0",
109
132
  "marked": "^16.1.2",
110
133
  "playwright": "^1.54.2",
111
134
  "rollup": "^4.18.1",