stream-markdown-parser 0.0.76 → 0.0.78
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/dist/index.d.ts +22 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +604 -202
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -9409,8 +9409,8 @@ function applyContainers(md) {
|
|
|
9409
9409
|
}
|
|
9410
9410
|
|
|
9411
9411
|
//#endregion
|
|
9412
|
-
//#region src/
|
|
9413
|
-
const
|
|
9412
|
+
//#region src/htmlTags.ts
|
|
9413
|
+
const VOID_HTML_TAG_NAMES = [
|
|
9414
9414
|
"area",
|
|
9415
9415
|
"base",
|
|
9416
9416
|
"br",
|
|
@@ -9425,9 +9425,8 @@ const VOID_TAGS$2 = new Set([
|
|
|
9425
9425
|
"source",
|
|
9426
9426
|
"track",
|
|
9427
9427
|
"wbr"
|
|
9428
|
-
]
|
|
9429
|
-
const
|
|
9430
|
-
...Array.from(VOID_TAGS$2),
|
|
9428
|
+
];
|
|
9429
|
+
const INLINE_HTML_TAG_NAMES = [
|
|
9431
9430
|
"a",
|
|
9432
9431
|
"abbr",
|
|
9433
9432
|
"b",
|
|
@@ -9442,8 +9441,6 @@ const BASE_COMMON_HTML_TAGS = new Set([
|
|
|
9442
9441
|
"em",
|
|
9443
9442
|
"font",
|
|
9444
9443
|
"i",
|
|
9445
|
-
"img",
|
|
9446
|
-
"input",
|
|
9447
9444
|
"ins",
|
|
9448
9445
|
"kbd",
|
|
9449
9446
|
"label",
|
|
@@ -9458,12 +9455,14 @@ const BASE_COMMON_HTML_TAGS = new Set([
|
|
|
9458
9455
|
"sup",
|
|
9459
9456
|
"time",
|
|
9460
9457
|
"u",
|
|
9461
|
-
"var"
|
|
9458
|
+
"var"
|
|
9459
|
+
];
|
|
9460
|
+
const BLOCK_HTML_TAG_NAMES = [
|
|
9462
9461
|
"article",
|
|
9463
9462
|
"aside",
|
|
9464
9463
|
"blockquote",
|
|
9465
|
-
"div",
|
|
9466
9464
|
"details",
|
|
9465
|
+
"div",
|
|
9467
9466
|
"figcaption",
|
|
9468
9467
|
"figure",
|
|
9469
9468
|
"footer",
|
|
@@ -9488,11 +9487,127 @@ const BASE_COMMON_HTML_TAGS = new Set([
|
|
|
9488
9487
|
"th",
|
|
9489
9488
|
"thead",
|
|
9490
9489
|
"tr",
|
|
9491
|
-
"ul"
|
|
9490
|
+
"ul"
|
|
9491
|
+
];
|
|
9492
|
+
const SVG_HTML_TAG_NAMES = [
|
|
9492
9493
|
"svg",
|
|
9493
9494
|
"g",
|
|
9494
9495
|
"path"
|
|
9496
|
+
];
|
|
9497
|
+
const EXTENDED_STANDARD_HTML_TAG_NAMES = [
|
|
9498
|
+
"address",
|
|
9499
|
+
"audio",
|
|
9500
|
+
"body",
|
|
9501
|
+
"canvas",
|
|
9502
|
+
"caption",
|
|
9503
|
+
"colgroup",
|
|
9504
|
+
"datalist",
|
|
9505
|
+
"dd",
|
|
9506
|
+
"dialog",
|
|
9507
|
+
"dl",
|
|
9508
|
+
"dt",
|
|
9509
|
+
"fieldset",
|
|
9510
|
+
"form",
|
|
9511
|
+
"head",
|
|
9512
|
+
"hgroup",
|
|
9513
|
+
"html",
|
|
9514
|
+
"iframe",
|
|
9515
|
+
"legend",
|
|
9516
|
+
"map",
|
|
9517
|
+
"menu",
|
|
9518
|
+
"meter",
|
|
9519
|
+
"noscript",
|
|
9520
|
+
"object",
|
|
9521
|
+
"optgroup",
|
|
9522
|
+
"option",
|
|
9523
|
+
"output",
|
|
9524
|
+
"picture",
|
|
9525
|
+
"progress",
|
|
9526
|
+
"rp",
|
|
9527
|
+
"rt",
|
|
9528
|
+
"ruby",
|
|
9529
|
+
"script",
|
|
9530
|
+
"select",
|
|
9531
|
+
"style",
|
|
9532
|
+
"template",
|
|
9533
|
+
"textarea",
|
|
9534
|
+
"tfoot",
|
|
9535
|
+
"title",
|
|
9536
|
+
"video"
|
|
9537
|
+
];
|
|
9538
|
+
const DANGEROUS_HTML_ATTR_NAMES = [
|
|
9539
|
+
"onclick",
|
|
9540
|
+
"onerror",
|
|
9541
|
+
"onload",
|
|
9542
|
+
"onmouseover",
|
|
9543
|
+
"onmouseout",
|
|
9544
|
+
"onmousedown",
|
|
9545
|
+
"onmouseup",
|
|
9546
|
+
"onkeydown",
|
|
9547
|
+
"onkeyup",
|
|
9548
|
+
"onfocus",
|
|
9549
|
+
"onblur",
|
|
9550
|
+
"onsubmit",
|
|
9551
|
+
"onreset",
|
|
9552
|
+
"onchange",
|
|
9553
|
+
"onselect",
|
|
9554
|
+
"ondblclick",
|
|
9555
|
+
"ontouchstart",
|
|
9556
|
+
"ontouchend",
|
|
9557
|
+
"ontouchmove",
|
|
9558
|
+
"ontouchcancel",
|
|
9559
|
+
"onwheel",
|
|
9560
|
+
"onscroll",
|
|
9561
|
+
"oncopy",
|
|
9562
|
+
"oncut",
|
|
9563
|
+
"onpaste",
|
|
9564
|
+
"oninput",
|
|
9565
|
+
"oninvalid",
|
|
9566
|
+
"onsearch"
|
|
9567
|
+
];
|
|
9568
|
+
const URL_HTML_ATTR_NAMES = [
|
|
9569
|
+
"href",
|
|
9570
|
+
"src",
|
|
9571
|
+
"srcset",
|
|
9572
|
+
"xlink:href",
|
|
9573
|
+
"formaction"
|
|
9574
|
+
];
|
|
9575
|
+
const BLOCKED_HTML_TAG_NAMES = ["script"];
|
|
9576
|
+
const VOID_HTML_TAGS = new Set(VOID_HTML_TAG_NAMES);
|
|
9577
|
+
const STANDARD_BLOCK_HTML_TAGS = new Set(BLOCK_HTML_TAG_NAMES);
|
|
9578
|
+
const STANDARD_HTML_TAGS = new Set([
|
|
9579
|
+
...VOID_HTML_TAG_NAMES,
|
|
9580
|
+
...INLINE_HTML_TAG_NAMES,
|
|
9581
|
+
...BLOCK_HTML_TAG_NAMES,
|
|
9582
|
+
...SVG_HTML_TAG_NAMES
|
|
9495
9583
|
]);
|
|
9584
|
+
const EXTENDED_STANDARD_HTML_TAGS = new Set([...STANDARD_HTML_TAGS, ...EXTENDED_STANDARD_HTML_TAG_NAMES]);
|
|
9585
|
+
const DANGEROUS_HTML_ATTRS = new Set(DANGEROUS_HTML_ATTR_NAMES);
|
|
9586
|
+
const URL_HTML_ATTRS = new Set(URL_HTML_ATTR_NAMES);
|
|
9587
|
+
const BLOCKED_HTML_TAGS = new Set(BLOCKED_HTML_TAG_NAMES);
|
|
9588
|
+
function stripHtmlControlAndWhitespace(value) {
|
|
9589
|
+
let out = "";
|
|
9590
|
+
for (const ch of value) {
|
|
9591
|
+
const code$1 = ch.charCodeAt(0);
|
|
9592
|
+
if (code$1 <= 31 || code$1 === 127) continue;
|
|
9593
|
+
if (/\s/u.test(ch)) continue;
|
|
9594
|
+
out += ch;
|
|
9595
|
+
}
|
|
9596
|
+
return out;
|
|
9597
|
+
}
|
|
9598
|
+
function isUnsafeHtmlUrl(value) {
|
|
9599
|
+
const normalized = stripHtmlControlAndWhitespace(value).toLowerCase();
|
|
9600
|
+
if (normalized.startsWith("javascript:") || normalized.startsWith("vbscript:")) return true;
|
|
9601
|
+
if (normalized.startsWith("data:")) return !(normalized.startsWith("data:image/") || normalized.startsWith("data:video/") || normalized.startsWith("data:audio/"));
|
|
9602
|
+
return false;
|
|
9603
|
+
}
|
|
9604
|
+
|
|
9605
|
+
//#endregion
|
|
9606
|
+
//#region src/plugins/fixHtmlInline.ts
|
|
9607
|
+
const VOID_TAGS = VOID_HTML_TAGS;
|
|
9608
|
+
const BASE_COMMON_HTML_TAGS = STANDARD_HTML_TAGS;
|
|
9609
|
+
const BLOCK_LEVEL_HTML_TAGS = new Set(STANDARD_BLOCK_HTML_TAGS);
|
|
9610
|
+
BLOCK_LEVEL_HTML_TAGS.delete("details");
|
|
9496
9611
|
const OPEN_TAG_RE = /<([A-Z][\w-]*)(?=[\s/>]|$)/gi;
|
|
9497
9612
|
const CLOSE_TAG_RE = /<\/\s*([A-Z][\w-]*)(?=[\s/>]|$)/gi;
|
|
9498
9613
|
const TAG_NAME_AT_START_RE = /^<\s*(?:\/\s*)?([A-Z][\w-]*)/i;
|
|
@@ -9504,9 +9619,9 @@ function isHtmlInlineClosingTag(content) {
|
|
|
9504
9619
|
return /^\s*<\s*\//.test(content);
|
|
9505
9620
|
}
|
|
9506
9621
|
function isSelfClosingHtmlInline(content, tag) {
|
|
9507
|
-
return VOID_TAGS
|
|
9622
|
+
return VOID_TAGS.has(tag) || /\/\s*>\s*$/.test(content);
|
|
9508
9623
|
}
|
|
9509
|
-
function escapeRegex$
|
|
9624
|
+
function escapeRegex$2(value) {
|
|
9510
9625
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
9511
9626
|
}
|
|
9512
9627
|
function findMatchingCloseChildIndex(children, tag) {
|
|
@@ -9542,7 +9657,7 @@ function getTrailingOpenDepth(children, tag) {
|
|
|
9542
9657
|
return depth;
|
|
9543
9658
|
}
|
|
9544
9659
|
function findMatchingCloseRangeInHtml(content, tag, startIndex = 0) {
|
|
9545
|
-
const tokenRe = new RegExp(String.raw`<\s*(\/?)\s*${escapeRegex$
|
|
9660
|
+
const tokenRe = new RegExp(String.raw`<\s*(\/?)\s*${escapeRegex$2(tag)}(?=[\s>/])[^>]*>`, "gi");
|
|
9546
9661
|
tokenRe.lastIndex = Math.max(0, startIndex);
|
|
9547
9662
|
let depth = 0;
|
|
9548
9663
|
let match;
|
|
@@ -9562,13 +9677,8 @@ function findMatchingCloseRangeInHtml(content, tag, startIndex = 0) {
|
|
|
9562
9677
|
}
|
|
9563
9678
|
return null;
|
|
9564
9679
|
}
|
|
9565
|
-
function findMatchingCloseOffsetInHtml(content, tag, startIndex = 0) {
|
|
9566
|
-
const range = findMatchingCloseRangeInHtml(content, tag, startIndex);
|
|
9567
|
-
if (!range) return -1;
|
|
9568
|
-
return range.end;
|
|
9569
|
-
}
|
|
9570
9680
|
function getTrailingCustomTagDepthInHtml(content, tag) {
|
|
9571
|
-
const tokenRe = new RegExp(String.raw`<\s*(\/?)\s*${escapeRegex$
|
|
9681
|
+
const tokenRe = new RegExp(String.raw`<\s*(\/?)\s*${escapeRegex$2(tag)}(?=[\s>/])[^>]*>`, "gi");
|
|
9572
9682
|
let depth = 0;
|
|
9573
9683
|
let match;
|
|
9574
9684
|
while ((match = tokenRe.exec(content)) !== null) {
|
|
@@ -9583,7 +9693,7 @@ function getTrailingCustomTagDepthInHtml(content, tag) {
|
|
|
9583
9693
|
}
|
|
9584
9694
|
return depth;
|
|
9585
9695
|
}
|
|
9586
|
-
function findTagCloseIndexOutsideQuotes$
|
|
9696
|
+
function findTagCloseIndexOutsideQuotes$3(html) {
|
|
9587
9697
|
let inSingle = false;
|
|
9588
9698
|
let inDouble = false;
|
|
9589
9699
|
for (let i = 0; i < html.length; i++) {
|
|
@@ -9627,7 +9737,7 @@ function findFirstIncompleteTag(content, tagSet) {
|
|
|
9627
9737
|
if (idx < 0) continue;
|
|
9628
9738
|
const tag = (m[1] ?? "").toLowerCase();
|
|
9629
9739
|
if (!isCommonHtmlTagOrPrefix(tag, tagSet)) continue;
|
|
9630
|
-
if (findTagCloseIndexOutsideQuotes$
|
|
9740
|
+
if (findTagCloseIndexOutsideQuotes$3(content.slice(idx)) !== -1) continue;
|
|
9631
9741
|
if (!first || idx < first.index) first = {
|
|
9632
9742
|
index: idx,
|
|
9633
9743
|
tag,
|
|
@@ -9639,7 +9749,7 @@ function findFirstIncompleteTag(content, tagSet) {
|
|
|
9639
9749
|
if (idx < 0) continue;
|
|
9640
9750
|
const tag = (m[1] ?? "").toLowerCase();
|
|
9641
9751
|
if (!isCommonHtmlTagOrPrefix(tag, tagSet)) continue;
|
|
9642
|
-
if (findTagCloseIndexOutsideQuotes$
|
|
9752
|
+
if (findTagCloseIndexOutsideQuotes$3(content.slice(idx)) !== -1) continue;
|
|
9643
9753
|
if (!first || idx < first.index) first = {
|
|
9644
9754
|
index: idx,
|
|
9645
9755
|
tag,
|
|
@@ -9705,7 +9815,7 @@ function fixStreamingHtmlInlineChildren(children, tagSet) {
|
|
|
9705
9815
|
cursor = lt + 1;
|
|
9706
9816
|
continue;
|
|
9707
9817
|
}
|
|
9708
|
-
const closeIdx = findTagCloseIndexOutsideQuotes$
|
|
9818
|
+
const closeIdx = findTagCloseIndexOutsideQuotes$3(sub);
|
|
9709
9819
|
if (closeIdx === -1) {
|
|
9710
9820
|
pushTextPart("<", baseToken);
|
|
9711
9821
|
cursor = lt + 1;
|
|
@@ -9743,7 +9853,7 @@ function fixStreamingHtmlInlineChildren(children, tagSet) {
|
|
|
9743
9853
|
if (pending) {
|
|
9744
9854
|
pending.buffer += tokenToRaw$1(child);
|
|
9745
9855
|
pendingAtEnd = pending.buffer;
|
|
9746
|
-
const closeIdx = findTagCloseIndexOutsideQuotes$
|
|
9856
|
+
const closeIdx = findTagCloseIndexOutsideQuotes$3(pending.buffer);
|
|
9747
9857
|
if (closeIdx === -1) continue;
|
|
9748
9858
|
const tagChunk = pending.buffer.slice(0, closeIdx + 1);
|
|
9749
9859
|
const afterChunk = pending.buffer.slice(closeIdx + 1);
|
|
@@ -9761,7 +9871,7 @@ function fixStreamingHtmlInlineChildren(children, tagSet) {
|
|
|
9761
9871
|
if (child.type === "html_inline") {
|
|
9762
9872
|
const content = tokenToRaw$1(child);
|
|
9763
9873
|
const tagName = (content.match(TAG_NAME_AT_START_RE)?.[1] ?? "").toLowerCase();
|
|
9764
|
-
if (tagName && tagSet.has(tagName) && findTagCloseIndexOutsideQuotes$
|
|
9874
|
+
if (tagName && tagSet.has(tagName) && findTagCloseIndexOutsideQuotes$3(content) === -1) {
|
|
9765
9875
|
pending = {
|
|
9766
9876
|
tag: tagName,
|
|
9767
9877
|
buffer: content,
|
|
@@ -9808,7 +9918,20 @@ function applyFixHtmlInlineTokens(md, options = {}) {
|
|
|
9808
9918
|
customTagSet.add(name);
|
|
9809
9919
|
autoCloseInlineTagSet.add(name);
|
|
9810
9920
|
}
|
|
9811
|
-
const shouldMergeHtmlBlockTag = (tag) => customTagSet.has(tag) || !commonHtmlTags.has(tag);
|
|
9921
|
+
const shouldMergeHtmlBlockTag = (tag) => customTagSet.has(tag) || !commonHtmlTags.has(tag) || BLOCK_LEVEL_HTML_TAGS.has(tag);
|
|
9922
|
+
const getHtmlBlockCarrierContent = (token) => {
|
|
9923
|
+
if (token.type === "html_block") return String(token.content ?? "");
|
|
9924
|
+
if (token.type !== "inline" || !Array.isArray(token.children) || token.children.length !== 1) return "";
|
|
9925
|
+
const onlyChild = token.children[0];
|
|
9926
|
+
if (onlyChild?.type !== "html_block") return "";
|
|
9927
|
+
return String(token.content ?? onlyChild.content ?? "");
|
|
9928
|
+
};
|
|
9929
|
+
const normalizeHtmlBlockCarrier = (token, content) => {
|
|
9930
|
+
token.type = "html_block";
|
|
9931
|
+
token.content = content;
|
|
9932
|
+
token.raw = content;
|
|
9933
|
+
token.children = [];
|
|
9934
|
+
};
|
|
9812
9935
|
md.core.ruler.after("inline", "fix_html_inline_streaming", (state) => {
|
|
9813
9936
|
const toks = state.tokens ?? [];
|
|
9814
9937
|
for (const t of toks) {
|
|
@@ -9851,14 +9974,15 @@ function applyFixHtmlInlineTokens(md, options = {}) {
|
|
|
9851
9974
|
continue;
|
|
9852
9975
|
}
|
|
9853
9976
|
const chunk = String(t.content ?? t.raw ?? "");
|
|
9854
|
-
const closeEnd = chunk ? findMatchingCloseOffsetInHtml(chunk, openTag) : -1;
|
|
9855
|
-
const isClosingTag$1 = closeEnd !== -1;
|
|
9856
9977
|
if (chunk) {
|
|
9857
9978
|
const openToken = toks[openIndex];
|
|
9858
|
-
|
|
9859
|
-
|
|
9860
|
-
|
|
9861
|
-
|
|
9979
|
+
const mergedContent = `${String(openToken.content || "")}\n${chunk}`;
|
|
9980
|
+
const openEnd = findTagCloseIndexOutsideQuotes$3(mergedContent);
|
|
9981
|
+
const closeRange = openEnd === -1 ? null : findMatchingCloseRangeInHtml(mergedContent, openTag, openEnd + 1);
|
|
9982
|
+
if (closeRange) {
|
|
9983
|
+
const before = mergedContent.slice(0, closeRange.end);
|
|
9984
|
+
const after = mergedContent.slice(closeRange.end);
|
|
9985
|
+
openToken.content = before;
|
|
9862
9986
|
openToken.loading = false;
|
|
9863
9987
|
const afterTrimmed = after.replace(/^\s+/, "");
|
|
9864
9988
|
toks.splice(i, 1);
|
|
@@ -9878,20 +10002,20 @@ function applyFixHtmlInlineTokens(md, options = {}) {
|
|
|
9878
10002
|
i--;
|
|
9879
10003
|
continue;
|
|
9880
10004
|
}
|
|
9881
|
-
openToken.content =
|
|
9882
|
-
if (openToken.loading !== false) openToken.loading =
|
|
10005
|
+
openToken.content = mergedContent;
|
|
10006
|
+
if (openToken.loading !== false) openToken.loading = true;
|
|
9883
10007
|
}
|
|
9884
10008
|
toks.splice(i, 1);
|
|
9885
10009
|
i--;
|
|
9886
|
-
if (isClosingTag$1) tagStack.pop();
|
|
9887
10010
|
continue;
|
|
9888
10011
|
}
|
|
9889
10012
|
}
|
|
9890
|
-
|
|
9891
|
-
|
|
10013
|
+
const rawContent = getHtmlBlockCarrierContent(t);
|
|
10014
|
+
if (rawContent) {
|
|
9892
10015
|
const tag = (rawContent.match(/<\s*(?:\/\s*)?([^\s>/]+)/)?.[1] ?? "").toLowerCase();
|
|
9893
10016
|
const isClosingTag$1 = /^\s*<\s*\//.test(rawContent);
|
|
9894
10017
|
if (!tag || !shouldMergeHtmlBlockTag(tag)) continue;
|
|
10018
|
+
normalizeHtmlBlockCarrier(t, rawContent);
|
|
9895
10019
|
if (!isClosingTag$1) {
|
|
9896
10020
|
if (tag) {
|
|
9897
10021
|
if (!new RegExp(`^\\s*<\\s*${tag}\\b[^>]*\\/\\s*>`, "i").test(rawContent) && getTrailingCustomTagDepthInHtml(rawContent, tag) > 0) tagStack.push([tag, i]);
|
|
@@ -10052,7 +10176,7 @@ function applyFixHtmlInlineTokens(md, options = {}) {
|
|
|
10052
10176
|
}
|
|
10053
10177
|
if (customTagSet.has(tag)) {
|
|
10054
10178
|
const raw$2 = String(t.content ?? "");
|
|
10055
|
-
const openEnd = findTagCloseIndexOutsideQuotes$
|
|
10179
|
+
const openEnd = findTagCloseIndexOutsideQuotes$3(raw$2);
|
|
10056
10180
|
const closeRange = openEnd === -1 ? null : findMatchingCloseRangeInHtml(raw$2, tag, openEnd + 1);
|
|
10057
10181
|
t.loading = !!closeRange ? false : t.loading !== void 0 ? t.loading : true;
|
|
10058
10182
|
const endTagIndex$1 = closeRange?.start ?? -1;
|
|
@@ -10185,7 +10309,7 @@ function applyFixHtmlInlineTokens(md, options = {}) {
|
|
|
10185
10309
|
}
|
|
10186
10310
|
const strictTagName = String(onlyChild.content ?? raw).match(STRICT_OPEN_TAG_NAME_AT_START_RE)?.[1]?.toLowerCase() ?? "";
|
|
10187
10311
|
if (!strictTagName) continue;
|
|
10188
|
-
if (/\/\s*>\s*$/.test(raw) || VOID_TAGS
|
|
10312
|
+
if (/\/\s*>\s*$/.test(raw) || VOID_TAGS.has(strictTagName)) {
|
|
10189
10313
|
htmlToken.children = [{
|
|
10190
10314
|
type: "html_inline",
|
|
10191
10315
|
content: raw
|
|
@@ -11075,13 +11199,7 @@ function createTh(text$1) {
|
|
|
11075
11199
|
{
|
|
11076
11200
|
type: "inline",
|
|
11077
11201
|
tag: "",
|
|
11078
|
-
children:
|
|
11079
|
-
tag: "",
|
|
11080
|
-
type: "text",
|
|
11081
|
-
block: false,
|
|
11082
|
-
content: text$1,
|
|
11083
|
-
children: null
|
|
11084
|
-
}],
|
|
11202
|
+
children: null,
|
|
11085
11203
|
content: text$1,
|
|
11086
11204
|
level: 4,
|
|
11087
11205
|
attrs: null,
|
|
@@ -11097,6 +11215,35 @@ function createTh(text$1) {
|
|
|
11097
11215
|
}
|
|
11098
11216
|
];
|
|
11099
11217
|
}
|
|
11218
|
+
function getPipeRowCells(line, requireTrailingPipe) {
|
|
11219
|
+
if (!line.startsWith("|") || line.includes("\n")) return null;
|
|
11220
|
+
if (requireTrailingPipe && !line.endsWith("|")) return null;
|
|
11221
|
+
const cells = line.slice(1).split("|");
|
|
11222
|
+
if (cells.at(-1) === "") cells.pop();
|
|
11223
|
+
return cells.length > 0 && cells.every((cell) => cell.length > 0) ? cells : null;
|
|
11224
|
+
}
|
|
11225
|
+
function isSingleLineFallbackTable(line) {
|
|
11226
|
+
return getPipeRowCells(line, false) !== null;
|
|
11227
|
+
}
|
|
11228
|
+
function hasTrailingPipeHeaderRow(line) {
|
|
11229
|
+
return getPipeRowCells(line, true) !== null;
|
|
11230
|
+
}
|
|
11231
|
+
function isSeparatorCell(cell) {
|
|
11232
|
+
return /^:?-+:?$/.test(cell.trim());
|
|
11233
|
+
}
|
|
11234
|
+
function isTableSeparatorRow(line) {
|
|
11235
|
+
if (!line.startsWith("|")) return false;
|
|
11236
|
+
const cells = line.slice(1).split("|");
|
|
11237
|
+
if (cells.at(-1) === "") cells.pop();
|
|
11238
|
+
return cells.length > 0 && cells.every(isSeparatorCell);
|
|
11239
|
+
}
|
|
11240
|
+
function isTruncatedSeparatorRow(line) {
|
|
11241
|
+
return line === "|" || line === "|:";
|
|
11242
|
+
}
|
|
11243
|
+
function hasTrailingPipeHeaderRowWithoutColon(line) {
|
|
11244
|
+
const cells = getPipeRowCells(line, true);
|
|
11245
|
+
return cells !== null && cells.every((cell) => !cell.includes(":"));
|
|
11246
|
+
}
|
|
11100
11247
|
function fixTableTokens(tokens) {
|
|
11101
11248
|
const fixedTokens = [...tokens];
|
|
11102
11249
|
if (tokens.length < 3) return fixedTokens;
|
|
@@ -11104,24 +11251,25 @@ function fixTableTokens(tokens) {
|
|
|
11104
11251
|
const token = tokens[i];
|
|
11105
11252
|
if (token.type === "inline") {
|
|
11106
11253
|
const tcontent = String(token.content ?? "");
|
|
11107
|
-
const
|
|
11108
|
-
|
|
11109
|
-
|
|
11254
|
+
const headerContent = tcontent.split("\n")[0] ?? "";
|
|
11255
|
+
const [headerLine = "", separatorLine = "", ...rest] = tcontent.split("\n");
|
|
11256
|
+
if (!tcontent.includes("\n") && isSingleLineFallbackTable(tcontent)) {
|
|
11257
|
+
const body = headerContent.slice(1).split("|").map((i$1) => i$1.trim()).filter(Boolean).flatMap((i$1) => createTh(i$1));
|
|
11110
11258
|
const insert = [
|
|
11111
11259
|
...createStart(),
|
|
11112
11260
|
...body,
|
|
11113
11261
|
...createEnd()
|
|
11114
11262
|
];
|
|
11115
11263
|
fixedTokens.splice(i - 1, 3, ...insert);
|
|
11116
|
-
} else if (
|
|
11117
|
-
const body =
|
|
11264
|
+
} else if (tcontent.includes("\n") && rest.length === 0 && hasTrailingPipeHeaderRow(headerLine) && isTableSeparatorRow(separatorLine)) {
|
|
11265
|
+
const body = headerContent.slice(1, -1).split("|").map((i$1) => i$1.trim()).flatMap((i$1) => createTh(i$1));
|
|
11118
11266
|
const insert = [
|
|
11119
11267
|
...createStart(),
|
|
11120
11268
|
...body,
|
|
11121
11269
|
...createEnd()
|
|
11122
11270
|
];
|
|
11123
11271
|
fixedTokens.splice(i - 1, 3, ...insert);
|
|
11124
|
-
} else if (
|
|
11272
|
+
} else if (tcontent.includes("\n") && rest.length === 0 && hasTrailingPipeHeaderRowWithoutColon(headerLine) && isTruncatedSeparatorRow(separatorLine)) {
|
|
11125
11273
|
token.content = tcontent.slice(0, -2);
|
|
11126
11274
|
token.children.splice(2, 1);
|
|
11127
11275
|
}
|
|
@@ -11207,24 +11355,27 @@ const TEX_BRACE_COMMANDS = [
|
|
|
11207
11355
|
const ESCAPED_TEX_BRACE_COMMANDS = TEX_BRACE_COMMANDS.map((c) => c.replace(/[.*+?^${}()|[\\]"\]/g, "\\$&")).join("|");
|
|
11208
11356
|
const TEX_CMD_RE = /\\[a-z]+/i;
|
|
11209
11357
|
const PREFIX_CLASS = "(?:\\\\|\\u0008)";
|
|
11210
|
-
const TEX_CMD_WITH_BRACES_RE = new RegExp(`${PREFIX_CLASS}(?:${ESCAPED_TEX_BRACE_COMMANDS})
|
|
11211
|
-
const TEX_BRACE_CMD_START_RE = new RegExp(`(?:${PREFIX_CLASS})?(?:${ESCAPED_TEX_BRACE_COMMANDS})\s*\{`, "i");
|
|
11358
|
+
const TEX_CMD_WITH_BRACES_RE = new RegExp(String.raw`${PREFIX_CLASS}(?:${ESCAPED_TEX_BRACE_COMMANDS})\s*\{[^}]+\}`, "i");
|
|
11359
|
+
const TEX_BRACE_CMD_START_RE = new RegExp(String.raw`(?:${PREFIX_CLASS})?(?:${ESCAPED_TEX_BRACE_COMMANDS})\s*\{`, "i");
|
|
11212
11360
|
const TEX_SPECIFIC_RE = /\\(?:text|frac|left|right|times)/;
|
|
11213
|
-
const OPS_RE =
|
|
11361
|
+
const OPS_RE = /(?:^|[^+])\+(?!\+)|[=\-*/^<>]|\\times|\\pm|\\cdot|\\le|\\ge|\\neq/;
|
|
11214
11362
|
const HYPHENATED_MULTIWORD_RE = /\b[A-Z]{2,}-[A-Z]{2,}\b/i;
|
|
11215
11363
|
const FUNC_CALL_RE = /[A-Z]+\s*\([^)]+\)/i;
|
|
11216
11364
|
const WORDS_RE = /\b(?:sin|cos|tan|log|ln|exp|sqrt|frac|sum|lim|int|prod)\b/;
|
|
11217
11365
|
const DATE_TIME_RE = /\b\d{4}\/\d{1,2}\/\d{1,2}(?:[ T]\d{1,2}:\d{2}(?::\d{2})?)?\b/;
|
|
11366
|
+
const CONTROL_TEX_REPLACEMENTS = {
|
|
11367
|
+
[String.fromCharCode(8)]: "\\b",
|
|
11368
|
+
[String.fromCharCode(11)]: "\\v",
|
|
11369
|
+
[String.fromCharCode(12)]: "\\f"
|
|
11370
|
+
};
|
|
11371
|
+
function normalizeMathControlChars(value) {
|
|
11372
|
+
let result = "";
|
|
11373
|
+
for (const ch of value) result += CONTROL_TEX_REPLACEMENTS[ch] ?? ch;
|
|
11374
|
+
return result;
|
|
11375
|
+
}
|
|
11218
11376
|
function isMathLike(s) {
|
|
11219
11377
|
if (!s) return false;
|
|
11220
|
-
const norm = s
|
|
11221
|
-
switch (ch) {
|
|
11222
|
-
case "\b": return "\\b";
|
|
11223
|
-
case "\v": return "\\v";
|
|
11224
|
-
case "\f": return "\\f";
|
|
11225
|
-
default: return ch;
|
|
11226
|
-
}
|
|
11227
|
-
});
|
|
11378
|
+
const norm = normalizeMathControlChars(s);
|
|
11228
11379
|
const stripped = norm.trim();
|
|
11229
11380
|
if (DATE_TIME_RE.test(stripped)) return false;
|
|
11230
11381
|
if (stripped.includes("**")) return false;
|
|
@@ -12170,22 +12321,6 @@ function parseHighlightToken(tokens, startIndex, options) {
|
|
|
12170
12321
|
|
|
12171
12322
|
//#endregion
|
|
12172
12323
|
//#region src/parser/inline-parsers/html-inline-code-parser.ts
|
|
12173
|
-
const VOID_TAGS$1 = new Set([
|
|
12174
|
-
"area",
|
|
12175
|
-
"base",
|
|
12176
|
-
"br",
|
|
12177
|
-
"col",
|
|
12178
|
-
"embed",
|
|
12179
|
-
"hr",
|
|
12180
|
-
"img",
|
|
12181
|
-
"input",
|
|
12182
|
-
"link",
|
|
12183
|
-
"meta",
|
|
12184
|
-
"param",
|
|
12185
|
-
"source",
|
|
12186
|
-
"track",
|
|
12187
|
-
"wbr"
|
|
12188
|
-
]);
|
|
12189
12324
|
let emptyTagSets = null;
|
|
12190
12325
|
const TAG_SET_CACHE = /* @__PURE__ */ new WeakMap();
|
|
12191
12326
|
function getEmptyTagSets() {
|
|
@@ -12203,7 +12338,7 @@ function isClosingTag(html) {
|
|
|
12203
12338
|
return /^<\s*\//.test(html);
|
|
12204
12339
|
}
|
|
12205
12340
|
function isSelfClosing(tag, html) {
|
|
12206
|
-
return /\/\s*>\s*$/.test(html) ||
|
|
12341
|
+
return /\/\s*>\s*$/.test(html) || VOID_HTML_TAGS.has(tag);
|
|
12207
12342
|
}
|
|
12208
12343
|
function normalizeCustomTag$1(t) {
|
|
12209
12344
|
const raw = String(t ?? "").trim();
|
|
@@ -12233,7 +12368,7 @@ function tokenToRaw(token) {
|
|
|
12233
12368
|
const raw = shape.raw ?? shape.content ?? shape.markup ?? "";
|
|
12234
12369
|
return String(raw ?? "");
|
|
12235
12370
|
}
|
|
12236
|
-
function parseTagAttrs(openTag) {
|
|
12371
|
+
function parseTagAttrs$1(openTag) {
|
|
12237
12372
|
const attrs = [];
|
|
12238
12373
|
const attrRegex = /\s([\w:-]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'>]+)))?/g;
|
|
12239
12374
|
let match;
|
|
@@ -12339,7 +12474,7 @@ function parseHtmlInlineCodeToken(token, tokens, i, parseInlineTokens$1, raw, pP
|
|
|
12339
12474
|
}, i + 1];
|
|
12340
12475
|
if (tag === "a") {
|
|
12341
12476
|
const fragment$1 = collectHtmlFragment(tokens, i, tag);
|
|
12342
|
-
const attrs$1 = parseTagAttrs(code$1);
|
|
12477
|
+
const attrs$1 = parseTagAttrs$1(code$1);
|
|
12343
12478
|
const innerTokens = fragment$1.innerTokens;
|
|
12344
12479
|
const href = String(getAttrValue$1(attrs$1, "href") ?? "");
|
|
12345
12480
|
const titleAttr = getAttrValue$1(attrs$1, "title");
|
|
@@ -13872,6 +14007,28 @@ function parseAdmonition(tokens, index, match, options) {
|
|
|
13872
14007
|
|
|
13873
14008
|
//#endregion
|
|
13874
14009
|
//#region src/parser/node-parsers/container-parser.ts
|
|
14010
|
+
const CONTAINER_KINDS = new Set([
|
|
14011
|
+
"warning",
|
|
14012
|
+
"info",
|
|
14013
|
+
"note",
|
|
14014
|
+
"tip",
|
|
14015
|
+
"danger",
|
|
14016
|
+
"caution"
|
|
14017
|
+
]);
|
|
14018
|
+
function parseContainerInfo(info) {
|
|
14019
|
+
let markerEnd = 0;
|
|
14020
|
+
while (markerEnd < info.length && markerEnd < 3 && info[markerEnd] === ":") markerEnd++;
|
|
14021
|
+
if (markerEnd === 0 || info[markerEnd] === ":") return null;
|
|
14022
|
+
const rest = info.slice(markerEnd).trimStart();
|
|
14023
|
+
if (!rest) return null;
|
|
14024
|
+
const firstWhitespace = rest.search(/\s/);
|
|
14025
|
+
const rawKind = (firstWhitespace === -1 ? rest : rest.slice(0, firstWhitespace)).toLowerCase();
|
|
14026
|
+
if (!CONTAINER_KINDS.has(rawKind)) return null;
|
|
14027
|
+
return {
|
|
14028
|
+
kind: rawKind,
|
|
14029
|
+
title: firstWhitespace === -1 ? "" : rest.slice(firstWhitespace).trim()
|
|
14030
|
+
};
|
|
14031
|
+
}
|
|
13875
14032
|
function parseContainer(tokens, index, options) {
|
|
13876
14033
|
const openToken = tokens[index];
|
|
13877
14034
|
let kind = "note";
|
|
@@ -13881,15 +14038,16 @@ function parseContainer(tokens, index, options) {
|
|
|
13881
14038
|
kind = typeMatch[1];
|
|
13882
14039
|
const info = String(openToken.info ?? "").trim();
|
|
13883
14040
|
if (info && !info.startsWith(":::")) {
|
|
13884
|
-
|
|
13885
|
-
|
|
14041
|
+
if (info.toLowerCase().startsWith(kind)) {
|
|
14042
|
+
const maybe = info.slice(kind.length).trim();
|
|
14043
|
+
if (maybe) title = maybe;
|
|
14044
|
+
}
|
|
13886
14045
|
}
|
|
13887
14046
|
} else {
|
|
13888
|
-
const
|
|
13889
|
-
|
|
13890
|
-
|
|
13891
|
-
|
|
13892
|
-
title = String(match[2] ?? "");
|
|
14047
|
+
const parsedInfo = parseContainerInfo(String(openToken.info ?? "").trim());
|
|
14048
|
+
if (parsedInfo) {
|
|
14049
|
+
kind = parsedInfo.kind;
|
|
14050
|
+
title = parsedInfo.title;
|
|
13893
14051
|
}
|
|
13894
14052
|
}
|
|
13895
14053
|
if (!title) title = kind.charAt(0).toUpperCase() + kind.slice(1);
|
|
@@ -14106,23 +14264,7 @@ function parseHeading(tokens, index, options) {
|
|
|
14106
14264
|
|
|
14107
14265
|
//#endregion
|
|
14108
14266
|
//#region src/parser/node-parsers/html-block-parser.ts
|
|
14109
|
-
|
|
14110
|
-
"area",
|
|
14111
|
-
"base",
|
|
14112
|
-
"br",
|
|
14113
|
-
"col",
|
|
14114
|
-
"embed",
|
|
14115
|
-
"hr",
|
|
14116
|
-
"img",
|
|
14117
|
-
"input",
|
|
14118
|
-
"link",
|
|
14119
|
-
"meta",
|
|
14120
|
-
"param",
|
|
14121
|
-
"source",
|
|
14122
|
-
"track",
|
|
14123
|
-
"wbr"
|
|
14124
|
-
]);
|
|
14125
|
-
function findTagCloseIndexOutsideQuotes$1(input) {
|
|
14267
|
+
function findTagCloseIndexOutsideQuotes$2(input) {
|
|
14126
14268
|
let inSingle = false;
|
|
14127
14269
|
let inDouble = false;
|
|
14128
14270
|
for (let i = 0; i < input.length; i++) {
|
|
@@ -14154,7 +14296,7 @@ function findMatchingCloseTagEnd(rawHtml, tag, startIndex) {
|
|
|
14154
14296
|
if (lt === -1) return -1;
|
|
14155
14297
|
const slice = rawHtml.slice(lt);
|
|
14156
14298
|
if (closeTagRe.test(slice)) {
|
|
14157
|
-
const endRel = findTagCloseIndexOutsideQuotes$
|
|
14299
|
+
const endRel = findTagCloseIndexOutsideQuotes$2(slice);
|
|
14158
14300
|
if (endRel === -1) return -1;
|
|
14159
14301
|
if (depth === 0) return lt + endRel + 1;
|
|
14160
14302
|
depth--;
|
|
@@ -14162,7 +14304,7 @@ function findMatchingCloseTagEnd(rawHtml, tag, startIndex) {
|
|
|
14162
14304
|
continue;
|
|
14163
14305
|
}
|
|
14164
14306
|
if (openTagRe.test(slice)) {
|
|
14165
|
-
const endRel = findTagCloseIndexOutsideQuotes$
|
|
14307
|
+
const endRel = findTagCloseIndexOutsideQuotes$2(slice);
|
|
14166
14308
|
if (endRel === -1) return -1;
|
|
14167
14309
|
const rawTag = slice.slice(0, endRel + 1);
|
|
14168
14310
|
if (!/\/\s*>$/.test(rawTag)) depth++;
|
|
@@ -14173,6 +14315,18 @@ function findMatchingCloseTagEnd(rawHtml, tag, startIndex) {
|
|
|
14173
14315
|
}
|
|
14174
14316
|
return -1;
|
|
14175
14317
|
}
|
|
14318
|
+
function parseTagAttrs(openTag) {
|
|
14319
|
+
const attrs = [];
|
|
14320
|
+
const attrRegex = /\s([\w:-]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'>]+)))?/g;
|
|
14321
|
+
let match;
|
|
14322
|
+
while ((match = attrRegex.exec(openTag)) !== null) {
|
|
14323
|
+
const attrName = match[1];
|
|
14324
|
+
if (!attrName) continue;
|
|
14325
|
+
const attrValue = match[2] || match[3] || match[4] || "";
|
|
14326
|
+
attrs.push([attrName, attrValue]);
|
|
14327
|
+
}
|
|
14328
|
+
return attrs;
|
|
14329
|
+
}
|
|
14176
14330
|
function parseHtmlBlock(token) {
|
|
14177
14331
|
const raw = String(token.content ?? "");
|
|
14178
14332
|
if (/^\s*<!--/.test(raw) || /^\s*<!/.test(raw) || /^\s*<\?/.test(raw)) return {
|
|
@@ -14190,10 +14344,11 @@ function parseHtmlBlock(token) {
|
|
|
14190
14344
|
tag: "",
|
|
14191
14345
|
loading: false
|
|
14192
14346
|
};
|
|
14193
|
-
const openEnd = findTagCloseIndexOutsideQuotes$
|
|
14347
|
+
const openEnd = findTagCloseIndexOutsideQuotes$2(raw);
|
|
14194
14348
|
const openTag = openEnd === -1 ? raw : raw.slice(0, openEnd + 1);
|
|
14195
14349
|
const selfClosing = openEnd !== -1 && /\/\s*>$/.test(openTag);
|
|
14196
|
-
const isVoid =
|
|
14350
|
+
const isVoid = VOID_HTML_TAGS.has(tag);
|
|
14351
|
+
const attrs = parseTagAttrs(openTag);
|
|
14197
14352
|
const hasClosing = (openEnd === -1 ? -1 : findMatchingCloseTagEnd(raw, tag, openEnd + 1)) !== -1;
|
|
14198
14353
|
const loading = !(isVoid || selfClosing || hasClosing);
|
|
14199
14354
|
return {
|
|
@@ -14201,6 +14356,7 @@ function parseHtmlBlock(token) {
|
|
|
14201
14356
|
content: loading ? `${raw.replace(/<[^>]*$/, "")}\n</${tag}>` : raw,
|
|
14202
14357
|
raw,
|
|
14203
14358
|
tag,
|
|
14359
|
+
attrs: attrs.length ? attrs : void 0,
|
|
14204
14360
|
loading
|
|
14205
14361
|
};
|
|
14206
14362
|
}
|
|
@@ -14395,7 +14551,7 @@ function parseVmrContainer(tokens, index, options) {
|
|
|
14395
14551
|
raw
|
|
14396
14552
|
}, hasCloseToken ? j + 1 : j];
|
|
14397
14553
|
}
|
|
14398
|
-
function findTagCloseIndexOutsideQuotes(input) {
|
|
14554
|
+
function findTagCloseIndexOutsideQuotes$1(input) {
|
|
14399
14555
|
let inSingle = false;
|
|
14400
14556
|
let inDouble = false;
|
|
14401
14557
|
for (let i = 0; i < input.length; i++) {
|
|
@@ -14424,14 +14580,14 @@ function stripTrailingPartialClosingTag(inner, tag) {
|
|
|
14424
14580
|
const re = new RegExp(String.raw`[\t ]*<\s*\/\s*${tag}[^>]*$`, "i");
|
|
14425
14581
|
return inner.replace(re, "");
|
|
14426
14582
|
}
|
|
14427
|
-
function escapeRegex(value) {
|
|
14583
|
+
function escapeRegex$1(value) {
|
|
14428
14584
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
14429
14585
|
}
|
|
14430
14586
|
function findMatchingCloseTagRange(rawHtml, tag, startIndex) {
|
|
14431
14587
|
if (!rawHtml || !tag) return null;
|
|
14432
14588
|
const lowerTag = tag.toLowerCase();
|
|
14433
|
-
const openTagRe = new RegExp(String.raw`^<\s*${escapeRegex(lowerTag)}(?=\s|>|/)`, "i");
|
|
14434
|
-
const closeTagRe = new RegExp(String.raw`^<\s*\/\s*${escapeRegex(lowerTag)}(?=\s|>)`, "i");
|
|
14589
|
+
const openTagRe = new RegExp(String.raw`^<\s*${escapeRegex$1(lowerTag)}(?=\s|>|/)`, "i");
|
|
14590
|
+
const closeTagRe = new RegExp(String.raw`^<\s*\/\s*${escapeRegex$1(lowerTag)}(?=\s|>)`, "i");
|
|
14435
14591
|
let depth = 0;
|
|
14436
14592
|
let index = Math.max(0, startIndex);
|
|
14437
14593
|
while (index < rawHtml.length) {
|
|
@@ -14439,7 +14595,7 @@ function findMatchingCloseTagRange(rawHtml, tag, startIndex) {
|
|
|
14439
14595
|
if (lt === -1) break;
|
|
14440
14596
|
const slice = rawHtml.slice(lt);
|
|
14441
14597
|
if (closeTagRe.test(slice)) {
|
|
14442
|
-
const endRel = findTagCloseIndexOutsideQuotes(slice);
|
|
14598
|
+
const endRel = findTagCloseIndexOutsideQuotes$1(slice);
|
|
14443
14599
|
if (endRel === -1) return null;
|
|
14444
14600
|
if (depth === 0) return {
|
|
14445
14601
|
start: lt,
|
|
@@ -14450,7 +14606,7 @@ function findMatchingCloseTagRange(rawHtml, tag, startIndex) {
|
|
|
14450
14606
|
continue;
|
|
14451
14607
|
}
|
|
14452
14608
|
if (openTagRe.test(slice)) {
|
|
14453
|
-
const endRel = findTagCloseIndexOutsideQuotes(slice);
|
|
14609
|
+
const endRel = findTagCloseIndexOutsideQuotes$1(slice);
|
|
14454
14610
|
if (endRel === -1) return null;
|
|
14455
14611
|
const raw = slice.slice(0, endRel + 1);
|
|
14456
14612
|
if (!/\/\s*>$/.test(raw)) depth++;
|
|
@@ -14470,7 +14626,7 @@ function findNextCustomHtmlBlockFromSource(source, tag, startIndex) {
|
|
|
14470
14626
|
if (!openMatch || openMatch.index == null) return null;
|
|
14471
14627
|
const openStart = openMatch.index;
|
|
14472
14628
|
const openSlice = source.slice(openStart);
|
|
14473
|
-
const openEndRel = findTagCloseIndexOutsideQuotes(openSlice);
|
|
14629
|
+
const openEndRel = findTagCloseIndexOutsideQuotes$1(openSlice);
|
|
14474
14630
|
if (openEndRel === -1) return null;
|
|
14475
14631
|
const openEnd = openStart + openEndRel;
|
|
14476
14632
|
if (/\/\s*>\s*$/.test(openSlice.slice(0, openEndRel + 1))) {
|
|
@@ -14511,7 +14667,7 @@ function findNextCustomHtmlBlockFromSource(source, tag, startIndex) {
|
|
|
14511
14667
|
continue;
|
|
14512
14668
|
}
|
|
14513
14669
|
if (isOpenAt(lt)) {
|
|
14514
|
-
const rel = findTagCloseIndexOutsideQuotes(source.slice(lt));
|
|
14670
|
+
const rel = findTagCloseIndexOutsideQuotes$1(source.slice(lt));
|
|
14515
14671
|
if (rel === -1) return null;
|
|
14516
14672
|
depth++;
|
|
14517
14673
|
i = lt + rel + 1;
|
|
@@ -14567,7 +14723,7 @@ function parseBasicBlockToken(tokens, index, options) {
|
|
|
14567
14723
|
const fromSource = findNextCustomHtmlBlockFromSource(source, tag, Math.max(clampNonNegative(cursor), clampNonNegative(mappedLineStart)));
|
|
14568
14724
|
if (fromSource) options.__customHtmlBlockCursor = fromSource.end;
|
|
14569
14725
|
const rawHtml = String(fromSource?.raw ?? htmlBlockNode.raw ?? "");
|
|
14570
|
-
const openEnd = findTagCloseIndexOutsideQuotes(rawHtml);
|
|
14726
|
+
const openEnd = findTagCloseIndexOutsideQuotes$1(rawHtml);
|
|
14571
14727
|
const openTag = openEnd !== -1 ? rawHtml.slice(0, openEnd + 1) : rawHtml;
|
|
14572
14728
|
const selfClosing = openEnd !== -1 && /\/\s*>\s*$/.test(openTag);
|
|
14573
14729
|
const closeRange = openEnd === -1 ? null : findMatchingCloseTagRange(rawHtml, tag, openEnd + 1);
|
|
@@ -14662,84 +14818,6 @@ function parseParagraph(tokens, index, options) {
|
|
|
14662
14818
|
|
|
14663
14819
|
//#endregion
|
|
14664
14820
|
//#region src/parser/index.ts
|
|
14665
|
-
const STANDARD_HTML_TAGS = new Set([
|
|
14666
|
-
"area",
|
|
14667
|
-
"base",
|
|
14668
|
-
"br",
|
|
14669
|
-
"col",
|
|
14670
|
-
"embed",
|
|
14671
|
-
"hr",
|
|
14672
|
-
"img",
|
|
14673
|
-
"input",
|
|
14674
|
-
"link",
|
|
14675
|
-
"meta",
|
|
14676
|
-
"param",
|
|
14677
|
-
"source",
|
|
14678
|
-
"track",
|
|
14679
|
-
"wbr",
|
|
14680
|
-
"a",
|
|
14681
|
-
"abbr",
|
|
14682
|
-
"b",
|
|
14683
|
-
"bdi",
|
|
14684
|
-
"bdo",
|
|
14685
|
-
"button",
|
|
14686
|
-
"cite",
|
|
14687
|
-
"code",
|
|
14688
|
-
"data",
|
|
14689
|
-
"del",
|
|
14690
|
-
"dfn",
|
|
14691
|
-
"em",
|
|
14692
|
-
"font",
|
|
14693
|
-
"i",
|
|
14694
|
-
"ins",
|
|
14695
|
-
"kbd",
|
|
14696
|
-
"label",
|
|
14697
|
-
"mark",
|
|
14698
|
-
"q",
|
|
14699
|
-
"s",
|
|
14700
|
-
"samp",
|
|
14701
|
-
"small",
|
|
14702
|
-
"span",
|
|
14703
|
-
"strong",
|
|
14704
|
-
"sub",
|
|
14705
|
-
"sup",
|
|
14706
|
-
"time",
|
|
14707
|
-
"u",
|
|
14708
|
-
"var",
|
|
14709
|
-
"article",
|
|
14710
|
-
"aside",
|
|
14711
|
-
"blockquote",
|
|
14712
|
-
"div",
|
|
14713
|
-
"details",
|
|
14714
|
-
"figcaption",
|
|
14715
|
-
"figure",
|
|
14716
|
-
"footer",
|
|
14717
|
-
"header",
|
|
14718
|
-
"h1",
|
|
14719
|
-
"h2",
|
|
14720
|
-
"h3",
|
|
14721
|
-
"h4",
|
|
14722
|
-
"h5",
|
|
14723
|
-
"h6",
|
|
14724
|
-
"li",
|
|
14725
|
-
"main",
|
|
14726
|
-
"nav",
|
|
14727
|
-
"ol",
|
|
14728
|
-
"p",
|
|
14729
|
-
"pre",
|
|
14730
|
-
"section",
|
|
14731
|
-
"summary",
|
|
14732
|
-
"table",
|
|
14733
|
-
"tbody",
|
|
14734
|
-
"td",
|
|
14735
|
-
"th",
|
|
14736
|
-
"thead",
|
|
14737
|
-
"tr",
|
|
14738
|
-
"ul",
|
|
14739
|
-
"svg",
|
|
14740
|
-
"g",
|
|
14741
|
-
"path"
|
|
14742
|
-
]);
|
|
14743
14821
|
function normalizeTagName(t) {
|
|
14744
14822
|
const raw = String(t ?? "").trim();
|
|
14745
14823
|
if (!raw) return "";
|
|
@@ -14818,6 +14896,328 @@ function parseStandaloneHtmlDocument(markdown) {
|
|
|
14818
14896
|
loading: false
|
|
14819
14897
|
}];
|
|
14820
14898
|
}
|
|
14899
|
+
function escapeRegex(value) {
|
|
14900
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
14901
|
+
}
|
|
14902
|
+
function findTagCloseIndexOutsideQuotes(input) {
|
|
14903
|
+
let inSingle = false;
|
|
14904
|
+
let inDouble = false;
|
|
14905
|
+
for (let i = 0; i < input.length; i++) {
|
|
14906
|
+
const ch = input[i];
|
|
14907
|
+
if (ch === "\\") {
|
|
14908
|
+
i++;
|
|
14909
|
+
continue;
|
|
14910
|
+
}
|
|
14911
|
+
if (!inDouble && ch === "'") {
|
|
14912
|
+
inSingle = !inSingle;
|
|
14913
|
+
continue;
|
|
14914
|
+
}
|
|
14915
|
+
if (!inSingle && ch === "\"") {
|
|
14916
|
+
inDouble = !inDouble;
|
|
14917
|
+
continue;
|
|
14918
|
+
}
|
|
14919
|
+
if (!inSingle && !inDouble && ch === ">") return i;
|
|
14920
|
+
}
|
|
14921
|
+
return -1;
|
|
14922
|
+
}
|
|
14923
|
+
function getMergeableNodeRaw(node) {
|
|
14924
|
+
const raw = node?.raw;
|
|
14925
|
+
if (typeof raw === "string") return raw;
|
|
14926
|
+
const content = node?.content;
|
|
14927
|
+
if (typeof content === "string") return content;
|
|
14928
|
+
return "";
|
|
14929
|
+
}
|
|
14930
|
+
const SOURCE_EXACT_HTML_BLOCK_TAGS = new Set([
|
|
14931
|
+
"article",
|
|
14932
|
+
"aside",
|
|
14933
|
+
"blockquote",
|
|
14934
|
+
"div",
|
|
14935
|
+
"figcaption",
|
|
14936
|
+
"figure",
|
|
14937
|
+
"footer",
|
|
14938
|
+
"h1",
|
|
14939
|
+
"h2",
|
|
14940
|
+
"h3",
|
|
14941
|
+
"h4",
|
|
14942
|
+
"h5",
|
|
14943
|
+
"h6",
|
|
14944
|
+
"header",
|
|
14945
|
+
"li",
|
|
14946
|
+
"main",
|
|
14947
|
+
"nav",
|
|
14948
|
+
"ol",
|
|
14949
|
+
"p",
|
|
14950
|
+
"pre",
|
|
14951
|
+
"section",
|
|
14952
|
+
"summary",
|
|
14953
|
+
"table",
|
|
14954
|
+
"tbody",
|
|
14955
|
+
"td",
|
|
14956
|
+
"th",
|
|
14957
|
+
"thead",
|
|
14958
|
+
"tr",
|
|
14959
|
+
"ul"
|
|
14960
|
+
]);
|
|
14961
|
+
function findNextHtmlBlockFromSource(source, tag, startIndex) {
|
|
14962
|
+
if (!source || !tag) return null;
|
|
14963
|
+
const lowerTag = tag.toLowerCase();
|
|
14964
|
+
const openRe = new RegExp(String.raw`<\s*${escapeRegex(lowerTag)}(?=\s|>|/)`, "gi");
|
|
14965
|
+
openRe.lastIndex = Math.max(0, startIndex);
|
|
14966
|
+
const openMatch = openRe.exec(source);
|
|
14967
|
+
if (!openMatch || openMatch.index == null) return null;
|
|
14968
|
+
const start = openMatch.index;
|
|
14969
|
+
const openEndRel = findTagCloseIndexOutsideQuotes(source.slice(start));
|
|
14970
|
+
if (openEndRel === -1) return null;
|
|
14971
|
+
const openEnd = start + openEndRel;
|
|
14972
|
+
const openTag = source.slice(start, openEnd + 1);
|
|
14973
|
+
if (VOID_HTML_TAGS.has(lowerTag) || /\/\s*>$/.test(openTag)) return {
|
|
14974
|
+
raw: openTag,
|
|
14975
|
+
start,
|
|
14976
|
+
end: openEnd + 1,
|
|
14977
|
+
closed: true
|
|
14978
|
+
};
|
|
14979
|
+
let depth = 1;
|
|
14980
|
+
let index = openEnd + 1;
|
|
14981
|
+
const isOpenAt = (pos) => {
|
|
14982
|
+
const slice = source.slice(pos);
|
|
14983
|
+
return new RegExp(String.raw`^<\s*${escapeRegex(lowerTag)}(?=\s|>|/)`, "i").test(slice);
|
|
14984
|
+
};
|
|
14985
|
+
const isCloseAt = (pos) => {
|
|
14986
|
+
const slice = source.slice(pos);
|
|
14987
|
+
return new RegExp(String.raw`^<\s*\/\s*${escapeRegex(lowerTag)}(?=\s|>)`, "i").test(slice);
|
|
14988
|
+
};
|
|
14989
|
+
while (index < source.length) {
|
|
14990
|
+
const lt = source.indexOf("<", index);
|
|
14991
|
+
if (lt === -1) return {
|
|
14992
|
+
raw: source.slice(start),
|
|
14993
|
+
start,
|
|
14994
|
+
end: source.length,
|
|
14995
|
+
closed: false
|
|
14996
|
+
};
|
|
14997
|
+
if (isCloseAt(lt)) {
|
|
14998
|
+
const endRel = findTagCloseIndexOutsideQuotes(source.slice(lt));
|
|
14999
|
+
if (endRel === -1) return null;
|
|
15000
|
+
depth--;
|
|
15001
|
+
const end = lt + endRel + 1;
|
|
15002
|
+
if (depth === 0) return {
|
|
15003
|
+
raw: source.slice(start, end),
|
|
15004
|
+
start,
|
|
15005
|
+
end,
|
|
15006
|
+
closed: true
|
|
15007
|
+
};
|
|
15008
|
+
index = end;
|
|
15009
|
+
continue;
|
|
15010
|
+
}
|
|
15011
|
+
if (isOpenAt(lt)) {
|
|
15012
|
+
const endRel = findTagCloseIndexOutsideQuotes(source.slice(lt));
|
|
15013
|
+
if (endRel === -1) return null;
|
|
15014
|
+
const raw = source.slice(lt, lt + endRel + 1);
|
|
15015
|
+
if (!/\/\s*>$/.test(raw)) depth++;
|
|
15016
|
+
index = lt + endRel + 1;
|
|
15017
|
+
continue;
|
|
15018
|
+
}
|
|
15019
|
+
index = lt + 1;
|
|
15020
|
+
}
|
|
15021
|
+
return {
|
|
15022
|
+
raw: source.slice(start),
|
|
15023
|
+
start,
|
|
15024
|
+
end: source.length,
|
|
15025
|
+
closed: false
|
|
15026
|
+
};
|
|
15027
|
+
}
|
|
15028
|
+
function findApproximateConsumedPrefixEnd(exact, approximate) {
|
|
15029
|
+
if (!approximate) return 0;
|
|
15030
|
+
let i = 0;
|
|
15031
|
+
let j = 0;
|
|
15032
|
+
while (i < exact.length && j < approximate.length) {
|
|
15033
|
+
if (exact[i] === approximate[j]) {
|
|
15034
|
+
i++;
|
|
15035
|
+
j++;
|
|
15036
|
+
continue;
|
|
15037
|
+
}
|
|
15038
|
+
if (exact[i] === "\r" || exact[i] === "\n") {
|
|
15039
|
+
i++;
|
|
15040
|
+
continue;
|
|
15041
|
+
}
|
|
15042
|
+
return -1;
|
|
15043
|
+
}
|
|
15044
|
+
return j === approximate.length ? i : -1;
|
|
15045
|
+
}
|
|
15046
|
+
function buildHtmlBlockContent(raw, tag, closed) {
|
|
15047
|
+
if (closed) return raw;
|
|
15048
|
+
return `${raw.replace(/<[^>]*$/, "")}\n</${tag}>`;
|
|
15049
|
+
}
|
|
15050
|
+
function extendHtmlBlockCloseToLineEnding(source, startIndex) {
|
|
15051
|
+
let end = Math.max(0, startIndex);
|
|
15052
|
+
while (end < source.length && (source[end] === " " || source[end] === " ")) end++;
|
|
15053
|
+
if (source[end] === "\r") {
|
|
15054
|
+
end++;
|
|
15055
|
+
if (source[end] === "\n") end++;
|
|
15056
|
+
return end;
|
|
15057
|
+
}
|
|
15058
|
+
if (source[end] === "\n") return end + 1;
|
|
15059
|
+
return startIndex;
|
|
15060
|
+
}
|
|
15061
|
+
function isDetailsOpenHtmlBlock(node) {
|
|
15062
|
+
if (node.type !== "html_block") return false;
|
|
15063
|
+
if (String(node.tag ?? "").toLowerCase() !== "details") return false;
|
|
15064
|
+
const raw = String(node.raw ?? node.content ?? "");
|
|
15065
|
+
return /^\s*<details\b/i.test(raw);
|
|
15066
|
+
}
|
|
15067
|
+
function isDetailsCloseHtmlBlock(node) {
|
|
15068
|
+
if (node.type !== "html_block") return false;
|
|
15069
|
+
const raw = String(node.raw ?? node.content ?? "");
|
|
15070
|
+
return /^\s*<\/details\b/i.test(raw);
|
|
15071
|
+
}
|
|
15072
|
+
function findLastClosingTagStart(raw, tag) {
|
|
15073
|
+
const closeRe = new RegExp(String.raw`<\s*\/\s*${escapeRegex(tag)}(?=\s|>)`, "gi");
|
|
15074
|
+
let last = -1;
|
|
15075
|
+
let match;
|
|
15076
|
+
while ((match = closeRe.exec(raw)) !== null) last = match.index;
|
|
15077
|
+
return last;
|
|
15078
|
+
}
|
|
15079
|
+
function buildDetailsChildParseOptions(options, final) {
|
|
15080
|
+
return {
|
|
15081
|
+
final,
|
|
15082
|
+
requireClosingStrong: options.requireClosingStrong,
|
|
15083
|
+
customHtmlTags: options.customHtmlTags,
|
|
15084
|
+
validateLink: options.validateLink
|
|
15085
|
+
};
|
|
15086
|
+
}
|
|
15087
|
+
function parseDetailsFragmentChildren(fragment, md, options) {
|
|
15088
|
+
if (!fragment.trim()) return [];
|
|
15089
|
+
return parseMarkdownToStructure(fragment, md, options);
|
|
15090
|
+
}
|
|
15091
|
+
function buildStructuredSummaryNode(summaryRaw, md, options) {
|
|
15092
|
+
const summaryNode = parseHtmlBlock({ content: summaryRaw });
|
|
15093
|
+
const openEnd = findTagCloseIndexOutsideQuotes(summaryRaw);
|
|
15094
|
+
const closeStart = findLastClosingTagStart(summaryRaw, "summary");
|
|
15095
|
+
if (openEnd !== -1 && closeStart !== -1 && closeStart >= openEnd + 1) {
|
|
15096
|
+
const children = parseDetailsFragmentChildren(summaryRaw.slice(openEnd + 1, closeStart), md, options);
|
|
15097
|
+
if (children.length > 0) summaryNode.children = children;
|
|
15098
|
+
}
|
|
15099
|
+
summaryNode.raw = summaryRaw;
|
|
15100
|
+
return summaryNode;
|
|
15101
|
+
}
|
|
15102
|
+
function buildDetailsPrefixChildren(openRaw, md, options) {
|
|
15103
|
+
const openEnd = findTagCloseIndexOutsideQuotes(openRaw);
|
|
15104
|
+
if (openEnd === -1) return [];
|
|
15105
|
+
const innerPrefix = openRaw.slice(openEnd + 1);
|
|
15106
|
+
if (!innerPrefix.trim()) return [];
|
|
15107
|
+
const summaryBlock = findNextHtmlBlockFromSource(innerPrefix, "summary", 0);
|
|
15108
|
+
if (!summaryBlock) return parseDetailsFragmentChildren(innerPrefix, md, options);
|
|
15109
|
+
const beforeSummary = innerPrefix.slice(0, summaryBlock.start);
|
|
15110
|
+
const afterSummary = innerPrefix.slice(summaryBlock.end);
|
|
15111
|
+
return [
|
|
15112
|
+
...parseDetailsFragmentChildren(beforeSummary, md, options),
|
|
15113
|
+
buildStructuredSummaryNode(summaryBlock.raw, md, options),
|
|
15114
|
+
...parseDetailsFragmentChildren(afterSummary, md, options)
|
|
15115
|
+
];
|
|
15116
|
+
}
|
|
15117
|
+
function combineStructuredDetailsHtmlBlocks(nodes, source, md, options, final, sourceCursor = 0) {
|
|
15118
|
+
const merged = [];
|
|
15119
|
+
let cursor = sourceCursor;
|
|
15120
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
15121
|
+
const node = nodes[i];
|
|
15122
|
+
const nodeRaw = getMergeableNodeRaw(node);
|
|
15123
|
+
let nodePos = -1;
|
|
15124
|
+
if (nodeRaw) {
|
|
15125
|
+
nodePos = source.indexOf(nodeRaw, cursor);
|
|
15126
|
+
if (nodePos !== -1) cursor = nodePos + nodeRaw.length;
|
|
15127
|
+
}
|
|
15128
|
+
if (!isDetailsOpenHtmlBlock(node)) {
|
|
15129
|
+
merged.push(node);
|
|
15130
|
+
continue;
|
|
15131
|
+
}
|
|
15132
|
+
const openRaw = String(node.raw ?? getMergeableNodeRaw(node) ?? "");
|
|
15133
|
+
const openStart = nodePos !== -1 ? nodePos : source.indexOf(openRaw, Math.max(0, cursor - openRaw.length));
|
|
15134
|
+
if (openStart === -1) {
|
|
15135
|
+
merged.push(node);
|
|
15136
|
+
continue;
|
|
15137
|
+
}
|
|
15138
|
+
let depth = 1;
|
|
15139
|
+
let closeIndex = -1;
|
|
15140
|
+
for (let j = i + 1; j < nodes.length; j++) {
|
|
15141
|
+
const current = nodes[j];
|
|
15142
|
+
if (isDetailsOpenHtmlBlock(current)) {
|
|
15143
|
+
depth++;
|
|
15144
|
+
continue;
|
|
15145
|
+
}
|
|
15146
|
+
if (!isDetailsCloseHtmlBlock(current)) continue;
|
|
15147
|
+
depth--;
|
|
15148
|
+
if (depth === 0) {
|
|
15149
|
+
closeIndex = j;
|
|
15150
|
+
break;
|
|
15151
|
+
}
|
|
15152
|
+
}
|
|
15153
|
+
const [children] = combineStructuredDetailsHtmlBlocks(closeIndex === -1 ? nodes.slice(i + 1) : nodes.slice(i + 1, closeIndex), source, md, options, final, openStart + openRaw.length);
|
|
15154
|
+
const prefixChildren = buildDetailsPrefixChildren(openRaw, md, buildDetailsChildParseOptions(options, final));
|
|
15155
|
+
const exact = findNextHtmlBlockFromSource(source, "details", openStart);
|
|
15156
|
+
const closeRaw = closeIndex === -1 ? "</details>" : String(nodes[closeIndex]?.raw ?? getMergeableNodeRaw(nodes[closeIndex]) ?? "</details>");
|
|
15157
|
+
const explicitClose = closeIndex !== -1 && exact?.closed === true;
|
|
15158
|
+
const trimmedCloseRaw = closeRaw.replace(/[\t\r\n ]+$/, "");
|
|
15159
|
+
const closeStart = explicitClose ? (() => {
|
|
15160
|
+
const closeOffset = exact.raw.lastIndexOf(trimmedCloseRaw);
|
|
15161
|
+
return closeOffset === -1 ? source.length : openStart + closeOffset;
|
|
15162
|
+
})() : source.length;
|
|
15163
|
+
const middleSource = source.slice(openStart + openRaw.length, closeStart === -1 ? source.length : closeStart);
|
|
15164
|
+
const middleTokens = md.parse(middleSource, { __markstreamFinal: final });
|
|
15165
|
+
const renderedMiddle = md.renderer.render(middleTokens, md.options, { __markstreamFinal: final });
|
|
15166
|
+
const closeMarkupEnd = closeStart + trimmedCloseRaw.length;
|
|
15167
|
+
const closeSliceEnd = explicitClose ? Math.max(closeStart + closeRaw.length, extendHtmlBlockCloseToLineEnding(source, closeMarkupEnd)) : source.length;
|
|
15168
|
+
const renderedCloseRaw = explicitClose ? source.slice(closeStart, closeSliceEnd) : closeRaw;
|
|
15169
|
+
const mergedRaw = explicitClose ? source.slice(openStart, closeSliceEnd) : source.slice(openStart);
|
|
15170
|
+
merged.push({
|
|
15171
|
+
...node,
|
|
15172
|
+
tag: "details",
|
|
15173
|
+
attrs: parseTagAttrs(openRaw.slice(0, findTagCloseIndexOutsideQuotes(openRaw) + 1)),
|
|
15174
|
+
raw: mergedRaw,
|
|
15175
|
+
content: `${openRaw}${renderedMiddle}${renderedCloseRaw}`,
|
|
15176
|
+
children: [...prefixChildren, ...children],
|
|
15177
|
+
loading: !final && !explicitClose
|
|
15178
|
+
});
|
|
15179
|
+
cursor = explicitClose ? closeSliceEnd : source.length;
|
|
15180
|
+
if (closeIndex === -1) break;
|
|
15181
|
+
i = closeIndex;
|
|
15182
|
+
}
|
|
15183
|
+
return [merged, cursor];
|
|
15184
|
+
}
|
|
15185
|
+
function mergeSplitTopLevelHtmlBlocks(nodes, final, source) {
|
|
15186
|
+
if (!source) return nodes;
|
|
15187
|
+
const merged = nodes.slice();
|
|
15188
|
+
let sourceHtmlCursor = 0;
|
|
15189
|
+
for (let i = 0; i < merged.length; i++) {
|
|
15190
|
+
const node = merged[i];
|
|
15191
|
+
if (node?.type !== "html_block") continue;
|
|
15192
|
+
const tag = String(node?.tag ?? "").toLowerCase();
|
|
15193
|
+
if (!tag) continue;
|
|
15194
|
+
if (!SOURCE_EXACT_HTML_BLOCK_TAGS.has(tag)) continue;
|
|
15195
|
+
const exact = findNextHtmlBlockFromSource(source, tag, sourceHtmlCursor);
|
|
15196
|
+
if (!exact) continue;
|
|
15197
|
+
sourceHtmlCursor = exact.end;
|
|
15198
|
+
const currentContent = String(node?.content ?? getMergeableNodeRaw(node));
|
|
15199
|
+
const currentRaw = String(node?.raw ?? currentContent);
|
|
15200
|
+
const nextContent = buildHtmlBlockContent(exact.raw, tag, exact.closed);
|
|
15201
|
+
const desiredLoading = !final && !exact.closed;
|
|
15202
|
+
const needsExpansion = currentContent !== nextContent || currentRaw !== exact.raw || Boolean(node?.loading) !== desiredLoading;
|
|
15203
|
+
node.content = nextContent;
|
|
15204
|
+
node.raw = exact.raw;
|
|
15205
|
+
node.loading = desiredLoading;
|
|
15206
|
+
if (!needsExpansion) continue;
|
|
15207
|
+
let tailCursor = findApproximateConsumedPrefixEnd(exact.raw, currentContent);
|
|
15208
|
+
if (tailCursor === -1) tailCursor = 0;
|
|
15209
|
+
const j = i + 1;
|
|
15210
|
+
while (j < merged.length) {
|
|
15211
|
+
const nextRaw = getMergeableNodeRaw(merged[j]);
|
|
15212
|
+
if (!nextRaw) break;
|
|
15213
|
+
const nextPos = exact.raw.indexOf(nextRaw, tailCursor);
|
|
15214
|
+
if (nextPos === -1) break;
|
|
15215
|
+
tailCursor = nextPos + nextRaw.length;
|
|
15216
|
+
merged.splice(j, 1);
|
|
15217
|
+
}
|
|
15218
|
+
}
|
|
15219
|
+
return merged;
|
|
15220
|
+
}
|
|
14821
15221
|
function stripDanglingHtmlLikeTail(markdown) {
|
|
14822
15222
|
const isWs = (ch) => ch === " " || ch === " " || ch === "\n" || ch === "\r";
|
|
14823
15223
|
const isLikelyHtmlTagPrefix = (tail$1) => {
|
|
@@ -14986,7 +15386,7 @@ function ensureBlankLineBeforeInlineMultilineCustomHtmlBlocks(markdown, tags) {
|
|
|
14986
15386
|
}
|
|
14987
15387
|
return false;
|
|
14988
15388
|
};
|
|
14989
|
-
const findTagCloseIndexOutsideQuotes$
|
|
15389
|
+
const findTagCloseIndexOutsideQuotes$4 = (input) => {
|
|
14990
15390
|
let inSingle = false;
|
|
14991
15391
|
let inDouble = false;
|
|
14992
15392
|
for (let i = 0; i < input.length; i++) {
|
|
@@ -15035,7 +15435,7 @@ function ensureBlankLineBeforeInlineMultilineCustomHtmlBlocks(markdown, tags) {
|
|
|
15035
15435
|
i++;
|
|
15036
15436
|
continue;
|
|
15037
15437
|
}
|
|
15038
|
-
const closeIdxRel = findTagCloseIndexOutsideQuotes$
|
|
15438
|
+
const closeIdxRel = findTagCloseIndexOutsideQuotes$4(line.slice(i));
|
|
15039
15439
|
if (closeIdxRel === -1) {
|
|
15040
15440
|
hasRenderablePrefix = true;
|
|
15041
15441
|
i++;
|
|
@@ -15139,7 +15539,7 @@ function normalizeCustomHtmlOpeningTagSameLine(markdown, tags) {
|
|
|
15139
15539
|
while (i < s.length && isIndentWs(s[i])) i++;
|
|
15140
15540
|
return s.slice(i);
|
|
15141
15541
|
};
|
|
15142
|
-
const findTagCloseIndexOutsideQuotes$
|
|
15542
|
+
const findTagCloseIndexOutsideQuotes$4 = (input) => {
|
|
15143
15543
|
let inSingle = false;
|
|
15144
15544
|
let inDouble = false;
|
|
15145
15545
|
for (let i = 0; i < input.length; i++) {
|
|
@@ -15211,7 +15611,7 @@ function normalizeCustomHtmlOpeningTagSameLine(markdown, tags) {
|
|
|
15211
15611
|
if (i === nameStart) return line;
|
|
15212
15612
|
const tagName = line.slice(nameStart, i).toLowerCase();
|
|
15213
15613
|
if (!tagSet.has(tagName)) return line;
|
|
15214
|
-
const gtRel = findTagCloseIndexOutsideQuotes$
|
|
15614
|
+
const gtRel = findTagCloseIndexOutsideQuotes$4(line.slice(i));
|
|
15215
15615
|
if (gtRel === -1) return line;
|
|
15216
15616
|
const gt = i + gtRel;
|
|
15217
15617
|
if (hasClosingTagOnLine(line, gt + 1, tagName)) return line;
|
|
@@ -15655,6 +16055,8 @@ function parseMarkdownToStructure(markdown, md, options = {}) {
|
|
|
15655
16055
|
else result = postResult;
|
|
15656
16056
|
}
|
|
15657
16057
|
}
|
|
16058
|
+
result = mergeSplitTopLevelHtmlBlocks(result, isFinal, safeMarkdown);
|
|
16059
|
+
result = combineStructuredDetailsHtmlBlocks(result, safeMarkdown, md, options, isFinal)[0];
|
|
15658
16060
|
if (isFinal) {
|
|
15659
16061
|
const seen = /* @__PURE__ */ new WeakSet();
|
|
15660
16062
|
const finalizeHtmlBlockLoading = (value) => {
|
|
@@ -15902,5 +16304,5 @@ function getMarkdown(msgId = `editor-${Date.now()}`, options = {}) {
|
|
|
15902
16304
|
}
|
|
15903
16305
|
|
|
15904
16306
|
//#endregion
|
|
15905
|
-
export { ESCAPED_TEX_BRACE_COMMANDS, KATEX_COMMANDS, TEX_BRACE_COMMANDS, applyContainers, applyMath, clearRegisteredMarkdownPlugins, findMatchingClose, getMarkdown, isMathLike, normalizeStandaloneBackslashT, parseFenceToken, parseInlineTokens, parseMarkdownToStructure, processTokens, registerMarkdownPlugin, setDefaultMathOptions };
|
|
16307
|
+
export { BLOCKED_HTML_TAGS, BLOCKED_HTML_TAG_NAMES, BLOCK_HTML_TAG_NAMES, DANGEROUS_HTML_ATTRS, DANGEROUS_HTML_ATTR_NAMES, ESCAPED_TEX_BRACE_COMMANDS, EXTENDED_STANDARD_HTML_TAGS, EXTENDED_STANDARD_HTML_TAG_NAMES, INLINE_HTML_TAG_NAMES, KATEX_COMMANDS, STANDARD_BLOCK_HTML_TAGS, STANDARD_HTML_TAGS, SVG_HTML_TAG_NAMES, TEX_BRACE_COMMANDS, URL_HTML_ATTRS, URL_HTML_ATTR_NAMES, VOID_HTML_TAGS, VOID_HTML_TAG_NAMES, applyContainers, applyMath, clearRegisteredMarkdownPlugins, findMatchingClose, getMarkdown, isMathLike, isUnsafeHtmlUrl, normalizeStandaloneBackslashT, parseFenceToken, parseInlineTokens, parseMarkdownToStructure, processTokens, registerMarkdownPlugin, setDefaultMathOptions, stripHtmlControlAndWhitespace };
|
|
15906
16308
|
//# sourceMappingURL=index.js.map
|