stream-markdown-parser 0.0.77 → 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 +600 -192
- 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
|
|
@@ -11091,6 +11215,35 @@ function createTh(text$1) {
|
|
|
11091
11215
|
}
|
|
11092
11216
|
];
|
|
11093
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
|
+
}
|
|
11094
11247
|
function fixTableTokens(tokens) {
|
|
11095
11248
|
const fixedTokens = [...tokens];
|
|
11096
11249
|
if (tokens.length < 3) return fixedTokens;
|
|
@@ -11099,7 +11252,8 @@ function fixTableTokens(tokens) {
|
|
|
11099
11252
|
if (token.type === "inline") {
|
|
11100
11253
|
const tcontent = String(token.content ?? "");
|
|
11101
11254
|
const headerContent = tcontent.split("\n")[0] ?? "";
|
|
11102
|
-
|
|
11255
|
+
const [headerLine = "", separatorLine = "", ...rest] = tcontent.split("\n");
|
|
11256
|
+
if (!tcontent.includes("\n") && isSingleLineFallbackTable(tcontent)) {
|
|
11103
11257
|
const body = headerContent.slice(1).split("|").map((i$1) => i$1.trim()).filter(Boolean).flatMap((i$1) => createTh(i$1));
|
|
11104
11258
|
const insert = [
|
|
11105
11259
|
...createStart(),
|
|
@@ -11107,7 +11261,7 @@ function fixTableTokens(tokens) {
|
|
|
11107
11261
|
...createEnd()
|
|
11108
11262
|
];
|
|
11109
11263
|
fixedTokens.splice(i - 1, 3, ...insert);
|
|
11110
|
-
} else if (
|
|
11264
|
+
} else if (tcontent.includes("\n") && rest.length === 0 && hasTrailingPipeHeaderRow(headerLine) && isTableSeparatorRow(separatorLine)) {
|
|
11111
11265
|
const body = headerContent.slice(1, -1).split("|").map((i$1) => i$1.trim()).flatMap((i$1) => createTh(i$1));
|
|
11112
11266
|
const insert = [
|
|
11113
11267
|
...createStart(),
|
|
@@ -11115,7 +11269,7 @@ function fixTableTokens(tokens) {
|
|
|
11115
11269
|
...createEnd()
|
|
11116
11270
|
];
|
|
11117
11271
|
fixedTokens.splice(i - 1, 3, ...insert);
|
|
11118
|
-
} else if (
|
|
11272
|
+
} else if (tcontent.includes("\n") && rest.length === 0 && hasTrailingPipeHeaderRowWithoutColon(headerLine) && isTruncatedSeparatorRow(separatorLine)) {
|
|
11119
11273
|
token.content = tcontent.slice(0, -2);
|
|
11120
11274
|
token.children.splice(2, 1);
|
|
11121
11275
|
}
|
|
@@ -11201,24 +11355,27 @@ const TEX_BRACE_COMMANDS = [
|
|
|
11201
11355
|
const ESCAPED_TEX_BRACE_COMMANDS = TEX_BRACE_COMMANDS.map((c) => c.replace(/[.*+?^${}()|[\\]"\]/g, "\\$&")).join("|");
|
|
11202
11356
|
const TEX_CMD_RE = /\\[a-z]+/i;
|
|
11203
11357
|
const PREFIX_CLASS = "(?:\\\\|\\u0008)";
|
|
11204
|
-
const TEX_CMD_WITH_BRACES_RE = new RegExp(`${PREFIX_CLASS}(?:${ESCAPED_TEX_BRACE_COMMANDS})
|
|
11205
|
-
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");
|
|
11206
11360
|
const TEX_SPECIFIC_RE = /\\(?:text|frac|left|right|times)/;
|
|
11207
|
-
const OPS_RE =
|
|
11361
|
+
const OPS_RE = /(?:^|[^+])\+(?!\+)|[=\-*/^<>]|\\times|\\pm|\\cdot|\\le|\\ge|\\neq/;
|
|
11208
11362
|
const HYPHENATED_MULTIWORD_RE = /\b[A-Z]{2,}-[A-Z]{2,}\b/i;
|
|
11209
11363
|
const FUNC_CALL_RE = /[A-Z]+\s*\([^)]+\)/i;
|
|
11210
11364
|
const WORDS_RE = /\b(?:sin|cos|tan|log|ln|exp|sqrt|frac|sum|lim|int|prod)\b/;
|
|
11211
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
|
+
}
|
|
11212
11376
|
function isMathLike(s) {
|
|
11213
11377
|
if (!s) return false;
|
|
11214
|
-
const norm = s
|
|
11215
|
-
switch (ch) {
|
|
11216
|
-
case "\b": return "\\b";
|
|
11217
|
-
case "\v": return "\\v";
|
|
11218
|
-
case "\f": return "\\f";
|
|
11219
|
-
default: return ch;
|
|
11220
|
-
}
|
|
11221
|
-
});
|
|
11378
|
+
const norm = normalizeMathControlChars(s);
|
|
11222
11379
|
const stripped = norm.trim();
|
|
11223
11380
|
if (DATE_TIME_RE.test(stripped)) return false;
|
|
11224
11381
|
if (stripped.includes("**")) return false;
|
|
@@ -12164,22 +12321,6 @@ function parseHighlightToken(tokens, startIndex, options) {
|
|
|
12164
12321
|
|
|
12165
12322
|
//#endregion
|
|
12166
12323
|
//#region src/parser/inline-parsers/html-inline-code-parser.ts
|
|
12167
|
-
const VOID_TAGS$1 = new Set([
|
|
12168
|
-
"area",
|
|
12169
|
-
"base",
|
|
12170
|
-
"br",
|
|
12171
|
-
"col",
|
|
12172
|
-
"embed",
|
|
12173
|
-
"hr",
|
|
12174
|
-
"img",
|
|
12175
|
-
"input",
|
|
12176
|
-
"link",
|
|
12177
|
-
"meta",
|
|
12178
|
-
"param",
|
|
12179
|
-
"source",
|
|
12180
|
-
"track",
|
|
12181
|
-
"wbr"
|
|
12182
|
-
]);
|
|
12183
12324
|
let emptyTagSets = null;
|
|
12184
12325
|
const TAG_SET_CACHE = /* @__PURE__ */ new WeakMap();
|
|
12185
12326
|
function getEmptyTagSets() {
|
|
@@ -12197,7 +12338,7 @@ function isClosingTag(html) {
|
|
|
12197
12338
|
return /^<\s*\//.test(html);
|
|
12198
12339
|
}
|
|
12199
12340
|
function isSelfClosing(tag, html) {
|
|
12200
|
-
return /\/\s*>\s*$/.test(html) ||
|
|
12341
|
+
return /\/\s*>\s*$/.test(html) || VOID_HTML_TAGS.has(tag);
|
|
12201
12342
|
}
|
|
12202
12343
|
function normalizeCustomTag$1(t) {
|
|
12203
12344
|
const raw = String(t ?? "").trim();
|
|
@@ -12227,7 +12368,7 @@ function tokenToRaw(token) {
|
|
|
12227
12368
|
const raw = shape.raw ?? shape.content ?? shape.markup ?? "";
|
|
12228
12369
|
return String(raw ?? "");
|
|
12229
12370
|
}
|
|
12230
|
-
function parseTagAttrs(openTag) {
|
|
12371
|
+
function parseTagAttrs$1(openTag) {
|
|
12231
12372
|
const attrs = [];
|
|
12232
12373
|
const attrRegex = /\s([\w:-]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'>]+)))?/g;
|
|
12233
12374
|
let match;
|
|
@@ -12333,7 +12474,7 @@ function parseHtmlInlineCodeToken(token, tokens, i, parseInlineTokens$1, raw, pP
|
|
|
12333
12474
|
}, i + 1];
|
|
12334
12475
|
if (tag === "a") {
|
|
12335
12476
|
const fragment$1 = collectHtmlFragment(tokens, i, tag);
|
|
12336
|
-
const attrs$1 = parseTagAttrs(code$1);
|
|
12477
|
+
const attrs$1 = parseTagAttrs$1(code$1);
|
|
12337
12478
|
const innerTokens = fragment$1.innerTokens;
|
|
12338
12479
|
const href = String(getAttrValue$1(attrs$1, "href") ?? "");
|
|
12339
12480
|
const titleAttr = getAttrValue$1(attrs$1, "title");
|
|
@@ -13866,6 +14007,28 @@ function parseAdmonition(tokens, index, match, options) {
|
|
|
13866
14007
|
|
|
13867
14008
|
//#endregion
|
|
13868
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
|
+
}
|
|
13869
14032
|
function parseContainer(tokens, index, options) {
|
|
13870
14033
|
const openToken = tokens[index];
|
|
13871
14034
|
let kind = "note";
|
|
@@ -13875,15 +14038,16 @@ function parseContainer(tokens, index, options) {
|
|
|
13875
14038
|
kind = typeMatch[1];
|
|
13876
14039
|
const info = String(openToken.info ?? "").trim();
|
|
13877
14040
|
if (info && !info.startsWith(":::")) {
|
|
13878
|
-
|
|
13879
|
-
|
|
14041
|
+
if (info.toLowerCase().startsWith(kind)) {
|
|
14042
|
+
const maybe = info.slice(kind.length).trim();
|
|
14043
|
+
if (maybe) title = maybe;
|
|
14044
|
+
}
|
|
13880
14045
|
}
|
|
13881
14046
|
} else {
|
|
13882
|
-
const
|
|
13883
|
-
|
|
13884
|
-
|
|
13885
|
-
|
|
13886
|
-
title = String(match[2] ?? "");
|
|
14047
|
+
const parsedInfo = parseContainerInfo(String(openToken.info ?? "").trim());
|
|
14048
|
+
if (parsedInfo) {
|
|
14049
|
+
kind = parsedInfo.kind;
|
|
14050
|
+
title = parsedInfo.title;
|
|
13887
14051
|
}
|
|
13888
14052
|
}
|
|
13889
14053
|
if (!title) title = kind.charAt(0).toUpperCase() + kind.slice(1);
|
|
@@ -14100,23 +14264,7 @@ function parseHeading(tokens, index, options) {
|
|
|
14100
14264
|
|
|
14101
14265
|
//#endregion
|
|
14102
14266
|
//#region src/parser/node-parsers/html-block-parser.ts
|
|
14103
|
-
|
|
14104
|
-
"area",
|
|
14105
|
-
"base",
|
|
14106
|
-
"br",
|
|
14107
|
-
"col",
|
|
14108
|
-
"embed",
|
|
14109
|
-
"hr",
|
|
14110
|
-
"img",
|
|
14111
|
-
"input",
|
|
14112
|
-
"link",
|
|
14113
|
-
"meta",
|
|
14114
|
-
"param",
|
|
14115
|
-
"source",
|
|
14116
|
-
"track",
|
|
14117
|
-
"wbr"
|
|
14118
|
-
]);
|
|
14119
|
-
function findTagCloseIndexOutsideQuotes$1(input) {
|
|
14267
|
+
function findTagCloseIndexOutsideQuotes$2(input) {
|
|
14120
14268
|
let inSingle = false;
|
|
14121
14269
|
let inDouble = false;
|
|
14122
14270
|
for (let i = 0; i < input.length; i++) {
|
|
@@ -14148,7 +14296,7 @@ function findMatchingCloseTagEnd(rawHtml, tag, startIndex) {
|
|
|
14148
14296
|
if (lt === -1) return -1;
|
|
14149
14297
|
const slice = rawHtml.slice(lt);
|
|
14150
14298
|
if (closeTagRe.test(slice)) {
|
|
14151
|
-
const endRel = findTagCloseIndexOutsideQuotes$
|
|
14299
|
+
const endRel = findTagCloseIndexOutsideQuotes$2(slice);
|
|
14152
14300
|
if (endRel === -1) return -1;
|
|
14153
14301
|
if (depth === 0) return lt + endRel + 1;
|
|
14154
14302
|
depth--;
|
|
@@ -14156,7 +14304,7 @@ function findMatchingCloseTagEnd(rawHtml, tag, startIndex) {
|
|
|
14156
14304
|
continue;
|
|
14157
14305
|
}
|
|
14158
14306
|
if (openTagRe.test(slice)) {
|
|
14159
|
-
const endRel = findTagCloseIndexOutsideQuotes$
|
|
14307
|
+
const endRel = findTagCloseIndexOutsideQuotes$2(slice);
|
|
14160
14308
|
if (endRel === -1) return -1;
|
|
14161
14309
|
const rawTag = slice.slice(0, endRel + 1);
|
|
14162
14310
|
if (!/\/\s*>$/.test(rawTag)) depth++;
|
|
@@ -14167,6 +14315,18 @@ function findMatchingCloseTagEnd(rawHtml, tag, startIndex) {
|
|
|
14167
14315
|
}
|
|
14168
14316
|
return -1;
|
|
14169
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
|
+
}
|
|
14170
14330
|
function parseHtmlBlock(token) {
|
|
14171
14331
|
const raw = String(token.content ?? "");
|
|
14172
14332
|
if (/^\s*<!--/.test(raw) || /^\s*<!/.test(raw) || /^\s*<\?/.test(raw)) return {
|
|
@@ -14184,10 +14344,11 @@ function parseHtmlBlock(token) {
|
|
|
14184
14344
|
tag: "",
|
|
14185
14345
|
loading: false
|
|
14186
14346
|
};
|
|
14187
|
-
const openEnd = findTagCloseIndexOutsideQuotes$
|
|
14347
|
+
const openEnd = findTagCloseIndexOutsideQuotes$2(raw);
|
|
14188
14348
|
const openTag = openEnd === -1 ? raw : raw.slice(0, openEnd + 1);
|
|
14189
14349
|
const selfClosing = openEnd !== -1 && /\/\s*>$/.test(openTag);
|
|
14190
|
-
const isVoid =
|
|
14350
|
+
const isVoid = VOID_HTML_TAGS.has(tag);
|
|
14351
|
+
const attrs = parseTagAttrs(openTag);
|
|
14191
14352
|
const hasClosing = (openEnd === -1 ? -1 : findMatchingCloseTagEnd(raw, tag, openEnd + 1)) !== -1;
|
|
14192
14353
|
const loading = !(isVoid || selfClosing || hasClosing);
|
|
14193
14354
|
return {
|
|
@@ -14195,6 +14356,7 @@ function parseHtmlBlock(token) {
|
|
|
14195
14356
|
content: loading ? `${raw.replace(/<[^>]*$/, "")}\n</${tag}>` : raw,
|
|
14196
14357
|
raw,
|
|
14197
14358
|
tag,
|
|
14359
|
+
attrs: attrs.length ? attrs : void 0,
|
|
14198
14360
|
loading
|
|
14199
14361
|
};
|
|
14200
14362
|
}
|
|
@@ -14389,7 +14551,7 @@ function parseVmrContainer(tokens, index, options) {
|
|
|
14389
14551
|
raw
|
|
14390
14552
|
}, hasCloseToken ? j + 1 : j];
|
|
14391
14553
|
}
|
|
14392
|
-
function findTagCloseIndexOutsideQuotes(input) {
|
|
14554
|
+
function findTagCloseIndexOutsideQuotes$1(input) {
|
|
14393
14555
|
let inSingle = false;
|
|
14394
14556
|
let inDouble = false;
|
|
14395
14557
|
for (let i = 0; i < input.length; i++) {
|
|
@@ -14418,14 +14580,14 @@ function stripTrailingPartialClosingTag(inner, tag) {
|
|
|
14418
14580
|
const re = new RegExp(String.raw`[\t ]*<\s*\/\s*${tag}[^>]*$`, "i");
|
|
14419
14581
|
return inner.replace(re, "");
|
|
14420
14582
|
}
|
|
14421
|
-
function escapeRegex(value) {
|
|
14583
|
+
function escapeRegex$1(value) {
|
|
14422
14584
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
14423
14585
|
}
|
|
14424
14586
|
function findMatchingCloseTagRange(rawHtml, tag, startIndex) {
|
|
14425
14587
|
if (!rawHtml || !tag) return null;
|
|
14426
14588
|
const lowerTag = tag.toLowerCase();
|
|
14427
|
-
const openTagRe = new RegExp(String.raw`^<\s*${escapeRegex(lowerTag)}(?=\s|>|/)`, "i");
|
|
14428
|
-
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");
|
|
14429
14591
|
let depth = 0;
|
|
14430
14592
|
let index = Math.max(0, startIndex);
|
|
14431
14593
|
while (index < rawHtml.length) {
|
|
@@ -14433,7 +14595,7 @@ function findMatchingCloseTagRange(rawHtml, tag, startIndex) {
|
|
|
14433
14595
|
if (lt === -1) break;
|
|
14434
14596
|
const slice = rawHtml.slice(lt);
|
|
14435
14597
|
if (closeTagRe.test(slice)) {
|
|
14436
|
-
const endRel = findTagCloseIndexOutsideQuotes(slice);
|
|
14598
|
+
const endRel = findTagCloseIndexOutsideQuotes$1(slice);
|
|
14437
14599
|
if (endRel === -1) return null;
|
|
14438
14600
|
if (depth === 0) return {
|
|
14439
14601
|
start: lt,
|
|
@@ -14444,7 +14606,7 @@ function findMatchingCloseTagRange(rawHtml, tag, startIndex) {
|
|
|
14444
14606
|
continue;
|
|
14445
14607
|
}
|
|
14446
14608
|
if (openTagRe.test(slice)) {
|
|
14447
|
-
const endRel = findTagCloseIndexOutsideQuotes(slice);
|
|
14609
|
+
const endRel = findTagCloseIndexOutsideQuotes$1(slice);
|
|
14448
14610
|
if (endRel === -1) return null;
|
|
14449
14611
|
const raw = slice.slice(0, endRel + 1);
|
|
14450
14612
|
if (!/\/\s*>$/.test(raw)) depth++;
|
|
@@ -14464,7 +14626,7 @@ function findNextCustomHtmlBlockFromSource(source, tag, startIndex) {
|
|
|
14464
14626
|
if (!openMatch || openMatch.index == null) return null;
|
|
14465
14627
|
const openStart = openMatch.index;
|
|
14466
14628
|
const openSlice = source.slice(openStart);
|
|
14467
|
-
const openEndRel = findTagCloseIndexOutsideQuotes(openSlice);
|
|
14629
|
+
const openEndRel = findTagCloseIndexOutsideQuotes$1(openSlice);
|
|
14468
14630
|
if (openEndRel === -1) return null;
|
|
14469
14631
|
const openEnd = openStart + openEndRel;
|
|
14470
14632
|
if (/\/\s*>\s*$/.test(openSlice.slice(0, openEndRel + 1))) {
|
|
@@ -14505,7 +14667,7 @@ function findNextCustomHtmlBlockFromSource(source, tag, startIndex) {
|
|
|
14505
14667
|
continue;
|
|
14506
14668
|
}
|
|
14507
14669
|
if (isOpenAt(lt)) {
|
|
14508
|
-
const rel = findTagCloseIndexOutsideQuotes(source.slice(lt));
|
|
14670
|
+
const rel = findTagCloseIndexOutsideQuotes$1(source.slice(lt));
|
|
14509
14671
|
if (rel === -1) return null;
|
|
14510
14672
|
depth++;
|
|
14511
14673
|
i = lt + rel + 1;
|
|
@@ -14561,7 +14723,7 @@ function parseBasicBlockToken(tokens, index, options) {
|
|
|
14561
14723
|
const fromSource = findNextCustomHtmlBlockFromSource(source, tag, Math.max(clampNonNegative(cursor), clampNonNegative(mappedLineStart)));
|
|
14562
14724
|
if (fromSource) options.__customHtmlBlockCursor = fromSource.end;
|
|
14563
14725
|
const rawHtml = String(fromSource?.raw ?? htmlBlockNode.raw ?? "");
|
|
14564
|
-
const openEnd = findTagCloseIndexOutsideQuotes(rawHtml);
|
|
14726
|
+
const openEnd = findTagCloseIndexOutsideQuotes$1(rawHtml);
|
|
14565
14727
|
const openTag = openEnd !== -1 ? rawHtml.slice(0, openEnd + 1) : rawHtml;
|
|
14566
14728
|
const selfClosing = openEnd !== -1 && /\/\s*>\s*$/.test(openTag);
|
|
14567
14729
|
const closeRange = openEnd === -1 ? null : findMatchingCloseTagRange(rawHtml, tag, openEnd + 1);
|
|
@@ -14656,84 +14818,6 @@ function parseParagraph(tokens, index, options) {
|
|
|
14656
14818
|
|
|
14657
14819
|
//#endregion
|
|
14658
14820
|
//#region src/parser/index.ts
|
|
14659
|
-
const STANDARD_HTML_TAGS = new Set([
|
|
14660
|
-
"area",
|
|
14661
|
-
"base",
|
|
14662
|
-
"br",
|
|
14663
|
-
"col",
|
|
14664
|
-
"embed",
|
|
14665
|
-
"hr",
|
|
14666
|
-
"img",
|
|
14667
|
-
"input",
|
|
14668
|
-
"link",
|
|
14669
|
-
"meta",
|
|
14670
|
-
"param",
|
|
14671
|
-
"source",
|
|
14672
|
-
"track",
|
|
14673
|
-
"wbr",
|
|
14674
|
-
"a",
|
|
14675
|
-
"abbr",
|
|
14676
|
-
"b",
|
|
14677
|
-
"bdi",
|
|
14678
|
-
"bdo",
|
|
14679
|
-
"button",
|
|
14680
|
-
"cite",
|
|
14681
|
-
"code",
|
|
14682
|
-
"data",
|
|
14683
|
-
"del",
|
|
14684
|
-
"dfn",
|
|
14685
|
-
"em",
|
|
14686
|
-
"font",
|
|
14687
|
-
"i",
|
|
14688
|
-
"ins",
|
|
14689
|
-
"kbd",
|
|
14690
|
-
"label",
|
|
14691
|
-
"mark",
|
|
14692
|
-
"q",
|
|
14693
|
-
"s",
|
|
14694
|
-
"samp",
|
|
14695
|
-
"small",
|
|
14696
|
-
"span",
|
|
14697
|
-
"strong",
|
|
14698
|
-
"sub",
|
|
14699
|
-
"sup",
|
|
14700
|
-
"time",
|
|
14701
|
-
"u",
|
|
14702
|
-
"var",
|
|
14703
|
-
"article",
|
|
14704
|
-
"aside",
|
|
14705
|
-
"blockquote",
|
|
14706
|
-
"div",
|
|
14707
|
-
"details",
|
|
14708
|
-
"figcaption",
|
|
14709
|
-
"figure",
|
|
14710
|
-
"footer",
|
|
14711
|
-
"header",
|
|
14712
|
-
"h1",
|
|
14713
|
-
"h2",
|
|
14714
|
-
"h3",
|
|
14715
|
-
"h4",
|
|
14716
|
-
"h5",
|
|
14717
|
-
"h6",
|
|
14718
|
-
"li",
|
|
14719
|
-
"main",
|
|
14720
|
-
"nav",
|
|
14721
|
-
"ol",
|
|
14722
|
-
"p",
|
|
14723
|
-
"pre",
|
|
14724
|
-
"section",
|
|
14725
|
-
"summary",
|
|
14726
|
-
"table",
|
|
14727
|
-
"tbody",
|
|
14728
|
-
"td",
|
|
14729
|
-
"th",
|
|
14730
|
-
"thead",
|
|
14731
|
-
"tr",
|
|
14732
|
-
"ul",
|
|
14733
|
-
"svg",
|
|
14734
|
-
"g",
|
|
14735
|
-
"path"
|
|
14736
|
-
]);
|
|
14737
14821
|
function normalizeTagName(t) {
|
|
14738
14822
|
const raw = String(t ?? "").trim();
|
|
14739
14823
|
if (!raw) return "";
|
|
@@ -14812,6 +14896,328 @@ function parseStandaloneHtmlDocument(markdown) {
|
|
|
14812
14896
|
loading: false
|
|
14813
14897
|
}];
|
|
14814
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
|
+
}
|
|
14815
15221
|
function stripDanglingHtmlLikeTail(markdown) {
|
|
14816
15222
|
const isWs = (ch) => ch === " " || ch === " " || ch === "\n" || ch === "\r";
|
|
14817
15223
|
const isLikelyHtmlTagPrefix = (tail$1) => {
|
|
@@ -14980,7 +15386,7 @@ function ensureBlankLineBeforeInlineMultilineCustomHtmlBlocks(markdown, tags) {
|
|
|
14980
15386
|
}
|
|
14981
15387
|
return false;
|
|
14982
15388
|
};
|
|
14983
|
-
const findTagCloseIndexOutsideQuotes$
|
|
15389
|
+
const findTagCloseIndexOutsideQuotes$4 = (input) => {
|
|
14984
15390
|
let inSingle = false;
|
|
14985
15391
|
let inDouble = false;
|
|
14986
15392
|
for (let i = 0; i < input.length; i++) {
|
|
@@ -15029,7 +15435,7 @@ function ensureBlankLineBeforeInlineMultilineCustomHtmlBlocks(markdown, tags) {
|
|
|
15029
15435
|
i++;
|
|
15030
15436
|
continue;
|
|
15031
15437
|
}
|
|
15032
|
-
const closeIdxRel = findTagCloseIndexOutsideQuotes$
|
|
15438
|
+
const closeIdxRel = findTagCloseIndexOutsideQuotes$4(line.slice(i));
|
|
15033
15439
|
if (closeIdxRel === -1) {
|
|
15034
15440
|
hasRenderablePrefix = true;
|
|
15035
15441
|
i++;
|
|
@@ -15133,7 +15539,7 @@ function normalizeCustomHtmlOpeningTagSameLine(markdown, tags) {
|
|
|
15133
15539
|
while (i < s.length && isIndentWs(s[i])) i++;
|
|
15134
15540
|
return s.slice(i);
|
|
15135
15541
|
};
|
|
15136
|
-
const findTagCloseIndexOutsideQuotes$
|
|
15542
|
+
const findTagCloseIndexOutsideQuotes$4 = (input) => {
|
|
15137
15543
|
let inSingle = false;
|
|
15138
15544
|
let inDouble = false;
|
|
15139
15545
|
for (let i = 0; i < input.length; i++) {
|
|
@@ -15205,7 +15611,7 @@ function normalizeCustomHtmlOpeningTagSameLine(markdown, tags) {
|
|
|
15205
15611
|
if (i === nameStart) return line;
|
|
15206
15612
|
const tagName = line.slice(nameStart, i).toLowerCase();
|
|
15207
15613
|
if (!tagSet.has(tagName)) return line;
|
|
15208
|
-
const gtRel = findTagCloseIndexOutsideQuotes$
|
|
15614
|
+
const gtRel = findTagCloseIndexOutsideQuotes$4(line.slice(i));
|
|
15209
15615
|
if (gtRel === -1) return line;
|
|
15210
15616
|
const gt = i + gtRel;
|
|
15211
15617
|
if (hasClosingTagOnLine(line, gt + 1, tagName)) return line;
|
|
@@ -15649,6 +16055,8 @@ function parseMarkdownToStructure(markdown, md, options = {}) {
|
|
|
15649
16055
|
else result = postResult;
|
|
15650
16056
|
}
|
|
15651
16057
|
}
|
|
16058
|
+
result = mergeSplitTopLevelHtmlBlocks(result, isFinal, safeMarkdown);
|
|
16059
|
+
result = combineStructuredDetailsHtmlBlocks(result, safeMarkdown, md, options, isFinal)[0];
|
|
15652
16060
|
if (isFinal) {
|
|
15653
16061
|
const seen = /* @__PURE__ */ new WeakSet();
|
|
15654
16062
|
const finalizeHtmlBlockLoading = (value) => {
|
|
@@ -15896,5 +16304,5 @@ function getMarkdown(msgId = `editor-${Date.now()}`, options = {}) {
|
|
|
15896
16304
|
}
|
|
15897
16305
|
|
|
15898
16306
|
//#endregion
|
|
15899
|
-
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 };
|
|
15900
16308
|
//# sourceMappingURL=index.js.map
|