stream-markdown-parser 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -0
- package/README.zh-CN.md +16 -0
- package/dist/index.d.ts +23 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +921 -181
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1621,14 +1621,14 @@ const hasOwn$2 = Object.prototype.hasOwnProperty;
|
|
|
1621
1621
|
function isGlobalMarkdownStateReason(value) {
|
|
1622
1622
|
return value === "reference-definition" || value === "footnote-definition" || value === "abbreviation-definition";
|
|
1623
1623
|
}
|
|
1624
|
-
function isPlainObject(value) {
|
|
1624
|
+
function isPlainObject$1(value) {
|
|
1625
1625
|
if (!value || typeof value !== "object") return false;
|
|
1626
1626
|
const proto = Object.getPrototypeOf(value);
|
|
1627
1627
|
return proto === Object.prototype || proto === null;
|
|
1628
1628
|
}
|
|
1629
1629
|
function cloneSnapshotValue(value) {
|
|
1630
1630
|
if (Array.isArray(value)) return value.map((item) => cloneSnapshotValue(item));
|
|
1631
|
-
if (isPlainObject(value)) {
|
|
1631
|
+
if (isPlainObject$1(value)) {
|
|
1632
1632
|
const out = {};
|
|
1633
1633
|
for (const key of Object.keys(value)) out[key] = cloneSnapshotValue(value[key]);
|
|
1634
1634
|
return out;
|
|
@@ -1637,7 +1637,7 @@ function cloneSnapshotValue(value) {
|
|
|
1637
1637
|
}
|
|
1638
1638
|
function ownKeys(value) {
|
|
1639
1639
|
if (Array.isArray(value)) return value.map((_, index) => String(index));
|
|
1640
|
-
if (isPlainObject(value)) return Object.keys(value);
|
|
1640
|
+
if (isPlainObject$1(value)) return Object.keys(value);
|
|
1641
1641
|
return [];
|
|
1642
1642
|
}
|
|
1643
1643
|
function snapshotValueEquals(left, right) {
|
|
@@ -1647,8 +1647,8 @@ function snapshotValueEquals(left, right) {
|
|
|
1647
1647
|
for (let i = 0; i < left.length; i++) if (!snapshotValueEquals(left[i], right[i])) return false;
|
|
1648
1648
|
return true;
|
|
1649
1649
|
}
|
|
1650
|
-
if (isPlainObject(left) || isPlainObject(right)) {
|
|
1651
|
-
if (!isPlainObject(left) || !isPlainObject(right)) return false;
|
|
1650
|
+
if (isPlainObject$1(left) || isPlainObject$1(right)) {
|
|
1651
|
+
if (!isPlainObject$1(left) || !isPlainObject$1(right)) return false;
|
|
1652
1652
|
const leftKeys = Object.keys(left);
|
|
1653
1653
|
const rightKeys = Object.keys(right);
|
|
1654
1654
|
if (leftKeys.length !== rightKeys.length) return false;
|
|
@@ -1659,7 +1659,7 @@ function snapshotValueEquals(left, right) {
|
|
|
1659
1659
|
}
|
|
1660
1660
|
function getSnapshotKeyValue(value, key) {
|
|
1661
1661
|
if (Array.isArray(value)) return value[Number(key)];
|
|
1662
|
-
if (isPlainObject(value)) return value[key];
|
|
1662
|
+
if (isPlainObject$1(value)) return value[key];
|
|
1663
1663
|
}
|
|
1664
1664
|
function restoreSnapshotValue(target, snapshot) {
|
|
1665
1665
|
if (Array.isArray(target) && Array.isArray(snapshot)) {
|
|
@@ -1667,7 +1667,7 @@ function restoreSnapshotValue(target, snapshot) {
|
|
|
1667
1667
|
for (let i = 0; i < snapshot.length; i++) target[i] = cloneSnapshotValue(snapshot[i]);
|
|
1668
1668
|
return target;
|
|
1669
1669
|
}
|
|
1670
|
-
if (isPlainObject(target) && isPlainObject(snapshot)) {
|
|
1670
|
+
if (isPlainObject$1(target) && isPlainObject$1(snapshot)) {
|
|
1671
1671
|
for (const key of Object.keys(target)) if (!hasOwn$2.call(snapshot, key)) delete target[key];
|
|
1672
1672
|
for (const key of Object.keys(snapshot)) target[key] = cloneSnapshotValue(snapshot[key]);
|
|
1673
1673
|
return target;
|
|
@@ -1677,7 +1677,7 @@ function restoreSnapshotValue(target, snapshot) {
|
|
|
1677
1677
|
function resetOwnedSnapshotValue(env, key, entry) {
|
|
1678
1678
|
const ownedKeys = entry.ownedKeys ?? [];
|
|
1679
1679
|
const target = env[key];
|
|
1680
|
-
if (isPlainObject(target) || Array.isArray(target)) {
|
|
1680
|
+
if (isPlainObject$1(target) || Array.isArray(target)) {
|
|
1681
1681
|
const snapshotKeys = new Set(ownKeys(entry.value));
|
|
1682
1682
|
for (const ownedKey of ownedKeys) if (entry.existed && snapshotKeys.has(ownedKey)) target[ownedKey] = cloneSnapshotValue(getSnapshotKeyValue(entry.value, ownedKey));
|
|
1683
1683
|
else delete target[ownedKey];
|
|
@@ -1749,7 +1749,7 @@ function finalizeKnownGlobalMarkdownState(env) {
|
|
|
1749
1749
|
if (!entry) continue;
|
|
1750
1750
|
entry.ownedKeys = [];
|
|
1751
1751
|
const after = env[key];
|
|
1752
|
-
if (!isPlainObject(after) && !Array.isArray(after)) continue;
|
|
1752
|
+
if (!isPlainObject$1(after) && !Array.isArray(after)) continue;
|
|
1753
1753
|
const beforeKeys = new Set(ownKeys(entry.existed ? entry.value : void 0));
|
|
1754
1754
|
entry.ownedKeys = ownKeys(after).filter((name) => {
|
|
1755
1755
|
if (!beforeKeys.has(name)) return true;
|
|
@@ -10507,6 +10507,134 @@ function tokenToRaw$1(token) {
|
|
|
10507
10507
|
const shape = token;
|
|
10508
10508
|
return String(shape.raw ?? shape.content ?? shape.markup ?? "");
|
|
10509
10509
|
}
|
|
10510
|
+
function getMutableMeta(token) {
|
|
10511
|
+
const target = token;
|
|
10512
|
+
if (!target.meta) target.meta = {};
|
|
10513
|
+
return target.meta;
|
|
10514
|
+
}
|
|
10515
|
+
function setCustomHtmlSourceMeta(token, raw, inner) {
|
|
10516
|
+
const meta = getMutableMeta(token);
|
|
10517
|
+
meta.markstreamCustomHtmlRaw = raw;
|
|
10518
|
+
meta.markstreamCustomHtmlInner = inner;
|
|
10519
|
+
}
|
|
10520
|
+
function attachCustomHtmlSourceMeta(tokens, customTagSet) {
|
|
10521
|
+
if (!customTagSet.size) return;
|
|
10522
|
+
const customTagOpenRes = Array.from(customTagSet, (tag) => new RegExp(String.raw`<\s*${escapeTagForRegExp(tag)}(?=[\s>/])`, "i"));
|
|
10523
|
+
const stack = [];
|
|
10524
|
+
let needsTopLevelSeparator = false;
|
|
10525
|
+
const mayOpenCustomTag = (source) => {
|
|
10526
|
+
if (!source) return false;
|
|
10527
|
+
return customTagOpenRes.some((re) => re.test(source));
|
|
10528
|
+
};
|
|
10529
|
+
const appendToOpenFrames = (raw) => {
|
|
10530
|
+
if (!raw || !stack.length) return;
|
|
10531
|
+
for (const frame of stack) {
|
|
10532
|
+
frame.raw += raw;
|
|
10533
|
+
frame.inner += raw;
|
|
10534
|
+
}
|
|
10535
|
+
};
|
|
10536
|
+
const appendTopLevelSeparator = () => {
|
|
10537
|
+
if (!stack.length || !needsTopLevelSeparator) return;
|
|
10538
|
+
appendToOpenFrames("\n");
|
|
10539
|
+
needsTopLevelSeparator = false;
|
|
10540
|
+
};
|
|
10541
|
+
const appendSourceGap = (gap) => {
|
|
10542
|
+
appendToOpenFrames(gap);
|
|
10543
|
+
};
|
|
10544
|
+
const closeTopFrameWithRaw = (raw) => {
|
|
10545
|
+
for (let i = 0; i < stack.length; i++) {
|
|
10546
|
+
stack[i].raw += raw;
|
|
10547
|
+
if (i < stack.length - 1) stack[i].inner += raw;
|
|
10548
|
+
}
|
|
10549
|
+
const frame = stack.pop();
|
|
10550
|
+
setCustomHtmlSourceMeta(frame.token, frame.raw, frame.inner);
|
|
10551
|
+
};
|
|
10552
|
+
const getTopFrameClosePrefix = (raw) => {
|
|
10553
|
+
const tag = stack[stack.length - 1]?.tag;
|
|
10554
|
+
if (!tag) return null;
|
|
10555
|
+
const closePrefixRe = new RegExp(String.raw`^\s*<\s*\/\s*${escapeTagForRegExp(tag)}\s*>`, "i");
|
|
10556
|
+
return raw.match(closePrefixRe)?.[0] ?? null;
|
|
10557
|
+
};
|
|
10558
|
+
const startsWithTopFrameClose = (source) => {
|
|
10559
|
+
return !!getTopFrameClosePrefix(source);
|
|
10560
|
+
};
|
|
10561
|
+
const handleToken = (child, raw, knownTag) => {
|
|
10562
|
+
const tag = knownTag ?? (child.type === "html_inline" ? getHtmlInlineTagName(raw) : "");
|
|
10563
|
+
if (!(tag && customTagSet.has(tag))) {
|
|
10564
|
+
appendToOpenFrames(raw);
|
|
10565
|
+
return;
|
|
10566
|
+
}
|
|
10567
|
+
const closing = isHtmlInlineClosingTag(raw);
|
|
10568
|
+
const selfClosing = !closing && isSelfClosingHtmlInline(raw, tag);
|
|
10569
|
+
if (closing) {
|
|
10570
|
+
if (!stack.length || stack[stack.length - 1].tag !== tag) {
|
|
10571
|
+
appendToOpenFrames(raw);
|
|
10572
|
+
return;
|
|
10573
|
+
}
|
|
10574
|
+
closeTopFrameWithRaw(raw);
|
|
10575
|
+
return;
|
|
10576
|
+
}
|
|
10577
|
+
appendToOpenFrames(raw);
|
|
10578
|
+
if (selfClosing) {
|
|
10579
|
+
setCustomHtmlSourceMeta(child, raw, "");
|
|
10580
|
+
return;
|
|
10581
|
+
}
|
|
10582
|
+
stack.push({
|
|
10583
|
+
tag,
|
|
10584
|
+
token: child,
|
|
10585
|
+
raw,
|
|
10586
|
+
inner: ""
|
|
10587
|
+
});
|
|
10588
|
+
};
|
|
10589
|
+
for (const token of tokens) {
|
|
10590
|
+
if (token.type === "inline" && Array.isArray(token.children)) {
|
|
10591
|
+
const source = String(token.content ?? "");
|
|
10592
|
+
if (startsWithTopFrameClose(source)) needsTopLevelSeparator = false;
|
|
10593
|
+
else appendTopLevelSeparator();
|
|
10594
|
+
if (!stack.length && !mayOpenCustomTag(source)) {
|
|
10595
|
+
needsTopLevelSeparator = false;
|
|
10596
|
+
continue;
|
|
10597
|
+
}
|
|
10598
|
+
let cursor = 0;
|
|
10599
|
+
let sourceReliable = true;
|
|
10600
|
+
for (const child of token.children) {
|
|
10601
|
+
const childRaw = tokenToRaw$1(child);
|
|
10602
|
+
const tag = child.type === "html_inline" ? getHtmlInlineTagName(childRaw) : "";
|
|
10603
|
+
const isCustomTag = tag && customTagSet.has(tag);
|
|
10604
|
+
let raw = childRaw;
|
|
10605
|
+
if (sourceReliable && source && childRaw && (stack.length || isCustomTag)) {
|
|
10606
|
+
const index = source.indexOf(childRaw, cursor);
|
|
10607
|
+
if (index !== -1) {
|
|
10608
|
+
appendSourceGap(source.slice(cursor, index));
|
|
10609
|
+
raw = source.slice(index, index + childRaw.length);
|
|
10610
|
+
cursor = index + childRaw.length;
|
|
10611
|
+
} else {
|
|
10612
|
+
if (stack.length && !isCustomTag) continue;
|
|
10613
|
+
sourceReliable = false;
|
|
10614
|
+
}
|
|
10615
|
+
}
|
|
10616
|
+
handleToken(child, raw, tag);
|
|
10617
|
+
}
|
|
10618
|
+
if (sourceReliable && source && cursor < source.length && stack.length) appendSourceGap(source.slice(cursor));
|
|
10619
|
+
needsTopLevelSeparator = stack.length > 0;
|
|
10620
|
+
continue;
|
|
10621
|
+
}
|
|
10622
|
+
if (stack.length && typeof token.content === "string") {
|
|
10623
|
+
const raw = tokenToRaw$1(token);
|
|
10624
|
+
const closePrefix = token.type === "html_block" ? getTopFrameClosePrefix(raw) : null;
|
|
10625
|
+
if (closePrefix) {
|
|
10626
|
+
closeTopFrameWithRaw(`${needsTopLevelSeparator ? "\n" : ""}${closePrefix}`);
|
|
10627
|
+
needsTopLevelSeparator = stack.length > 0;
|
|
10628
|
+
continue;
|
|
10629
|
+
}
|
|
10630
|
+
if (!token.content) continue;
|
|
10631
|
+
appendTopLevelSeparator();
|
|
10632
|
+
appendToOpenFrames(token.content);
|
|
10633
|
+
needsTopLevelSeparator = true;
|
|
10634
|
+
}
|
|
10635
|
+
}
|
|
10636
|
+
for (const frame of stack) setCustomHtmlSourceMeta(frame.token, frame.raw, frame.inner);
|
|
10637
|
+
}
|
|
10510
10638
|
function isNonElementHtmlBlock(content) {
|
|
10511
10639
|
return /^\s*<\s*[!?]/.test(content);
|
|
10512
10640
|
}
|
|
@@ -10693,25 +10821,41 @@ function fixStreamingHtmlInlineChildren(children, tagSet) {
|
|
|
10693
10821
|
pendingBuffer: pendingAtEnd ?? void 0
|
|
10694
10822
|
};
|
|
10695
10823
|
}
|
|
10824
|
+
const BASE_AUTO_CLOSE_INLINE_TAGS = [
|
|
10825
|
+
"a",
|
|
10826
|
+
"span",
|
|
10827
|
+
"strong",
|
|
10828
|
+
"em",
|
|
10829
|
+
"b",
|
|
10830
|
+
"i",
|
|
10831
|
+
"u"
|
|
10832
|
+
];
|
|
10696
10833
|
function applyFixHtmlInlineTokens(md, options = {}) {
|
|
10697
|
-
const
|
|
10698
|
-
const autoCloseInlineTagSet = new Set([
|
|
10699
|
-
"a",
|
|
10700
|
-
"span",
|
|
10701
|
-
"strong",
|
|
10702
|
-
"em",
|
|
10703
|
-
"b",
|
|
10704
|
-
"i",
|
|
10705
|
-
"u"
|
|
10706
|
-
]);
|
|
10707
|
-
const customTagSet = /* @__PURE__ */ new Set();
|
|
10834
|
+
const configuredCustomTagSet = /* @__PURE__ */ new Set();
|
|
10708
10835
|
if (options.customHtmlTags?.length) for (const t of options.customHtmlTags) {
|
|
10709
10836
|
const name = normalizeCustomHtmlTagName(t);
|
|
10710
10837
|
if (!name) continue;
|
|
10711
|
-
|
|
10712
|
-
autoCloseInlineTagSet.add(name);
|
|
10838
|
+
configuredCustomTagSet.add(name);
|
|
10713
10839
|
}
|
|
10714
|
-
const
|
|
10840
|
+
const getRuleContext = (state) => {
|
|
10841
|
+
const s = state;
|
|
10842
|
+
const customTagSet = new Set(configuredCustomTagSet);
|
|
10843
|
+
const envTags = Array.isArray(s.env?.__markstreamCustomHtmlTags) ? s.env.__markstreamCustomHtmlTags : [];
|
|
10844
|
+
for (const t of envTags) {
|
|
10845
|
+
const name = normalizeCustomHtmlTagName(String(t ?? ""));
|
|
10846
|
+
if (name) customTagSet.add(name);
|
|
10847
|
+
}
|
|
10848
|
+
const commonHtmlTags = buildCommonHtmlTagSet(Array.from(customTagSet));
|
|
10849
|
+
const autoCloseInlineTagSet = new Set(BASE_AUTO_CLOSE_INLINE_TAGS);
|
|
10850
|
+
for (const tag of customTagSet) autoCloseInlineTagSet.add(tag);
|
|
10851
|
+
const shouldMergeHtmlBlockTag = (tag) => customTagSet.has(tag) || !commonHtmlTags.has(tag) || BLOCK_LEVEL_HTML_TAGS.has(tag);
|
|
10852
|
+
return {
|
|
10853
|
+
autoCloseInlineTagSet,
|
|
10854
|
+
commonHtmlTags,
|
|
10855
|
+
customTagSet,
|
|
10856
|
+
shouldMergeHtmlBlockTag
|
|
10857
|
+
};
|
|
10858
|
+
};
|
|
10715
10859
|
const getHtmlBlockCarrierContent = (token) => {
|
|
10716
10860
|
if (token.type === "html_block") return String(token.content ?? "");
|
|
10717
10861
|
if (token.type !== "inline" || !Array.isArray(token.children) || token.children.length !== 1) return "";
|
|
@@ -10725,8 +10869,71 @@ function applyFixHtmlInlineTokens(md, options = {}) {
|
|
|
10725
10869
|
token.raw = content;
|
|
10726
10870
|
token.children = [];
|
|
10727
10871
|
};
|
|
10872
|
+
const stripLeadingLineSeparators = (content) => content.replace(/^(?:\r?\n)+/, "");
|
|
10873
|
+
const isIndentedCodeTrailingContent = (content) => /^(?: {4}|\t)/.test(content);
|
|
10874
|
+
const normalizeIndentedCodeTrailingContent = (content) => content.replace(/^(?: {4}|\t)/gm, "");
|
|
10875
|
+
const createTrailingContentTokens = (content, textMode) => {
|
|
10876
|
+
const source = stripLeadingLineSeparators(content);
|
|
10877
|
+
if (!/\S/.test(source)) return [];
|
|
10878
|
+
if (isIndentedCodeTrailingContent(source)) return [{
|
|
10879
|
+
type: "code_block",
|
|
10880
|
+
content: normalizeIndentedCodeTrailingContent(source),
|
|
10881
|
+
raw: source
|
|
10882
|
+
}];
|
|
10883
|
+
const text$1 = source.replace(/^[\t ]+/, "");
|
|
10884
|
+
if (!text$1) return [];
|
|
10885
|
+
if (text$1.startsWith("<")) return [{
|
|
10886
|
+
type: "html_block",
|
|
10887
|
+
content: text$1
|
|
10888
|
+
}];
|
|
10889
|
+
const inlineToken = {
|
|
10890
|
+
type: "inline",
|
|
10891
|
+
tag: "",
|
|
10892
|
+
nesting: 0,
|
|
10893
|
+
content: text$1,
|
|
10894
|
+
children: [{
|
|
10895
|
+
type: "text",
|
|
10896
|
+
content: text$1,
|
|
10897
|
+
raw: text$1
|
|
10898
|
+
}]
|
|
10899
|
+
};
|
|
10900
|
+
if (textMode === "paragraph") return [
|
|
10901
|
+
{
|
|
10902
|
+
type: "paragraph_open",
|
|
10903
|
+
tag: "p",
|
|
10904
|
+
nesting: 1
|
|
10905
|
+
},
|
|
10906
|
+
inlineToken,
|
|
10907
|
+
{
|
|
10908
|
+
type: "paragraph_close",
|
|
10909
|
+
tag: "p",
|
|
10910
|
+
nesting: -1
|
|
10911
|
+
}
|
|
10912
|
+
];
|
|
10913
|
+
if (textMode === "text") return [{
|
|
10914
|
+
type: "text",
|
|
10915
|
+
content: text$1,
|
|
10916
|
+
raw: text$1
|
|
10917
|
+
}];
|
|
10918
|
+
return [inlineToken];
|
|
10919
|
+
};
|
|
10920
|
+
const getTrailingContentTextMode = (tokens, index, fallback) => {
|
|
10921
|
+
return tokens[index - 1]?.type === "paragraph_open" && tokens[index + 1]?.type === "paragraph_close" ? "inline" : fallback;
|
|
10922
|
+
};
|
|
10923
|
+
const appendTrailingInlineContent = (token, content) => {
|
|
10924
|
+
const source = stripLeadingLineSeparators(content);
|
|
10925
|
+
if (!/\S/.test(source) || token.type !== "inline" || !Array.isArray(token.children)) return false;
|
|
10926
|
+
token.content = `${String(token.content ?? "")}${source}`;
|
|
10927
|
+
token.children.push({
|
|
10928
|
+
type: "text",
|
|
10929
|
+
content: source,
|
|
10930
|
+
raw: source
|
|
10931
|
+
});
|
|
10932
|
+
return true;
|
|
10933
|
+
};
|
|
10728
10934
|
md.core.ruler.after("inline", "fix_html_inline_streaming", (state) => {
|
|
10729
10935
|
const toks = state.tokens ?? [];
|
|
10936
|
+
const { commonHtmlTags, customTagSet } = getRuleContext(state);
|
|
10730
10937
|
for (const t of toks) {
|
|
10731
10938
|
const tok = t;
|
|
10732
10939
|
if (tok.type !== "inline" || !Array.isArray(tok.children)) continue;
|
|
@@ -10752,9 +10959,11 @@ function applyFixHtmlInlineTokens(md, options = {}) {
|
|
|
10752
10959
|
console.error("[applyFixHtmlInlineTokens] failed to fix streaming html inline", e);
|
|
10753
10960
|
}
|
|
10754
10961
|
}
|
|
10962
|
+
attachCustomHtmlSourceMeta(toks, customTagSet);
|
|
10755
10963
|
});
|
|
10756
10964
|
md.core.ruler.push("fix_html_inline_tokens", (state) => {
|
|
10757
10965
|
const toks = state.tokens ?? [];
|
|
10966
|
+
const { autoCloseInlineTagSet, customTagSet, shouldMergeHtmlBlockTag } = getRuleContext(state);
|
|
10758
10967
|
const tagStack = [];
|
|
10759
10968
|
for (let i = 0; i < toks.length; i++) {
|
|
10760
10969
|
const t = toks[i];
|
|
@@ -10777,21 +10986,10 @@ function applyFixHtmlInlineTokens(md, options = {}) {
|
|
|
10777
10986
|
const after = mergedContent.slice(closeRange.end);
|
|
10778
10987
|
openToken.content = before;
|
|
10779
10988
|
openToken.loading = false;
|
|
10780
|
-
const afterTrimmed = after.replace(/^\s+/, "");
|
|
10781
10989
|
toks.splice(i, 1);
|
|
10782
10990
|
tagStack.pop();
|
|
10783
|
-
|
|
10784
|
-
|
|
10785
|
-
content: afterTrimmed
|
|
10786
|
-
} : {
|
|
10787
|
-
type: "inline",
|
|
10788
|
-
content: afterTrimmed,
|
|
10789
|
-
children: [{
|
|
10790
|
-
type: "text",
|
|
10791
|
-
content: afterTrimmed,
|
|
10792
|
-
raw: afterTrimmed
|
|
10793
|
-
}]
|
|
10794
|
-
});
|
|
10991
|
+
const replacement = appendTrailingInlineContent(openToken, after) ? [] : createTrailingContentTokens(after, getTrailingContentTextMode(toks, i, "paragraph"));
|
|
10992
|
+
if (replacement.length) toks.splice(i, 0, ...replacement);
|
|
10795
10993
|
i--;
|
|
10796
10994
|
continue;
|
|
10797
10995
|
}
|
|
@@ -10869,16 +11067,24 @@ function applyFixHtmlInlineTokens(md, options = {}) {
|
|
|
10869
11067
|
if (stack.length > 0) {
|
|
10870
11068
|
const top = stack[stack.length - 1];
|
|
10871
11069
|
const openTok = toks[top.index];
|
|
10872
|
-
|
|
10873
|
-
|
|
11070
|
+
const htmlBlockCloseMatch = tok.type === "html_block" ? getCloseRe(top.tag).exec(content) : null;
|
|
11071
|
+
if (htmlBlockCloseMatch) {
|
|
11072
|
+
const closeEnd = htmlBlockCloseMatch.index + htmlBlockCloseMatch[0].length;
|
|
11073
|
+
const closeContent = content.slice(0, closeEnd);
|
|
11074
|
+
const afterContent = content.slice(closeEnd);
|
|
11075
|
+
openTok.content = `${String(openTok.content ?? "")}\n${closeContent}`;
|
|
10874
11076
|
if (Array.isArray(openTok.children)) openTok.children.push({
|
|
10875
11077
|
type: "html_inline",
|
|
10876
11078
|
content: `</${top.tag}>`,
|
|
10877
11079
|
raw: `</${top.tag}>`
|
|
10878
11080
|
});
|
|
10879
|
-
toks.splice(i, 1);
|
|
10880
|
-
i--;
|
|
10881
11081
|
stack.pop();
|
|
11082
|
+
const replacement = appendTrailingInlineContent(openTok, afterContent) ? [] : createTrailingContentTokens(afterContent, getTrailingContentTextMode(toks, i, "paragraph"));
|
|
11083
|
+
if (replacement.length) toks.splice(i, 1, ...replacement);
|
|
11084
|
+
else {
|
|
11085
|
+
toks.splice(i, 1);
|
|
11086
|
+
i--;
|
|
11087
|
+
}
|
|
10882
11088
|
continue;
|
|
10883
11089
|
}
|
|
10884
11090
|
if (tok.type !== "inline") continue;
|
|
@@ -10894,29 +11100,17 @@ function applyFixHtmlInlineTokens(md, options = {}) {
|
|
|
10894
11100
|
const afterText = afterChildren.map((c) => String(c.content ?? c.raw ?? "")).join("");
|
|
10895
11101
|
if (afterText.trim()) {
|
|
10896
11102
|
const trimmed = afterText.replace(/^\s+/, "");
|
|
10897
|
-
if (
|
|
11103
|
+
if (appendTrailingInlineContent(openTok, afterText)) {
|
|
11104
|
+
toks.splice(i, 1);
|
|
11105
|
+
i--;
|
|
11106
|
+
} else if (trimmed.startsWith("<")) toks.splice(i, 1, {
|
|
10898
11107
|
type: "html_block",
|
|
10899
11108
|
content: trimmed
|
|
10900
11109
|
});
|
|
10901
|
-
else
|
|
10902
|
-
|
|
10903
|
-
|
|
10904
|
-
|
|
10905
|
-
}, {
|
|
10906
|
-
type: "inline",
|
|
10907
|
-
tag: "",
|
|
10908
|
-
nesting: 0,
|
|
10909
|
-
content: afterText,
|
|
10910
|
-
children: [{
|
|
10911
|
-
type: "text",
|
|
10912
|
-
content: afterText,
|
|
10913
|
-
raw: afterText
|
|
10914
|
-
}]
|
|
10915
|
-
}, {
|
|
10916
|
-
type: "paragraph_close",
|
|
10917
|
-
tag: "p",
|
|
10918
|
-
nesting: -1
|
|
10919
|
-
});
|
|
11110
|
+
else {
|
|
11111
|
+
const replacement = createTrailingContentTokens(afterText, getTrailingContentTextMode(toks, i, "paragraph"));
|
|
11112
|
+
toks.splice(i, 1, ...replacement);
|
|
11113
|
+
}
|
|
10920
11114
|
} else {
|
|
10921
11115
|
toks.splice(i, 1);
|
|
10922
11116
|
i--;
|
|
@@ -10989,15 +11183,8 @@ function applyFixHtmlInlineTokens(md, options = {}) {
|
|
|
10989
11183
|
}];
|
|
10990
11184
|
t.content = rawForNode;
|
|
10991
11185
|
t.raw = rawForNode;
|
|
10992
|
-
const
|
|
10993
|
-
if (
|
|
10994
|
-
type: "html_block",
|
|
10995
|
-
content: afterTrimmed
|
|
10996
|
-
} : {
|
|
10997
|
-
type: "text",
|
|
10998
|
-
content: afterTrimmed,
|
|
10999
|
-
raw: afterTrimmed
|
|
11000
|
-
});
|
|
11186
|
+
const replacement = createTrailingContentTokens(raw$2.slice(endTagIndex$1 + closeLen$1) || "", "text");
|
|
11187
|
+
if (replacement.length) toks.splice(i + 1, 0, ...replacement);
|
|
11001
11188
|
} else t.children = [{
|
|
11002
11189
|
type: tag,
|
|
11003
11190
|
content: "",
|
|
@@ -11194,7 +11381,7 @@ function applyFixIndentedCodeBlock(md, options = {}) {
|
|
|
11194
11381
|
|
|
11195
11382
|
//#endregion
|
|
11196
11383
|
//#region src/parser/linkifyHeuristics.ts
|
|
11197
|
-
const FILENAMEISH_EXTENSION_RE = /\.([a-z0-9]{1,
|
|
11384
|
+
const FILENAMEISH_EXTENSION_RE = /\.([a-z0-9]{1,15})$/i;
|
|
11198
11385
|
const FILENAMEISH_SEGMENT_RE = /[_()[\]{}<>]/u;
|
|
11199
11386
|
const URL_PREFIX_HINT_RE = /^(?:https?:\/\/|ftp:\/\/|mailto:|www\.)/i;
|
|
11200
11387
|
const URL_QUERY_OR_AUTH_HINT_RE = /[?#@]/u;
|
|
@@ -11202,7 +11389,11 @@ const PATH_SEPARATOR_RE = /[\\/]/u;
|
|
|
11202
11389
|
const DOMAINISH_TEXT_RE = /^[\p{L}\p{N}./\\-]+$/u;
|
|
11203
11390
|
const DOMAIN_LABEL_RE = /^[A-Za-z0-9-]{1,63}$/u;
|
|
11204
11391
|
const PUNYCODE_TLD_RE = /^xn--[a-z0-9-]{2,59}$/i;
|
|
11205
|
-
const
|
|
11392
|
+
const MARKET_TICKER_SYMBOL_RE = /^(?:[A-Z]{1,6}|\d{1,8})$/u;
|
|
11393
|
+
const MARKET_TICKER_CONTEXT_SYMBOL_RE = /^(?=.{1,12}$)[A-Z0-9]+(?:[-.][A-Z0-9]+)*$/iu;
|
|
11394
|
+
const EXPLICIT_FILENAME_CONTEXT_RE = /文件名\s*[::]?|附件\s*[::]?|路径\s*[::]?|路徑\s*[::]?|文件列表\s*[::]?|文档列表\s*[::]?|文檔列表\s*[::]?|\bfile\s*names?\b\s*[::]?|\battachments?\b\s*[::]?|\bpaths?\b\s*[::]?|\bfile\s+lists?\b\s*[::]?|\bdocument\s+lists?\b\s*[::]?/iu;
|
|
11395
|
+
const FILENAME_CONTEXT_RE = /文件名\s*[::]?|文件\s*[::]?|附件\s*[::]?|档案\s*[::]?|檔案\s*[::]?|文档\s*[::]?|文檔\s*[::]?|资料\s*[::]?|資料\s*[::]?|路径\s*[::]?|路徑\s*[::]?|\bfile\s*name\b\s*[::]?|\battachments?\b\s*[::]?|\bfiles?\b\s*[::]?|\bdocuments?\b\s*[::]?|\bdocs?\b\s*[::]?|\bpaths?\b\s*[::]?/iu;
|
|
11396
|
+
const MARKET_TICKER_CONTEXT_RE = /股票代码|股票代碼|证券代码|證券代碼|(?:代码|代碼|交易所|后缀|後綴|市场|市場)(?=$|[\s::/|,,、()()])|\btickers?\b|\bsymbols?\b|\bexchanges?\b/iu;
|
|
11206
11397
|
const AMBIGUOUS_BARE_DOMAIN_EXTENSIONS = new Set([
|
|
11207
11398
|
"ai",
|
|
11208
11399
|
"md",
|
|
@@ -11211,6 +11402,57 @@ const AMBIGUOUS_BARE_DOMAIN_EXTENSIONS = new Set([
|
|
|
11211
11402
|
"sh",
|
|
11212
11403
|
"zip"
|
|
11213
11404
|
]);
|
|
11405
|
+
const MARKET_TICKER_SUFFIXES = new Set([
|
|
11406
|
+
"as",
|
|
11407
|
+
"bj",
|
|
11408
|
+
"de",
|
|
11409
|
+
"hk",
|
|
11410
|
+
"l",
|
|
11411
|
+
"ln",
|
|
11412
|
+
"ny",
|
|
11413
|
+
"pa",
|
|
11414
|
+
"sh",
|
|
11415
|
+
"ss",
|
|
11416
|
+
"sz",
|
|
11417
|
+
"t",
|
|
11418
|
+
"us"
|
|
11419
|
+
]);
|
|
11420
|
+
const MARKET_TICKER_CONTEXT_SUFFIXES = new Set([
|
|
11421
|
+
...MARKET_TICKER_SUFFIXES,
|
|
11422
|
+
"at",
|
|
11423
|
+
"ax",
|
|
11424
|
+
"cn",
|
|
11425
|
+
"co",
|
|
11426
|
+
"it",
|
|
11427
|
+
"jp",
|
|
11428
|
+
"ks",
|
|
11429
|
+
"mc",
|
|
11430
|
+
"mx",
|
|
11431
|
+
"nz",
|
|
11432
|
+
"pl",
|
|
11433
|
+
"sa",
|
|
11434
|
+
"si",
|
|
11435
|
+
"to",
|
|
11436
|
+
"tw"
|
|
11437
|
+
]);
|
|
11438
|
+
const EXPLICIT_FILENAME_CONTEXT_ONLY_EXTENSIONS = new Set([
|
|
11439
|
+
"com",
|
|
11440
|
+
"dev",
|
|
11441
|
+
"io",
|
|
11442
|
+
"page",
|
|
11443
|
+
"site"
|
|
11444
|
+
]);
|
|
11445
|
+
const FILENAME_CONTEXT_ONLY_EXTENSIONS = new Set([
|
|
11446
|
+
"app",
|
|
11447
|
+
"apk",
|
|
11448
|
+
"dmg",
|
|
11449
|
+
"exe",
|
|
11450
|
+
"ipa",
|
|
11451
|
+
"lock",
|
|
11452
|
+
"log",
|
|
11453
|
+
"markdown",
|
|
11454
|
+
"webmanifest"
|
|
11455
|
+
]);
|
|
11214
11456
|
const FILENAMEISH_LINK_EXTENSIONS = new Set([
|
|
11215
11457
|
"7z",
|
|
11216
11458
|
"ai",
|
|
@@ -11278,6 +11520,65 @@ const FILENAMEISH_LINK_EXTENSIONS = new Set([
|
|
|
11278
11520
|
"zip",
|
|
11279
11521
|
"zsh"
|
|
11280
11522
|
]);
|
|
11523
|
+
function hasLinkifyDemotionContext(context) {
|
|
11524
|
+
return context?.filename === true || context?.explicitFilename === true || context?.marketTicker === true;
|
|
11525
|
+
}
|
|
11526
|
+
function mergeLinkifyDemotionContext(left, right) {
|
|
11527
|
+
const merged = {
|
|
11528
|
+
filename: left?.filename || right?.filename,
|
|
11529
|
+
explicitFilename: left?.explicitFilename || right?.explicitFilename,
|
|
11530
|
+
marketTicker: left?.marketTicker || right?.marketTicker
|
|
11531
|
+
};
|
|
11532
|
+
return hasLinkifyDemotionContext(merged) ? merged : void 0;
|
|
11533
|
+
}
|
|
11534
|
+
function withLinkifyDemotionContext(options, context) {
|
|
11535
|
+
if (!hasLinkifyDemotionContext(context)) return options;
|
|
11536
|
+
const inheritedContext = options?.__linkifyDemotionContext;
|
|
11537
|
+
return {
|
|
11538
|
+
...options,
|
|
11539
|
+
__linkifyDemotionContext: {
|
|
11540
|
+
filename: inheritedContext?.filename || context?.filename,
|
|
11541
|
+
explicitFilename: inheritedContext?.explicitFilename || context?.explicitFilename,
|
|
11542
|
+
marketTicker: inheritedContext?.marketTicker || context?.marketTicker
|
|
11543
|
+
}
|
|
11544
|
+
};
|
|
11545
|
+
}
|
|
11546
|
+
function inferNextBlockLinkifyContext(raw) {
|
|
11547
|
+
const context = inferLinkifyDemotionContext(raw);
|
|
11548
|
+
return hasLinkifyDemotionContext(context) ? context : void 0;
|
|
11549
|
+
}
|
|
11550
|
+
function normalizeStandaloneContinuationText(text$1) {
|
|
11551
|
+
return text$1.replace(/^[\s>*_`[\]((【《"'“‘]+/u, "").replace(/[\s<*_`\]))】》"'.。;;,,、::!?!?]+$/u, "");
|
|
11552
|
+
}
|
|
11553
|
+
function inferContinuationLinkifyContext(raw, inherited) {
|
|
11554
|
+
if (!hasLinkifyDemotionContext(inherited)) return void 0;
|
|
11555
|
+
const parts = String(raw ?? "").trim().split(/\s+/u).map(normalizeStandaloneContinuationText).filter(Boolean);
|
|
11556
|
+
if (parts.length === 0) return void 0;
|
|
11557
|
+
const continuation = {};
|
|
11558
|
+
if (inherited?.filename && parts.every((part) => shouldDemoteFilenameLikeLinkify(part, {
|
|
11559
|
+
filename: true,
|
|
11560
|
+
explicitFilename: inherited.explicitFilename
|
|
11561
|
+
}))) continuation.filename = true;
|
|
11562
|
+
if (inherited?.explicitFilename && continuation.filename) continuation.explicitFilename = true;
|
|
11563
|
+
if (inherited?.marketTicker && parts.every((part) => shouldDemoteFilenameLikeLinkify(part, { marketTicker: true }))) continuation.marketTicker = true;
|
|
11564
|
+
return hasLinkifyDemotionContext(continuation) ? continuation : void 0;
|
|
11565
|
+
}
|
|
11566
|
+
function createLinkifyDemotionContextTracker(options, sticky = false) {
|
|
11567
|
+
let context;
|
|
11568
|
+
return {
|
|
11569
|
+
options(raw) {
|
|
11570
|
+
if (sticky || raw == null) return withLinkifyDemotionContext(options, context);
|
|
11571
|
+
return withLinkifyDemotionContext(options, mergeLinkifyDemotionContext(inferNextBlockLinkifyContext(raw), inferContinuationLinkifyContext(raw, context)));
|
|
11572
|
+
},
|
|
11573
|
+
remember(raw) {
|
|
11574
|
+
const nextContext = inferNextBlockLinkifyContext(raw);
|
|
11575
|
+
context = sticky ? mergeLinkifyDemotionContext(context, nextContext) : mergeLinkifyDemotionContext(nextContext, inferContinuationLinkifyContext(raw, context));
|
|
11576
|
+
},
|
|
11577
|
+
reset() {
|
|
11578
|
+
context = void 0;
|
|
11579
|
+
}
|
|
11580
|
+
};
|
|
11581
|
+
}
|
|
11281
11582
|
function isValidDomainLabel(label) {
|
|
11282
11583
|
return DOMAIN_LABEL_RE.test(label) && !label.startsWith("-") && !label.endsWith("-");
|
|
11283
11584
|
}
|
|
@@ -11288,6 +11589,27 @@ function isPlausibleBareDomain(text$1) {
|
|
|
11288
11589
|
if (!(isValidDomainLabel(tld) || PUNYCODE_TLD_RE.test(tld))) return false;
|
|
11289
11590
|
return labels.every(isValidDomainLabel);
|
|
11290
11591
|
}
|
|
11592
|
+
function hasNonAsciiText(input) {
|
|
11593
|
+
return Array.from(input).some((char) => char.charCodeAt(0) > 127);
|
|
11594
|
+
}
|
|
11595
|
+
function getHrefAuthority(href) {
|
|
11596
|
+
return href.replace(/^[a-z][a-z0-9+.-]*:\/\//i, "").split(/[/?#]/, 1)[0] ?? "";
|
|
11597
|
+
}
|
|
11598
|
+
function hasPunycodeAuthorityLabel(authority) {
|
|
11599
|
+
return authority.split(".").some((label) => label.toLowerCase().startsWith("xn--"));
|
|
11600
|
+
}
|
|
11601
|
+
function isDecodedFromRawPunycode(linkText, href, raw) {
|
|
11602
|
+
const authority = getHrefAuthority(href);
|
|
11603
|
+
return hasNonAsciiText(linkText) && hasPunycodeAuthorityLabel(authority) && String(raw ?? "").toLowerCase().includes(authority.toLowerCase());
|
|
11604
|
+
}
|
|
11605
|
+
function inferLinkifyDemotionContext(contextText) {
|
|
11606
|
+
const text$1 = String(contextText ?? "");
|
|
11607
|
+
return {
|
|
11608
|
+
explicitFilename: EXPLICIT_FILENAME_CONTEXT_RE.test(text$1),
|
|
11609
|
+
filename: FILENAME_CONTEXT_RE.test(text$1),
|
|
11610
|
+
marketTicker: MARKET_TICKER_CONTEXT_RE.test(text$1)
|
|
11611
|
+
};
|
|
11612
|
+
}
|
|
11291
11613
|
function hasDomainAuthorityPrefix(text$1) {
|
|
11292
11614
|
return isPlausibleBareDomain(text$1.split(/[\\/]/)[0] ?? "");
|
|
11293
11615
|
}
|
|
@@ -11300,16 +11622,28 @@ function hasStrongFilenameSignals(linkText) {
|
|
|
11300
11622
|
if (!DOMAINISH_TEXT_RE.test(linkText)) return true;
|
|
11301
11623
|
if (PATH_SEPARATOR_RE.test(linkText)) return !hasDomainAuthorityPrefix(linkText);
|
|
11302
11624
|
const extensionless = linkText.replace(FILENAMEISH_EXTENSION_RE, "");
|
|
11303
|
-
if (
|
|
11625
|
+
if (hasNonAsciiText(extensionless)) return true;
|
|
11304
11626
|
return extensionless.split(".").filter(Boolean).some(isUppercaseFilenameSegment);
|
|
11305
11627
|
}
|
|
11306
|
-
function
|
|
11628
|
+
function isMarketTickerLikeText(linkText, extension, hasMarketTickerContext) {
|
|
11629
|
+
if (!(hasMarketTickerContext ? MARKET_TICKER_CONTEXT_SUFFIXES : MARKET_TICKER_SUFFIXES).has(extension)) return false;
|
|
11630
|
+
const symbol = linkText.slice(0, -(extension.length + 1));
|
|
11631
|
+
if (symbol === "") return linkText.startsWith(".");
|
|
11632
|
+
return (hasMarketTickerContext ? MARKET_TICKER_CONTEXT_SYMBOL_RE : MARKET_TICKER_SYMBOL_RE).test(symbol);
|
|
11633
|
+
}
|
|
11634
|
+
function shouldDemoteFilenameLikeLinkify(linkText, context = {}) {
|
|
11307
11635
|
if (!linkText || URL_PREFIX_HINT_RE.test(linkText) || URL_QUERY_OR_AUTH_HINT_RE.test(linkText)) return false;
|
|
11308
11636
|
const extensionMatch = linkText.match(FILENAMEISH_EXTENSION_RE);
|
|
11309
11637
|
if (!extensionMatch) return false;
|
|
11310
11638
|
const extension = String(extensionMatch[1] ?? "").toLowerCase();
|
|
11311
|
-
if (
|
|
11639
|
+
if (isMarketTickerLikeText(linkText, extension, context.marketTicker === true)) return true;
|
|
11640
|
+
if (!FILENAMEISH_LINK_EXTENSIONS.has(extension)) {
|
|
11641
|
+
if (context.explicitFilename && EXPLICIT_FILENAME_CONTEXT_ONLY_EXTENSIONS.has(extension)) return true;
|
|
11642
|
+
if (context.filename && FILENAME_CONTEXT_ONLY_EXTENSIONS.has(extension)) return true;
|
|
11643
|
+
return false;
|
|
11644
|
+
}
|
|
11312
11645
|
if (!AMBIGUOUS_BARE_DOMAIN_EXTENSIONS.has(extension)) return true;
|
|
11646
|
+
if (context.filename) return true;
|
|
11313
11647
|
return hasStrongFilenameSignals(linkText);
|
|
11314
11648
|
}
|
|
11315
11649
|
|
|
@@ -11439,16 +11773,17 @@ function applyFixLinkTokens(md) {
|
|
|
11439
11773
|
for (let i = 0; i < toks.length; i++) {
|
|
11440
11774
|
const t = toks[i];
|
|
11441
11775
|
if (t && t.type === "inline" && Array.isArray(t.children)) try {
|
|
11442
|
-
t.children = fixLinkToken(t.children);
|
|
11776
|
+
t.children = fixLinkToken(t.children, typeof t.content === "string" ? t.content : void 0);
|
|
11443
11777
|
} catch (e) {
|
|
11444
11778
|
console.error("[applyFixLinkTokens] failed to fix inline children", e);
|
|
11445
11779
|
}
|
|
11446
11780
|
}
|
|
11447
11781
|
});
|
|
11448
11782
|
}
|
|
11449
|
-
function fixLinkToken(tokens) {
|
|
11783
|
+
function fixLinkToken(tokens, raw) {
|
|
11450
11784
|
if (tokens.length < 3) return tokens;
|
|
11451
11785
|
if (tokens.some((token) => token.type === "code_inline")) return tokens;
|
|
11786
|
+
const linkifyDemotionContext = inferLinkifyDemotionContext(raw);
|
|
11452
11787
|
for (let i = 0; i <= tokens.length - 1; i++) {
|
|
11453
11788
|
if (i < 0) i = 0;
|
|
11454
11789
|
const curToken = tokens[i];
|
|
@@ -11461,11 +11796,11 @@ function fixLinkToken(tokens) {
|
|
|
11461
11796
|
}
|
|
11462
11797
|
if (closeIdx !== -1) {
|
|
11463
11798
|
const linkText = collectLinkifyText(tokens, i, closeIdx);
|
|
11464
|
-
|
|
11799
|
+
const href = getHrefFromLinkOpen(curToken);
|
|
11800
|
+
if (curToken.markup === "linkify" && linkText && !isDecodedFromRawPunycode(linkText, href, raw) && shouldDemoteFilenameLikeLinkify(linkText, linkifyDemotionContext)) {
|
|
11465
11801
|
tokens.splice(i, closeIdx - i + 1, textToken(linkText));
|
|
11466
11802
|
continue;
|
|
11467
11803
|
}
|
|
11468
|
-
const href = getHrefFromLinkOpen(curToken);
|
|
11469
11804
|
const hrefStop = firstIndexOfAny(href, LINKIFY_HARD_STOP_CHARS);
|
|
11470
11805
|
for (let j = i + 1; j < closeIdx; j++) {
|
|
11471
11806
|
const t = tokens[j];
|
|
@@ -12570,23 +12905,25 @@ function findRangeAt(ranges, index) {
|
|
|
12570
12905
|
for (const range of ranges) if (index >= range[0] && index < range[1]) return range;
|
|
12571
12906
|
return null;
|
|
12572
12907
|
}
|
|
12573
|
-
function buildImageRanges(src) {
|
|
12908
|
+
function buildImageRanges(src, allowIncomplete = false) {
|
|
12574
12909
|
const ranges = [];
|
|
12575
12910
|
let i = 0;
|
|
12576
12911
|
while (i < src.length - 1) {
|
|
12577
12912
|
if (src[i] === "!" && src[i + 1] === "[") {
|
|
12578
12913
|
const start = i;
|
|
12579
12914
|
let j = i + 2;
|
|
12580
|
-
|
|
12915
|
+
let labelDepth = 1;
|
|
12916
|
+
while (j < src.length && labelDepth > 0) {
|
|
12581
12917
|
if (src[j] === "\\" && j + 1 < src.length) {
|
|
12582
12918
|
j += 2;
|
|
12583
12919
|
continue;
|
|
12584
12920
|
}
|
|
12585
|
-
if (src[j] === "
|
|
12921
|
+
if (src[j] === "[") labelDepth++;
|
|
12922
|
+
else if (src[j] === "]") labelDepth--;
|
|
12586
12923
|
j++;
|
|
12587
12924
|
}
|
|
12588
|
-
if (
|
|
12589
|
-
let k = j +
|
|
12925
|
+
if (labelDepth === 0 && j < src.length && src[j] === "(") {
|
|
12926
|
+
let k = j + 1;
|
|
12590
12927
|
let depth = 1;
|
|
12591
12928
|
while (k < src.length && depth > 0) {
|
|
12592
12929
|
if (src[k] === "\\" && k + 1 < src.length) {
|
|
@@ -12602,6 +12939,11 @@ function buildImageRanges(src) {
|
|
|
12602
12939
|
i = k;
|
|
12603
12940
|
continue;
|
|
12604
12941
|
}
|
|
12942
|
+
if (allowIncomplete) {
|
|
12943
|
+
ranges.push([start, src.length]);
|
|
12944
|
+
i = src.length;
|
|
12945
|
+
continue;
|
|
12946
|
+
}
|
|
12605
12947
|
}
|
|
12606
12948
|
}
|
|
12607
12949
|
i++;
|
|
@@ -12691,7 +13033,7 @@ function applyMath(md, mathOpts) {
|
|
|
12691
13033
|
for (const [open, close] of delimiters) {
|
|
12692
13034
|
const src = s.src;
|
|
12693
13035
|
const codeSpanRanges = buildCodeSpanRanges(src);
|
|
12694
|
-
const imageRanges = buildImageRanges(src);
|
|
13036
|
+
const imageRanges = buildImageRanges(src, allowLoading);
|
|
12695
13037
|
let foundAny = false;
|
|
12696
13038
|
if (open === "$$" && searchPos !== initialPos) searchPos = initialPos;
|
|
12697
13039
|
let lastIndex = -1;
|
|
@@ -13111,6 +13453,7 @@ function applyMath(md, mathOpts) {
|
|
|
13111
13453
|
let content = "";
|
|
13112
13454
|
let found = false;
|
|
13113
13455
|
const firstLineContent = lineText === openDelim ? "" : lineText.slice(openDelim.length);
|
|
13456
|
+
const fallbackPlainBracketClose = !strict && openDelim === "\\[" ? "]" : "";
|
|
13114
13457
|
if (firstLineContent.includes(closeDelim)) {
|
|
13115
13458
|
const endIndex = firstLineContent.indexOf(closeDelim);
|
|
13116
13459
|
content = firstLineContent.slice(0, endIndex);
|
|
@@ -13122,6 +13465,11 @@ function applyMath(md, mathOpts) {
|
|
|
13122
13465
|
const lineStart = s.bMarks[nextLine] + s.tShift[nextLine];
|
|
13123
13466
|
const lineEnd = s.eMarks[nextLine];
|
|
13124
13467
|
const currentLine = s.src.slice(lineStart, lineEnd);
|
|
13468
|
+
if (fallbackPlainBracketClose && currentLine.trim() === fallbackPlainBracketClose) {
|
|
13469
|
+
closeDelim = fallbackPlainBracketClose;
|
|
13470
|
+
found = true;
|
|
13471
|
+
break;
|
|
13472
|
+
}
|
|
13125
13473
|
if (currentLine.trim() === closeDelim) {
|
|
13126
13474
|
found = true;
|
|
13127
13475
|
break;
|
|
@@ -13220,6 +13568,16 @@ function factory(opts = {}) {
|
|
|
13220
13568
|
return md;
|
|
13221
13569
|
}
|
|
13222
13570
|
|
|
13571
|
+
//#endregion
|
|
13572
|
+
//#region src/parser/token-copy.ts
|
|
13573
|
+
function cloneTokenWithMutableChildren(token) {
|
|
13574
|
+
const copy = Object.assign(Object.create(Object.getPrototypeOf(token)), token);
|
|
13575
|
+
if (Array.isArray(token.attrs)) copy.attrs = token.attrs.map((attr) => [...attr]);
|
|
13576
|
+
if (Array.isArray(token.map)) copy.map = [...token.map];
|
|
13577
|
+
if (Array.isArray(token.children)) copy.children = token.children.map((child) => cloneTokenWithMutableChildren(child));
|
|
13578
|
+
return copy;
|
|
13579
|
+
}
|
|
13580
|
+
|
|
13223
13581
|
//#endregion
|
|
13224
13582
|
//#region src/parser/inline-parsers/checkbox-parser.ts
|
|
13225
13583
|
function parseCheckboxToken(token) {
|
|
@@ -13288,6 +13646,11 @@ const DIFF_HEADER_PREFIXES = [
|
|
|
13288
13646
|
"@@ "
|
|
13289
13647
|
];
|
|
13290
13648
|
const NEWLINE_RE = /\r?\n/;
|
|
13649
|
+
function isPotentialDiffMetadataTail(line) {
|
|
13650
|
+
const value = String(line ?? "");
|
|
13651
|
+
if (!value) return false;
|
|
13652
|
+
return DIFF_HEADER_PREFIXES.some((prefix) => prefix.startsWith(value) || value.startsWith(prefix));
|
|
13653
|
+
}
|
|
13291
13654
|
function flushPendingDiffHunk(orig, updated, pendingOrig, pendingUpdated) {
|
|
13292
13655
|
if (pendingOrig.length > 0) orig.push(...pendingOrig);
|
|
13293
13656
|
if (pendingUpdated.length > 0) updated.push(...pendingUpdated);
|
|
@@ -13300,7 +13663,7 @@ function splitUnifiedDiff(content, closed) {
|
|
|
13300
13663
|
const pendingOrig = [];
|
|
13301
13664
|
const pendingUpdated = [];
|
|
13302
13665
|
const lines = content.split(NEWLINE_RE);
|
|
13303
|
-
const
|
|
13666
|
+
const endsWithNewline = /\r?\n$/.test(content);
|
|
13304
13667
|
const hasUnifiedDiffHeaders = lines.some((line) => line.startsWith("diff ") || line.startsWith("--- ") || line.startsWith("+++ ") || line.startsWith("@@ "));
|
|
13305
13668
|
const processLine = (rawLine) => {
|
|
13306
13669
|
const line = rawLine;
|
|
@@ -13318,18 +13681,25 @@ function splitUnifiedDiff(content, closed) {
|
|
|
13318
13681
|
updated.push(contextLine);
|
|
13319
13682
|
}
|
|
13320
13683
|
};
|
|
13321
|
-
|
|
13322
|
-
|
|
13323
|
-
|
|
13684
|
+
const lineCountToProcess = endsWithNewline ? Math.max(0, lines.length - 1) : lines.length;
|
|
13685
|
+
for (let index = 0; index < lineCountToProcess; index++) {
|
|
13686
|
+
const line = lines[index] ?? "";
|
|
13687
|
+
if (!closed && !endsWithNewline && index === lineCountToProcess - 1 && isPotentialDiffMetadataTail(line)) continue;
|
|
13688
|
+
processLine(line);
|
|
13689
|
+
}
|
|
13690
|
+
if (closed || pendingOrig.length > 0 || pendingUpdated.length > 0) flushPendingDiffHunk(orig, updated, pendingOrig, pendingUpdated);
|
|
13691
|
+
const originalCode = orig.join("\n");
|
|
13692
|
+
const updatedCode = updated.join("\n");
|
|
13324
13693
|
return {
|
|
13325
|
-
original:
|
|
13326
|
-
updated:
|
|
13694
|
+
original: closed && endsWithNewline && originalCode ? `${originalCode}\n` : originalCode,
|
|
13695
|
+
updated: closed && endsWithNewline && updatedCode ? `${updatedCode}\n` : updatedCode
|
|
13327
13696
|
};
|
|
13328
13697
|
}
|
|
13329
13698
|
function parseFenceToken(token) {
|
|
13330
13699
|
const hasMap = Array.isArray(token.map) && token.map.length === 2;
|
|
13331
13700
|
const tokenMeta = token.meta ?? {};
|
|
13332
|
-
const
|
|
13701
|
+
const metaClosed = typeof tokenMeta.closed === "boolean" ? tokenMeta.closed : void 0;
|
|
13702
|
+
const closed = metaClosed === true || metaClosed !== false && hasMap;
|
|
13333
13703
|
const info = String(token.info ?? "");
|
|
13334
13704
|
const diff = info.startsWith("diff");
|
|
13335
13705
|
const language = diff ? (() => {
|
|
@@ -13347,7 +13717,7 @@ function parseFenceToken(token) {
|
|
|
13347
13717
|
code: String(updated ?? ""),
|
|
13348
13718
|
raw: String(content ?? ""),
|
|
13349
13719
|
diff,
|
|
13350
|
-
loading:
|
|
13720
|
+
loading: metaClosed === true ? false : metaClosed === false ? true : !hasMap,
|
|
13351
13721
|
originalCode: original,
|
|
13352
13722
|
updatedCode: updated
|
|
13353
13723
|
};
|
|
@@ -13358,7 +13728,7 @@ function parseFenceToken(token) {
|
|
|
13358
13728
|
code: String(content ?? ""),
|
|
13359
13729
|
raw: String(content ?? ""),
|
|
13360
13730
|
diff,
|
|
13361
|
-
loading:
|
|
13731
|
+
loading: metaClosed === true ? false : metaClosed === false ? true : !hasMap
|
|
13362
13732
|
};
|
|
13363
13733
|
}
|
|
13364
13734
|
|
|
@@ -13448,6 +13818,15 @@ function tokenToRaw(token) {
|
|
|
13448
13818
|
const raw = shape.raw ?? shape.content ?? shape.markup ?? "";
|
|
13449
13819
|
return String(raw ?? "");
|
|
13450
13820
|
}
|
|
13821
|
+
function getCustomHtmlSourceMeta(token) {
|
|
13822
|
+
const meta = token.meta;
|
|
13823
|
+
const raw = meta?.markstreamCustomHtmlRaw;
|
|
13824
|
+
const inner = meta?.markstreamCustomHtmlInner;
|
|
13825
|
+
return typeof raw === "string" && typeof inner === "string" ? {
|
|
13826
|
+
raw,
|
|
13827
|
+
inner
|
|
13828
|
+
} : null;
|
|
13829
|
+
}
|
|
13451
13830
|
function getAttrValue$1(attrs, name) {
|
|
13452
13831
|
const lowerName = name.toLowerCase();
|
|
13453
13832
|
for (let i = attrs.length - 1; i >= 0; i--) {
|
|
@@ -13632,16 +14011,19 @@ function parseHtmlInlineCodeToken(token, tokens, i, parseInlineTokens$1, raw, pP
|
|
|
13632
14011
|
const attrValue = match[2] || match[3] || match[4] || "";
|
|
13633
14012
|
attrs.push([attrName, attrValue]);
|
|
13634
14013
|
}
|
|
13635
|
-
if (customTagSet?.has(tag))
|
|
13636
|
-
|
|
13637
|
-
|
|
13638
|
-
|
|
13639
|
-
|
|
13640
|
-
|
|
13641
|
-
|
|
13642
|
-
|
|
13643
|
-
|
|
13644
|
-
|
|
14014
|
+
if (customTagSet?.has(tag)) {
|
|
14015
|
+
const sourceMeta = getCustomHtmlSourceMeta(token);
|
|
14016
|
+
return [{
|
|
14017
|
+
type: tag,
|
|
14018
|
+
tag,
|
|
14019
|
+
attrs,
|
|
14020
|
+
content: sourceMeta ? sourceMeta.inner : fragment.innerTokens.length ? stringifyTokens(fragment.innerTokens) : "",
|
|
14021
|
+
children: fragment.innerTokens.length ? parseInlineTokens$1(fragment.innerTokens, raw, pPreToken, options) : [],
|
|
14022
|
+
raw: sourceMeta?.raw ?? content,
|
|
14023
|
+
loading: token.loading || loading,
|
|
14024
|
+
autoClosed
|
|
14025
|
+
}, fragment.nextIndex];
|
|
14026
|
+
}
|
|
13645
14027
|
return [{
|
|
13646
14028
|
type: "html_inline",
|
|
13647
14029
|
tag,
|
|
@@ -13656,6 +14038,19 @@ function parseHtmlInlineCodeToken(token, tokens, i, parseInlineTokens$1, raw, pP
|
|
|
13656
14038
|
|
|
13657
14039
|
//#endregion
|
|
13658
14040
|
//#region src/parser/inline-parsers/image-parser.ts
|
|
14041
|
+
function stringifyAltToken(token) {
|
|
14042
|
+
if (token.type === "math_inline") {
|
|
14043
|
+
if (token.raw) return String(token.raw);
|
|
14044
|
+
const markup = token.markup === "$$" ? "$$" : "$";
|
|
14045
|
+
return `${markup}${String(token.content ?? "")}${markup}`;
|
|
14046
|
+
}
|
|
14047
|
+
if (Array.isArray(token.children) && token.children.length > 0) return token.children.map((child) => stringifyAltToken(child)).join("");
|
|
14048
|
+
return String(token.content ?? "");
|
|
14049
|
+
}
|
|
14050
|
+
function getAltFromTokenChildren(token) {
|
|
14051
|
+
if (!token || !Array.isArray(token.children) || token.children.length === 0) return "";
|
|
14052
|
+
return token.children.map((child) => stringifyAltToken(child)).join("");
|
|
14053
|
+
}
|
|
13659
14054
|
function parseImageToken(token, loading = false) {
|
|
13660
14055
|
let attrs = token.attrs ?? [];
|
|
13661
14056
|
let childWithAttrs = null;
|
|
@@ -13669,8 +14064,10 @@ function parseImageToken(token, loading = false) {
|
|
|
13669
14064
|
}
|
|
13670
14065
|
const src = String(attrs.find((attr) => attr[0] === "src")?.[1] ?? "");
|
|
13671
14066
|
const altAttr = attrs.find((attr) => attr[0] === "alt")?.[1];
|
|
14067
|
+
const childAlt = getAltFromTokenChildren(childWithAttrs ?? token);
|
|
13672
14068
|
let alt = "";
|
|
13673
|
-
if (
|
|
14069
|
+
if (childAlt) alt = childAlt;
|
|
14070
|
+
else if (altAttr != null && String(altAttr).length > 0) alt = String(altAttr);
|
|
13674
14071
|
else if (childWithAttrs?.content != null && String(childWithAttrs.content).length > 0) alt = String(childWithAttrs.content);
|
|
13675
14072
|
else if (Array.isArray(childWithAttrs?.children) && childWithAttrs.children[0]?.content) alt = String(childWithAttrs.children[0].content);
|
|
13676
14073
|
else if (Array.isArray(token.children) && token.children[0]?.content) alt = String(token.children[0].content);
|
|
@@ -13762,14 +14159,18 @@ function parseLinkToken(tokens, startIndex, options) {
|
|
|
13762
14159
|
i++;
|
|
13763
14160
|
}
|
|
13764
14161
|
if (tokens[i]?.type === "link_close") loading = false;
|
|
14162
|
+
let childTokens = linkTokens;
|
|
13765
14163
|
const lastLinkToken = linkTokens[linkTokens.length - 1];
|
|
13766
14164
|
if (options?.__insideStrong && lastLinkToken?.type === "text" && String(lastLinkToken.content ?? "").endsWith("**") && !linkTokens.some((token) => token.type === "strong_open")) {
|
|
13767
14165
|
const originalContent = String(lastLinkToken.content ?? "");
|
|
13768
14166
|
const originalRaw = String(lastLinkToken.raw ?? originalContent);
|
|
13769
|
-
|
|
13770
|
-
|
|
14167
|
+
const adjustedLastLinkToken = cloneTokenWithMutableChildren(lastLinkToken);
|
|
14168
|
+
adjustedLastLinkToken.content = originalContent.slice(0, -2);
|
|
14169
|
+
adjustedLastLinkToken.raw = originalRaw.replace(/\*\*$/, "");
|
|
14170
|
+
childTokens = linkTokens.slice();
|
|
14171
|
+
childTokens[childTokens.length - 1] = adjustedLastLinkToken;
|
|
13771
14172
|
}
|
|
13772
|
-
const children = parseInlineTokens(
|
|
14173
|
+
const children = parseInlineTokens(childTokens, void 0, void 0, options);
|
|
13773
14174
|
const linkText = children.map((node) => {
|
|
13774
14175
|
const nodeAny = node;
|
|
13775
14176
|
if ("content" in node) return String(nodeAny.content ?? "");
|
|
@@ -14189,11 +14590,27 @@ function recoverTrailingMarkdownLinkLabel(raw, href) {
|
|
|
14189
14590
|
}
|
|
14190
14591
|
function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
14191
14592
|
if (!tokens || tokens.length === 0) return [];
|
|
14593
|
+
const inheritedContext = options?.__linkifyDemotionContext;
|
|
14594
|
+
const inferredContext = inferLinkifyDemotionContext(raw);
|
|
14595
|
+
const linkifyDemotionContext = {
|
|
14596
|
+
filename: inheritedContext?.filename || inferredContext.filename,
|
|
14597
|
+
explicitFilename: inheritedContext?.explicitFilename || inferredContext.explicitFilename,
|
|
14598
|
+
marketTicker: inheritedContext?.marketTicker || inferredContext.marketTicker
|
|
14599
|
+
};
|
|
14600
|
+
if (linkifyDemotionContext.filename || linkifyDemotionContext.explicitFilename || linkifyDemotionContext.marketTicker) options = {
|
|
14601
|
+
...options,
|
|
14602
|
+
__linkifyDemotionContext: linkifyDemotionContext
|
|
14603
|
+
};
|
|
14192
14604
|
const internalOptions = options;
|
|
14193
14605
|
const result = [];
|
|
14194
14606
|
let currentTextNode = null;
|
|
14195
14607
|
let i = 0;
|
|
14196
14608
|
const requireClosingStrong = options?.requireClosingStrong;
|
|
14609
|
+
const originalTokens = tokens;
|
|
14610
|
+
function ensureWorkingTokens() {
|
|
14611
|
+
if (tokens === originalTokens) tokens = tokens.slice();
|
|
14612
|
+
return tokens;
|
|
14613
|
+
}
|
|
14197
14614
|
function resetCurrentTextNode() {
|
|
14198
14615
|
currentTextNode = null;
|
|
14199
14616
|
}
|
|
@@ -14644,7 +15061,8 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
14644
15061
|
}
|
|
14645
15062
|
function pushToken(token) {
|
|
14646
15063
|
resetCurrentTextNode();
|
|
14647
|
-
|
|
15064
|
+
const node = cloneTokenWithMutableChildren(token);
|
|
15065
|
+
result.push(node);
|
|
14648
15066
|
}
|
|
14649
15067
|
function pushNode(node) {
|
|
14650
15068
|
pushParsed(node);
|
|
@@ -14880,6 +15298,7 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
14880
15298
|
pushText(displayText, displayText);
|
|
14881
15299
|
i++;
|
|
14882
15300
|
} else if (recoverOuterImageLinkFromSyntheticLinkToken(token)) i++;
|
|
15301
|
+
else if (recoverMarkdownImageFromLoadingImageTail(token)) i++;
|
|
14883
15302
|
else if (recoverMarkdownImageFromTrailingBang(token)) i++;
|
|
14884
15303
|
else if (recoverMarkdownLinkFromTrailingText(token)) i++;
|
|
14885
15304
|
else {
|
|
@@ -14930,10 +15349,6 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
14930
15349
|
result.length = trailingTextStart;
|
|
14931
15350
|
} else currentTextNode = result[result.length - 1];
|
|
14932
15351
|
const nextToken = tokens[i + 1];
|
|
14933
|
-
if (pPreToken?.type === "list_item_open" && /^\d$/.test(content)) {
|
|
14934
|
-
i++;
|
|
14935
|
-
return;
|
|
14936
|
-
}
|
|
14937
15352
|
if ((content === "`" || content === "|" || content === "$") && !hasEscapedMarkup(token, `\\${content}`) || /^\*+$/.test(content) && !hasEscapedMarkup(token, "\\*")) {
|
|
14938
15353
|
i++;
|
|
14939
15354
|
return;
|
|
@@ -14971,6 +15386,7 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
14971
15386
|
i++;
|
|
14972
15387
|
}
|
|
14973
15388
|
function handleLinkOpen(token) {
|
|
15389
|
+
if (recoverMarkdownImageFromLoadingImageTailLinkOpen(token)) return;
|
|
14974
15390
|
if (shouldTreatLinkOpenAsTextInEscapedOuterImageTail()) {
|
|
14975
15391
|
const { node: node$1, nextIndex: nextIndex$1 } = parseLinkToken(tokens, i, options);
|
|
14976
15392
|
const text$1 = String(node$1.text || node$1.href || "");
|
|
@@ -14981,8 +15397,9 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
14981
15397
|
resetCurrentTextNode();
|
|
14982
15398
|
const { node, nextIndex } = parseLinkToken(tokens, i, options);
|
|
14983
15399
|
i = nextIndex;
|
|
14984
|
-
|
|
14985
|
-
|
|
15400
|
+
const linkText = node.text || node.href || "";
|
|
15401
|
+
if (token.markup === "linkify" && !isDecodedFromRawPunycode(linkText, node.href, raw) && shouldDemoteFilenameLikeLinkify(linkText, internalOptions?.__linkifyDemotionContext)) {
|
|
15402
|
+
pushText(linkText, linkText);
|
|
14986
15403
|
return;
|
|
14987
15404
|
}
|
|
14988
15405
|
const hasSingleTextChild = node.children.length === 1 && node.children[0]?.type === "text";
|
|
@@ -15017,6 +15434,13 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
15017
15434
|
if (recoverMarkdownLinkFromTrailingText(node)) return;
|
|
15018
15435
|
pushParsed(node);
|
|
15019
15436
|
}
|
|
15437
|
+
function recoverMarkdownImageFromLoadingImageTailLinkOpen(token) {
|
|
15438
|
+
if (token.markup !== "linkify") return false;
|
|
15439
|
+
const { node, nextIndex } = parseLinkToken(tokens, i, options);
|
|
15440
|
+
if (!recoverMarkdownImageFromLoadingImageTailLink(node, nextIndex)) return false;
|
|
15441
|
+
i = nextIndex;
|
|
15442
|
+
return true;
|
|
15443
|
+
}
|
|
15020
15444
|
function handleReference(token) {
|
|
15021
15445
|
resetCurrentTextNode();
|
|
15022
15446
|
pushNode(parseReferenceToken(token));
|
|
@@ -15051,6 +15475,41 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
15051
15475
|
});
|
|
15052
15476
|
return true;
|
|
15053
15477
|
}
|
|
15478
|
+
function recoverMarkdownImageFromLoadingImageTail(token) {
|
|
15479
|
+
if (token.type !== "link") return false;
|
|
15480
|
+
const linkToken = token;
|
|
15481
|
+
const href = String(linkToken.href ?? "");
|
|
15482
|
+
if (!href) return false;
|
|
15483
|
+
return recoverMarkdownImageFromLoadingImageTailLink({
|
|
15484
|
+
href,
|
|
15485
|
+
title: linkToken.title == null || linkToken.title === "" ? null : String(linkToken.title),
|
|
15486
|
+
loading: Boolean(linkToken.loading)
|
|
15487
|
+
}, i + 1);
|
|
15488
|
+
}
|
|
15489
|
+
function recoverMarkdownImageFromLoadingImageTailLink(link$1, nextIndex) {
|
|
15490
|
+
const previous = result[result.length - 1];
|
|
15491
|
+
if (previous?.type !== "image" || previous.src || !previous.loading || !String(previous.raw ?? "").endsWith("](")) return false;
|
|
15492
|
+
const nextToken = tokens[nextIndex];
|
|
15493
|
+
const nextContent = String(nextToken?.content ?? "");
|
|
15494
|
+
if (nextToken?.type !== "text" || !nextContent.startsWith(")")) return false;
|
|
15495
|
+
result.pop();
|
|
15496
|
+
currentTextNode = null;
|
|
15497
|
+
const alt = String(previous.alt ?? "");
|
|
15498
|
+
pushParsed({
|
|
15499
|
+
type: "image",
|
|
15500
|
+
src: link$1.href,
|
|
15501
|
+
alt,
|
|
15502
|
+
title: link$1.title,
|
|
15503
|
+
raw: String(``),
|
|
15504
|
+
loading: Boolean(link$1.loading)
|
|
15505
|
+
});
|
|
15506
|
+
const trailing = nextContent.slice(1);
|
|
15507
|
+
const adjustedNext = cloneTokenWithMutableChildren(nextToken);
|
|
15508
|
+
adjustedNext.content = trailing;
|
|
15509
|
+
adjustedNext.raw = trailing;
|
|
15510
|
+
ensureWorkingTokens()[nextIndex] = adjustedNext;
|
|
15511
|
+
return true;
|
|
15512
|
+
}
|
|
15054
15513
|
function recoverMarkdownImageFromTrailingBang(token) {
|
|
15055
15514
|
if (token.type !== "link") return false;
|
|
15056
15515
|
const previous = result[result.length - 1];
|
|
@@ -15218,12 +15677,14 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
15218
15677
|
const lastContent = String(last.content ?? "");
|
|
15219
15678
|
if (lastContent.startsWith(")")) {
|
|
15220
15679
|
loading$1 = false;
|
|
15221
|
-
const
|
|
15222
|
-
if (
|
|
15223
|
-
|
|
15224
|
-
|
|
15680
|
+
const trailingAfterClose = lastContent.slice(1);
|
|
15681
|
+
if (trailingAfterClose) {
|
|
15682
|
+
const trailingToken = cloneTokenWithMutableChildren(last);
|
|
15683
|
+
trailingToken.content = trailingAfterClose;
|
|
15684
|
+
trailingToken.raw = trailingAfterClose;
|
|
15685
|
+
ensureWorkingTokens()[i + 4] = trailingToken;
|
|
15225
15686
|
} else index++;
|
|
15226
|
-
} else if (lastContent === ".")
|
|
15687
|
+
} else if (lastContent === ".") index++;
|
|
15227
15688
|
}
|
|
15228
15689
|
pushInlineTextContent(textNodeContent, _token);
|
|
15229
15690
|
const hrefFromToken = String(textToken$1.content ?? "");
|
|
@@ -15451,36 +15912,49 @@ function stripLeakedOrderedListMarkerSuffix(token) {
|
|
|
15451
15912
|
break;
|
|
15452
15913
|
}
|
|
15453
15914
|
}
|
|
15915
|
+
function needsListParagraphTokenPatch(token) {
|
|
15916
|
+
const rawContent = String(token.content ?? "");
|
|
15917
|
+
return /[ \t\r\n]+$/.test(rawContent) || /\r?\n\s*\d+[.)]?\s*$/.test(rawContent);
|
|
15918
|
+
}
|
|
15454
15919
|
function parseList(tokens, index, options) {
|
|
15455
15920
|
const token = tokens[index];
|
|
15456
15921
|
const listItems = [];
|
|
15922
|
+
const linkifyContext = createLinkifyDemotionContextTracker(options, true);
|
|
15457
15923
|
let j = index + 1;
|
|
15458
15924
|
while (j < tokens.length && tokens[j].type !== "bullet_list_close" && tokens[j].type !== "ordered_list_close") if (tokens[j].type === "list_item_open") {
|
|
15459
15925
|
const itemChildren = [];
|
|
15460
15926
|
let k = j + 1;
|
|
15461
15927
|
while (k < tokens.length && tokens[k].type !== "list_item_close") if (tokens[k].type === "paragraph_open") {
|
|
15462
|
-
const
|
|
15928
|
+
const originalContentToken = tokens[k + 1];
|
|
15929
|
+
const contentToken = needsListParagraphTokenPatch(originalContentToken) ? cloneTokenWithMutableChildren(originalContentToken) : originalContentToken;
|
|
15463
15930
|
const preToken = tokens[k - 1];
|
|
15464
|
-
|
|
15465
|
-
|
|
15931
|
+
if (contentToken !== originalContentToken) {
|
|
15932
|
+
stripLeakedOrderedListMarkerSuffix(contentToken);
|
|
15933
|
+
trimInlineTokenTail(contentToken);
|
|
15934
|
+
}
|
|
15935
|
+
const paragraphRaw = String(contentToken.content ?? "");
|
|
15466
15936
|
itemChildren.push({
|
|
15467
15937
|
type: "paragraph",
|
|
15468
|
-
children: parseInlineTokens(contentToken.children || [],
|
|
15469
|
-
raw:
|
|
15938
|
+
children: parseInlineTokens(contentToken.children || [], paragraphRaw, preToken, linkifyContext.options()),
|
|
15939
|
+
raw: paragraphRaw
|
|
15470
15940
|
});
|
|
15941
|
+
linkifyContext.remember(paragraphRaw);
|
|
15471
15942
|
k += 3;
|
|
15472
15943
|
} else if (tokens[k].type === "blockquote_open") {
|
|
15473
|
-
const [blockquoteNode, newIndex] = parseBlockquote(tokens, k, options);
|
|
15944
|
+
const [blockquoteNode, newIndex] = parseBlockquote(tokens, k, linkifyContext.options());
|
|
15474
15945
|
itemChildren.push(blockquoteNode);
|
|
15946
|
+
linkifyContext.remember(blockquoteNode.raw);
|
|
15475
15947
|
k = newIndex;
|
|
15476
15948
|
} else if (tokens[k].type === "bullet_list_open" || tokens[k].type === "ordered_list_open") {
|
|
15477
|
-
const [nestedListNode, newIndex] = parseList(tokens, k, options);
|
|
15949
|
+
const [nestedListNode, newIndex] = parseList(tokens, k, linkifyContext.options());
|
|
15478
15950
|
itemChildren.push(nestedListNode);
|
|
15951
|
+
linkifyContext.remember(nestedListNode.raw);
|
|
15479
15952
|
k = newIndex;
|
|
15480
15953
|
} else {
|
|
15481
|
-
const handled = parseCommonBlockToken(tokens, k, options, containerTokenHandlers);
|
|
15954
|
+
const handled = parseCommonBlockToken(tokens, k, linkifyContext.options(), containerTokenHandlers);
|
|
15482
15955
|
if (handled) {
|
|
15483
15956
|
itemChildren.push(handled[0]);
|
|
15957
|
+
linkifyContext.remember(handled[0].raw);
|
|
15484
15958
|
k = handled[1];
|
|
15485
15959
|
} else k += 1;
|
|
15486
15960
|
}
|
|
@@ -15514,27 +15988,35 @@ function parseAdmonition(tokens, index, match, options) {
|
|
|
15514
15988
|
const kind = String(match[1] ?? "note");
|
|
15515
15989
|
const title = String(match[2] ?? kind.charAt(0).toUpperCase() + kind.slice(1));
|
|
15516
15990
|
const admonitionChildren = [];
|
|
15991
|
+
const linkifyContext = createLinkifyDemotionContextTracker(options, true);
|
|
15517
15992
|
let j = index + 1;
|
|
15518
15993
|
while (j < tokens.length && tokens[j].type !== "container_close") if (tokens[j].type === "paragraph_open") {
|
|
15519
15994
|
const contentToken = tokens[j + 1];
|
|
15520
|
-
if (contentToken)
|
|
15521
|
-
|
|
15522
|
-
|
|
15523
|
-
|
|
15524
|
-
|
|
15995
|
+
if (contentToken) {
|
|
15996
|
+
const paragraphNode = {
|
|
15997
|
+
type: "paragraph",
|
|
15998
|
+
children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, linkifyContext.options()),
|
|
15999
|
+
raw: String(contentToken.content ?? "")
|
|
16000
|
+
};
|
|
16001
|
+
admonitionChildren.push(paragraphNode);
|
|
16002
|
+
linkifyContext.remember(paragraphNode.raw);
|
|
16003
|
+
}
|
|
15525
16004
|
j += 3;
|
|
15526
16005
|
} else if (tokens[j].type === "bullet_list_open" || tokens[j].type === "ordered_list_open") {
|
|
15527
|
-
const [listNode, newIndex] = parseList(tokens, j, options);
|
|
16006
|
+
const [listNode, newIndex] = parseList(tokens, j, linkifyContext.options());
|
|
15528
16007
|
admonitionChildren.push(listNode);
|
|
16008
|
+
linkifyContext.remember(listNode.raw);
|
|
15529
16009
|
j = newIndex;
|
|
15530
16010
|
} else if (tokens[j].type === "blockquote_open") {
|
|
15531
|
-
const [blockquoteNode, newIndex] = parseBlockquote(tokens, j, options);
|
|
16011
|
+
const [blockquoteNode, newIndex] = parseBlockquote(tokens, j, linkifyContext.options());
|
|
15532
16012
|
admonitionChildren.push(blockquoteNode);
|
|
16013
|
+
linkifyContext.remember(blockquoteNode.raw);
|
|
15533
16014
|
j = newIndex;
|
|
15534
16015
|
} else {
|
|
15535
|
-
const handled = parseBasicBlockToken(tokens, j, options);
|
|
16016
|
+
const handled = parseBasicBlockToken(tokens, j, linkifyContext.options());
|
|
15536
16017
|
if (handled) {
|
|
15537
16018
|
admonitionChildren.push(handled[0]);
|
|
16019
|
+
linkifyContext.remember(handled[0].raw);
|
|
15538
16020
|
j = handled[1];
|
|
15539
16021
|
} else j++;
|
|
15540
16022
|
}
|
|
@@ -15594,6 +16076,7 @@ function parseContainer(tokens, index, options) {
|
|
|
15594
16076
|
}
|
|
15595
16077
|
if (!title) title = kind.charAt(0).toUpperCase() + kind.slice(1);
|
|
15596
16078
|
const children = [];
|
|
16079
|
+
const linkifyContext = createLinkifyDemotionContextTracker(options, true);
|
|
15597
16080
|
let j = index + 1;
|
|
15598
16081
|
const closeType = /* @__PURE__ */ new RegExp(`^container_${kind}_close$`);
|
|
15599
16082
|
while (j < tokens.length && tokens[j].type !== "container_close" && !closeType.test(tokens[j].type)) if (tokens[j].type === "paragraph_open") {
|
|
@@ -15608,26 +16091,30 @@ function parseContainer(tokens, index, options) {
|
|
|
15608
16091
|
break;
|
|
15609
16092
|
}
|
|
15610
16093
|
}
|
|
15611
|
-
const
|
|
15612
|
-
children.push({
|
|
16094
|
+
const paragraphNode = {
|
|
15613
16095
|
type: "paragraph",
|
|
15614
|
-
children: parseInlineTokens(
|
|
16096
|
+
children: parseInlineTokens((i !== -1 ? childrenArr.slice(0, i) : childrenArr) || [], void 0, void 0, linkifyContext.options()),
|
|
15615
16097
|
raw: String(contentToken.content ?? "").replace(/\n:+$/, "").replace(/\n\s*:::\s*$/, "")
|
|
15616
|
-
}
|
|
16098
|
+
};
|
|
16099
|
+
children.push(paragraphNode);
|
|
16100
|
+
linkifyContext.remember(paragraphNode.raw);
|
|
15617
16101
|
}
|
|
15618
16102
|
j += 3;
|
|
15619
16103
|
} else if (tokens[j].type === "bullet_list_open" || tokens[j].type === "ordered_list_open") {
|
|
15620
|
-
const [listNode, newIndex] = parseList(tokens, j, options);
|
|
16104
|
+
const [listNode, newIndex] = parseList(tokens, j, linkifyContext.options());
|
|
15621
16105
|
children.push(listNode);
|
|
16106
|
+
linkifyContext.remember(listNode.raw);
|
|
15622
16107
|
j = newIndex;
|
|
15623
16108
|
} else if (tokens[j].type === "blockquote_open") {
|
|
15624
|
-
const [blockquoteNode, newIndex] = parseBlockquote(tokens, j, options);
|
|
16109
|
+
const [blockquoteNode, newIndex] = parseBlockquote(tokens, j, linkifyContext.options());
|
|
15625
16110
|
children.push(blockquoteNode);
|
|
16111
|
+
linkifyContext.remember(blockquoteNode.raw);
|
|
15626
16112
|
j = newIndex;
|
|
15627
16113
|
} else {
|
|
15628
|
-
const handled = parseBasicBlockToken(tokens, j, options);
|
|
16114
|
+
const handled = parseBasicBlockToken(tokens, j, linkifyContext.options());
|
|
15629
16115
|
if (handled) {
|
|
15630
16116
|
children.push(handled[0]);
|
|
16117
|
+
linkifyContext.remember(handled[0].raw);
|
|
15631
16118
|
j = handled[1];
|
|
15632
16119
|
} else j++;
|
|
15633
16120
|
}
|
|
@@ -15659,35 +16146,41 @@ const containerTokenHandlers = {
|
|
|
15659
16146
|
//#region src/parser/node-parsers/blockquote-parser.ts
|
|
15660
16147
|
function parseBlockquote(tokens, index, options) {
|
|
15661
16148
|
const blockquoteChildren = [];
|
|
16149
|
+
const linkifyContext = createLinkifyDemotionContextTracker(options, true);
|
|
15662
16150
|
let j = index + 1;
|
|
15663
16151
|
while (j < tokens.length && tokens[j].type !== "blockquote_close") switch (tokens[j].type) {
|
|
15664
16152
|
case "paragraph_open": {
|
|
15665
16153
|
const contentToken = tokens[j + 1];
|
|
15666
|
-
|
|
16154
|
+
const paragraphNode = {
|
|
15667
16155
|
type: "paragraph",
|
|
15668
|
-
children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, options),
|
|
16156
|
+
children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, linkifyContext.options()),
|
|
15669
16157
|
raw: String(contentToken.content ?? "")
|
|
15670
|
-
}
|
|
16158
|
+
};
|
|
16159
|
+
blockquoteChildren.push(paragraphNode);
|
|
16160
|
+
linkifyContext.remember(paragraphNode.raw);
|
|
15671
16161
|
j += 3;
|
|
15672
16162
|
break;
|
|
15673
16163
|
}
|
|
15674
16164
|
case "bullet_list_open":
|
|
15675
16165
|
case "ordered_list_open": {
|
|
15676
|
-
const [listNode, newIndex] = parseList(tokens, j, options);
|
|
16166
|
+
const [listNode, newIndex] = parseList(tokens, j, linkifyContext.options());
|
|
15677
16167
|
blockquoteChildren.push(listNode);
|
|
16168
|
+
linkifyContext.remember(listNode.raw);
|
|
15678
16169
|
j = newIndex;
|
|
15679
16170
|
break;
|
|
15680
16171
|
}
|
|
15681
16172
|
case "blockquote_open": {
|
|
15682
|
-
const [nestedBlockquote, newIndex] = parseBlockquote(tokens, j, options);
|
|
16173
|
+
const [nestedBlockquote, newIndex] = parseBlockquote(tokens, j, linkifyContext.options());
|
|
15683
16174
|
blockquoteChildren.push(nestedBlockquote);
|
|
16175
|
+
linkifyContext.remember(nestedBlockquote.raw);
|
|
15684
16176
|
j = newIndex;
|
|
15685
16177
|
break;
|
|
15686
16178
|
}
|
|
15687
16179
|
default: {
|
|
15688
|
-
const handled = parseCommonBlockToken(tokens, j, options, containerTokenHandlers);
|
|
16180
|
+
const handled = parseCommonBlockToken(tokens, j, linkifyContext.options(), containerTokenHandlers);
|
|
15689
16181
|
if (handled) {
|
|
15690
16182
|
blockquoteChildren.push(handled[0]);
|
|
16183
|
+
linkifyContext.remember(handled[0].raw);
|
|
15691
16184
|
j = handled[1];
|
|
15692
16185
|
} else j++;
|
|
15693
16186
|
break;
|
|
@@ -15706,13 +16199,14 @@ function parseCodeBlock(token) {
|
|
|
15706
16199
|
if (token.info?.startsWith("diff")) return parseFenceToken(token);
|
|
15707
16200
|
const contentStr = String(token.content ?? "");
|
|
15708
16201
|
const match = contentStr.match(/ type="application\/vnd\.ant\.([^"]+)"/);
|
|
15709
|
-
|
|
16202
|
+
let code$1 = contentStr;
|
|
16203
|
+
if (match?.[1]) code$1 = contentStr.replace(/<antArtifact[^>]*>/g, "").replace(/<\/antArtifact>/g, "");
|
|
15710
16204
|
const hasMap = Array.isArray(token.map) && token.map.length === 2;
|
|
15711
16205
|
return {
|
|
15712
16206
|
type: "code_block",
|
|
15713
16207
|
language: match ? match[1] : String(token.info ?? ""),
|
|
15714
|
-
code:
|
|
15715
|
-
raw:
|
|
16208
|
+
code: code$1,
|
|
16209
|
+
raw: code$1,
|
|
15716
16210
|
loading: !hasMap
|
|
15717
16211
|
};
|
|
15718
16212
|
}
|
|
@@ -15724,9 +16218,11 @@ function parseDefinitionList(tokens, index, options) {
|
|
|
15724
16218
|
let j = index + 1;
|
|
15725
16219
|
let termNodes = [];
|
|
15726
16220
|
let definitionNodes = [];
|
|
16221
|
+
const linkifyContext = createLinkifyDemotionContextTracker(options, true);
|
|
15727
16222
|
while (j < tokens.length && tokens[j].type !== "dl_close") if (tokens[j].type === "dt_open") {
|
|
15728
16223
|
const termToken = tokens[j + 1];
|
|
15729
|
-
termNodes = parseInlineTokens(termToken.children || [], void 0, void 0, options);
|
|
16224
|
+
termNodes = parseInlineTokens(termToken.children || [], void 0, void 0, linkifyContext.options());
|
|
16225
|
+
linkifyContext.remember(termNodes.map((term) => term.raw).join(""));
|
|
15730
16226
|
j += 3;
|
|
15731
16227
|
} else if (tokens[j].type === "dd_open") {
|
|
15732
16228
|
let k = j + 1;
|
|
@@ -15735,9 +16231,10 @@ function parseDefinitionList(tokens, index, options) {
|
|
|
15735
16231
|
const contentToken = tokens[k + 1];
|
|
15736
16232
|
definitionNodes.push({
|
|
15737
16233
|
type: "paragraph",
|
|
15738
|
-
children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, options),
|
|
16234
|
+
children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, linkifyContext.options()),
|
|
15739
16235
|
raw: String(contentToken.content ?? "")
|
|
15740
16236
|
});
|
|
16237
|
+
linkifyContext.remember(String(contentToken.content ?? ""));
|
|
15741
16238
|
k += 3;
|
|
15742
16239
|
} else k++;
|
|
15743
16240
|
if (termNodes.length > 0) {
|
|
@@ -15764,16 +16261,19 @@ function parseFootnote(tokens, index, options) {
|
|
|
15764
16261
|
const meta = tokens[index].meta ?? {};
|
|
15765
16262
|
const id = String(meta?.label ?? "0");
|
|
15766
16263
|
const footnoteChildren = [];
|
|
16264
|
+
const linkifyContext = createLinkifyDemotionContextTracker(options, true);
|
|
15767
16265
|
let j = index + 1;
|
|
15768
16266
|
while (j < tokens.length && tokens[j].type !== "footnote_close") if (tokens[j].type === "paragraph_open") {
|
|
15769
16267
|
const contentToken = tokens[j + 1];
|
|
15770
16268
|
const children = contentToken.children ? [...contentToken.children] : [];
|
|
15771
16269
|
if (tokens[j + 2].type === "footnote_anchor") children.push(tokens[j + 2]);
|
|
15772
|
-
|
|
16270
|
+
const paragraphNode = {
|
|
15773
16271
|
type: "paragraph",
|
|
15774
|
-
children: parseInlineTokens(children, String(contentToken.content ?? ""), void 0, options),
|
|
16272
|
+
children: parseInlineTokens(children, String(contentToken.content ?? ""), void 0, linkifyContext.options()),
|
|
15775
16273
|
raw: String(contentToken.content ?? "")
|
|
15776
|
-
}
|
|
16274
|
+
};
|
|
16275
|
+
footnoteChildren.push(paragraphNode);
|
|
16276
|
+
linkifyContext.remember(paragraphNode.raw);
|
|
15777
16277
|
j += 3;
|
|
15778
16278
|
} else j++;
|
|
15779
16279
|
return [{
|
|
@@ -15900,6 +16400,30 @@ function extractAlign(attrs) {
|
|
|
15900
16400
|
}
|
|
15901
16401
|
return "left";
|
|
15902
16402
|
}
|
|
16403
|
+
function hasTableCellContext(context) {
|
|
16404
|
+
return context?.filename === true || context?.explicitFilename === true || context?.marketTicker === true;
|
|
16405
|
+
}
|
|
16406
|
+
function mergeTableCellContext(left, right) {
|
|
16407
|
+
const merged = {
|
|
16408
|
+
filename: left?.filename || right?.filename,
|
|
16409
|
+
explicitFilename: left?.explicitFilename || right?.explicitFilename,
|
|
16410
|
+
marketTicker: left?.marketTicker || right?.marketTicker
|
|
16411
|
+
};
|
|
16412
|
+
return hasTableCellContext(merged) ? merged : void 0;
|
|
16413
|
+
}
|
|
16414
|
+
function parseOptionsForTableCell(options, headerRaw, rowContext) {
|
|
16415
|
+
const cellContext = mergeTableCellContext(inferLinkifyDemotionContext(headerRaw), rowContext);
|
|
16416
|
+
if (!hasTableCellContext(cellContext)) return options;
|
|
16417
|
+
const inheritedContext = options?.__linkifyDemotionContext;
|
|
16418
|
+
return {
|
|
16419
|
+
...options,
|
|
16420
|
+
__linkifyDemotionContext: {
|
|
16421
|
+
filename: inheritedContext?.filename || cellContext?.filename,
|
|
16422
|
+
explicitFilename: inheritedContext?.explicitFilename || cellContext?.explicitFilename,
|
|
16423
|
+
marketTicker: inheritedContext?.marketTicker || cellContext?.marketTicker
|
|
16424
|
+
}
|
|
16425
|
+
};
|
|
16426
|
+
}
|
|
15903
16427
|
function parseTable(tokens, index, options) {
|
|
15904
16428
|
let j = index + 1;
|
|
15905
16429
|
let headerRow = null;
|
|
@@ -15915,18 +16439,23 @@ function parseTable(tokens, index, options) {
|
|
|
15915
16439
|
else if (tokens[j].type === "tr_open") {
|
|
15916
16440
|
const cells = [];
|
|
15917
16441
|
let k = j + 1;
|
|
16442
|
+
let rowContext;
|
|
15918
16443
|
while (k < tokens.length && tokens[k].type !== "tr_close") if (tokens[k].type === "th_open" || tokens[k].type === "td_open") {
|
|
15919
16444
|
const isHeaderCell = tokens[k].type === "th_open";
|
|
15920
16445
|
const contentToken = tokens[k + 1];
|
|
15921
16446
|
const content = String(contentToken.content ?? "");
|
|
15922
16447
|
const align = extractAlign(tokens[k].attrs);
|
|
16448
|
+
const cellIndex = cells.length;
|
|
16449
|
+
const isBodyCell = !isHeaderCell && !isHeader;
|
|
16450
|
+
const headerRaw = isBodyCell ? headerRow?.cells[cellIndex]?.raw : void 0;
|
|
15923
16451
|
cells.push({
|
|
15924
16452
|
type: "table_cell",
|
|
15925
16453
|
header: isHeaderCell || isHeader,
|
|
15926
|
-
children: parseInlineTokens(contentToken.children || [], content, void 0, options),
|
|
16454
|
+
children: parseInlineTokens(contentToken.children || [], content, void 0, parseOptionsForTableCell(options, headerRaw, isBodyCell ? rowContext : void 0)),
|
|
15927
16455
|
raw: content,
|
|
15928
16456
|
align
|
|
15929
16457
|
});
|
|
16458
|
+
if (isBodyCell) rowContext = mergeTableCellContext(rowContext, inferLinkifyDemotionContext(content));
|
|
15930
16459
|
k += 3;
|
|
15931
16460
|
} else k++;
|
|
15932
16461
|
const rowNode = {
|
|
@@ -15943,11 +16472,12 @@ function parseTable(tokens, index, options) {
|
|
|
15943
16472
|
cells: [],
|
|
15944
16473
|
raw: ""
|
|
15945
16474
|
};
|
|
16475
|
+
const tokenLoading = tokens[index].loading === true;
|
|
15946
16476
|
return [{
|
|
15947
16477
|
type: "table",
|
|
15948
16478
|
header: headerRow,
|
|
15949
16479
|
rows,
|
|
15950
|
-
loading:
|
|
16480
|
+
loading: tokenLoading && !options?.final && rows.length === 0,
|
|
15951
16481
|
raw: [headerRow, ...rows].map((row) => row.raw).join("\n")
|
|
15952
16482
|
}, j + 1];
|
|
15953
16483
|
}
|
|
@@ -16008,30 +16538,35 @@ function parseVmrContainer(tokens, index, options) {
|
|
|
16008
16538
|
}
|
|
16009
16539
|
}
|
|
16010
16540
|
const children = [];
|
|
16541
|
+
const linkifyContext = createLinkifyDemotionContextTracker(options, true);
|
|
16011
16542
|
let j = index + 1;
|
|
16012
16543
|
while (j < tokens.length && tokens[j].type !== "vmr_container_close") if (tokens[j].type === "paragraph_open") {
|
|
16013
16544
|
const contentToken = tokens[j + 1];
|
|
16014
16545
|
if (contentToken) {
|
|
16015
|
-
const
|
|
16016
|
-
children.push({
|
|
16546
|
+
const paragraphNode = {
|
|
16017
16547
|
type: "paragraph",
|
|
16018
|
-
children: parseInlineTokens(
|
|
16548
|
+
children: parseInlineTokens(contentToken.children || [], void 0, void 0, linkifyContext.options()),
|
|
16019
16549
|
raw: String(contentToken.content ?? "")
|
|
16020
|
-
}
|
|
16550
|
+
};
|
|
16551
|
+
children.push(paragraphNode);
|
|
16552
|
+
linkifyContext.remember(paragraphNode.raw);
|
|
16021
16553
|
}
|
|
16022
16554
|
j += 3;
|
|
16023
16555
|
} else if (tokens[j].type === "bullet_list_open" || tokens[j].type === "ordered_list_open") {
|
|
16024
|
-
const [listNode, newIndex] = parseList(tokens, j, options);
|
|
16556
|
+
const [listNode, newIndex] = parseList(tokens, j, linkifyContext.options());
|
|
16025
16557
|
children.push(listNode);
|
|
16558
|
+
linkifyContext.remember(listNode.raw);
|
|
16026
16559
|
j = newIndex;
|
|
16027
16560
|
} else if (tokens[j].type === "blockquote_open") {
|
|
16028
|
-
const [blockquoteNode, newIndex] = parseBlockquote(tokens, j, options);
|
|
16561
|
+
const [blockquoteNode, newIndex] = parseBlockquote(tokens, j, linkifyContext.options());
|
|
16029
16562
|
children.push(blockquoteNode);
|
|
16563
|
+
linkifyContext.remember(blockquoteNode.raw);
|
|
16030
16564
|
j = newIndex;
|
|
16031
16565
|
} else {
|
|
16032
|
-
const handled = parseBasicBlockToken(tokens, j, options);
|
|
16566
|
+
const handled = parseBasicBlockToken(tokens, j, linkifyContext.options());
|
|
16033
16567
|
if (handled) {
|
|
16034
16568
|
children.push(handled[0]);
|
|
16569
|
+
linkifyContext.remember(handled[0].raw);
|
|
16035
16570
|
j = handled[1];
|
|
16036
16571
|
} else j++;
|
|
16037
16572
|
}
|
|
@@ -16297,15 +16832,201 @@ function parseParagraph(tokens, index, options) {
|
|
|
16297
16832
|
|
|
16298
16833
|
//#endregion
|
|
16299
16834
|
//#region src/parser/index.ts
|
|
16835
|
+
const streamParseEnvCache = /* @__PURE__ */ new WeakMap();
|
|
16300
16836
|
function getNodeFields(node) {
|
|
16301
16837
|
return node;
|
|
16302
16838
|
}
|
|
16839
|
+
function getParserNow() {
|
|
16840
|
+
return typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
16841
|
+
}
|
|
16842
|
+
function addTiming(metrics, key, value) {
|
|
16843
|
+
if (!metrics) return;
|
|
16844
|
+
metrics[key] = (metrics[key] ?? 0) + value;
|
|
16845
|
+
}
|
|
16846
|
+
function getParseTiming(options) {
|
|
16847
|
+
return options.__timing;
|
|
16848
|
+
}
|
|
16849
|
+
function finishTimedParse(result, timing, startedAt) {
|
|
16850
|
+
if (timing) addTiming(timing, "parseMarkdownToStructureTotalMs", getParserNow() - startedAt);
|
|
16851
|
+
return result;
|
|
16852
|
+
}
|
|
16853
|
+
function processTokensWithTiming(tokens, options, timing) {
|
|
16854
|
+
if (!timing) return processTokens(tokens, options);
|
|
16855
|
+
const startedAt = getParserNow();
|
|
16856
|
+
const result = processTokens(tokens, options);
|
|
16857
|
+
addTiming(timing, "processTokensMs", getParserNow() - startedAt);
|
|
16858
|
+
return result;
|
|
16859
|
+
}
|
|
16303
16860
|
function getCustomHtmlTagSet(options) {
|
|
16304
16861
|
const custom = options?.customHtmlTags;
|
|
16305
16862
|
if (!Array.isArray(custom) || custom.length === 0) return null;
|
|
16306
16863
|
const normalized = normalizeCustomHtmlTags(custom);
|
|
16307
16864
|
return normalized.length ? new Set(normalized) : null;
|
|
16308
16865
|
}
|
|
16866
|
+
function getStableStreamEnv(md, env) {
|
|
16867
|
+
const mdKey = md;
|
|
16868
|
+
let byMode = streamParseEnvCache.get(mdKey);
|
|
16869
|
+
if (!byMode) {
|
|
16870
|
+
byMode = /* @__PURE__ */ new Map();
|
|
16871
|
+
streamParseEnvCache.set(mdKey, byMode);
|
|
16872
|
+
}
|
|
16873
|
+
const modeKey = env.__markstreamFinal === true ? "final" : "streaming";
|
|
16874
|
+
let stableEnv = byMode.get(modeKey);
|
|
16875
|
+
if (!stableEnv) {
|
|
16876
|
+
stableEnv = {};
|
|
16877
|
+
byMode.set(modeKey, stableEnv);
|
|
16878
|
+
}
|
|
16879
|
+
for (const key of Object.keys(stableEnv)) if (!Object.prototype.hasOwnProperty.call(env, key)) delete stableEnv[key];
|
|
16880
|
+
Object.assign(stableEnv, env);
|
|
16881
|
+
return stableEnv;
|
|
16882
|
+
}
|
|
16883
|
+
function isPlainObject(value) {
|
|
16884
|
+
if (!value || typeof value !== "object") return false;
|
|
16885
|
+
const proto = Object.getPrototypeOf(value);
|
|
16886
|
+
return proto === Object.prototype || proto === null;
|
|
16887
|
+
}
|
|
16888
|
+
function copyCloneableOwnDataProperties(source, target, seen) {
|
|
16889
|
+
for (const key of Reflect.ownKeys(source)) {
|
|
16890
|
+
const descriptor = Object.getOwnPropertyDescriptor(source, key);
|
|
16891
|
+
if (!descriptor || !("value" in descriptor)) continue;
|
|
16892
|
+
const targetDescriptor = Object.getOwnPropertyDescriptor(target, key);
|
|
16893
|
+
if (targetDescriptor && (!("value" in targetDescriptor) || targetDescriptor.writable === false)) continue;
|
|
16894
|
+
target[key] = safeCloneTokenField(descriptor.value, seen);
|
|
16895
|
+
}
|
|
16896
|
+
}
|
|
16897
|
+
function safeCloneTokenField(value, seen = /* @__PURE__ */ new WeakMap()) {
|
|
16898
|
+
if (!value || typeof value !== "object") return value;
|
|
16899
|
+
const object = value;
|
|
16900
|
+
const existing = seen.get(object);
|
|
16901
|
+
if (existing) return existing;
|
|
16902
|
+
if (Array.isArray(value)) {
|
|
16903
|
+
const cloned$1 = [];
|
|
16904
|
+
seen.set(object, cloned$1);
|
|
16905
|
+
for (const item of value) cloned$1.push(safeCloneTokenField(item, seen));
|
|
16906
|
+
return cloned$1;
|
|
16907
|
+
}
|
|
16908
|
+
if (value instanceof Map) {
|
|
16909
|
+
const cloned$1 = /* @__PURE__ */ new Map();
|
|
16910
|
+
seen.set(object, cloned$1);
|
|
16911
|
+
for (const [key, item] of value) cloned$1.set(safeCloneTokenField(key, seen), safeCloneTokenField(item, seen));
|
|
16912
|
+
return cloned$1;
|
|
16913
|
+
}
|
|
16914
|
+
if (value instanceof Set) {
|
|
16915
|
+
const cloned$1 = /* @__PURE__ */ new Set();
|
|
16916
|
+
seen.set(object, cloned$1);
|
|
16917
|
+
for (const item of value) cloned$1.add(safeCloneTokenField(item, seen));
|
|
16918
|
+
return cloned$1;
|
|
16919
|
+
}
|
|
16920
|
+
if (value instanceof Date) {
|
|
16921
|
+
const cloned$1 = new Date(value.getTime());
|
|
16922
|
+
seen.set(object, cloned$1);
|
|
16923
|
+
return cloned$1;
|
|
16924
|
+
}
|
|
16925
|
+
if (value instanceof RegExp) {
|
|
16926
|
+
const cloned$1 = new RegExp(value.source, value.flags);
|
|
16927
|
+
cloned$1.lastIndex = value.lastIndex;
|
|
16928
|
+
seen.set(object, cloned$1);
|
|
16929
|
+
return cloned$1;
|
|
16930
|
+
}
|
|
16931
|
+
if (typeof URL !== "undefined" && value instanceof URL) {
|
|
16932
|
+
const cloned$1 = new URL(value.href);
|
|
16933
|
+
seen.set(object, cloned$1);
|
|
16934
|
+
copyCloneableOwnDataProperties(object, cloned$1, seen);
|
|
16935
|
+
return cloned$1;
|
|
16936
|
+
}
|
|
16937
|
+
if (typeof URLSearchParams !== "undefined" && value instanceof URLSearchParams) {
|
|
16938
|
+
const cloned$1 = new URLSearchParams(value.toString());
|
|
16939
|
+
seen.set(object, cloned$1);
|
|
16940
|
+
copyCloneableOwnDataProperties(object, cloned$1, seen);
|
|
16941
|
+
return cloned$1;
|
|
16942
|
+
}
|
|
16943
|
+
if (value instanceof Error) {
|
|
16944
|
+
let cloned$1;
|
|
16945
|
+
const ErrorCtor = value.constructor;
|
|
16946
|
+
try {
|
|
16947
|
+
cloned$1 = new ErrorCtor(value.message);
|
|
16948
|
+
} catch {
|
|
16949
|
+
cloned$1 = new Error(value.message);
|
|
16950
|
+
}
|
|
16951
|
+
Object.setPrototypeOf(cloned$1, Object.getPrototypeOf(value));
|
|
16952
|
+
seen.set(object, cloned$1);
|
|
16953
|
+
copyCloneableOwnDataProperties(object, cloned$1, seen);
|
|
16954
|
+
return cloned$1;
|
|
16955
|
+
}
|
|
16956
|
+
if (typeof Promise !== "undefined" && value instanceof Promise) {
|
|
16957
|
+
seen.set(object, value);
|
|
16958
|
+
return value;
|
|
16959
|
+
}
|
|
16960
|
+
if (typeof Node !== "undefined" && value instanceof Node) {
|
|
16961
|
+
seen.set(object, value);
|
|
16962
|
+
return value;
|
|
16963
|
+
}
|
|
16964
|
+
if (!isPlainObject(value)) {
|
|
16965
|
+
const cloned$1 = Object.create(Object.getPrototypeOf(value));
|
|
16966
|
+
seen.set(object, cloned$1);
|
|
16967
|
+
copyCloneableOwnDataProperties(object, cloned$1, seen);
|
|
16968
|
+
return cloned$1;
|
|
16969
|
+
}
|
|
16970
|
+
const cloned = {};
|
|
16971
|
+
seen.set(object, cloned);
|
|
16972
|
+
const record = value;
|
|
16973
|
+
for (const key of Object.keys(record)) cloned[key] = safeCloneTokenField(record[key], seen);
|
|
16974
|
+
return cloned;
|
|
16975
|
+
}
|
|
16976
|
+
function cloneMarkdownToken(token, cloneObjectFields = true) {
|
|
16977
|
+
if (!cloneObjectFields) return cloneTokenWithMutableChildren(token);
|
|
16978
|
+
const cloned = Object.create(Object.getPrototypeOf(token));
|
|
16979
|
+
const seen = /* @__PURE__ */ new WeakMap();
|
|
16980
|
+
for (const key of Reflect.ownKeys(token)) {
|
|
16981
|
+
const descriptor = Object.getOwnPropertyDescriptor(token, key);
|
|
16982
|
+
if (!descriptor) continue;
|
|
16983
|
+
if (!("value" in descriptor)) {
|
|
16984
|
+
Object.defineProperty(cloned, key, descriptor);
|
|
16985
|
+
continue;
|
|
16986
|
+
}
|
|
16987
|
+
const value = descriptor.value;
|
|
16988
|
+
let clonedValue = value;
|
|
16989
|
+
if (key === "attrs" && Array.isArray(value)) clonedValue = value.map((attr) => [...attr]);
|
|
16990
|
+
else if (key === "map" && Array.isArray(value)) clonedValue = [...value];
|
|
16991
|
+
else if (key === "children" && Array.isArray(value)) clonedValue = value.map((child) => cloneMarkdownToken(child, cloneObjectFields));
|
|
16992
|
+
else if (cloneObjectFields && value && typeof value === "object") clonedValue = safeCloneTokenField(value, seen);
|
|
16993
|
+
Object.defineProperty(cloned, key, {
|
|
16994
|
+
...descriptor,
|
|
16995
|
+
value: clonedValue
|
|
16996
|
+
});
|
|
16997
|
+
}
|
|
16998
|
+
return cloned;
|
|
16999
|
+
}
|
|
17000
|
+
function cloneMarkdownTokens(tokens, cloneObjectFields = true) {
|
|
17001
|
+
return tokens.map((token) => cloneMarkdownToken(token, cloneObjectFields));
|
|
17002
|
+
}
|
|
17003
|
+
function shouldUseTopLevelStreamParse(md, options) {
|
|
17004
|
+
const internalOptions = options;
|
|
17005
|
+
const stream = md.stream;
|
|
17006
|
+
const streamParse = options.streamParse ?? "auto";
|
|
17007
|
+
return internalOptions.__disableStreamParse !== true && (streamParse === true || streamParse === "auto" && options.final !== true) && stream?.enabled === true && typeof stream.parse === "function";
|
|
17008
|
+
}
|
|
17009
|
+
function shouldResetTopLevelStreamCacheForFinalAutoParse(md, options) {
|
|
17010
|
+
const internalOptions = options;
|
|
17011
|
+
const streamParse = options.streamParse ?? "auto";
|
|
17012
|
+
const stream = md.stream;
|
|
17013
|
+
return options.final === true && streamParse === "auto" && internalOptions.__disableStreamParse !== true && stream?.enabled === true && typeof stream.reset === "function";
|
|
17014
|
+
}
|
|
17015
|
+
function shouldCloneTopLevelStreamTokens(options) {
|
|
17016
|
+
return typeof options.preTransformTokens === "function" || typeof options.postTransformTokens === "function";
|
|
17017
|
+
}
|
|
17018
|
+
function parseTopLevelTokens(md, source, env, options) {
|
|
17019
|
+
if (options.customHtmlTags?.length) env.__markstreamCustomHtmlTags = options.customHtmlTags;
|
|
17020
|
+
if (!shouldUseTopLevelStreamParse(md, options)) return md.parse(source, env);
|
|
17021
|
+
const tokens = md.stream.parse(source, getStableStreamEnv(md, env));
|
|
17022
|
+
if (!shouldCloneTopLevelStreamTokens(options)) return tokens;
|
|
17023
|
+
const timing = getParseTiming(options);
|
|
17024
|
+
if (!timing) return cloneMarkdownTokens(tokens, true);
|
|
17025
|
+
const startedAt = getParserNow();
|
|
17026
|
+
const cloned = cloneMarkdownTokens(tokens, true);
|
|
17027
|
+
addTiming(timing, "tokenCloneMs", getParserNow() - startedAt);
|
|
17028
|
+
return cloned;
|
|
17029
|
+
}
|
|
16309
17030
|
function buildAllowedHtmlTagSet(options) {
|
|
16310
17031
|
const custom = options?.customHtmlTags;
|
|
16311
17032
|
if (!Array.isArray(custom) || custom.length === 0) return STANDARD_HTML_TAGS;
|
|
@@ -16511,6 +17232,7 @@ function findLastClosingTagStart(raw, tag) {
|
|
|
16511
17232
|
function buildDetailsChildParseOptions(options, final) {
|
|
16512
17233
|
return {
|
|
16513
17234
|
final,
|
|
17235
|
+
__disableStreamParse: true,
|
|
16514
17236
|
requireClosingStrong: options.requireClosingStrong,
|
|
16515
17237
|
customHtmlTags: options.customHtmlTags,
|
|
16516
17238
|
validateLink: options.validateLink
|
|
@@ -16568,7 +17290,10 @@ function structureGenericHtmlBlockChildren(nodes, md, options, final) {
|
|
|
16568
17290
|
}
|
|
16569
17291
|
function parseDetailsFragmentChildren(fragment, md, options) {
|
|
16570
17292
|
if (!fragment.trim()) return [];
|
|
16571
|
-
return parseMarkdownToStructure(fragment, md,
|
|
17293
|
+
return parseMarkdownToStructure(fragment, md, {
|
|
17294
|
+
...options,
|
|
17295
|
+
__disableStreamParse: true
|
|
17296
|
+
});
|
|
16572
17297
|
}
|
|
16573
17298
|
function parseSummaryChildren(fragment, md, options) {
|
|
16574
17299
|
const children = parseDetailsFragmentChildren(fragment, md, options);
|
|
@@ -17495,8 +18220,11 @@ function ensureBlankLineBeforeCustomHtmlBlocks(markdown, tags) {
|
|
|
17495
18220
|
return out;
|
|
17496
18221
|
}
|
|
17497
18222
|
function parseMarkdownToStructure(markdown, md, options = {}) {
|
|
18223
|
+
const timing = getParseTiming(options);
|
|
18224
|
+
const parseStartedAt = timing ? getParserNow() : 0;
|
|
17498
18225
|
const isFinal = !!options.final;
|
|
17499
18226
|
let safeMarkdown = (markdown ?? "").toString().replace(/([^\\])\r(ight|ho)/g, "$1\\r$2").replace(/([^\\])\n(abla|eq|ot|exists)/g, "$1\\n$2");
|
|
18227
|
+
if (shouldResetTopLevelStreamCacheForFinalAutoParse(md, options)) md.stream.reset();
|
|
17500
18228
|
if (!isFinal) {
|
|
17501
18229
|
if (safeMarkdown.endsWith("- *")) safeMarkdown = safeMarkdown.replace(/- \*$/, "- \\*");
|
|
17502
18230
|
if (/(?:^|\n)\s*-\s*$/.test(safeMarkdown)) safeMarkdown = safeMarkdown.replace(/(?:^|\n)\s*-\s*$/, (m) => {
|
|
@@ -17537,15 +18265,15 @@ function parseMarkdownToStructure(markdown, md, options = {}) {
|
|
|
17537
18265
|
if (standaloneHtmlDocument) {
|
|
17538
18266
|
const preHook = options.preTransformTokens;
|
|
17539
18267
|
const postHook = options.postTransformTokens;
|
|
17540
|
-
if (typeof preHook === "function" || typeof postHook === "function") {
|
|
17541
|
-
const rawTokens = md
|
|
18268
|
+
if (shouldUseTopLevelStreamParse(md, options) || typeof preHook === "function" || typeof postHook === "function") {
|
|
18269
|
+
const rawTokens = parseTopLevelTokens(md, safeMarkdown, { __markstreamFinal: isFinal }, options);
|
|
17542
18270
|
const hookedTokens = typeof preHook === "function" ? preHook(rawTokens) || rawTokens : rawTokens;
|
|
17543
18271
|
if (typeof postHook === "function") postHook(hookedTokens);
|
|
17544
18272
|
}
|
|
17545
|
-
return standaloneHtmlDocument;
|
|
18273
|
+
return finishTimedParse(standaloneHtmlDocument, timing, parseStartedAt);
|
|
17546
18274
|
}
|
|
17547
|
-
const tokens = md
|
|
17548
|
-
if (!tokens || !Array.isArray(tokens)) return [];
|
|
18275
|
+
const tokens = parseTopLevelTokens(md, safeMarkdown, { __markstreamFinal: isFinal }, options);
|
|
18276
|
+
if (!tokens || !Array.isArray(tokens)) return finishTimedParse([], timing, parseStartedAt);
|
|
17549
18277
|
const pre = options.preTransformTokens;
|
|
17550
18278
|
const post = options.postTransformTokens;
|
|
17551
18279
|
let transformedTokens = tokens;
|
|
@@ -17559,13 +18287,13 @@ function parseMarkdownToStructure(markdown, md, options = {}) {
|
|
|
17559
18287
|
__sourceMarkdown: safeMarkdown,
|
|
17560
18288
|
__customHtmlBlockCursor: 0
|
|
17561
18289
|
};
|
|
17562
|
-
let result =
|
|
18290
|
+
let result = processTokensWithTiming(transformedTokens, internalOptions, timing);
|
|
17563
18291
|
if (post && typeof post === "function") {
|
|
17564
18292
|
const postResult = post(transformedTokens);
|
|
17565
18293
|
if (Array.isArray(postResult)) {
|
|
17566
18294
|
const first = postResult[0];
|
|
17567
18295
|
const firstType = first?.type;
|
|
17568
|
-
if (first && typeof firstType === "string") result =
|
|
18296
|
+
if (first && typeof firstType === "string") result = processTokensWithTiming(postResult, void 0, timing);
|
|
17569
18297
|
else result = postResult;
|
|
17570
18298
|
}
|
|
17571
18299
|
}
|
|
@@ -17589,39 +18317,45 @@ function parseMarkdownToStructure(markdown, md, options = {}) {
|
|
|
17589
18317
|
finalizeHtmlBlockLoading(result);
|
|
17590
18318
|
}
|
|
17591
18319
|
if (options.debug) console.log("Parsed Markdown Tree Structure:", result);
|
|
17592
|
-
return result;
|
|
18320
|
+
return finishTimedParse(result, timing, parseStartedAt);
|
|
17593
18321
|
}
|
|
17594
18322
|
function processTokens(tokens, options) {
|
|
17595
18323
|
if (!tokens || !Array.isArray(tokens)) return [];
|
|
17596
18324
|
const result = [];
|
|
18325
|
+
const linkifyContext = createLinkifyDemotionContextTracker(options);
|
|
17597
18326
|
let i = 0;
|
|
17598
18327
|
while (i < tokens.length) {
|
|
17599
|
-
const handled = parseCommonBlockToken(tokens, i, options, containerTokenHandlers);
|
|
18328
|
+
const handled = parseCommonBlockToken(tokens, i, linkifyContext.options(), containerTokenHandlers);
|
|
17600
18329
|
if (handled) {
|
|
17601
18330
|
result.push(handled[0]);
|
|
18331
|
+
linkifyContext.remember(handled[0].raw);
|
|
17602
18332
|
i = handled[1];
|
|
17603
18333
|
continue;
|
|
17604
18334
|
}
|
|
17605
18335
|
const token = tokens[i];
|
|
17606
18336
|
switch (token.type) {
|
|
17607
18337
|
case "paragraph_open": {
|
|
17608
|
-
const
|
|
18338
|
+
const paragraphRaw = String(tokens[i + 1]?.content ?? "");
|
|
18339
|
+
const paragraphNode = parseParagraph(tokens, i, linkifyContext.options(paragraphRaw));
|
|
17609
18340
|
const promoted = maybePromoteCustomNodeFromParagraph(paragraphNode, options);
|
|
17610
18341
|
if (promoted) result.push(...promoted);
|
|
17611
18342
|
else result.push(paragraphNode);
|
|
18343
|
+
linkifyContext.remember(paragraphNode.raw);
|
|
17612
18344
|
i += 3;
|
|
17613
18345
|
break;
|
|
17614
18346
|
}
|
|
17615
18347
|
case "bullet_list_open":
|
|
17616
18348
|
case "ordered_list_open": {
|
|
17617
|
-
const [listNode, newIndex] = parseList(tokens, i, options);
|
|
18349
|
+
const [listNode, newIndex] = parseList(tokens, i, linkifyContext.options());
|
|
17618
18350
|
result.push(listNode);
|
|
18351
|
+
linkifyContext.remember(listNode.raw);
|
|
17619
18352
|
i = newIndex;
|
|
17620
18353
|
break;
|
|
17621
18354
|
}
|
|
17622
18355
|
case "blockquote_open": {
|
|
17623
|
-
const [blockquoteNode, newIndex] = parseBlockquote(tokens, i, options);
|
|
18356
|
+
const [blockquoteNode, newIndex] = parseBlockquote(tokens, i, linkifyContext.options());
|
|
17624
18357
|
result.push(blockquoteNode);
|
|
18358
|
+
linkifyContext.remember(blockquoteNode.raw);
|
|
17625
18359
|
i = newIndex;
|
|
17626
18360
|
break;
|
|
17627
18361
|
}
|
|
@@ -17633,11 +18367,13 @@ function processTokens(tokens, options) {
|
|
|
17633
18367
|
id,
|
|
17634
18368
|
raw: String(token.content ?? "")
|
|
17635
18369
|
});
|
|
18370
|
+
linkifyContext.remember(String(token.content ?? ""));
|
|
17636
18371
|
i++;
|
|
17637
18372
|
break;
|
|
17638
18373
|
}
|
|
17639
18374
|
case "hardbreak":
|
|
17640
18375
|
result.push(parseHardBreak());
|
|
18376
|
+
linkifyContext.reset();
|
|
17641
18377
|
i++;
|
|
17642
18378
|
break;
|
|
17643
18379
|
case "text": {
|
|
@@ -17651,23 +18387,26 @@ function processTokens(tokens, options) {
|
|
|
17651
18387
|
raw: content
|
|
17652
18388
|
}] : []
|
|
17653
18389
|
});
|
|
18390
|
+
linkifyContext.remember(content);
|
|
17654
18391
|
i++;
|
|
17655
18392
|
break;
|
|
17656
18393
|
}
|
|
17657
18394
|
case "inline":
|
|
17658
18395
|
{
|
|
17659
|
-
const
|
|
18396
|
+
const raw = String(token.content ?? "");
|
|
18397
|
+
const parsed = parseInlineTokens(token.children || [], raw, void 0, linkifyContext.options(raw));
|
|
17660
18398
|
if (parsed.length === 0) {} else if (parsed.every((n) => n.type === "html_block")) result.push(...parsed);
|
|
17661
18399
|
else {
|
|
17662
18400
|
const paragraphNode = {
|
|
17663
18401
|
type: "paragraph",
|
|
17664
|
-
raw
|
|
18402
|
+
raw,
|
|
17665
18403
|
children: parsed
|
|
17666
18404
|
};
|
|
17667
18405
|
const promoted = maybePromoteCustomNodeFromParagraph(paragraphNode, options);
|
|
17668
18406
|
if (promoted) result.push(...promoted);
|
|
17669
18407
|
else result.push(paragraphNode);
|
|
17670
18408
|
}
|
|
18409
|
+
linkifyContext.remember(raw);
|
|
17671
18410
|
}
|
|
17672
18411
|
i += 1;
|
|
17673
18412
|
break;
|
|
@@ -18554,7 +19293,8 @@ function getMarkdown(msgId = `editor-${Date.now()}`, options = {}) {
|
|
|
18554
19293
|
md.use(sub_plugin);
|
|
18555
19294
|
md.use(sup_plugin);
|
|
18556
19295
|
md.use(ins_plugin$1);
|
|
18557
|
-
const
|
|
19296
|
+
const checkboxModule = import_markdown_it_task_checkbox;
|
|
19297
|
+
const markdownItCheckboxPlugin = checkboxModule.default ?? checkboxModule;
|
|
18558
19298
|
md.use(markdownItCheckboxPlugin);
|
|
18559
19299
|
md.use(ins_plugin);
|
|
18560
19300
|
md.use(footnote_plugin);
|