quikdown 1.2.9 → 1.2.11
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.
- package/README.md +5 -5
- package/dist/quikdown.cjs +104 -5
- package/dist/quikdown.d.ts +12 -0
- package/dist/quikdown.dark.css +1 -1
- package/dist/quikdown.esm.js +104 -5
- package/dist/quikdown.esm.min.js +2 -2
- package/dist/quikdown.esm.min.js.gz +0 -0
- package/dist/quikdown.esm.min.js.map +1 -1
- package/dist/quikdown.light.css +1 -1
- package/dist/quikdown.umd.js +104 -5
- package/dist/quikdown.umd.min.js +2 -2
- package/dist/quikdown.umd.min.js.gz +0 -0
- package/dist/quikdown.umd.min.js.map +1 -1
- package/dist/quikdown_ast.cjs +16 -28
- package/dist/quikdown_ast.esm.js +16 -28
- package/dist/quikdown_ast.esm.min.js +2 -2
- package/dist/quikdown_ast.esm.min.js.gz +0 -0
- package/dist/quikdown_ast.esm.min.js.map +1 -1
- package/dist/quikdown_ast.umd.js +16 -28
- package/dist/quikdown_ast.umd.min.js +2 -2
- package/dist/quikdown_ast.umd.min.js.gz +0 -0
- package/dist/quikdown_ast.umd.min.js.map +1 -1
- package/dist/quikdown_ast_html.cjs +17 -29
- package/dist/quikdown_ast_html.esm.js +17 -29
- package/dist/quikdown_ast_html.esm.min.js +2 -2
- package/dist/quikdown_ast_html.esm.min.js.gz +0 -0
- package/dist/quikdown_ast_html.esm.min.js.map +1 -1
- package/dist/quikdown_ast_html.umd.js +17 -29
- package/dist/quikdown_ast_html.umd.min.js +2 -2
- package/dist/quikdown_ast_html.umd.min.js.gz +0 -0
- package/dist/quikdown_ast_html.umd.min.js.map +1 -1
- package/dist/quikdown_bd.cjs +104 -5
- package/dist/quikdown_bd.esm.js +104 -5
- package/dist/quikdown_bd.esm.min.js +2 -2
- package/dist/quikdown_bd.esm.min.js.gz +0 -0
- package/dist/quikdown_bd.esm.min.js.map +1 -1
- package/dist/quikdown_bd.umd.js +104 -5
- package/dist/quikdown_bd.umd.min.js +2 -2
- package/dist/quikdown_bd.umd.min.js.gz +0 -0
- package/dist/quikdown_bd.umd.min.js.map +1 -1
- package/dist/quikdown_edit.cjs +244 -12
- package/dist/quikdown_edit.esm.js +244 -12
- package/dist/quikdown_edit.esm.min.js +3 -3
- package/dist/quikdown_edit.esm.min.js.gz +0 -0
- package/dist/quikdown_edit.esm.min.js.map +1 -1
- package/dist/quikdown_edit.umd.js +244 -12
- package/dist/quikdown_edit.umd.min.js +3 -3
- package/dist/quikdown_edit.umd.min.js.gz +0 -0
- package/dist/quikdown_edit.umd.min.js.map +1 -1
- package/dist/quikdown_json.cjs +17 -29
- package/dist/quikdown_json.esm.js +17 -29
- package/dist/quikdown_json.esm.min.js +2 -2
- package/dist/quikdown_json.esm.min.js.gz +0 -0
- package/dist/quikdown_json.esm.min.js.map +1 -1
- package/dist/quikdown_json.umd.js +17 -29
- package/dist/quikdown_json.umd.min.js +2 -2
- package/dist/quikdown_json.umd.min.js.gz +0 -0
- package/dist/quikdown_json.umd.min.js.map +1 -1
- package/dist/quikdown_yaml.cjs +17 -29
- package/dist/quikdown_yaml.esm.js +17 -29
- package/dist/quikdown_yaml.esm.min.js +2 -2
- package/dist/quikdown_yaml.esm.min.js.gz +0 -0
- package/dist/quikdown_yaml.esm.min.js.map +1 -1
- package/dist/quikdown_yaml.umd.js +17 -29
- package/dist/quikdown_yaml.umd.min.js +2 -2
- package/dist/quikdown_yaml.umd.min.js.gz +0 -0
- package/dist/quikdown_yaml.umd.min.js.map +1 -1
- package/package.json +10 -10
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* quikdown_ast_html - AST to HTML Markdown Parser
|
|
3
|
-
* @version 1.2.
|
|
3
|
+
* @version 1.2.11
|
|
4
4
|
* @license BSD-2-Clause
|
|
5
5
|
* @copyright DeftIO 2025
|
|
6
6
|
*/
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
// Version will be injected at build time
|
|
16
|
-
const quikdownVersion$1 = '1.2.
|
|
16
|
+
const quikdownVersion$1 = '1.2.11';
|
|
17
17
|
|
|
18
18
|
// Safety limit to prevent infinite loops in list parsing
|
|
19
19
|
const MAX_LOOP_ITERATIONS = 1000;
|
|
@@ -334,8 +334,6 @@ function parseInline(text, options) {
|
|
|
334
334
|
let remaining = text;
|
|
335
335
|
|
|
336
336
|
while (remaining.length > 0) {
|
|
337
|
-
let matched = false;
|
|
338
|
-
|
|
339
337
|
// Line break (1+ trailing spaces or explicit \n after processing)
|
|
340
338
|
// Handle inline line breaks (two spaces at end of line or backslash before newline)
|
|
341
339
|
const brMatch = remaining.match(/^(.+?)(?: {2}|\\\n|\n)/);
|
|
@@ -352,7 +350,6 @@ function parseInline(text, options) {
|
|
|
352
350
|
}
|
|
353
351
|
nodes.push({ type: 'br' });
|
|
354
352
|
remaining = afterText;
|
|
355
|
-
matched = true;
|
|
356
353
|
continue;
|
|
357
354
|
}
|
|
358
355
|
}
|
|
@@ -366,7 +363,6 @@ function parseInline(text, options) {
|
|
|
366
363
|
url: imgMatch[2].trim() // Forgiving: trim whitespace in URL
|
|
367
364
|
});
|
|
368
365
|
remaining = remaining.slice(imgMatch[0].length);
|
|
369
|
-
matched = true;
|
|
370
366
|
continue;
|
|
371
367
|
}
|
|
372
368
|
|
|
@@ -379,7 +375,6 @@ function parseInline(text, options) {
|
|
|
379
375
|
children: parseInlineContent(linkMatch[1])
|
|
380
376
|
});
|
|
381
377
|
remaining = remaining.slice(linkMatch[0].length);
|
|
382
|
-
matched = true;
|
|
383
378
|
continue;
|
|
384
379
|
}
|
|
385
380
|
|
|
@@ -391,7 +386,6 @@ function parseInline(text, options) {
|
|
|
391
386
|
value: codeMatch[1]
|
|
392
387
|
});
|
|
393
388
|
remaining = remaining.slice(codeMatch[0].length);
|
|
394
|
-
matched = true;
|
|
395
389
|
continue;
|
|
396
390
|
}
|
|
397
391
|
|
|
@@ -403,7 +397,6 @@ function parseInline(text, options) {
|
|
|
403
397
|
children: parseInlineContent(boldMatch[2])
|
|
404
398
|
});
|
|
405
399
|
remaining = remaining.slice(boldMatch[0].length);
|
|
406
|
-
matched = true;
|
|
407
400
|
continue;
|
|
408
401
|
}
|
|
409
402
|
|
|
@@ -415,7 +408,6 @@ function parseInline(text, options) {
|
|
|
415
408
|
children: parseInlineContent(strikeMatch[1])
|
|
416
409
|
});
|
|
417
410
|
remaining = remaining.slice(strikeMatch[0].length);
|
|
418
|
-
matched = true;
|
|
419
411
|
continue;
|
|
420
412
|
}
|
|
421
413
|
|
|
@@ -427,7 +419,6 @@ function parseInline(text, options) {
|
|
|
427
419
|
children: parseInlineContent(emMatch[2])
|
|
428
420
|
});
|
|
429
421
|
remaining = remaining.slice(emMatch[0].length);
|
|
430
|
-
matched = true;
|
|
431
422
|
continue;
|
|
432
423
|
}
|
|
433
424
|
|
|
@@ -440,27 +431,24 @@ function parseInline(text, options) {
|
|
|
440
431
|
children: [{ type: 'text', value: urlMatch[1] }]
|
|
441
432
|
});
|
|
442
433
|
remaining = remaining.slice(urlMatch[0].length);
|
|
443
|
-
matched = true;
|
|
444
434
|
continue;
|
|
445
435
|
}
|
|
446
436
|
|
|
447
437
|
// Plain text - consume until next potential inline element or end
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
remaining = remaining.slice(nextMarker);
|
|
463
|
-
}
|
|
438
|
+
// Find next potential inline marker
|
|
439
|
+
const nextMarker = remaining.search(/[`*_~![\\n]|https?:\/\//);
|
|
440
|
+
if (nextMarker === -1) {
|
|
441
|
+
// No more markers, consume rest as text
|
|
442
|
+
nodes.push({ type: 'text', value: remaining });
|
|
443
|
+
break;
|
|
444
|
+
} else if (nextMarker === 0) {
|
|
445
|
+
// Current char is a marker but didn't match - consume it as text
|
|
446
|
+
nodes.push({ type: 'text', value: remaining[0] });
|
|
447
|
+
remaining = remaining.slice(1);
|
|
448
|
+
} else {
|
|
449
|
+
// Consume text up to next marker
|
|
450
|
+
nodes.push({ type: 'text', value: remaining.slice(0, nextMarker) });
|
|
451
|
+
remaining = remaining.slice(nextMarker);
|
|
464
452
|
}
|
|
465
453
|
}
|
|
466
454
|
|
|
@@ -518,7 +506,7 @@ if (typeof window !== 'undefined') {
|
|
|
518
506
|
|
|
519
507
|
|
|
520
508
|
// Version will be injected at build time
|
|
521
|
-
const quikdownVersion = '1.2.
|
|
509
|
+
const quikdownVersion = '1.2.11';
|
|
522
510
|
|
|
523
511
|
// Constants
|
|
524
512
|
const CLASS_PREFIX = 'quikdown-';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* quikdown_ast_html - AST to HTML Markdown Parser
|
|
3
|
-
* @version 1.2.
|
|
3
|
+
* @version 1.2.11
|
|
4
4
|
* @license BSD-2-Clause
|
|
5
5
|
* @copyright DeftIO 2025
|
|
6
6
|
*/
|
|
7
|
-
function e(e,n={}){if(!e||"string"!=typeof e)return{type:"document",children:[]};return{type:"document",children:t(e.replace(/\r\n/g,"\n").replace(/\r/g,"\n"))}}function t(e,r){const c=[],l=e.split("\n");let o=0;for(;o<l.length;){const e=l[o];if(""===e.trim()){o++;continue}const r=e.match(/^(```|~~~)(.*)$/);if(r){const[,e,t]=r,n=t.trim(),i=[];for(o++;o<l.length;){if(l[o].match(/^(```|~~~)\s*$/)){o++;break}i.push(l[o]),o++}c.push({type:"code_block",lang:n||null,content:i.join("\n"),fence:e});continue}if(/^---+\s*$/.test(e)||/^\*\*\*+\s*$/.test(e)||/^___+\s*$/.test(e)){c.push({type:"hr"}),o++;continue}const a=e.match(/^(#{1,6})\s*(.+?)\s*#*$/);if(a){const[,e,t]=a;c.push({type:"heading",level:e.length,children:s(t)}),o++;continue}if(e.includes("|")){const e=n(l,o);if(e){c.push(e.node),o=e.nextIndex;continue}}if(e.match(/^>\s*/)){const e=[];for(;o<l.length&&l[o].match(/^>\s*/);)e.push(l[o].replace(/^>\s*/,"")),o++;c.push({type:"blockquote",children:t(e.join("\n"))});continue}if(e.match(/^(\s*)([*\-+]|\d+\.)\s+(.*)$/)){const e=i(l,o);c.push(e.node),o=e.nextIndex;continue}const u=[];for(;o<l.length;){const e=l[o];if(""===e.trim())break;if(/^(```|~~~)/.test(e))break;if(/^#{1,6}\s/.test(e))break;if(/^---+\s*$/.test(e)||/^\*\*\*+\s*$/.test(e)||/^___+\s*$/.test(e))break;if(/^>\s*/.test(e))break;if(/^(\s*)([*\-+]|\d+\.)\s+/.test(e))break;if(e.includes("|")&&o+1<l.length&&/^\|?[\s\-:|]+\|?$/.test(l[o+1]))break;u.push(e),o++}u.length>0&&c.push({type:"paragraph",children:s(u.join("\n"))})}return c}function n(e,t,n){if(t+1>=e.length)return null;const i=e[t],c=e[t+1];if(!/^\|?[\s\-:|]+\|?$/.test(c)||!c.includes("-"))return null;const l=r(i);if(0===l.length)return null;const o=r(c).map(e=>{const t=e.trim();return t.startsWith(":")&&t.endsWith(":")?"center":t.endsWith(":")?"right":"left"}),a=l.map(e=>s(e.trim())),u=[];let h=t+2;for(;h<e.length;){const t=e[h];if(!t.includes("|")||""===t.trim())break;const n=r(t);u.push(n.map(e=>s(e.trim()))),h++}return{node:{type:"table",headers:a,rows:u,alignments:o},nextIndex:h}}function r(e){let t=e.trim();return t.startsWith("|")&&(t=t.slice(1)),t.endsWith("|")&&(t=t.slice(0,-1)),t.split("|")}function i(e,t,n){const r=[];let c=t,l=0;const o=e[c].match(/^(\s*)([*\-+]|\d+\.)\s+(.*)$/),a=/^\d+\./.test(o[2]),u=o[1].length;for(;c<e.length&&l<1e3;){l++;const t=e[c].match(/^(\s*)([*\-+]|\d+\.)\s+(.*)$/);if(!t)break;const[,n,o,h]=t,d=n.length;if(d<u)break;const f=/^\d+\./.test(o);if(d===u&&f!==a)break;if(d>u){const t=[];let n=0;for(;c<e.length&&n<1e3;){n++;const r=e[c],i=r.match(/^(\s*)([*\-+]|\d+\.)\s+/);if(!i)break;if(i[1].length<u)break;if(i[1].length===u)break;t.push(r),c++}if(t.length>0&&r.length>0){const e=i(t,0),n=r[r.length-1];n.children?Array.isArray(n.children)||(n.children=[{type:"paragraph",children:n.children}]):n.children=[],n.children.push(e.node)}continue}const p={type:"list_item",checked:null,children:null},m=h.match(/^\[([x ])\]\s*(.*)$/i);m&&!a?(p.checked="x"===m[1].toLowerCase(),p.children=s(m[2])):p.children=s(h),r.push(p),c++}return{node:{type:"list",ordered:a,items:r},nextIndex:c}}function s(e,t){if(!e)return[];const n=[];let r=e;for(;r.length>0;){let e=!1;if(r.match(/^(.+?)(?: {2}|\\\n|\n)/)&&r.includes("\n")){const t=r.indexOf("\n"),i=r.slice(0,t),s=r.slice(t+1);if(i.endsWith(" ")||i.endsWith("\\")){const t=i.replace(/\\$/,"").replace(/ +$/,"");t&&n.push(...c(t)),n.push({type:"br"}),r=s,e=!0;continue}}const t=r.match(/^!\[([^\]]*)\]\(\s*([^)\s]+)\s*\)/);if(t){n.push({type:"image",alt:t[1],url:t[2].trim()}),r=r.slice(t[0].length),e=!0;continue}const i=r.match(/^\[([^\]]+)\]\(\s*([^)\s]+)\s*\)/);if(i){n.push({type:"link",url:i[2].trim(),children:c(i[1])}),r=r.slice(i[0].length),e=!0;continue}const s=r.match(/^`([^`]+)`/);if(s){n.push({type:"code",value:s[1]}),r=r.slice(s[0].length),e=!0;continue}const l=r.match(/^(\*\*|__)(.+?)\1/);if(l){n.push({type:"strong",children:c(l[2])}),r=r.slice(l[0].length),e=!0;continue}const o=r.match(/^~~(.+?)~~/);if(o){n.push({type:"del",children:c(o[1])}),r=r.slice(o[0].length),e=!0;continue}const a=r.match(/^(\*|_)(?!\1)(.+?)(?<!\1)\1(?!\1)/);if(a){n.push({type:"em",children:c(a[2])}),r=r.slice(a[0].length),e=!0;continue}const u=r.match(/^(https?:\/\/[^\s<>[\]]+)/);if(u)n.push({type:"link",url:u[1],children:[{type:"text",value:u[1]}]}),r=r.slice(u[0].length),e=!0;else if(!e){const e=r.search(/[`*_~![\\n]|https?:\/\//);if(-1===e){n.push({type:"text",value:r});break}0===e?(n.push({type:"text",value:r[0]}),r=r.slice(1)):(n.push({type:"text",value:r.slice(0,e)}),r=r.slice(e))}}return function(e){const t=[];for(const n of e)"text"===n.type&&t.length>0&&"text"===t[t.length-1].type?t[t.length-1].value+=n.value:t.push(n);return t}(n)}function c(e,t){return s(e.replace(/\n/g," "))}e.version="1.2.9","undefined"!=typeof module&&module.exports&&(module.exports=e),"undefined"!=typeof window&&(window.quikdown_ast=e);const l="quikdown-",o={"&":"&","<":"<",">":">",'"':""","'":"'"},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"};function u(e){return e?String(e).replace(/[&<>"']/g,e=>o[e]):""}function h(e){if(!e)return"";const t=e.trim(),n=t.toLowerCase(),r=["javascript:","vbscript:","data:"];for(const e of r)if(n.startsWith(e))return"data:"===e&&n.startsWith("data:image/")?t:"#";return t}function d(t,n={}){if(!t)return{type:"document",children:[]};if("object"==typeof t&&t.type)return t;if("string"==typeof t){const r=t.trim();if(r.startsWith("{")||r.startsWith("["))try{const e=JSON.parse(r);return"document"===e.type?e:Array.isArray(e)?{type:"document",children:e}:e}catch(e){}if(r.includes("type:")&&(r.includes("children:")||r.includes("value:")))try{const e=f(r.split("\n"),0,0).value;if(e&&e.type)return e}catch(e){}return e(t,n)}return{type:"document",children:[]}}function f(e,t,n){if(t>=e.length)return{value:null,nextLine:t};const r=e[t],i=r.trim();if(""===i)return f(e,t+1,n);const s=r.search(/\S/);if(s<n&&s>=0)return{value:null,nextLine:t};if(i.startsWith("- "))return function(e,t,n){const r=[];let i=t;for(;i<e.length;){const t=e[i],s=t.trim();if(""===s){i++;continue}const c=t.search(/\S/);if(c<n&&c>=0)break;if(c>n&&r.length>0){i++;continue}if(!s.startsWith("- "))break;const l=s.slice(2);if(l.includes(":")){const t={},s=l.indexOf(":"),o=l.slice(0,s).trim(),a=l.slice(s+1).trim();if(""===a||a.startsWith("\n")){const n=f(e,i+1,c+2);t[o]=n.value,i=n.nextLine}else t[o]=p(a),i++;for(;i<e.length;){const r=e[i],s=r.trim();if(""===s){i++;continue}const c=r.search(/\S/);if(c<=n)break;if(s.startsWith("- "))break;const l=s.indexOf(":");if(l>0){const n=s.slice(0,l).trim(),r=s.slice(l+1).trim();if(""===r||r.startsWith("\n")){const r=f(e,i+1,c+2);t[n]=r.value,i=r.nextLine}else t[n]=p(r),i++}else i++}r.push(t)}else r.push(p(l)),i++}return{value:r,nextLine:i}}(e,t,s);if("[]"===i)return{value:[],nextLine:t+1};if("{}"===i)return{value:{},nextLine:t+1};return i.indexOf(":")>0?function(e,t,n){const r={};let i=t;for(;i<e.length;){const t=e[i],s=t.trim();if(""===s){i++;continue}const c=t.search(/\S/);if(c<n&&c>=0)break;const l=s.indexOf(":");if(l<=0){i++;continue}const o=s.slice(0,l).trim(),a=s.slice(l+1).trim();if(""===a||"|"===a||">"===a){const t=f(e,i+1,c+2);r[o]=t.value,i=t.nextLine}else r[o]=p(a),i++}return{value:r,nextLine:i}}(e,t,s):{value:p(i),nextLine:t+1}}function p(e){if(!e)return null;const t=e.trim();return"null"===t||"~"===t?null:"true"===t||"false"!==t&&(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1).replace(/\\n/g,"\n").replace(/\\"/g,'"').replace(/\\\\/g,"\\"):/^-?\d+$/.test(t)?parseInt(t,10):/^-?\d+\.\d+$/.test(t)?parseFloat(t):t)}function m(e,t={}){return g(d(e,t),t)}function g(e,t={}){if(!e)return"";const{inline_styles:n=!1}=t,r=function(e){return function(t,n=""){if(e){let e=a[t];return e||n?(n&&n.includes("text-align")&&e&&e.includes("text-align")&&(e=e.replace(/text-align:[^;]+;?/,"").trim(),e&&!e.endsWith(";")&&(e+=";")),` style="${n?e?`${e}${n}`:n:e}"`):""}{const e=` class="${l}${t}"`;return n?`${e} style="${n}"`:e}}}(n);return $(e,r,t)}function $(e,t,n){if(!e)return"";switch(e.type){case"document":return y(e.children,t,n);case"paragraph":return`<p>${y(e.children,t,n)}</p>`;case"heading":const r=e.level||1;return`<h${r}${t("h"+r)}>${y(e.children,t,n)}</h${r}>`;case"code_block":const i=!n.inline_styles&&e.lang?` class="language-${e.lang}"`:"",s=n.inline_styles?t("code"):i;return`<pre${t("pre")}><code${s}>${u(e.content)}</code></pre>`;case"blockquote":return`<blockquote${t("blockquote")}>${y(e.children,t,n)}</blockquote>`;case"list":const c=e.ordered?"ol":"ul",o=(e.items||[]).map(e=>$(e,t,n)).join("");return`<${c}${t(c)}>${o}</${c}>`;case"list_item":if(null!==e.checked&&void 0!==e.checked){const r=n.inline_styles?' style="margin-right:.5em"':` class="${l}task-checkbox"`,i=e.checked?" checked":"";return`<li${n.inline_styles?' style="list-style:none"':` class="${l}task-item"`}><input type="checkbox"${r}${i} disabled> ${y(e.children,t,n)}</li>`}return`<li${t("li")}>${y(e.children,t,n)}</li>`;case"table":return function(e,t,n){const r=e.alignments||[];let i=`<table${t("table")}>\n`;e.headers&&e.headers.length>0&&(i+="<thead>\n<tr>\n",e.headers.forEach((e,s)=>{const c=r[s]&&"left"!==r[s]?`text-align:${r[s]}`:"";i+=`<th${t("th",c)}>${y(e,t,n)}</th>\n`}),i+="</tr>\n</thead>\n");e.rows&&e.rows.length>0&&(i+="<tbody>\n",e.rows.forEach(e=>{i+="<tr>\n",e.forEach((e,s)=>{const c=r[s]&&"left"!==r[s]?`text-align:${r[s]}`:"";i+=`<td${t("td",c)}>${y(e,t,n)}</td>\n`}),i+="</tr>\n"}),i+="</tbody>\n");return i+="</table>",i}(e,t,n);case"hr":return`<hr${t("hr")}>`;case"text":return u(e.value||"");case"strong":return`<strong${t("strong")}>${y(e.children,t,n)}</strong>`;case"em":return`<em${t("em")}>${y(e.children,t,n)}</em>`;case"del":return`<del${t("del")}>${y(e.children,t,n)}</del>`;case"code":return`<code${t("code")}>${u(e.value||"")}</code>`;case"link":const a=h(e.url),d=/^https?:\/\//i.test(a)?' rel="noopener noreferrer"':"";return`<a${t("a")} href="${a}"${d}>${y(e.children,t,n)}</a>`;case"image":const f=h(e.url);return`<img${t("img")} src="${f}" alt="${u(e.alt||"")}">`;case"br":return"<br>";default:return e.children?y(e.children,t,n):void 0!==e.value?u(String(e.value)):""}}function y(e,t,n){return e?Array.isArray(e)?e.map(e=>$(e,t,n)).join(""):$(e,t,n):""}m.toAst=d,m.renderAst=g,m.version="1.2.9","undefined"!=typeof module&&module.exports&&(module.exports=m),"undefined"!=typeof window&&(window.quikdown_ast_html=m);export{m as default};
|
|
7
|
+
function e(e,n={}){if(!e||"string"!=typeof e)return{type:"document",children:[]};return{type:"document",children:t(e.replace(/\r\n/g,"\n").replace(/\r/g,"\n"))}}function t(e,r){const c=[],l=e.split("\n");let o=0;for(;o<l.length;){const e=l[o];if(""===e.trim()){o++;continue}const r=e.match(/^(```|~~~)(.*)$/);if(r){const[,e,t]=r,n=t.trim(),i=[];for(o++;o<l.length;){if(l[o].match(/^(```|~~~)\s*$/)){o++;break}i.push(l[o]),o++}c.push({type:"code_block",lang:n||null,content:i.join("\n"),fence:e});continue}if(/^---+\s*$/.test(e)||/^\*\*\*+\s*$/.test(e)||/^___+\s*$/.test(e)){c.push({type:"hr"}),o++;continue}const a=e.match(/^(#{1,6})\s*(.+?)\s*#*$/);if(a){const[,e,t]=a;c.push({type:"heading",level:e.length,children:s(t)}),o++;continue}if(e.includes("|")){const e=n(l,o);if(e){c.push(e.node),o=e.nextIndex;continue}}if(e.match(/^>\s*/)){const e=[];for(;o<l.length&&l[o].match(/^>\s*/);)e.push(l[o].replace(/^>\s*/,"")),o++;c.push({type:"blockquote",children:t(e.join("\n"))});continue}if(e.match(/^(\s*)([*\-+]|\d+\.)\s+(.*)$/)){const e=i(l,o);c.push(e.node),o=e.nextIndex;continue}const u=[];for(;o<l.length;){const e=l[o];if(""===e.trim())break;if(/^(```|~~~)/.test(e))break;if(/^#{1,6}\s/.test(e))break;if(/^---+\s*$/.test(e)||/^\*\*\*+\s*$/.test(e)||/^___+\s*$/.test(e))break;if(/^>\s*/.test(e))break;if(/^(\s*)([*\-+]|\d+\.)\s+/.test(e))break;if(e.includes("|")&&o+1<l.length&&/^\|?[\s\-:|]+\|?$/.test(l[o+1]))break;u.push(e),o++}u.length>0&&c.push({type:"paragraph",children:s(u.join("\n"))})}return c}function n(e,t,n){if(t+1>=e.length)return null;const i=e[t],c=e[t+1];if(!/^\|?[\s\-:|]+\|?$/.test(c)||!c.includes("-"))return null;const l=r(i);if(0===l.length)return null;const o=r(c).map(e=>{const t=e.trim();return t.startsWith(":")&&t.endsWith(":")?"center":t.endsWith(":")?"right":"left"}),a=l.map(e=>s(e.trim())),u=[];let h=t+2;for(;h<e.length;){const t=e[h];if(!t.includes("|")||""===t.trim())break;const n=r(t);u.push(n.map(e=>s(e.trim()))),h++}return{node:{type:"table",headers:a,rows:u,alignments:o},nextIndex:h}}function r(e){let t=e.trim();return t.startsWith("|")&&(t=t.slice(1)),t.endsWith("|")&&(t=t.slice(0,-1)),t.split("|")}function i(e,t,n){const r=[];let c=t,l=0;const o=e[c].match(/^(\s*)([*\-+]|\d+\.)\s+(.*)$/),a=/^\d+\./.test(o[2]),u=o[1].length;for(;c<e.length&&l<1e3;){l++;const t=e[c].match(/^(\s*)([*\-+]|\d+\.)\s+(.*)$/);if(!t)break;const[,n,o,h]=t,d=n.length;if(d<u)break;const f=/^\d+\./.test(o);if(d===u&&f!==a)break;if(d>u){const t=[];let n=0;for(;c<e.length&&n<1e3;){n++;const r=e[c],i=r.match(/^(\s*)([*\-+]|\d+\.)\s+/);if(!i)break;if(i[1].length<u)break;if(i[1].length===u)break;t.push(r),c++}if(t.length>0&&r.length>0){const e=i(t,0),n=r[r.length-1];n.children?Array.isArray(n.children)||(n.children=[{type:"paragraph",children:n.children}]):n.children=[],n.children.push(e.node)}continue}const p={type:"list_item",checked:null,children:null},m=h.match(/^\[([x ])\]\s*(.*)$/i);m&&!a?(p.checked="x"===m[1].toLowerCase(),p.children=s(m[2])):p.children=s(h),r.push(p),c++}return{node:{type:"list",ordered:a,items:r},nextIndex:c}}function s(e,t){if(!e)return[];const n=[];let r=e;for(;r.length>0;){if(r.match(/^(.+?)(?: {2}|\\\n|\n)/)&&r.includes("\n")){const e=r.indexOf("\n"),t=r.slice(0,e),i=r.slice(e+1);if(t.endsWith(" ")||t.endsWith("\\")){const e=t.replace(/\\$/,"").replace(/ +$/,"");e&&n.push(...c(e)),n.push({type:"br"}),r=i;continue}}const e=r.match(/^!\[([^\]]*)\]\(\s*([^)\s]+)\s*\)/);if(e){n.push({type:"image",alt:e[1],url:e[2].trim()}),r=r.slice(e[0].length);continue}const t=r.match(/^\[([^\]]+)\]\(\s*([^)\s]+)\s*\)/);if(t){n.push({type:"link",url:t[2].trim(),children:c(t[1])}),r=r.slice(t[0].length);continue}const i=r.match(/^`([^`]+)`/);if(i){n.push({type:"code",value:i[1]}),r=r.slice(i[0].length);continue}const s=r.match(/^(\*\*|__)(.+?)\1/);if(s){n.push({type:"strong",children:c(s[2])}),r=r.slice(s[0].length);continue}const l=r.match(/^~~(.+?)~~/);if(l){n.push({type:"del",children:c(l[1])}),r=r.slice(l[0].length);continue}const o=r.match(/^(\*|_)(?!\1)(.+?)(?<!\1)\1(?!\1)/);if(o){n.push({type:"em",children:c(o[2])}),r=r.slice(o[0].length);continue}const a=r.match(/^(https?:\/\/[^\s<>[\]]+)/);if(a){n.push({type:"link",url:a[1],children:[{type:"text",value:a[1]}]}),r=r.slice(a[0].length);continue}const u=r.search(/[`*_~![\\n]|https?:\/\//);if(-1===u){n.push({type:"text",value:r});break}0===u?(n.push({type:"text",value:r[0]}),r=r.slice(1)):(n.push({type:"text",value:r.slice(0,u)}),r=r.slice(u))}return function(e){const t=[];for(const n of e)"text"===n.type&&t.length>0&&"text"===t[t.length-1].type?t[t.length-1].value+=n.value:t.push(n);return t}(n)}function c(e,t){return s(e.replace(/\n/g," "))}e.version="1.2.11","undefined"!=typeof module&&module.exports&&(module.exports=e),"undefined"!=typeof window&&(window.quikdown_ast=e);const l="quikdown-",o={"&":"&","<":"<",">":">",'"':""","'":"'"},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"};function u(e){return e?String(e).replace(/[&<>"']/g,e=>o[e]):""}function h(e){if(!e)return"";const t=e.trim(),n=t.toLowerCase(),r=["javascript:","vbscript:","data:"];for(const e of r)if(n.startsWith(e))return"data:"===e&&n.startsWith("data:image/")?t:"#";return t}function d(t,n={}){if(!t)return{type:"document",children:[]};if("object"==typeof t&&t.type)return t;if("string"==typeof t){const r=t.trim();if(r.startsWith("{")||r.startsWith("["))try{const e=JSON.parse(r);return"document"===e.type?e:Array.isArray(e)?{type:"document",children:e}:e}catch(e){}if(r.includes("type:")&&(r.includes("children:")||r.includes("value:")))try{const e=f(r.split("\n"),0,0).value;if(e&&e.type)return e}catch(e){}return e(t,n)}return{type:"document",children:[]}}function f(e,t,n){if(t>=e.length)return{value:null,nextLine:t};const r=e[t],i=r.trim();if(""===i)return f(e,t+1,n);const s=r.search(/\S/);if(s<n&&s>=0)return{value:null,nextLine:t};if(i.startsWith("- "))return function(e,t,n){const r=[];let i=t;for(;i<e.length;){const t=e[i],s=t.trim();if(""===s){i++;continue}const c=t.search(/\S/);if(c<n&&c>=0)break;if(c>n&&r.length>0){i++;continue}if(!s.startsWith("- "))break;const l=s.slice(2);if(l.includes(":")){const t={},s=l.indexOf(":"),o=l.slice(0,s).trim(),a=l.slice(s+1).trim();if(""===a||a.startsWith("\n")){const n=f(e,i+1,c+2);t[o]=n.value,i=n.nextLine}else t[o]=p(a),i++;for(;i<e.length;){const r=e[i],s=r.trim();if(""===s){i++;continue}const c=r.search(/\S/);if(c<=n)break;if(s.startsWith("- "))break;const l=s.indexOf(":");if(l>0){const n=s.slice(0,l).trim(),r=s.slice(l+1).trim();if(""===r||r.startsWith("\n")){const r=f(e,i+1,c+2);t[n]=r.value,i=r.nextLine}else t[n]=p(r),i++}else i++}r.push(t)}else r.push(p(l)),i++}return{value:r,nextLine:i}}(e,t,s);if("[]"===i)return{value:[],nextLine:t+1};if("{}"===i)return{value:{},nextLine:t+1};return i.indexOf(":")>0?function(e,t,n){const r={};let i=t;for(;i<e.length;){const t=e[i],s=t.trim();if(""===s){i++;continue}const c=t.search(/\S/);if(c<n&&c>=0)break;const l=s.indexOf(":");if(l<=0){i++;continue}const o=s.slice(0,l).trim(),a=s.slice(l+1).trim();if(""===a||"|"===a||">"===a){const t=f(e,i+1,c+2);r[o]=t.value,i=t.nextLine}else r[o]=p(a),i++}return{value:r,nextLine:i}}(e,t,s):{value:p(i),nextLine:t+1}}function p(e){if(!e)return null;const t=e.trim();return"null"===t||"~"===t?null:"true"===t||"false"!==t&&(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1).replace(/\\n/g,"\n").replace(/\\"/g,'"').replace(/\\\\/g,"\\"):/^-?\d+$/.test(t)?parseInt(t,10):/^-?\d+\.\d+$/.test(t)?parseFloat(t):t)}function m(e,t={}){return g(d(e,t),t)}function g(e,t={}){if(!e)return"";const{inline_styles:n=!1}=t,r=function(e){return function(t,n=""){if(e){let e=a[t];return e||n?(n&&n.includes("text-align")&&e&&e.includes("text-align")&&(e=e.replace(/text-align:[^;]+;?/,"").trim(),e&&!e.endsWith(";")&&(e+=";")),` style="${n?e?`${e}${n}`:n:e}"`):""}{const e=` class="${l}${t}"`;return n?`${e} style="${n}"`:e}}}(n);return $(e,r,t)}function $(e,t,n){if(!e)return"";switch(e.type){case"document":return y(e.children,t,n);case"paragraph":return`<p>${y(e.children,t,n)}</p>`;case"heading":const r=e.level||1;return`<h${r}${t("h"+r)}>${y(e.children,t,n)}</h${r}>`;case"code_block":const i=!n.inline_styles&&e.lang?` class="language-${e.lang}"`:"",s=n.inline_styles?t("code"):i;return`<pre${t("pre")}><code${s}>${u(e.content)}</code></pre>`;case"blockquote":return`<blockquote${t("blockquote")}>${y(e.children,t,n)}</blockquote>`;case"list":const c=e.ordered?"ol":"ul",o=(e.items||[]).map(e=>$(e,t,n)).join("");return`<${c}${t(c)}>${o}</${c}>`;case"list_item":if(null!==e.checked&&void 0!==e.checked){const r=n.inline_styles?' style="margin-right:.5em"':` class="${l}task-checkbox"`,i=e.checked?" checked":"";return`<li${n.inline_styles?' style="list-style:none"':` class="${l}task-item"`}><input type="checkbox"${r}${i} disabled> ${y(e.children,t,n)}</li>`}return`<li${t("li")}>${y(e.children,t,n)}</li>`;case"table":return function(e,t,n){const r=e.alignments||[];let i=`<table${t("table")}>\n`;e.headers&&e.headers.length>0&&(i+="<thead>\n<tr>\n",e.headers.forEach((e,s)=>{const c=r[s]&&"left"!==r[s]?`text-align:${r[s]}`:"";i+=`<th${t("th",c)}>${y(e,t,n)}</th>\n`}),i+="</tr>\n</thead>\n");e.rows&&e.rows.length>0&&(i+="<tbody>\n",e.rows.forEach(e=>{i+="<tr>\n",e.forEach((e,s)=>{const c=r[s]&&"left"!==r[s]?`text-align:${r[s]}`:"";i+=`<td${t("td",c)}>${y(e,t,n)}</td>\n`}),i+="</tr>\n"}),i+="</tbody>\n");return i+="</table>",i}(e,t,n);case"hr":return`<hr${t("hr")}>`;case"text":return u(e.value||"");case"strong":return`<strong${t("strong")}>${y(e.children,t,n)}</strong>`;case"em":return`<em${t("em")}>${y(e.children,t,n)}</em>`;case"del":return`<del${t("del")}>${y(e.children,t,n)}</del>`;case"code":return`<code${t("code")}>${u(e.value||"")}</code>`;case"link":const a=h(e.url),d=/^https?:\/\//i.test(a)?' rel="noopener noreferrer"':"";return`<a${t("a")} href="${a}"${d}>${y(e.children,t,n)}</a>`;case"image":const f=h(e.url);return`<img${t("img")} src="${f}" alt="${u(e.alt||"")}">`;case"br":return"<br>";default:return e.children?y(e.children,t,n):void 0!==e.value?u(String(e.value)):""}}function y(e,t,n){return e?Array.isArray(e)?e.map(e=>$(e,t,n)).join(""):$(e,t,n):""}m.toAst=d,m.renderAst=g,m.version="1.2.11","undefined"!=typeof module&&module.exports&&(module.exports=m),"undefined"!=typeof window&&(window.quikdown_ast_html=m);export{m as default};
|
|
8
8
|
//# sourceMappingURL=quikdown_ast_html.esm.min.js.map
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quikdown_ast_html.esm.min.js","sources":["../src/quikdown_ast.js","../src/quikdown_ast_html.js"],"sourcesContent":["/**\n * quikdown_ast - Forgiving markdown to AST parser\n * Converts markdown to a structured Abstract Syntax Tree\n * @param {string} markdown - The markdown source text\n * @param {Object} options - Optional configuration object\n * @returns {Object} - The AST object\n */\n\n// Version will be injected at build time\nconst quikdownVersion = '__QUIKDOWN_VERSION__';\n\n// Safety limit to prevent infinite loops in list parsing\nconst MAX_LOOP_ITERATIONS = 1000;\n\n/**\n * Parse markdown into an AST\n * @param {string} markdown - The markdown source text\n * @param {Object} options - Optional configuration object\n * @returns {Object} - The AST object\n */\nfunction quikdown_ast(markdown, options = {}) {\n if (!markdown || typeof markdown !== 'string') {\n return { type: 'document', children: [] };\n }\n\n // Normalize line endings (handle CRLF, CR, LF uniformly)\n const text = markdown.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n');\n\n const children = parseBlocks(text, options);\n\n return {\n type: 'document',\n children\n };\n}\n\n/**\n * Parse block-level elements\n */\nfunction parseBlocks(text, options) {\n const blocks = [];\n const lines = text.split('\\n');\n let i = 0;\n\n while (i < lines.length) {\n const line = lines[i];\n\n // Empty line - skip\n if (line.trim() === '') {\n i++;\n continue;\n }\n\n // Fenced code block (``` or ~~~)\n const fenceMatch = line.match(/^(```|~~~)(.*)$/);\n if (fenceMatch) {\n const [, openFence, langPart] = fenceMatch;\n const lang = langPart.trim();\n const codeLines = [];\n i++;\n\n // Find closing fence (forgiving: accept mismatched fences or EOF)\n while (i < lines.length) {\n const closingMatch = lines[i].match(/^(```|~~~)\\s*$/);\n if (closingMatch) {\n i++;\n break;\n }\n codeLines.push(lines[i]);\n i++;\n }\n\n blocks.push({\n type: 'code_block',\n lang: lang || null,\n content: codeLines.join('\\n'),\n fence: openFence\n });\n continue;\n }\n\n // Horizontal rule\n if (/^---+\\s*$/.test(line) || /^\\*\\*\\*+\\s*$/.test(line) || /^___+\\s*$/.test(line)) {\n blocks.push({ type: 'hr' });\n i++;\n continue;\n }\n\n // Heading (forgiving: accept #heading without space)\n const headingMatch = line.match(/^(#{1,6})\\s*(.+?)\\s*#*$/);\n if (headingMatch) {\n const [, hashes, content] = headingMatch;\n blocks.push({\n type: 'heading',\n level: hashes.length,\n children: parseInline(content, options)\n });\n i++;\n continue;\n }\n\n // Table (look for separator line)\n if (line.includes('|')) {\n const tableResult = tryParseTable(lines, i, options);\n if (tableResult) {\n blocks.push(tableResult.node);\n i = tableResult.nextIndex;\n continue;\n }\n }\n\n // Blockquote\n if (line.match(/^>\\s*/)) {\n const quoteLines = [];\n while (i < lines.length && lines[i].match(/^>\\s*/)) {\n quoteLines.push(lines[i].replace(/^>\\s*/, ''));\n i++;\n }\n blocks.push({\n type: 'blockquote',\n children: parseBlocks(quoteLines.join('\\n'), options)\n });\n continue;\n }\n\n // List (ordered or unordered)\n const listMatch = line.match(/^(\\s*)([*\\-+]|\\d+\\.)\\s+(.*)$/);\n if (listMatch) {\n const listResult = parseList(lines, i, options);\n blocks.push(listResult.node);\n i = listResult.nextIndex;\n continue;\n }\n\n // Paragraph - collect lines until empty line or block element\n const paragraphLines = [];\n while (i < lines.length) {\n const pLine = lines[i];\n\n // Stop on empty line\n if (pLine.trim() === '') break;\n\n // Stop on block elements\n if (/^(```|~~~)/.test(pLine)) break;\n if (/^#{1,6}\\s/.test(pLine)) break;\n if (/^---+\\s*$/.test(pLine) || /^\\*\\*\\*+\\s*$/.test(pLine) || /^___+\\s*$/.test(pLine)) break;\n if (/^>\\s*/.test(pLine)) break;\n if (/^(\\s*)([*\\-+]|\\d+\\.)\\s+/.test(pLine)) break;\n if (pLine.includes('|') && i + 1 < lines.length && /^\\|?[\\s\\-:|]+\\|?$/.test(lines[i + 1])) break;\n\n paragraphLines.push(pLine);\n i++;\n }\n\n if (paragraphLines.length > 0) {\n blocks.push({\n type: 'paragraph',\n children: parseInline(paragraphLines.join('\\n'), options)\n });\n }\n }\n\n return blocks;\n}\n\n/**\n * Try to parse a table starting at the given line\n */\nfunction tryParseTable(lines, startIndex, options) {\n // Need at least 2 lines (header + separator)\n if (startIndex + 1 >= lines.length) return null;\n\n const headerLine = lines[startIndex];\n const separatorLine = lines[startIndex + 1];\n\n // Check if separator line is valid\n if (!/^\\|?[\\s\\-:|]+\\|?$/.test(separatorLine) || !separatorLine.includes('-')) {\n return null;\n }\n\n // Parse header\n const headerCells = parseTableRow(headerLine);\n if (headerCells.length === 0) return null;\n\n // Parse alignments from separator\n const separatorCells = parseTableRow(separatorLine);\n const alignments = separatorCells.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\n // Parse headers with inline formatting\n const headers = headerCells.map(cell => parseInline(cell.trim(), options));\n\n // Parse body rows\n const rows = [];\n let i = startIndex + 2;\n while (i < lines.length) {\n const rowLine = lines[i];\n if (!rowLine.includes('|') || rowLine.trim() === '') break;\n\n const cells = parseTableRow(rowLine);\n rows.push(cells.map(cell => parseInline(cell.trim(), options)));\n i++;\n }\n\n return {\n node: {\n type: 'table',\n headers,\n rows,\n alignments\n },\n nextIndex: i\n };\n}\n\n/**\n * Parse a table row into cells\n */\nfunction parseTableRow(line) {\n // Handle pipes at start/end or not\n let trimmed = line.trim();\n if (trimmed.startsWith('|')) trimmed = trimmed.slice(1);\n if (trimmed.endsWith('|')) trimmed = trimmed.slice(0, -1);\n return trimmed.split('|');\n}\n\n/**\n * Parse a list starting at the given line\n */\nfunction parseList(lines, startIndex, options) {\n const items = [];\n let i = startIndex;\n let loopCount = 0;\n\n // Determine initial list type\n const firstMatch = lines[i].match(/^(\\s*)([*\\-+]|\\d+\\.)\\s+(.*)$/);\n const isOrdered = /^\\d+\\./.test(firstMatch[2]);\n const baseIndent = firstMatch[1].length;\n\n while (i < lines.length && loopCount < MAX_LOOP_ITERATIONS) {\n loopCount++;\n const line = lines[i];\n const match = line.match(/^(\\s*)([*\\-+]|\\d+\\.)\\s+(.*)$/);\n\n if (!match) break;\n\n const [, indent, marker, content] = match;\n const indentLevel = indent.length;\n\n // If less indented than base, stop\n if (indentLevel < baseIndent) break;\n\n // If same indentation but different list type, stop\n const itemIsOrdered = /^\\d+\\./.test(marker);\n if (indentLevel === baseIndent && itemIsOrdered !== isOrdered) break;\n\n // If more indented, it's a nested list - handle by collecting sub-lines\n if (indentLevel > baseIndent) {\n // This is a nested list item, collect and parse as sublist\n const subLines = [];\n let subLoopCount = 0;\n while (i < lines.length && subLoopCount < MAX_LOOP_ITERATIONS) {\n subLoopCount++;\n const subLine = lines[i];\n const subMatch = subLine.match(/^(\\s*)([*\\-+]|\\d+\\.)\\s+/);\n if (!subMatch) break;\n if (subMatch[1].length < baseIndent) break;\n if (subMatch[1].length === baseIndent) break;\n subLines.push(subLine);\n i++;\n }\n\n if (subLines.length > 0 && items.length > 0) {\n // Add nested list to last item\n const nestedResult = parseList(subLines, 0, options);\n const lastItem = items[items.length - 1];\n if (!lastItem.children) {\n lastItem.children = [];\n } else if (!Array.isArray(lastItem.children)) {\n lastItem.children = [{ type: 'paragraph', children: lastItem.children }];\n }\n lastItem.children.push(nestedResult.node);\n }\n continue;\n }\n\n // Parse list item\n const itemNode = {\n type: 'list_item',\n checked: null,\n children: null\n };\n\n // Check for task list syntax\n const taskMatch = content.match(/^\\[([x ])\\]\\s*(.*)$/i);\n if (taskMatch && !isOrdered) {\n itemNode.checked = taskMatch[1].toLowerCase() === 'x';\n itemNode.children = parseInline(taskMatch[2], options);\n } else {\n itemNode.children = parseInline(content, options);\n }\n\n items.push(itemNode);\n i++;\n }\n\n return {\n node: {\n type: 'list',\n ordered: isOrdered,\n items\n },\n nextIndex: i\n };\n}\n\n/**\n * Parse inline elements\n */\nfunction parseInline(text, options) {\n if (!text) return [];\n\n const nodes = [];\n let remaining = text;\n\n while (remaining.length > 0) {\n let matched = false;\n\n // Line break (1+ trailing spaces or explicit \\n after processing)\n // Handle inline line breaks (two spaces at end of line or backslash before newline)\n const brMatch = remaining.match(/^(.+?)(?: {2}|\\\\\\n|\\n)/);\n if (brMatch && remaining.includes('\\n')) {\n const beforeBr = remaining.indexOf('\\n');\n const beforeText = remaining.slice(0, beforeBr);\n const afterText = remaining.slice(beforeBr + 1);\n\n // Check if line break is significant (2+ trailing spaces or backslash)\n if (beforeText.endsWith(' ') || beforeText.endsWith('\\\\')) {\n const cleanText = beforeText.replace(/\\\\$/, '').replace(/ +$/, '');\n if (cleanText) {\n nodes.push(...parseInlineContent(cleanText, options));\n }\n nodes.push({ type: 'br' });\n remaining = afterText;\n matched = true;\n continue;\n }\n }\n\n // Images: \n const imgMatch = remaining.match(/^!\\[([^\\]]*)\\]\\(\\s*([^)\\s]+)\\s*\\)/);\n if (imgMatch) {\n nodes.push({\n type: 'image',\n alt: imgMatch[1],\n url: imgMatch[2].trim() // Forgiving: trim whitespace in URL\n });\n remaining = remaining.slice(imgMatch[0].length);\n matched = true;\n continue;\n }\n\n // Links: [text](url)\n const linkMatch = remaining.match(/^\\[([^\\]]+)\\]\\(\\s*([^)\\s]+)\\s*\\)/);\n if (linkMatch) {\n nodes.push({\n type: 'link',\n url: linkMatch[2].trim(), // Forgiving: trim whitespace in URL\n children: parseInlineContent(linkMatch[1], options)\n });\n remaining = remaining.slice(linkMatch[0].length);\n matched = true;\n continue;\n }\n\n // Inline code: `code`\n const codeMatch = remaining.match(/^`([^`]+)`/);\n if (codeMatch) {\n nodes.push({\n type: 'code',\n value: codeMatch[1]\n });\n remaining = remaining.slice(codeMatch[0].length);\n matched = true;\n continue;\n }\n\n // Bold: **text** or __text__\n const boldMatch = remaining.match(/^(\\*\\*|__)(.+?)\\1/);\n if (boldMatch) {\n nodes.push({\n type: 'strong',\n children: parseInlineContent(boldMatch[2], options)\n });\n remaining = remaining.slice(boldMatch[0].length);\n matched = true;\n continue;\n }\n\n // Strikethrough: ~~text~~\n const strikeMatch = remaining.match(/^~~(.+?)~~/);\n if (strikeMatch) {\n nodes.push({\n type: 'del',\n children: parseInlineContent(strikeMatch[1], options)\n });\n remaining = remaining.slice(strikeMatch[0].length);\n matched = true;\n continue;\n }\n\n // Italic: *text* or _text_ (not at word boundary for underscores)\n const emMatch = remaining.match(/^(\\*|_)(?!\\1)(.+?)(?<!\\1)\\1(?!\\1)/);\n if (emMatch) {\n nodes.push({\n type: 'em',\n children: parseInlineContent(emMatch[2], options)\n });\n remaining = remaining.slice(emMatch[0].length);\n matched = true;\n continue;\n }\n\n // Autolinks: URLs starting with http:// or https://\n const urlMatch = remaining.match(/^(https?:\\/\\/[^\\s<>[\\]]+)/);\n if (urlMatch) {\n nodes.push({\n type: 'link',\n url: urlMatch[1],\n children: [{ type: 'text', value: urlMatch[1] }]\n });\n remaining = remaining.slice(urlMatch[0].length);\n matched = true;\n continue;\n }\n\n // Plain text - consume until next potential inline element or end\n if (!matched) {\n // Find next potential inline marker\n const nextMarker = remaining.search(/[`*_~![\\\\n]|https?:\\/\\//);\n if (nextMarker === -1) {\n // No more markers, consume rest as text\n nodes.push({ type: 'text', value: remaining });\n break;\n } else if (nextMarker === 0) {\n // Current char is a marker but didn't match - consume it as text\n nodes.push({ type: 'text', value: remaining[0] });\n remaining = remaining.slice(1);\n } else {\n // Consume text up to next marker\n nodes.push({ type: 'text', value: remaining.slice(0, nextMarker) });\n remaining = remaining.slice(nextMarker);\n }\n }\n }\n\n // Merge adjacent text nodes\n return mergeTextNodes(nodes);\n}\n\n/**\n * Parse inline content (recursive helper for nested inline elements)\n */\nfunction parseInlineContent(text, options) {\n // For simple nested content, use parseInline\n // But handle newlines as spaces for inline content\n const normalized = text.replace(/\\n/g, ' ');\n return parseInline(normalized, options);\n}\n\n/**\n * Merge adjacent text nodes\n */\nfunction mergeTextNodes(nodes) {\n const merged = [];\n for (const node of nodes) {\n if (node.type === 'text' && merged.length > 0 && merged[merged.length - 1].type === 'text') {\n merged[merged.length - 1].value += node.value;\n } else {\n merged.push(node);\n }\n }\n return merged;\n}\n\n// Attach version\nquikdown_ast.version = quikdownVersion;\n\n// Export for both CommonJS and ES6\n/* istanbul ignore next */\nif (typeof module !== 'undefined' && module.exports) {\n module.exports = quikdown_ast;\n}\n\n// For browser global\n/* istanbul ignore next */\nif (typeof window !== 'undefined') {\n window.quikdown_ast = quikdown_ast;\n}\n\nexport default quikdown_ast;\n","/**\n * quikdown_ast_html - AST to HTML converter\n * Converts AST (or markdown/JSON/YAML) to HTML\n * @param {string|Object} input - Markdown string, AST object, JSON string, or YAML string\n * @param {Object} options - Optional configuration object\n * @returns {string} - HTML string\n */\n\nimport quikdown_ast from './quikdown_ast.js';\n\n// Version will be injected at build time\nconst quikdownVersion = '__QUIKDOWN_VERSION__';\n\n// Constants\nconst CLASS_PREFIX = 'quikdown-';\n\n// Escape map for HTML\nconst ESC_MAP = {'&':'&','<':'<','>':'>','\"':'"',\"'\":'''};\n\n// Style definitions (matching quikdown.js)\nconst 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/**\n * Escape HTML entities\n */\nfunction escapeHtml(text) {\n if (!text) return '';\n return String(text).replace(/[&<>\"']/g, m => ESC_MAP[m]);\n}\n\n/**\n * Create attribute string generator\n */\nfunction createGetAttr(inline_styles) {\n return function(tag, additionalStyle = '') {\n if (inline_styles) {\n let style = QUIKDOWN_STYLES[tag];\n if (!style && !additionalStyle) return '';\n\n if (additionalStyle && additionalStyle.includes('text-align') && style && style.includes('text-align')) {\n style = style.replace(/text-align:[^;]+;?/, '').trim();\n if (style && !style.endsWith(';')) style += ';';\n }\n\n const fullStyle = additionalStyle ? (style ? `${style}${additionalStyle}` : additionalStyle) : style;\n return ` style=\"${fullStyle}\"`;\n } else {\n const classAttr = ` class=\"${CLASS_PREFIX}${tag}\"`;\n if (additionalStyle) {\n return `${classAttr} style=\"${additionalStyle}\"`;\n }\n return classAttr;\n }\n };\n}\n\n/**\n * Sanitize URLs\n */\nfunction sanitizeUrl(url) {\n if (!url) return '';\n const trimmedUrl = url.trim();\n const lowerUrl = trimmedUrl.toLowerCase();\n\n const dangerousProtocols = ['javascript:', 'vbscript:', 'data:'];\n for (const protocol of dangerousProtocols) {\n if (lowerUrl.startsWith(protocol)) {\n if (protocol === 'data:' && lowerUrl.startsWith('data:image/')) {\n return trimmedUrl;\n }\n return '#';\n }\n }\n\n return trimmedUrl;\n}\n\n/**\n * Convert input to AST\n * Accepts markdown string, AST object, JSON string, or YAML string\n */\nfunction toAst(input, options = {}) {\n if (!input) {\n return { type: 'document', children: [] };\n }\n\n // Already an AST object\n if (typeof input === 'object' && input.type) {\n return input;\n }\n\n if (typeof input === 'string') {\n const trimmed = input.trim();\n\n // Try JSON first (starts with { or [)\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n try {\n const parsed = JSON.parse(trimmed);\n if (parsed.type === 'document') {\n return parsed;\n }\n // If it's an array, wrap it as document children\n if (Array.isArray(parsed)) {\n return { type: 'document', children: parsed };\n }\n return parsed;\n } catch (_e) {\n // Not valid JSON, fall through to markdown\n }\n }\n\n // Try YAML detection (has type: and children: patterns typical of AST)\n if (trimmed.includes('type:') && (trimmed.includes('children:') || trimmed.includes('value:'))) {\n try {\n const parsed = parseYaml(trimmed);\n if (parsed && parsed.type) {\n return parsed;\n }\n } catch (_e) {\n // Not valid YAML AST, fall through to markdown\n }\n }\n\n // Treat as markdown\n return quikdown_ast(input, options);\n }\n\n return { type: 'document', children: [] };\n}\n\n/**\n * Simple YAML parser for AST format\n * Only handles the subset needed for quikdown AST\n */\nfunction parseYaml(yaml) {\n const lines = yaml.split('\\n');\n return parseYamlNode(lines, 0, 0).value;\n}\n\n/**\n * Parse a YAML node starting at given line and indent\n */\nfunction parseYamlNode(lines, startLine, minIndent) {\n if (startLine >= lines.length) {\n return { value: null, nextLine: startLine };\n }\n\n const line = lines[startLine];\n const trimmed = line.trim();\n\n // Skip empty lines\n if (trimmed === '') {\n return parseYamlNode(lines, startLine + 1, minIndent);\n }\n\n // Get current indent\n const indent = line.search(/\\S/);\n if (indent < minIndent && indent >= 0) {\n return { value: null, nextLine: startLine };\n }\n\n // Array item\n if (trimmed.startsWith('- ')) {\n return parseYamlArray(lines, startLine, indent);\n }\n\n // Empty array\n if (trimmed === '[]') {\n return { value: [], nextLine: startLine + 1 };\n }\n\n // Empty object\n if (trimmed === '{}') {\n return { value: {}, nextLine: startLine + 1 };\n }\n\n // Key-value pair\n const colonIndex = trimmed.indexOf(':');\n if (colonIndex > 0) {\n return parseYamlObject(lines, startLine, indent);\n }\n\n // Scalar value\n return { value: parseYamlScalar(trimmed), nextLine: startLine + 1 };\n}\n\n/**\n * Parse YAML array\n */\nfunction parseYamlArray(lines, startLine, baseIndent) {\n const items = [];\n let i = startLine;\n\n while (i < lines.length) {\n const line = lines[i];\n const trimmed = line.trim();\n\n if (trimmed === '') {\n i++;\n continue;\n }\n\n const indent = line.search(/\\S/);\n if (indent < baseIndent && indent >= 0) break;\n if (indent > baseIndent && items.length > 0) {\n // Continuation of previous item\n i++;\n continue;\n }\n\n if (!trimmed.startsWith('- ')) break;\n\n // Parse the item after \"- \"\n const itemContent = trimmed.slice(2);\n\n if (itemContent.includes(':')) {\n // Object item - parse inline and following properties\n const obj = {};\n const colonIdx = itemContent.indexOf(':');\n const key = itemContent.slice(0, colonIdx).trim();\n const value = itemContent.slice(colonIdx + 1).trim();\n\n if (value === '' || value.startsWith('\\n')) {\n // Value on next lines\n const result = parseYamlNode(lines, i + 1, indent + 2);\n obj[key] = result.value;\n i = result.nextLine;\n } else {\n obj[key] = parseYamlScalar(value);\n i++;\n }\n\n // Parse remaining properties at same indent\n while (i < lines.length) {\n const nextLine = lines[i];\n const nextTrimmed = nextLine.trim();\n if (nextTrimmed === '') {\n i++;\n continue;\n }\n\n const nextIndent = nextLine.search(/\\S/);\n if (nextIndent <= baseIndent) break;\n if (nextTrimmed.startsWith('- ')) break;\n\n const nextColonIdx = nextTrimmed.indexOf(':');\n if (nextColonIdx > 0) {\n const nextKey = nextTrimmed.slice(0, nextColonIdx).trim();\n const nextValue = nextTrimmed.slice(nextColonIdx + 1).trim();\n\n if (nextValue === '' || nextValue.startsWith('\\n')) {\n const result = parseYamlNode(lines, i + 1, nextIndent + 2);\n obj[nextKey] = result.value;\n i = result.nextLine;\n } else {\n obj[nextKey] = parseYamlScalar(nextValue);\n i++;\n }\n } else {\n i++;\n }\n }\n\n items.push(obj);\n } else {\n items.push(parseYamlScalar(itemContent));\n i++;\n }\n }\n\n return { value: items, nextLine: i };\n}\n\n/**\n * Parse YAML object\n */\nfunction parseYamlObject(lines, startLine, baseIndent) {\n const obj = {};\n let i = startLine;\n\n while (i < lines.length) {\n const line = lines[i];\n const trimmed = line.trim();\n\n if (trimmed === '') {\n i++;\n continue;\n }\n\n const indent = line.search(/\\S/);\n if (indent < baseIndent && indent >= 0) break;\n\n const colonIdx = trimmed.indexOf(':');\n if (colonIdx <= 0) {\n i++;\n continue;\n }\n\n const key = trimmed.slice(0, colonIdx).trim();\n const value = trimmed.slice(colonIdx + 1).trim();\n\n if (value === '' || value === '|' || value === '>') {\n // Value on next lines\n const result = parseYamlNode(lines, i + 1, indent + 2);\n obj[key] = result.value;\n i = result.nextLine;\n } else {\n obj[key] = parseYamlScalar(value);\n i++;\n }\n }\n\n return { value: obj, nextLine: i };\n}\n\n/**\n * Parse YAML scalar value\n */\nfunction parseYamlScalar(str) {\n if (!str) return null;\n\n const trimmed = str.trim();\n\n if (trimmed === 'null' || trimmed === '~') return null;\n if (trimmed === 'true') return true;\n if (trimmed === 'false') return false;\n\n // Quoted string\n if ((trimmed.startsWith('\"') && trimmed.endsWith('\"')) ||\n (trimmed.startsWith(\"'\") && trimmed.endsWith(\"'\"))) {\n return trimmed.slice(1, -1)\n .replace(/\\\\n/g, '\\n')\n .replace(/\\\\\"/g, '\"')\n .replace(/\\\\\\\\/g, '\\\\');\n }\n\n // Number\n if (/^-?\\d+$/.test(trimmed)) return parseInt(trimmed, 10);\n if (/^-?\\d+\\.\\d+$/.test(trimmed)) return parseFloat(trimmed);\n\n return trimmed;\n}\n\n/**\n * Convert AST (or any valid input) to HTML\n * @param {string|Object} input - Markdown, AST, JSON, or YAML\n * @param {Object} options - Configuration options\n * @returns {string} - HTML string\n */\nfunction quikdown_ast_html(input, options = {}) {\n const ast = toAst(input, options);\n return renderAst(ast, options);\n}\n\n/**\n * Render an AST node to HTML\n */\nfunction renderAst(node, options = {}) {\n if (!node) return '';\n\n const { inline_styles = false } = options;\n const getAttr = createGetAttr(inline_styles);\n\n return renderNode(node, getAttr, options);\n}\n\n/**\n * Render a single node\n */\nfunction renderNode(node, getAttr, options) {\n if (!node) return '';\n\n switch (node.type) {\n case 'document':\n return renderChildren(node.children, getAttr, options);\n\n case 'paragraph':\n return `<p>${renderChildren(node.children, getAttr, options)}</p>`;\n\n case 'heading':\n const level = node.level || 1;\n return `<h${level}${getAttr('h' + level)}>${renderChildren(node.children, getAttr, options)}</h${level}>`;\n\n case 'code_block':\n const langClass = !options.inline_styles && node.lang ? ` class=\"language-${node.lang}\"` : '';\n const codeAttr = options.inline_styles ? getAttr('code') : langClass;\n return `<pre${getAttr('pre')}><code${codeAttr}>${escapeHtml(node.content)}</code></pre>`;\n\n case 'blockquote':\n return `<blockquote${getAttr('blockquote')}>${renderChildren(node.children, getAttr, options)}</blockquote>`;\n\n case 'list':\n const listTag = node.ordered ? 'ol' : 'ul';\n const items = (node.items || []).map(item => renderNode(item, getAttr, options)).join('');\n return `<${listTag}${getAttr(listTag)}>${items}</${listTag}>`;\n\n case 'list_item':\n // Handle task list items\n if (node.checked !== null && node.checked !== undefined) {\n const checkboxAttr = options.inline_styles\n ? ' style=\"margin-right:.5em\"'\n : ` class=\"${CLASS_PREFIX}task-checkbox\"`;\n const checked = node.checked ? ' checked' : '';\n const itemAttr = options.inline_styles\n ? ' style=\"list-style:none\"'\n : ` class=\"${CLASS_PREFIX}task-item\"`;\n return `<li${itemAttr}><input type=\"checkbox\"${checkboxAttr}${checked} disabled> ${renderChildren(node.children, getAttr, options)}</li>`;\n }\n return `<li${getAttr('li')}>${renderChildren(node.children, getAttr, options)}</li>`;\n\n case 'table':\n return renderTable(node, getAttr, options);\n\n case 'hr':\n return `<hr${getAttr('hr')}>`;\n\n case 'text':\n return escapeHtml(node.value || '');\n\n case 'strong':\n return `<strong${getAttr('strong')}>${renderChildren(node.children, getAttr, options)}</strong>`;\n\n case 'em':\n return `<em${getAttr('em')}>${renderChildren(node.children, getAttr, options)}</em>`;\n\n case 'del':\n return `<del${getAttr('del')}>${renderChildren(node.children, getAttr, options)}</del>`;\n\n case 'code':\n return `<code${getAttr('code')}>${escapeHtml(node.value || '')}</code>`;\n\n case 'link':\n const sanitizedHref = sanitizeUrl(node.url);\n const isExternal = /^https?:\\/\\//i.test(sanitizedHref);\n const rel = isExternal ? ' rel=\"noopener noreferrer\"' : '';\n return `<a${getAttr('a')} href=\"${sanitizedHref}\"${rel}>${renderChildren(node.children, getAttr, options)}</a>`;\n\n case 'image':\n const sanitizedSrc = sanitizeUrl(node.url);\n return `<img${getAttr('img')} src=\"${sanitizedSrc}\" alt=\"${escapeHtml(node.alt || '')}\">`;\n\n case 'br':\n return '<br>';\n\n default:\n // Unknown node type - try to render children if present\n if (node.children) {\n return renderChildren(node.children, getAttr, options);\n }\n if (node.value !== undefined) {\n return escapeHtml(String(node.value));\n }\n return '';\n }\n}\n\n/**\n * Render children array\n */\nfunction renderChildren(children, getAttr, options) {\n if (!children) return '';\n if (!Array.isArray(children)) {\n return renderNode(children, getAttr, options);\n }\n return children.map(child => renderNode(child, getAttr, options)).join('');\n}\n\n/**\n * Render a table node\n */\nfunction renderTable(node, getAttr, options) {\n const alignments = node.alignments || [];\n\n let html = `<table${getAttr('table')}>\\n`;\n\n // Headers\n if (node.headers && node.headers.length > 0) {\n html += '<thead>\\n<tr>\\n';\n node.headers.forEach((header, i) => {\n const alignStyle = alignments[i] && alignments[i] !== 'left' ? `text-align:${alignments[i]}` : '';\n html += `<th${getAttr('th', alignStyle)}>${renderChildren(header, getAttr, options)}</th>\\n`;\n });\n html += '</tr>\\n</thead>\\n';\n }\n\n // Body\n if (node.rows && node.rows.length > 0) {\n html += '<tbody>\\n';\n node.rows.forEach(row => {\n html += '<tr>\\n';\n row.forEach((cell, i) => {\n const alignStyle = alignments[i] && alignments[i] !== 'left' ? `text-align:${alignments[i]}` : '';\n html += `<td${getAttr('td', alignStyle)}>${renderChildren(cell, getAttr, options)}</td>\\n`;\n });\n html += '</tr>\\n';\n });\n html += '</tbody>\\n';\n }\n\n html += '</table>';\n return html;\n}\n\n// Expose helper functions\nquikdown_ast_html.toAst = toAst;\nquikdown_ast_html.renderAst = renderAst;\n\n// Attach version\nquikdown_ast_html.version = quikdownVersion;\n\n// Export for both CommonJS and ES6\n/* istanbul ignore next */\nif (typeof module !== 'undefined' && module.exports) {\n module.exports = quikdown_ast_html;\n}\n\n// For browser global\n/* istanbul ignore next */\nif (typeof window !== 'undefined') {\n window.quikdown_ast_html = quikdown_ast_html;\n}\n\nexport default quikdown_ast_html;\n"],"names":["quikdown_ast","markdown","options","type","children","parseBlocks","replace","text","blocks","lines","split","i","length","line","trim","fenceMatch","match","openFence","langPart","lang","codeLines","push","content","join","fence","test","headingMatch","hashes","level","parseInline","includes","tableResult","tryParseTable","node","nextIndex","quoteLines","listResult","parseList","paragraphLines","pLine","startIndex","headerLine","separatorLine","headerCells","parseTableRow","alignments","map","cell","trimmed","startsWith","endsWith","headers","rows","rowLine","cells","slice","items","loopCount","firstMatch","isOrdered","baseIndent","indent","marker","indentLevel","itemIsOrdered","subLines","subLoopCount","subLine","subMatch","nestedResult","lastItem","Array","isArray","itemNode","checked","taskMatch","toLowerCase","ordered","nodes","remaining","matched","beforeBr","indexOf","beforeText","afterText","cleanText","parseInlineContent","imgMatch","alt","url","linkMatch","codeMatch","value","boldMatch","strikeMatch","emMatch","urlMatch","nextMarker","search","merged","mergeTextNodes","version","module","exports","window","CLASS_PREFIX","ESC_MAP","QUIKDOWN_STYLES","h1","h2","h3","h4","h5","h6","pre","code","blockquote","table","th","td","hr","img","a","strong","em","del","ul","ol","li","escapeHtml","String","m","sanitizeUrl","trimmedUrl","lowerUrl","dangerousProtocols","protocol","toAst","input","parsed","JSON","parse","_e","parseYamlNode","startLine","minIndent","nextLine","itemContent","obj","colonIdx","key","result","parseYamlScalar","nextTrimmed","nextIndent","nextColonIdx","nextKey","nextValue","parseYamlArray","parseYamlObject","str","parseInt","parseFloat","quikdown_ast_html","renderAst","inline_styles","getAttr","tag","additionalStyle","style","classAttr","createGetAttr","renderNode","renderChildren","langClass","codeAttr","listTag","item","undefined","checkboxAttr","html","forEach","header","alignStyle","row","renderTable","sanitizedHref","rel","sanitizedSrc","child"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"quikdown_ast_html.esm.min.js","sources":["../src/quikdown_ast.js","../src/quikdown_ast_html.js"],"sourcesContent":["/**\n * quikdown_ast - Forgiving markdown to AST parser\n * Converts markdown to a structured Abstract Syntax Tree\n * @param {string} markdown - The markdown source text\n * @param {Object} options - Optional configuration object\n * @returns {Object} - The AST object\n */\n\n// Version will be injected at build time\nconst quikdownVersion = '__QUIKDOWN_VERSION__';\n\n// Safety limit to prevent infinite loops in list parsing\nconst MAX_LOOP_ITERATIONS = 1000;\n\n/**\n * Parse markdown into an AST\n * @param {string} markdown - The markdown source text\n * @param {Object} options - Optional configuration object\n * @returns {Object} - The AST object\n */\nfunction quikdown_ast(markdown, options = {}) {\n if (!markdown || typeof markdown !== 'string') {\n return { type: 'document', children: [] };\n }\n\n // Normalize line endings (handle CRLF, CR, LF uniformly)\n const text = markdown.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n');\n\n const children = parseBlocks(text, options);\n\n return {\n type: 'document',\n children\n };\n}\n\n/**\n * Parse block-level elements\n */\nfunction parseBlocks(text, options) {\n const blocks = [];\n const lines = text.split('\\n');\n let i = 0;\n\n while (i < lines.length) {\n const line = lines[i];\n\n // Empty line - skip\n if (line.trim() === '') {\n i++;\n continue;\n }\n\n // Fenced code block (``` or ~~~)\n const fenceMatch = line.match(/^(```|~~~)(.*)$/);\n if (fenceMatch) {\n const [, openFence, langPart] = fenceMatch;\n const lang = langPart.trim();\n const codeLines = [];\n i++;\n\n // Find closing fence (forgiving: accept mismatched fences or EOF)\n while (i < lines.length) {\n const closingMatch = lines[i].match(/^(```|~~~)\\s*$/);\n if (closingMatch) {\n i++;\n break;\n }\n codeLines.push(lines[i]);\n i++;\n }\n\n blocks.push({\n type: 'code_block',\n lang: lang || null,\n content: codeLines.join('\\n'),\n fence: openFence\n });\n continue;\n }\n\n // Horizontal rule\n if (/^---+\\s*$/.test(line) || /^\\*\\*\\*+\\s*$/.test(line) || /^___+\\s*$/.test(line)) {\n blocks.push({ type: 'hr' });\n i++;\n continue;\n }\n\n // Heading (forgiving: accept #heading without space)\n const headingMatch = line.match(/^(#{1,6})\\s*(.+?)\\s*#*$/);\n if (headingMatch) {\n const [, hashes, content] = headingMatch;\n blocks.push({\n type: 'heading',\n level: hashes.length,\n children: parseInline(content, options)\n });\n i++;\n continue;\n }\n\n // Table (look for separator line)\n if (line.includes('|')) {\n const tableResult = tryParseTable(lines, i, options);\n if (tableResult) {\n blocks.push(tableResult.node);\n i = tableResult.nextIndex;\n continue;\n }\n }\n\n // Blockquote\n if (line.match(/^>\\s*/)) {\n const quoteLines = [];\n while (i < lines.length && lines[i].match(/^>\\s*/)) {\n quoteLines.push(lines[i].replace(/^>\\s*/, ''));\n i++;\n }\n blocks.push({\n type: 'blockquote',\n children: parseBlocks(quoteLines.join('\\n'), options)\n });\n continue;\n }\n\n // List (ordered or unordered)\n const listMatch = line.match(/^(\\s*)([*\\-+]|\\d+\\.)\\s+(.*)$/);\n if (listMatch) {\n const listResult = parseList(lines, i, options);\n blocks.push(listResult.node);\n i = listResult.nextIndex;\n continue;\n }\n\n // Paragraph - collect lines until empty line or block element\n const paragraphLines = [];\n while (i < lines.length) {\n const pLine = lines[i];\n\n // Stop on empty line\n if (pLine.trim() === '') break;\n\n // Stop on block elements\n if (/^(```|~~~)/.test(pLine)) break;\n if (/^#{1,6}\\s/.test(pLine)) break;\n if (/^---+\\s*$/.test(pLine) || /^\\*\\*\\*+\\s*$/.test(pLine) || /^___+\\s*$/.test(pLine)) break;\n if (/^>\\s*/.test(pLine)) break;\n if (/^(\\s*)([*\\-+]|\\d+\\.)\\s+/.test(pLine)) break;\n if (pLine.includes('|') && i + 1 < lines.length && /^\\|?[\\s\\-:|]+\\|?$/.test(lines[i + 1])) break;\n\n paragraphLines.push(pLine);\n i++;\n }\n\n if (paragraphLines.length > 0) {\n blocks.push({\n type: 'paragraph',\n children: parseInline(paragraphLines.join('\\n'), options)\n });\n }\n }\n\n return blocks;\n}\n\n/**\n * Try to parse a table starting at the given line\n */\nfunction tryParseTable(lines, startIndex, options) {\n // Need at least 2 lines (header + separator)\n if (startIndex + 1 >= lines.length) return null;\n\n const headerLine = lines[startIndex];\n const separatorLine = lines[startIndex + 1];\n\n // Check if separator line is valid\n if (!/^\\|?[\\s\\-:|]+\\|?$/.test(separatorLine) || !separatorLine.includes('-')) {\n return null;\n }\n\n // Parse header\n const headerCells = parseTableRow(headerLine);\n if (headerCells.length === 0) return null;\n\n // Parse alignments from separator\n const separatorCells = parseTableRow(separatorLine);\n const alignments = separatorCells.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\n // Parse headers with inline formatting\n const headers = headerCells.map(cell => parseInline(cell.trim(), options));\n\n // Parse body rows\n const rows = [];\n let i = startIndex + 2;\n while (i < lines.length) {\n const rowLine = lines[i];\n if (!rowLine.includes('|') || rowLine.trim() === '') break;\n\n const cells = parseTableRow(rowLine);\n rows.push(cells.map(cell => parseInline(cell.trim(), options)));\n i++;\n }\n\n return {\n node: {\n type: 'table',\n headers,\n rows,\n alignments\n },\n nextIndex: i\n };\n}\n\n/**\n * Parse a table row into cells\n */\nfunction parseTableRow(line) {\n // Handle pipes at start/end or not\n let trimmed = line.trim();\n if (trimmed.startsWith('|')) trimmed = trimmed.slice(1);\n if (trimmed.endsWith('|')) trimmed = trimmed.slice(0, -1);\n return trimmed.split('|');\n}\n\n/**\n * Parse a list starting at the given line\n */\nfunction parseList(lines, startIndex, options) {\n const items = [];\n let i = startIndex;\n let loopCount = 0;\n\n // Determine initial list type\n const firstMatch = lines[i].match(/^(\\s*)([*\\-+]|\\d+\\.)\\s+(.*)$/);\n const isOrdered = /^\\d+\\./.test(firstMatch[2]);\n const baseIndent = firstMatch[1].length;\n\n while (i < lines.length && loopCount < MAX_LOOP_ITERATIONS) {\n loopCount++;\n const line = lines[i];\n const match = line.match(/^(\\s*)([*\\-+]|\\d+\\.)\\s+(.*)$/);\n\n if (!match) break;\n\n const [, indent, marker, content] = match;\n const indentLevel = indent.length;\n\n // If less indented than base, stop\n if (indentLevel < baseIndent) break;\n\n // If same indentation but different list type, stop\n const itemIsOrdered = /^\\d+\\./.test(marker);\n if (indentLevel === baseIndent && itemIsOrdered !== isOrdered) break;\n\n // If more indented, it's a nested list - handle by collecting sub-lines\n if (indentLevel > baseIndent) {\n // This is a nested list item, collect and parse as sublist\n const subLines = [];\n let subLoopCount = 0;\n while (i < lines.length && subLoopCount < MAX_LOOP_ITERATIONS) {\n subLoopCount++;\n const subLine = lines[i];\n const subMatch = subLine.match(/^(\\s*)([*\\-+]|\\d+\\.)\\s+/);\n if (!subMatch) break;\n if (subMatch[1].length < baseIndent) break;\n if (subMatch[1].length === baseIndent) break;\n subLines.push(subLine);\n i++;\n }\n\n if (subLines.length > 0 && items.length > 0) {\n // Add nested list to last item\n const nestedResult = parseList(subLines, 0, options);\n const lastItem = items[items.length - 1];\n if (!lastItem.children) {\n lastItem.children = [];\n } else if (!Array.isArray(lastItem.children)) {\n lastItem.children = [{ type: 'paragraph', children: lastItem.children }];\n }\n lastItem.children.push(nestedResult.node);\n }\n continue;\n }\n\n // Parse list item\n const itemNode = {\n type: 'list_item',\n checked: null,\n children: null\n };\n\n // Check for task list syntax\n const taskMatch = content.match(/^\\[([x ])\\]\\s*(.*)$/i);\n if (taskMatch && !isOrdered) {\n itemNode.checked = taskMatch[1].toLowerCase() === 'x';\n itemNode.children = parseInline(taskMatch[2], options);\n } else {\n itemNode.children = parseInline(content, options);\n }\n\n items.push(itemNode);\n i++;\n }\n\n return {\n node: {\n type: 'list',\n ordered: isOrdered,\n items\n },\n nextIndex: i\n };\n}\n\n/**\n * Parse inline elements\n */\nfunction parseInline(text, options) {\n if (!text) return [];\n\n const nodes = [];\n let remaining = text;\n\n while (remaining.length > 0) {\n // Line break (1+ trailing spaces or explicit \\n after processing)\n // Handle inline line breaks (two spaces at end of line or backslash before newline)\n const brMatch = remaining.match(/^(.+?)(?: {2}|\\\\\\n|\\n)/);\n if (brMatch && remaining.includes('\\n')) {\n const beforeBr = remaining.indexOf('\\n');\n const beforeText = remaining.slice(0, beforeBr);\n const afterText = remaining.slice(beforeBr + 1);\n\n // Check if line break is significant (2+ trailing spaces or backslash)\n if (beforeText.endsWith(' ') || beforeText.endsWith('\\\\')) {\n const cleanText = beforeText.replace(/\\\\$/, '').replace(/ +$/, '');\n if (cleanText) {\n nodes.push(...parseInlineContent(cleanText, options));\n }\n nodes.push({ type: 'br' });\n remaining = afterText;\n continue;\n }\n }\n\n // Images: \n const imgMatch = remaining.match(/^!\\[([^\\]]*)\\]\\(\\s*([^)\\s]+)\\s*\\)/);\n if (imgMatch) {\n nodes.push({\n type: 'image',\n alt: imgMatch[1],\n url: imgMatch[2].trim() // Forgiving: trim whitespace in URL\n });\n remaining = remaining.slice(imgMatch[0].length);\n continue;\n }\n\n // Links: [text](url)\n const linkMatch = remaining.match(/^\\[([^\\]]+)\\]\\(\\s*([^)\\s]+)\\s*\\)/);\n if (linkMatch) {\n nodes.push({\n type: 'link',\n url: linkMatch[2].trim(), // Forgiving: trim whitespace in URL\n children: parseInlineContent(linkMatch[1], options)\n });\n remaining = remaining.slice(linkMatch[0].length);\n continue;\n }\n\n // Inline code: `code`\n const codeMatch = remaining.match(/^`([^`]+)`/);\n if (codeMatch) {\n nodes.push({\n type: 'code',\n value: codeMatch[1]\n });\n remaining = remaining.slice(codeMatch[0].length);\n continue;\n }\n\n // Bold: **text** or __text__\n const boldMatch = remaining.match(/^(\\*\\*|__)(.+?)\\1/);\n if (boldMatch) {\n nodes.push({\n type: 'strong',\n children: parseInlineContent(boldMatch[2], options)\n });\n remaining = remaining.slice(boldMatch[0].length);\n continue;\n }\n\n // Strikethrough: ~~text~~\n const strikeMatch = remaining.match(/^~~(.+?)~~/);\n if (strikeMatch) {\n nodes.push({\n type: 'del',\n children: parseInlineContent(strikeMatch[1], options)\n });\n remaining = remaining.slice(strikeMatch[0].length);\n continue;\n }\n\n // Italic: *text* or _text_ (not at word boundary for underscores)\n const emMatch = remaining.match(/^(\\*|_)(?!\\1)(.+?)(?<!\\1)\\1(?!\\1)/);\n if (emMatch) {\n nodes.push({\n type: 'em',\n children: parseInlineContent(emMatch[2], options)\n });\n remaining = remaining.slice(emMatch[0].length);\n continue;\n }\n\n // Autolinks: URLs starting with http:// or https://\n const urlMatch = remaining.match(/^(https?:\\/\\/[^\\s<>[\\]]+)/);\n if (urlMatch) {\n nodes.push({\n type: 'link',\n url: urlMatch[1],\n children: [{ type: 'text', value: urlMatch[1] }]\n });\n remaining = remaining.slice(urlMatch[0].length);\n continue;\n }\n\n // Plain text - consume until next potential inline element or end\n // Find next potential inline marker\n const nextMarker = remaining.search(/[`*_~![\\\\n]|https?:\\/\\//);\n if (nextMarker === -1) {\n // No more markers, consume rest as text\n nodes.push({ type: 'text', value: remaining });\n break;\n } else if (nextMarker === 0) {\n // Current char is a marker but didn't match - consume it as text\n nodes.push({ type: 'text', value: remaining[0] });\n remaining = remaining.slice(1);\n } else {\n // Consume text up to next marker\n nodes.push({ type: 'text', value: remaining.slice(0, nextMarker) });\n remaining = remaining.slice(nextMarker);\n }\n }\n\n // Merge adjacent text nodes\n return mergeTextNodes(nodes);\n}\n\n/**\n * Parse inline content (recursive helper for nested inline elements)\n */\nfunction parseInlineContent(text, options) {\n // For simple nested content, use parseInline\n // But handle newlines as spaces for inline content\n const normalized = text.replace(/\\n/g, ' ');\n return parseInline(normalized, options);\n}\n\n/**\n * Merge adjacent text nodes\n */\nfunction mergeTextNodes(nodes) {\n const merged = [];\n for (const node of nodes) {\n if (node.type === 'text' && merged.length > 0 && merged[merged.length - 1].type === 'text') {\n merged[merged.length - 1].value += node.value;\n } else {\n merged.push(node);\n }\n }\n return merged;\n}\n\n// Attach version\nquikdown_ast.version = quikdownVersion;\n\n// Export for both CommonJS and ES6\n/* istanbul ignore next */\nif (typeof module !== 'undefined' && module.exports) {\n module.exports = quikdown_ast;\n}\n\n// For browser global\n/* istanbul ignore next */\nif (typeof window !== 'undefined') {\n window.quikdown_ast = quikdown_ast;\n}\n\nexport default quikdown_ast;\n","/**\n * quikdown_ast_html - AST to HTML converter\n * Converts AST (or markdown/JSON/YAML) to HTML\n * @param {string|Object} input - Markdown string, AST object, JSON string, or YAML string\n * @param {Object} options - Optional configuration object\n * @returns {string} - HTML string\n */\n\nimport quikdown_ast from './quikdown_ast.js';\n\n// Version will be injected at build time\nconst quikdownVersion = '__QUIKDOWN_VERSION__';\n\n// Constants\nconst CLASS_PREFIX = 'quikdown-';\n\n// Escape map for HTML\nconst ESC_MAP = {'&':'&','<':'<','>':'>','\"':'"',\"'\":'''};\n\n// Style definitions (matching quikdown.js)\nconst 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/**\n * Escape HTML entities\n */\nfunction escapeHtml(text) {\n if (!text) return '';\n return String(text).replace(/[&<>\"']/g, m => ESC_MAP[m]);\n}\n\n/**\n * Create attribute string generator\n */\nfunction createGetAttr(inline_styles) {\n return function(tag, additionalStyle = '') {\n if (inline_styles) {\n let style = QUIKDOWN_STYLES[tag];\n if (!style && !additionalStyle) return '';\n\n if (additionalStyle && additionalStyle.includes('text-align') && style && style.includes('text-align')) {\n style = style.replace(/text-align:[^;]+;?/, '').trim();\n if (style && !style.endsWith(';')) style += ';';\n }\n\n const fullStyle = additionalStyle ? (style ? `${style}${additionalStyle}` : additionalStyle) : style;\n return ` style=\"${fullStyle}\"`;\n } else {\n const classAttr = ` class=\"${CLASS_PREFIX}${tag}\"`;\n if (additionalStyle) {\n return `${classAttr} style=\"${additionalStyle}\"`;\n }\n return classAttr;\n }\n };\n}\n\n/**\n * Sanitize URLs\n */\nfunction sanitizeUrl(url) {\n if (!url) return '';\n const trimmedUrl = url.trim();\n const lowerUrl = trimmedUrl.toLowerCase();\n\n const dangerousProtocols = ['javascript:', 'vbscript:', 'data:'];\n for (const protocol of dangerousProtocols) {\n if (lowerUrl.startsWith(protocol)) {\n if (protocol === 'data:' && lowerUrl.startsWith('data:image/')) {\n return trimmedUrl;\n }\n return '#';\n }\n }\n\n return trimmedUrl;\n}\n\n/**\n * Convert input to AST\n * Accepts markdown string, AST object, JSON string, or YAML string\n */\nfunction toAst(input, options = {}) {\n if (!input) {\n return { type: 'document', children: [] };\n }\n\n // Already an AST object\n if (typeof input === 'object' && input.type) {\n return input;\n }\n\n if (typeof input === 'string') {\n const trimmed = input.trim();\n\n // Try JSON first (starts with { or [)\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n try {\n const parsed = JSON.parse(trimmed);\n if (parsed.type === 'document') {\n return parsed;\n }\n // If it's an array, wrap it as document children\n if (Array.isArray(parsed)) {\n return { type: 'document', children: parsed };\n }\n return parsed;\n } catch (_e) {\n // Not valid JSON, fall through to markdown\n }\n }\n\n // Try YAML detection (has type: and children: patterns typical of AST)\n if (trimmed.includes('type:') && (trimmed.includes('children:') || trimmed.includes('value:'))) {\n try {\n const parsed = parseYaml(trimmed);\n if (parsed && parsed.type) {\n return parsed;\n }\n } catch (_e) {\n // Not valid YAML AST, fall through to markdown\n }\n }\n\n // Treat as markdown\n return quikdown_ast(input, options);\n }\n\n return { type: 'document', children: [] };\n}\n\n/**\n * Simple YAML parser for AST format\n * Only handles the subset needed for quikdown AST\n */\nfunction parseYaml(yaml) {\n const lines = yaml.split('\\n');\n return parseYamlNode(lines, 0, 0).value;\n}\n\n/**\n * Parse a YAML node starting at given line and indent\n */\nfunction parseYamlNode(lines, startLine, minIndent) {\n if (startLine >= lines.length) {\n return { value: null, nextLine: startLine };\n }\n\n const line = lines[startLine];\n const trimmed = line.trim();\n\n // Skip empty lines\n if (trimmed === '') {\n return parseYamlNode(lines, startLine + 1, minIndent);\n }\n\n // Get current indent\n const indent = line.search(/\\S/);\n if (indent < minIndent && indent >= 0) {\n return { value: null, nextLine: startLine };\n }\n\n // Array item\n if (trimmed.startsWith('- ')) {\n return parseYamlArray(lines, startLine, indent);\n }\n\n // Empty array\n if (trimmed === '[]') {\n return { value: [], nextLine: startLine + 1 };\n }\n\n // Empty object\n if (trimmed === '{}') {\n return { value: {}, nextLine: startLine + 1 };\n }\n\n // Key-value pair\n const colonIndex = trimmed.indexOf(':');\n if (colonIndex > 0) {\n return parseYamlObject(lines, startLine, indent);\n }\n\n // Scalar value\n return { value: parseYamlScalar(trimmed), nextLine: startLine + 1 };\n}\n\n/**\n * Parse YAML array\n */\nfunction parseYamlArray(lines, startLine, baseIndent) {\n const items = [];\n let i = startLine;\n\n while (i < lines.length) {\n const line = lines[i];\n const trimmed = line.trim();\n\n if (trimmed === '') {\n i++;\n continue;\n }\n\n const indent = line.search(/\\S/);\n if (indent < baseIndent && indent >= 0) break;\n if (indent > baseIndent && items.length > 0) {\n // Continuation of previous item\n i++;\n continue;\n }\n\n if (!trimmed.startsWith('- ')) break;\n\n // Parse the item after \"- \"\n const itemContent = trimmed.slice(2);\n\n if (itemContent.includes(':')) {\n // Object item - parse inline and following properties\n const obj = {};\n const colonIdx = itemContent.indexOf(':');\n const key = itemContent.slice(0, colonIdx).trim();\n const value = itemContent.slice(colonIdx + 1).trim();\n\n if (value === '' || value.startsWith('\\n')) {\n // Value on next lines\n const result = parseYamlNode(lines, i + 1, indent + 2);\n obj[key] = result.value;\n i = result.nextLine;\n } else {\n obj[key] = parseYamlScalar(value);\n i++;\n }\n\n // Parse remaining properties at same indent\n while (i < lines.length) {\n const nextLine = lines[i];\n const nextTrimmed = nextLine.trim();\n if (nextTrimmed === '') {\n i++;\n continue;\n }\n\n const nextIndent = nextLine.search(/\\S/);\n if (nextIndent <= baseIndent) break;\n if (nextTrimmed.startsWith('- ')) break;\n\n const nextColonIdx = nextTrimmed.indexOf(':');\n if (nextColonIdx > 0) {\n const nextKey = nextTrimmed.slice(0, nextColonIdx).trim();\n const nextValue = nextTrimmed.slice(nextColonIdx + 1).trim();\n\n if (nextValue === '' || nextValue.startsWith('\\n')) {\n const result = parseYamlNode(lines, i + 1, nextIndent + 2);\n obj[nextKey] = result.value;\n i = result.nextLine;\n } else {\n obj[nextKey] = parseYamlScalar(nextValue);\n i++;\n }\n } else {\n i++;\n }\n }\n\n items.push(obj);\n } else {\n items.push(parseYamlScalar(itemContent));\n i++;\n }\n }\n\n return { value: items, nextLine: i };\n}\n\n/**\n * Parse YAML object\n */\nfunction parseYamlObject(lines, startLine, baseIndent) {\n const obj = {};\n let i = startLine;\n\n while (i < lines.length) {\n const line = lines[i];\n const trimmed = line.trim();\n\n if (trimmed === '') {\n i++;\n continue;\n }\n\n const indent = line.search(/\\S/);\n if (indent < baseIndent && indent >= 0) break;\n\n const colonIdx = trimmed.indexOf(':');\n if (colonIdx <= 0) {\n i++;\n continue;\n }\n\n const key = trimmed.slice(0, colonIdx).trim();\n const value = trimmed.slice(colonIdx + 1).trim();\n\n if (value === '' || value === '|' || value === '>') {\n // Value on next lines\n const result = parseYamlNode(lines, i + 1, indent + 2);\n obj[key] = result.value;\n i = result.nextLine;\n } else {\n obj[key] = parseYamlScalar(value);\n i++;\n }\n }\n\n return { value: obj, nextLine: i };\n}\n\n/**\n * Parse YAML scalar value\n */\nfunction parseYamlScalar(str) {\n if (!str) return null;\n\n const trimmed = str.trim();\n\n if (trimmed === 'null' || trimmed === '~') return null;\n if (trimmed === 'true') return true;\n if (trimmed === 'false') return false;\n\n // Quoted string\n if ((trimmed.startsWith('\"') && trimmed.endsWith('\"')) ||\n (trimmed.startsWith(\"'\") && trimmed.endsWith(\"'\"))) {\n return trimmed.slice(1, -1)\n .replace(/\\\\n/g, '\\n')\n .replace(/\\\\\"/g, '\"')\n .replace(/\\\\\\\\/g, '\\\\');\n }\n\n // Number\n if (/^-?\\d+$/.test(trimmed)) return parseInt(trimmed, 10);\n if (/^-?\\d+\\.\\d+$/.test(trimmed)) return parseFloat(trimmed);\n\n return trimmed;\n}\n\n/**\n * Convert AST (or any valid input) to HTML\n * @param {string|Object} input - Markdown, AST, JSON, or YAML\n * @param {Object} options - Configuration options\n * @returns {string} - HTML string\n */\nfunction quikdown_ast_html(input, options = {}) {\n const ast = toAst(input, options);\n return renderAst(ast, options);\n}\n\n/**\n * Render an AST node to HTML\n */\nfunction renderAst(node, options = {}) {\n if (!node) return '';\n\n const { inline_styles = false } = options;\n const getAttr = createGetAttr(inline_styles);\n\n return renderNode(node, getAttr, options);\n}\n\n/**\n * Render a single node\n */\nfunction renderNode(node, getAttr, options) {\n if (!node) return '';\n\n switch (node.type) {\n case 'document':\n return renderChildren(node.children, getAttr, options);\n\n case 'paragraph':\n return `<p>${renderChildren(node.children, getAttr, options)}</p>`;\n\n case 'heading':\n const level = node.level || 1;\n return `<h${level}${getAttr('h' + level)}>${renderChildren(node.children, getAttr, options)}</h${level}>`;\n\n case 'code_block':\n const langClass = !options.inline_styles && node.lang ? ` class=\"language-${node.lang}\"` : '';\n const codeAttr = options.inline_styles ? getAttr('code') : langClass;\n return `<pre${getAttr('pre')}><code${codeAttr}>${escapeHtml(node.content)}</code></pre>`;\n\n case 'blockquote':\n return `<blockquote${getAttr('blockquote')}>${renderChildren(node.children, getAttr, options)}</blockquote>`;\n\n case 'list':\n const listTag = node.ordered ? 'ol' : 'ul';\n const items = (node.items || []).map(item => renderNode(item, getAttr, options)).join('');\n return `<${listTag}${getAttr(listTag)}>${items}</${listTag}>`;\n\n case 'list_item':\n // Handle task list items\n if (node.checked !== null && node.checked !== undefined) {\n const checkboxAttr = options.inline_styles\n ? ' style=\"margin-right:.5em\"'\n : ` class=\"${CLASS_PREFIX}task-checkbox\"`;\n const checked = node.checked ? ' checked' : '';\n const itemAttr = options.inline_styles\n ? ' style=\"list-style:none\"'\n : ` class=\"${CLASS_PREFIX}task-item\"`;\n return `<li${itemAttr}><input type=\"checkbox\"${checkboxAttr}${checked} disabled> ${renderChildren(node.children, getAttr, options)}</li>`;\n }\n return `<li${getAttr('li')}>${renderChildren(node.children, getAttr, options)}</li>`;\n\n case 'table':\n return renderTable(node, getAttr, options);\n\n case 'hr':\n return `<hr${getAttr('hr')}>`;\n\n case 'text':\n return escapeHtml(node.value || '');\n\n case 'strong':\n return `<strong${getAttr('strong')}>${renderChildren(node.children, getAttr, options)}</strong>`;\n\n case 'em':\n return `<em${getAttr('em')}>${renderChildren(node.children, getAttr, options)}</em>`;\n\n case 'del':\n return `<del${getAttr('del')}>${renderChildren(node.children, getAttr, options)}</del>`;\n\n case 'code':\n return `<code${getAttr('code')}>${escapeHtml(node.value || '')}</code>`;\n\n case 'link':\n const sanitizedHref = sanitizeUrl(node.url);\n const isExternal = /^https?:\\/\\//i.test(sanitizedHref);\n const rel = isExternal ? ' rel=\"noopener noreferrer\"' : '';\n return `<a${getAttr('a')} href=\"${sanitizedHref}\"${rel}>${renderChildren(node.children, getAttr, options)}</a>`;\n\n case 'image':\n const sanitizedSrc = sanitizeUrl(node.url);\n return `<img${getAttr('img')} src=\"${sanitizedSrc}\" alt=\"${escapeHtml(node.alt || '')}\">`;\n\n case 'br':\n return '<br>';\n\n default:\n // Unknown node type - try to render children if present\n if (node.children) {\n return renderChildren(node.children, getAttr, options);\n }\n if (node.value !== undefined) {\n return escapeHtml(String(node.value));\n }\n return '';\n }\n}\n\n/**\n * Render children array\n */\nfunction renderChildren(children, getAttr, options) {\n if (!children) return '';\n if (!Array.isArray(children)) {\n return renderNode(children, getAttr, options);\n }\n return children.map(child => renderNode(child, getAttr, options)).join('');\n}\n\n/**\n * Render a table node\n */\nfunction renderTable(node, getAttr, options) {\n const alignments = node.alignments || [];\n\n let html = `<table${getAttr('table')}>\\n`;\n\n // Headers\n if (node.headers && node.headers.length > 0) {\n html += '<thead>\\n<tr>\\n';\n node.headers.forEach((header, i) => {\n const alignStyle = alignments[i] && alignments[i] !== 'left' ? `text-align:${alignments[i]}` : '';\n html += `<th${getAttr('th', alignStyle)}>${renderChildren(header, getAttr, options)}</th>\\n`;\n });\n html += '</tr>\\n</thead>\\n';\n }\n\n // Body\n if (node.rows && node.rows.length > 0) {\n html += '<tbody>\\n';\n node.rows.forEach(row => {\n html += '<tr>\\n';\n row.forEach((cell, i) => {\n const alignStyle = alignments[i] && alignments[i] !== 'left' ? `text-align:${alignments[i]}` : '';\n html += `<td${getAttr('td', alignStyle)}>${renderChildren(cell, getAttr, options)}</td>\\n`;\n });\n html += '</tr>\\n';\n });\n html += '</tbody>\\n';\n }\n\n html += '</table>';\n return html;\n}\n\n// Expose helper functions\nquikdown_ast_html.toAst = toAst;\nquikdown_ast_html.renderAst = renderAst;\n\n// Attach version\nquikdown_ast_html.version = quikdownVersion;\n\n// Export for both CommonJS and ES6\n/* istanbul ignore next */\nif (typeof module !== 'undefined' && module.exports) {\n module.exports = quikdown_ast_html;\n}\n\n// For browser global\n/* istanbul ignore next */\nif (typeof window !== 'undefined') {\n window.quikdown_ast_html = quikdown_ast_html;\n}\n\nexport default quikdown_ast_html;\n"],"names":["quikdown_ast","markdown","options","type","children","parseBlocks","replace","text","blocks","lines","split","i","length","line","trim","fenceMatch","match","openFence","langPart","lang","codeLines","push","content","join","fence","test","headingMatch","hashes","level","parseInline","includes","tableResult","tryParseTable","node","nextIndex","quoteLines","listResult","parseList","paragraphLines","pLine","startIndex","headerLine","separatorLine","headerCells","parseTableRow","alignments","map","cell","trimmed","startsWith","endsWith","headers","rows","rowLine","cells","slice","items","loopCount","firstMatch","isOrdered","baseIndent","indent","marker","indentLevel","itemIsOrdered","subLines","subLoopCount","subLine","subMatch","nestedResult","lastItem","Array","isArray","itemNode","checked","taskMatch","toLowerCase","ordered","nodes","remaining","beforeBr","indexOf","beforeText","afterText","cleanText","parseInlineContent","imgMatch","alt","url","linkMatch","codeMatch","value","boldMatch","strikeMatch","emMatch","urlMatch","nextMarker","search","merged","mergeTextNodes","version","module","exports","window","CLASS_PREFIX","ESC_MAP","QUIKDOWN_STYLES","h1","h2","h3","h4","h5","h6","pre","code","blockquote","table","th","td","hr","img","a","strong","em","del","ul","ol","li","escapeHtml","String","m","sanitizeUrl","trimmedUrl","lowerUrl","dangerousProtocols","protocol","toAst","input","parsed","JSON","parse","_e","parseYamlNode","startLine","minIndent","nextLine","itemContent","obj","colonIdx","key","result","parseYamlScalar","nextTrimmed","nextIndent","nextColonIdx","nextKey","nextValue","parseYamlArray","parseYamlObject","str","parseInt","parseFloat","quikdown_ast_html","renderAst","inline_styles","getAttr","tag","additionalStyle","style","classAttr","createGetAttr","renderNode","renderChildren","langClass","codeAttr","listTag","item","undefined","checkboxAttr","html","forEach","header","alignStyle","row","renderTable","sanitizedHref","rel","sanitizedSrc","child"],"mappings":";;;;;;AAoBA,SAASA,EAAaC,EAAUC,EAAU,IACtC,IAAKD,GAAgC,iBAAbA,EACpB,MAAO,CAAEE,KAAM,WAAYC,SAAU,IAQzC,MAAO,CACHD,KAAM,WACNC,SAJaC,EAFJJ,EAASK,QAAQ,QAAS,MAAMA,QAAQ,MAAO,OAQhE,CAKA,SAASD,EAAYE,EAAML,GACvB,MAAMM,EAAS,GACTC,EAAQF,EAAKG,MAAM,MACzB,IAAIC,EAAI,EAER,KAAOA,EAAIF,EAAMG,QAAQ,CACrB,MAAMC,EAAOJ,EAAME,GAGnB,GAAoB,KAAhBE,EAAKC,OAAe,CACpBH,IACA,QACJ,CAGA,MAAMI,EAAaF,EAAKG,MAAM,mBAC9B,GAAID,EAAY,CACZ,MAAM,CAAGE,EAAWC,GAAYH,EAC1BI,EAAOD,EAASJ,OAChBM,EAAY,GAIlB,IAHAT,IAGOA,EAAIF,EAAMG,QAAQ,CAErB,GADqBH,EAAME,GAAGK,MAAM,kBAClB,CACdL,IACA,KACJ,CACAS,EAAUC,KAAKZ,EAAME,IACrBA,GACJ,CAEAH,EAAOa,KAAK,CACRlB,KAAM,aACNgB,KAAMA,GAAQ,KACdG,QAASF,EAAUG,KAAK,MACxBC,MAAOP,IAEX,QACJ,CAGA,GAAI,YAAYQ,KAAKZ,IAAS,eAAeY,KAAKZ,IAAS,YAAYY,KAAKZ,GAAO,CAC/EL,EAAOa,KAAK,CAAElB,KAAM,OACpBQ,IACA,QACJ,CAGA,MAAMe,EAAeb,EAAKG,MAAM,2BAChC,GAAIU,EAAc,CACd,MAAM,CAAGC,EAAQL,GAAWI,EAC5BlB,EAAOa,KAAK,CACRlB,KAAM,UACNyB,MAAOD,EAAOf,OACdR,SAAUyB,EAAYP,KAE1BX,IACA,QACJ,CAGA,GAAIE,EAAKiB,SAAS,KAAM,CACpB,MAAMC,EAAcC,EAAcvB,EAAOE,GACzC,GAAIoB,EAAa,CACbvB,EAAOa,KAAKU,EAAYE,MACxBtB,EAAIoB,EAAYG,UAChB,QACJ,CACJ,CAGA,GAAIrB,EAAKG,MAAM,SAAU,CACrB,MAAMmB,EAAa,GACnB,KAAOxB,EAAIF,EAAMG,QAAUH,EAAME,GAAGK,MAAM,UACtCmB,EAAWd,KAAKZ,EAAME,GAAGL,QAAQ,QAAS,KAC1CK,IAEJH,EAAOa,KAAK,CACRlB,KAAM,aACNC,SAAUC,EAAY8B,EAAWZ,KAAK,SAE1C,QACJ,CAIA,GADkBV,EAAKG,MAAM,gCACd,CACX,MAAMoB,EAAaC,EAAU5B,EAAOE,GACpCH,EAAOa,KAAKe,EAAWH,MACvBtB,EAAIyB,EAAWF,UACf,QACJ,CAGA,MAAMI,EAAiB,GACvB,KAAO3B,EAAIF,EAAMG,QAAQ,CACrB,MAAM2B,EAAQ9B,EAAME,GAGpB,GAAqB,KAAjB4B,EAAMzB,OAAe,MAGzB,GAAI,aAAaW,KAAKc,GAAQ,MAC9B,GAAI,YAAYd,KAAKc,GAAQ,MAC7B,GAAI,YAAYd,KAAKc,IAAU,eAAed,KAAKc,IAAU,YAAYd,KAAKc,GAAQ,MACtF,GAAI,QAAQd,KAAKc,GAAQ,MACzB,GAAI,0BAA0Bd,KAAKc,GAAQ,MAC3C,GAAIA,EAAMT,SAAS,MAAQnB,EAAI,EAAIF,EAAMG,QAAU,oBAAoBa,KAAKhB,EAAME,EAAI,IAAK,MAE3F2B,EAAejB,KAAKkB,GACpB5B,GACJ,CAEI2B,EAAe1B,OAAS,GACxBJ,EAAOa,KAAK,CACRlB,KAAM,YACNC,SAAUyB,EAAYS,EAAef,KAAK,QAGtD,CAEA,OAAOf,CACX,CAKA,SAASwB,EAAcvB,EAAO+B,EAAYtC,GAEtC,GAAIsC,EAAa,GAAK/B,EAAMG,OAAQ,OAAO,KAE3C,MAAM6B,EAAahC,EAAM+B,GACnBE,EAAgBjC,EAAM+B,EAAa,GAGzC,IAAK,oBAAoBf,KAAKiB,KAAmBA,EAAcZ,SAAS,KACpE,OAAO,KAIX,MAAMa,EAAcC,EAAcH,GAClC,GAA2B,IAAvBE,EAAY/B,OAAc,OAAO,KAGrC,MACMiC,EADiBD,EAAcF,GACHI,IAAIC,IAClC,MAAMC,EAAUD,EAAKjC,OACrB,OAAIkC,EAAQC,WAAW,MAAQD,EAAQE,SAAS,KAAa,SACzDF,EAAQE,SAAS,KAAa,QAC3B,SAILC,EAAUR,EAAYG,IAAIC,GAAQlB,EAAYkB,EAAKjC,SAGnDsC,EAAO,GACb,IAAIzC,EAAI6B,EAAa,EACrB,KAAO7B,EAAIF,EAAMG,QAAQ,CACrB,MAAMyC,EAAU5C,EAAME,GACtB,IAAK0C,EAAQvB,SAAS,MAA2B,KAAnBuB,EAAQvC,OAAe,MAErD,MAAMwC,EAAQV,EAAcS,GAC5BD,EAAK/B,KAAKiC,EAAMR,IAAIC,GAAQlB,EAAYkB,EAAKjC,UAC7CH,GACJ,CAEA,MAAO,CACHsB,KAAM,CACF9B,KAAM,QACNgD,UACAC,OACAP,cAEJX,UAAWvB,EAEnB,CAKA,SAASiC,EAAc/B,GAEnB,IAAImC,EAAUnC,EAAKC,OAGnB,OAFIkC,EAAQC,WAAW,OAAMD,EAAUA,EAAQO,MAAM,IACjDP,EAAQE,SAAS,OAAMF,EAAUA,EAAQO,MAAM,OAC5CP,EAAQtC,MAAM,IACzB,CAKA,SAAS2B,EAAU5B,EAAO+B,EAAYtC,GAClC,MAAMsD,EAAQ,GACd,IAAI7C,EAAI6B,EACJiB,EAAY,EAGhB,MAAMC,EAAajD,EAAME,GAAGK,MAAM,gCAC5B2C,EAAY,SAASlC,KAAKiC,EAAW,IACrCE,EAAaF,EAAW,GAAG9C,OAEjC,KAAOD,EAAIF,EAAMG,QAAU6C,EAvOH,KAuOoC,CACxDA,IACA,MACMzC,EADOP,EAAME,GACAK,MAAM,gCAEzB,IAAKA,EAAO,MAEZ,OAAS6C,EAAQC,EAAQxC,GAAWN,EAC9B+C,EAAcF,EAAOjD,OAG3B,GAAImD,EAAcH,EAAY,MAG9B,MAAMI,EAAgB,SAASvC,KAAKqC,GACpC,GAAIC,IAAgBH,GAAcI,IAAkBL,EAAW,MAG/D,GAAII,EAAcH,EAAY,CAE1B,MAAMK,EAAW,GACjB,IAAIC,EAAe,EACnB,KAAOvD,EAAIF,EAAMG,QAAUsD,EA7PX,KA6P+C,CAC3DA,IACA,MAAMC,EAAU1D,EAAME,GAChByD,EAAWD,EAAQnD,MAAM,2BAC/B,IAAKoD,EAAU,MACf,GAAIA,EAAS,GAAGxD,OAASgD,EAAY,MACrC,GAAIQ,EAAS,GAAGxD,SAAWgD,EAAY,MACvCK,EAAS5C,KAAK8C,GACdxD,GACJ,CAEA,GAAIsD,EAASrD,OAAS,GAAK4C,EAAM5C,OAAS,EAAG,CAEzC,MAAMyD,EAAehC,EAAU4B,EAAU,GACnCK,EAAWd,EAAMA,EAAM5C,OAAS,GACjC0D,EAASlE,SAEFmE,MAAMC,QAAQF,EAASlE,YAC/BkE,EAASlE,SAAW,CAAC,CAAED,KAAM,YAAaC,SAAUkE,EAASlE,YAF7DkE,EAASlE,SAAW,GAIxBkE,EAASlE,SAASiB,KAAKgD,EAAapC,KACxC,CACA,QACJ,CAGA,MAAMwC,EAAW,CACbtE,KAAM,YACNuE,QAAS,KACTtE,SAAU,MAIRuE,EAAYrD,EAAQN,MAAM,wBAC5B2D,IAAchB,GACdc,EAASC,QAAyC,MAA/BC,EAAU,GAAGC,cAChCH,EAASrE,SAAWyB,EAAY8C,EAAU,KAE1CF,EAASrE,SAAWyB,EAAYP,GAGpCkC,EAAMnC,KAAKoD,GACX9D,GACJ,CAEA,MAAO,CACHsB,KAAM,CACF9B,KAAM,OACN0E,QAASlB,EACTH,SAEJtB,UAAWvB,EAEnB,CAKA,SAASkB,EAAYtB,EAAML,GACvB,IAAKK,EAAM,MAAO,GAElB,MAAMuE,EAAQ,GACd,IAAIC,EAAYxE,EAEhB,KAAOwE,EAAUnE,OAAS,GAAG,CAIzB,GADgBmE,EAAU/D,MAAM,2BACjB+D,EAAUjD,SAAS,MAAO,CACrC,MAAMkD,EAAWD,EAAUE,QAAQ,MAC7BC,EAAaH,EAAUxB,MAAM,EAAGyB,GAChCG,EAAYJ,EAAUxB,MAAMyB,EAAW,GAG7C,GAAIE,EAAWhC,SAAS,OAASgC,EAAWhC,SAAS,MAAO,CACxD,MAAMkC,EAAYF,EAAW5E,QAAQ,MAAO,IAAIA,QAAQ,OAAQ,IAC5D8E,GACAN,EAAMzD,QAAQgE,EAAmBD,IAErCN,EAAMzD,KAAK,CAAElB,KAAM,OACnB4E,EAAYI,EACZ,QACJ,CACJ,CAGA,MAAMG,EAAWP,EAAU/D,MAAM,qCACjC,GAAIsE,EAAU,CACVR,EAAMzD,KAAK,CACPlB,KAAM,QACNoF,IAAKD,EAAS,GACdE,IAAKF,EAAS,GAAGxE,SAErBiE,EAAYA,EAAUxB,MAAM+B,EAAS,GAAG1E,QACxC,QACJ,CAGA,MAAM6E,EAAYV,EAAU/D,MAAM,oCAClC,GAAIyE,EAAW,CACXX,EAAMzD,KAAK,CACPlB,KAAM,OACNqF,IAAKC,EAAU,GAAG3E,OAClBV,SAAUiF,EAAmBI,EAAU,MAE3CV,EAAYA,EAAUxB,MAAMkC,EAAU,GAAG7E,QACzC,QACJ,CAGA,MAAM8E,EAAYX,EAAU/D,MAAM,cAClC,GAAI0E,EAAW,CACXZ,EAAMzD,KAAK,CACPlB,KAAM,OACNwF,MAAOD,EAAU,KAErBX,EAAYA,EAAUxB,MAAMmC,EAAU,GAAG9E,QACzC,QACJ,CAGA,MAAMgF,EAAYb,EAAU/D,MAAM,qBAClC,GAAI4E,EAAW,CACXd,EAAMzD,KAAK,CACPlB,KAAM,SACNC,SAAUiF,EAAmBO,EAAU,MAE3Cb,EAAYA,EAAUxB,MAAMqC,EAAU,GAAGhF,QACzC,QACJ,CAGA,MAAMiF,EAAcd,EAAU/D,MAAM,cACpC,GAAI6E,EAAa,CACbf,EAAMzD,KAAK,CACPlB,KAAM,MACNC,SAAUiF,EAAmBQ,EAAY,MAE7Cd,EAAYA,EAAUxB,MAAMsC,EAAY,GAAGjF,QAC3C,QACJ,CAGA,MAAMkF,EAAUf,EAAU/D,MAAM,qCAChC,GAAI8E,EAAS,CACThB,EAAMzD,KAAK,CACPlB,KAAM,KACNC,SAAUiF,EAAmBS,EAAQ,MAEzCf,EAAYA,EAAUxB,MAAMuC,EAAQ,GAAGlF,QACvC,QACJ,CAGA,MAAMmF,EAAWhB,EAAU/D,MAAM,6BACjC,GAAI+E,EAAU,CACVjB,EAAMzD,KAAK,CACPlB,KAAM,OACNqF,IAAKO,EAAS,GACd3F,SAAU,CAAC,CAAED,KAAM,OAAQwF,MAAOI,EAAS,OAE/ChB,EAAYA,EAAUxB,MAAMwC,EAAS,GAAGnF,QACxC,QACJ,CAIA,MAAMoF,EAAajB,EAAUkB,OAAO,2BACpC,IAAmB,IAAfD,EAAmB,CAEnBlB,EAAMzD,KAAK,CAAElB,KAAM,OAAQwF,MAAOZ,IAClC,KACJ,CAA0B,IAAfiB,GAEPlB,EAAMzD,KAAK,CAAElB,KAAM,OAAQwF,MAAOZ,EAAU,KAC5CA,EAAYA,EAAUxB,MAAM,KAG5BuB,EAAMzD,KAAK,CAAElB,KAAM,OAAQwF,MAAOZ,EAAUxB,MAAM,EAAGyC,KACrDjB,EAAYA,EAAUxB,MAAMyC,GAEpC,CAGA,OAgBJ,SAAwBlB,GACpB,MAAMoB,EAAS,GACf,IAAK,MAAMjE,KAAQ6C,EACG,SAAd7C,EAAK9B,MAAmB+F,EAAOtF,OAAS,GAAwC,SAAnCsF,EAAOA,EAAOtF,OAAS,GAAGT,KACvE+F,EAAOA,EAAOtF,OAAS,GAAG+E,OAAS1D,EAAK0D,MAExCO,EAAO7E,KAAKY,GAGpB,OAAOiE,CACX,CA1BWC,CAAerB,EAC1B,CAKA,SAASO,EAAmB9E,EAAML,GAI9B,OAAO2B,EADYtB,EAAKD,QAAQ,MAAO,KAE3C,CAkBAN,EAAaoG,QArdW,SAydF,oBAAXC,QAA0BA,OAAOC,UACxCD,OAAOC,QAAUtG,GAKC,oBAAXuG,SACPA,OAAOvG,aAAeA,GC9d1B,MAGMwG,EAAe,YAGfC,EAAU,CAAC,IAAI,QAAQ,IAAI,OAAO,IAAI,OAAO,IAAI,SAAS,IAAI,SAG9DC,EAAkB,CACpBC,GAAI,+DACJC,GAAI,iDACJC,GAAI,gDACJC,GAAI,gDACJC,GAAI,mDACJC,GAAI,+CACJC,IAAK,iFACLC,KAAM,6EACNC,WAAY,4DACZC,MAAO,mDACPC,GAAI,8FACJC,GAAI,oDACJC,GAAI,qDACJC,IAAK,6BACLC,EAAG,uCACHC,OAAQ,mBACRC,GAAI,oBACJC,IAAK,+BACLC,GAAI,iCACJC,GAAI,iCACJC,GAAI,iBACJ,YAAa,kBACb,gBAAiB,qBAMrB,SAASC,EAAWzH,GAChB,OAAKA,EACE0H,OAAO1H,GAAMD,QAAQ,WAAY4H,GAAKzB,EAAQyB,IADnC,EAEtB,CA+BA,SAASC,EAAY3C,GACjB,IAAKA,EAAK,MAAO,GACjB,MAAM4C,EAAa5C,EAAI1E,OACjBuH,EAAWD,EAAWxD,cAEtB0D,EAAqB,CAAC,cAAe,YAAa,SACxD,IAAK,MAAMC,KAAYD,EACnB,GAAID,EAASpF,WAAWsF,GACpB,MAAiB,UAAbA,GAAwBF,EAASpF,WAAW,eACrCmF,EAEJ,IAIf,OAAOA,CACX,CAMA,SAASI,EAAMC,EAAOvI,EAAU,IAC5B,IAAKuI,EACD,MAAO,CAAEtI,KAAM,WAAYC,SAAU,IAIzC,GAAqB,iBAAVqI,GAAsBA,EAAMtI,KACnC,OAAOsI,EAGX,GAAqB,iBAAVA,EAAoB,CAC3B,MAAMzF,EAAUyF,EAAM3H,OAGtB,GAAIkC,EAAQC,WAAW,MAAQD,EAAQC,WAAW,KAC9C,IACI,MAAMyF,EAASC,KAAKC,MAAM5F,GAC1B,MAAoB,aAAhB0F,EAAOvI,KACAuI,EAGPnE,MAAMC,QAAQkE,GACP,CAAEvI,KAAM,WAAYC,SAAUsI,GAElCA,CACX,CAAE,MAAOG,GAET,CAIJ,GAAI7F,EAAQlB,SAAS,WAAakB,EAAQlB,SAAS,cAAgBkB,EAAQlB,SAAS,WAChF,IACI,MAAM4G,EAsBXI,EAtB8B9F,EAqBlBtC,MAAM,MACG,EAAG,GAAGiF,MArBtB,GAAI+C,GAAUA,EAAOvI,KACjB,OAAOuI,CAEf,CAAE,MAAOG,GAET,CAIJ,OAAO7I,EAAayI,EAAOvI,EAC/B,CAEA,MAAO,CAAEC,KAAM,WAAYC,SAAU,GACzC,CAcA,SAAS0I,EAAcrI,EAAOsI,EAAWC,GACrC,GAAID,GAAatI,EAAMG,OACnB,MAAO,CAAE+E,MAAO,KAAMsD,SAAUF,GAGpC,MAAMlI,EAAOJ,EAAMsI,GACb/F,EAAUnC,EAAKC,OAGrB,GAAgB,KAAZkC,EACA,OAAO8F,EAAcrI,EAAOsI,EAAY,EAAGC,GAI/C,MAAMnF,EAAShD,EAAKoF,OAAO,MAC3B,GAAIpC,EAASmF,GAAanF,GAAU,EAChC,MAAO,CAAE8B,MAAO,KAAMsD,SAAUF,GAIpC,GAAI/F,EAAQC,WAAW,MACnB,OA0BR,SAAwBxC,EAAOsI,EAAWnF,GACtC,MAAMJ,EAAQ,GACd,IAAI7C,EAAIoI,EAER,KAAOpI,EAAIF,EAAMG,QAAQ,CACrB,MAAMC,EAAOJ,EAAME,GACbqC,EAAUnC,EAAKC,OAErB,GAAgB,KAAZkC,EAAgB,CAChBrC,IACA,QACJ,CAEA,MAAMkD,EAAShD,EAAKoF,OAAO,MAC3B,GAAIpC,EAASD,GAAcC,GAAU,EAAG,MACxC,GAAIA,EAASD,GAAcJ,EAAM5C,OAAS,EAAG,CAEzCD,IACA,QACJ,CAEA,IAAKqC,EAAQC,WAAW,MAAO,MAG/B,MAAMiG,EAAclG,EAAQO,MAAM,GAElC,GAAI2F,EAAYpH,SAAS,KAAM,CAE3B,MAAMqH,EAAM,CAAA,EACNC,EAAWF,EAAYjE,QAAQ,KAC/BoE,EAAMH,EAAY3F,MAAM,EAAG6F,GAAUtI,OACrC6E,EAAQuD,EAAY3F,MAAM6F,EAAW,GAAGtI,OAE9C,GAAc,KAAV6E,GAAgBA,EAAM1C,WAAW,MAAO,CAExC,MAAMqG,EAASR,EAAcrI,EAAOE,EAAI,EAAGkD,EAAS,GACpDsF,EAAIE,GAAOC,EAAO3D,MAClBhF,EAAI2I,EAAOL,QACf,MACIE,EAAIE,GAAOE,EAAgB5D,GAC3BhF,IAIJ,KAAOA,EAAIF,EAAMG,QAAQ,CACrB,MAAMqI,EAAWxI,EAAME,GACjB6I,EAAcP,EAASnI,OAC7B,GAAoB,KAAhB0I,EAAoB,CACpB7I,IACA,QACJ,CAEA,MAAM8I,EAAaR,EAAShD,OAAO,MACnC,GAAIwD,GAAc7F,EAAY,MAC9B,GAAI4F,EAAYvG,WAAW,MAAO,MAElC,MAAMyG,EAAeF,EAAYvE,QAAQ,KACzC,GAAIyE,EAAe,EAAG,CAClB,MAAMC,EAAUH,EAAYjG,MAAM,EAAGmG,GAAc5I,OAC7C8I,EAAYJ,EAAYjG,MAAMmG,EAAe,GAAG5I,OAEtD,GAAkB,KAAd8I,GAAoBA,EAAU3G,WAAW,MAAO,CAChD,MAAMqG,EAASR,EAAcrI,EAAOE,EAAI,EAAG8I,EAAa,GACxDN,EAAIQ,GAAWL,EAAO3D,MACtBhF,EAAI2I,EAAOL,QACf,MACIE,EAAIQ,GAAWJ,EAAgBK,GAC/BjJ,GAER,MACIA,GAER,CAEA6C,EAAMnC,KAAK8H,EACf,MACI3F,EAAMnC,KAAKkI,EAAgBL,IAC3BvI,GAER,CAEA,MAAO,CAAEgF,MAAOnC,EAAOyF,SAAUtI,EACrC,CA5GekJ,CAAepJ,EAAOsI,EAAWlF,GAI5C,GAAgB,OAAZb,EACA,MAAO,CAAE2C,MAAO,GAAIsD,SAAUF,EAAY,GAI9C,GAAgB,OAAZ/F,EACA,MAAO,CAAE2C,MAAO,CAAA,EAAIsD,SAAUF,EAAY,GAK9C,OADmB/F,EAAQiC,QAAQ,KAClB,EAkGrB,SAAyBxE,EAAOsI,EAAWnF,GACvC,MAAMuF,EAAM,CAAA,EACZ,IAAIxI,EAAIoI,EAER,KAAOpI,EAAIF,EAAMG,QAAQ,CACrB,MAAMC,EAAOJ,EAAME,GACbqC,EAAUnC,EAAKC,OAErB,GAAgB,KAAZkC,EAAgB,CAChBrC,IACA,QACJ,CAEA,MAAMkD,EAAShD,EAAKoF,OAAO,MAC3B,GAAIpC,EAASD,GAAcC,GAAU,EAAG,MAExC,MAAMuF,EAAWpG,EAAQiC,QAAQ,KACjC,GAAImE,GAAY,EAAG,CACfzI,IACA,QACJ,CAEA,MAAM0I,EAAMrG,EAAQO,MAAM,EAAG6F,GAAUtI,OACjC6E,EAAQ3C,EAAQO,MAAM6F,EAAW,GAAGtI,OAE1C,GAAc,KAAV6E,GAA0B,MAAVA,GAA2B,MAAVA,EAAe,CAEhD,MAAM2D,EAASR,EAAcrI,EAAOE,EAAI,EAAGkD,EAAS,GACpDsF,EAAIE,GAAOC,EAAO3D,MAClBhF,EAAI2I,EAAOL,QACf,MACIE,EAAIE,GAAOE,EAAgB5D,GAC3BhF,GAER,CAEA,MAAO,CAAEgF,MAAOwD,EAAKF,SAAUtI,EACnC,CAtIemJ,CAAgBrJ,EAAOsI,EAAWlF,GAItC,CAAE8B,MAAO4D,EAAgBvG,GAAUiG,SAAUF,EAAY,EACpE,CAsIA,SAASQ,EAAgBQ,GACrB,IAAKA,EAAK,OAAO,KAEjB,MAAM/G,EAAU+G,EAAIjJ,OAEpB,MAAgB,SAAZkC,GAAkC,MAAZA,EAAwB,KAClC,SAAZA,GACY,UAAZA,IAGCA,EAAQC,WAAW,MAAQD,EAAQE,SAAS,MAC5CF,EAAQC,WAAW,MAAQD,EAAQE,SAAS,KACtCF,EAAQO,MAAM,GAAG,GACnBjD,QAAQ,OAAQ,MAChBA,QAAQ,OAAQ,KAChBA,QAAQ,QAAS,MAItB,UAAUmB,KAAKuB,GAAiBgH,SAAShH,EAAS,IAClD,eAAevB,KAAKuB,GAAiBiH,WAAWjH,GAE7CA,EACX,CAQA,SAASkH,EAAkBzB,EAAOvI,EAAU,IAExC,OAAOiK,EADK3B,EAAMC,EAAOvI,GACHA,EAC1B,CAKA,SAASiK,EAAUlI,EAAM/B,EAAU,IAC/B,IAAK+B,EAAM,MAAO,GAElB,MAAMmI,cAAEA,GAAgB,GAAUlK,EAC5BmK,EAxUV,SAAuBD,GACnB,OAAO,SAASE,EAAKC,EAAkB,IACnC,GAAIH,EAAe,CACf,IAAII,EAAQ9D,EAAgB4D,GAC5B,OAAKE,GAAUD,GAEXA,GAAmBA,EAAgBzI,SAAS,eAAiB0I,GAASA,EAAM1I,SAAS,gBACrF0I,EAAQA,EAAMlK,QAAQ,qBAAsB,IAAIQ,OAC5C0J,IAAUA,EAAMtH,SAAS,OAAMsH,GAAS,MAIzC,WADWD,EAAmBC,EAAQ,GAAGA,IAAQD,IAAoBA,EAAmBC,MAPxD,EAS3C,CAAO,CACH,MAAMC,EAAY,WAAWjE,IAAe8D,KAC5C,OAAIC,EACO,GAAGE,YAAoBF,KAE3BE,CACX,CACJ,CACJ,CAmToBC,CAAcN,GAE9B,OAAOO,EAAW1I,EAAMoI,EAASnK,EACrC,CAKA,SAASyK,EAAW1I,EAAMoI,EAASnK,GAC/B,IAAK+B,EAAM,MAAO,GAElB,OAAQA,EAAK9B,MACT,IAAK,WACD,OAAOyK,EAAe3I,EAAK7B,SAAUiK,EAASnK,GAElD,IAAK,YACD,MAAO,MAAM0K,EAAe3I,EAAK7B,SAAUiK,EAASnK,SAExD,IAAK,UACD,MAAM0B,EAAQK,EAAKL,OAAS,EAC5B,MAAO,KAAKA,IAAQyI,EAAQ,IAAMzI,MAAUgJ,EAAe3I,EAAK7B,SAAUiK,EAASnK,QAAc0B,KAErG,IAAK,aACD,MAAMiJ,GAAa3K,EAAQkK,eAAiBnI,EAAKd,KAAO,oBAAoBc,EAAKd,QAAU,GACrF2J,EAAW5K,EAAQkK,cAAgBC,EAAQ,QAAUQ,EAC3D,MAAO,OAAOR,EAAQ,eAAeS,KAAY9C,EAAW/F,EAAKX,wBAErE,IAAK,aACD,MAAO,cAAc+I,EAAQ,iBAAiBO,EAAe3I,EAAK7B,SAAUiK,EAASnK,kBAEzF,IAAK,OACD,MAAM6K,EAAU9I,EAAK4C,QAAU,KAAO,KAChCrB,GAASvB,EAAKuB,OAAS,IAAIV,IAAIkI,GAAQL,EAAWK,EAAMX,EAASnK,IAAUqB,KAAK,IACtF,MAAO,IAAIwJ,IAAUV,EAAQU,MAAYvH,MAAUuH,KAEvD,IAAK,YAED,GAAqB,OAAjB9I,EAAKyC,cAAqCuG,IAAjBhJ,EAAKyC,QAAuB,CACrD,MAAMwG,EAAehL,EAAQkK,cACvB,6BACA,WAAW5D,kBACX9B,EAAUzC,EAAKyC,QAAU,WAAa,GAI5C,MAAO,MAHUxE,EAAQkK,cACnB,2BACA,WAAW5D,uCAC8B0E,IAAexG,eAAqBkG,EAAe3I,EAAK7B,SAAUiK,EAASnK,SAC9H,CACA,MAAO,MAAMmK,EAAQ,SAASO,EAAe3I,EAAK7B,SAAUiK,EAASnK,UAEzE,IAAK,QACD,OA2DZ,SAAqB+B,EAAMoI,EAASnK,GAChC,MAAM2C,EAAaZ,EAAKY,YAAc,GAEtC,IAAIsI,EAAO,SAASd,EAAQ,cAGxBpI,EAAKkB,SAAWlB,EAAKkB,QAAQvC,OAAS,IACtCuK,GAAQ,kBACRlJ,EAAKkB,QAAQiI,QAAQ,CAACC,EAAQ1K,KAC1B,MAAM2K,EAAazI,EAAWlC,IAAwB,SAAlBkC,EAAWlC,GAAgB,cAAckC,EAAWlC,KAAO,GAC/FwK,GAAQ,MAAMd,EAAQ,KAAMiB,MAAeV,EAAeS,EAAQhB,EAASnK,cAE/EiL,GAAQ,qBAIRlJ,EAAKmB,MAAQnB,EAAKmB,KAAKxC,OAAS,IAChCuK,GAAQ,YACRlJ,EAAKmB,KAAKgI,QAAQG,IACdJ,GAAQ,SACRI,EAAIH,QAAQ,CAACrI,EAAMpC,KACf,MAAM2K,EAAazI,EAAWlC,IAAwB,SAAlBkC,EAAWlC,GAAgB,cAAckC,EAAWlC,KAAO,GAC/FwK,GAAQ,MAAMd,EAAQ,KAAMiB,MAAeV,EAAe7H,EAAMsH,EAASnK,cAE7EiL,GAAQ,YAEZA,GAAQ,cAIZ,OADAA,GAAQ,WACDA,CACX,CA1FmBK,CAAYvJ,EAAMoI,EAASnK,GAEtC,IAAK,KACD,MAAO,MAAMmK,EAAQ,SAEzB,IAAK,OACD,OAAOrC,EAAW/F,EAAK0D,OAAS,IAEpC,IAAK,SACD,MAAO,UAAU0E,EAAQ,aAAaO,EAAe3I,EAAK7B,SAAUiK,EAASnK,cAEjF,IAAK,KACD,MAAO,MAAMmK,EAAQ,SAASO,EAAe3I,EAAK7B,SAAUiK,EAASnK,UAEzE,IAAK,MACD,MAAO,OAAOmK,EAAQ,UAAUO,EAAe3I,EAAK7B,SAAUiK,EAASnK,WAE3E,IAAK,OACD,MAAO,QAAQmK,EAAQ,WAAWrC,EAAW/F,EAAK0D,OAAS,aAE/D,IAAK,OACD,MAAM8F,EAAgBtD,EAAYlG,EAAKuD,KAEjCkG,EADa,gBAAgBjK,KAAKgK,GACf,6BAA+B,GACxD,MAAO,KAAKpB,EAAQ,cAAcoB,KAAiBC,KAAOd,EAAe3I,EAAK7B,SAAUiK,EAASnK,SAErG,IAAK,QACD,MAAMyL,EAAexD,EAAYlG,EAAKuD,KACtC,MAAO,OAAO6E,EAAQ,eAAesB,WAAsB3D,EAAW/F,EAAKsD,KAAO,QAEtF,IAAK,KACD,MAAO,OAEX,QAEI,OAAItD,EAAK7B,SACEwK,EAAe3I,EAAK7B,SAAUiK,EAASnK,QAE/B+K,IAAfhJ,EAAK0D,MACEqC,EAAWC,OAAOhG,EAAK0D,QAE3B,GAEnB,CAKA,SAASiF,EAAexK,EAAUiK,EAASnK,GACvC,OAAKE,EACAmE,MAAMC,QAAQpE,GAGZA,EAAS0C,IAAI8I,GAASjB,EAAWiB,EAAOvB,EAASnK,IAAUqB,KAAK,IAF5DoJ,EAAWvK,EAAUiK,EAASnK,GAFnB,EAK1B,CAuCAgK,EAAkB1B,MAAQA,EAC1B0B,EAAkBC,UAAYA,EAG9BD,EAAkB9D,QAzgBM,SA6gBF,oBAAXC,QAA0BA,OAAOC,UACxCD,OAAOC,QAAU4D,GAKC,oBAAX3D,SACPA,OAAO2D,kBAAoBA"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* quikdown_ast_html - AST to HTML Markdown Parser
|
|
3
|
-
* @version 1.2.
|
|
3
|
+
* @version 1.2.11
|
|
4
4
|
* @license BSD-2-Clause
|
|
5
5
|
* @copyright DeftIO 2025
|
|
6
6
|
*/
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
// Version will be injected at build time
|
|
22
|
-
const quikdownVersion$1 = '1.2.
|
|
22
|
+
const quikdownVersion$1 = '1.2.11';
|
|
23
23
|
|
|
24
24
|
// Safety limit to prevent infinite loops in list parsing
|
|
25
25
|
const MAX_LOOP_ITERATIONS = 1000;
|
|
@@ -340,8 +340,6 @@
|
|
|
340
340
|
let remaining = text;
|
|
341
341
|
|
|
342
342
|
while (remaining.length > 0) {
|
|
343
|
-
let matched = false;
|
|
344
|
-
|
|
345
343
|
// Line break (1+ trailing spaces or explicit \n after processing)
|
|
346
344
|
// Handle inline line breaks (two spaces at end of line or backslash before newline)
|
|
347
345
|
const brMatch = remaining.match(/^(.+?)(?: {2}|\\\n|\n)/);
|
|
@@ -358,7 +356,6 @@
|
|
|
358
356
|
}
|
|
359
357
|
nodes.push({ type: 'br' });
|
|
360
358
|
remaining = afterText;
|
|
361
|
-
matched = true;
|
|
362
359
|
continue;
|
|
363
360
|
}
|
|
364
361
|
}
|
|
@@ -372,7 +369,6 @@
|
|
|
372
369
|
url: imgMatch[2].trim() // Forgiving: trim whitespace in URL
|
|
373
370
|
});
|
|
374
371
|
remaining = remaining.slice(imgMatch[0].length);
|
|
375
|
-
matched = true;
|
|
376
372
|
continue;
|
|
377
373
|
}
|
|
378
374
|
|
|
@@ -385,7 +381,6 @@
|
|
|
385
381
|
children: parseInlineContent(linkMatch[1])
|
|
386
382
|
});
|
|
387
383
|
remaining = remaining.slice(linkMatch[0].length);
|
|
388
|
-
matched = true;
|
|
389
384
|
continue;
|
|
390
385
|
}
|
|
391
386
|
|
|
@@ -397,7 +392,6 @@
|
|
|
397
392
|
value: codeMatch[1]
|
|
398
393
|
});
|
|
399
394
|
remaining = remaining.slice(codeMatch[0].length);
|
|
400
|
-
matched = true;
|
|
401
395
|
continue;
|
|
402
396
|
}
|
|
403
397
|
|
|
@@ -409,7 +403,6 @@
|
|
|
409
403
|
children: parseInlineContent(boldMatch[2])
|
|
410
404
|
});
|
|
411
405
|
remaining = remaining.slice(boldMatch[0].length);
|
|
412
|
-
matched = true;
|
|
413
406
|
continue;
|
|
414
407
|
}
|
|
415
408
|
|
|
@@ -421,7 +414,6 @@
|
|
|
421
414
|
children: parseInlineContent(strikeMatch[1])
|
|
422
415
|
});
|
|
423
416
|
remaining = remaining.slice(strikeMatch[0].length);
|
|
424
|
-
matched = true;
|
|
425
417
|
continue;
|
|
426
418
|
}
|
|
427
419
|
|
|
@@ -433,7 +425,6 @@
|
|
|
433
425
|
children: parseInlineContent(emMatch[2])
|
|
434
426
|
});
|
|
435
427
|
remaining = remaining.slice(emMatch[0].length);
|
|
436
|
-
matched = true;
|
|
437
428
|
continue;
|
|
438
429
|
}
|
|
439
430
|
|
|
@@ -446,27 +437,24 @@
|
|
|
446
437
|
children: [{ type: 'text', value: urlMatch[1] }]
|
|
447
438
|
});
|
|
448
439
|
remaining = remaining.slice(urlMatch[0].length);
|
|
449
|
-
matched = true;
|
|
450
440
|
continue;
|
|
451
441
|
}
|
|
452
442
|
|
|
453
443
|
// Plain text - consume until next potential inline element or end
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
remaining = remaining.slice(nextMarker);
|
|
469
|
-
}
|
|
444
|
+
// Find next potential inline marker
|
|
445
|
+
const nextMarker = remaining.search(/[`*_~![\\n]|https?:\/\//);
|
|
446
|
+
if (nextMarker === -1) {
|
|
447
|
+
// No more markers, consume rest as text
|
|
448
|
+
nodes.push({ type: 'text', value: remaining });
|
|
449
|
+
break;
|
|
450
|
+
} else if (nextMarker === 0) {
|
|
451
|
+
// Current char is a marker but didn't match - consume it as text
|
|
452
|
+
nodes.push({ type: 'text', value: remaining[0] });
|
|
453
|
+
remaining = remaining.slice(1);
|
|
454
|
+
} else {
|
|
455
|
+
// Consume text up to next marker
|
|
456
|
+
nodes.push({ type: 'text', value: remaining.slice(0, nextMarker) });
|
|
457
|
+
remaining = remaining.slice(nextMarker);
|
|
470
458
|
}
|
|
471
459
|
}
|
|
472
460
|
|
|
@@ -524,7 +512,7 @@
|
|
|
524
512
|
|
|
525
513
|
|
|
526
514
|
// Version will be injected at build time
|
|
527
|
-
const quikdownVersion = '1.2.
|
|
515
|
+
const quikdownVersion = '1.2.11';
|
|
528
516
|
|
|
529
517
|
// Constants
|
|
530
518
|
const CLASS_PREFIX = 'quikdown-';
|