stream-markdown-parser 0.0.92 → 0.0.94
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +28 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +155 -68
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9347,7 +9347,7 @@ function applyContainers(md) {
|
|
|
9347
9347
|
if (!jsonStr) argsStr = trimmedRest || void 0;
|
|
9348
9348
|
}
|
|
9349
9349
|
if (silent) return true;
|
|
9350
|
-
const envFinal = !!s.env
|
|
9350
|
+
const envFinal = !!s.env.__markstreamFinal;
|
|
9351
9351
|
let nextLine = startLine + 1;
|
|
9352
9352
|
let found = false;
|
|
9353
9353
|
while (nextLine <= endLine) {
|
|
@@ -9363,7 +9363,7 @@ function applyContainers(md) {
|
|
|
9363
9363
|
const tokenOpen = s.push("vmr_container_open", "div", 1);
|
|
9364
9364
|
tokenOpen.attrSet("class", `vmr-container vmr-container-${name}`);
|
|
9365
9365
|
tokenOpen.meta = {
|
|
9366
|
-
...tokenOpen.meta,
|
|
9366
|
+
...tokenOpen.meta ?? {},
|
|
9367
9367
|
unclosed: !found && !envFinal
|
|
9368
9368
|
};
|
|
9369
9369
|
if (argsStr) tokenOpen.attrSet("data-args", argsStr);
|
|
@@ -10392,7 +10392,7 @@ function applyFixHtmlInlineTokens(md, options = {}) {
|
|
|
10392
10392
|
type: "html_block",
|
|
10393
10393
|
loading: true,
|
|
10394
10394
|
tag,
|
|
10395
|
-
content: t.children[0]
|
|
10395
|
+
content: String(t.children[0]?.content ?? "") + String(t.children[1]?.content ?? "")
|
|
10396
10396
|
}];
|
|
10397
10397
|
continue;
|
|
10398
10398
|
} else if (t.children.length === 3 && t.children[0].type === "html_inline" && t.children[2].type === "html_inline") {
|
|
@@ -10465,7 +10465,7 @@ function looksLikeCode(line) {
|
|
|
10465
10465
|
function applyFixIndentedCodeBlock(md, options = {}) {
|
|
10466
10466
|
if (options.enabled === false) return;
|
|
10467
10467
|
md.core.ruler.after("inline", "fix_indented_code_block", (state) => {
|
|
10468
|
-
const tokens = state.tokens;
|
|
10468
|
+
const tokens = state.tokens ?? [];
|
|
10469
10469
|
for (let i = 0; i < tokens.length; i++) {
|
|
10470
10470
|
const token = tokens[i];
|
|
10471
10471
|
if (token.type !== "code_block") continue;
|
|
@@ -10474,28 +10474,30 @@ function applyFixIndentedCodeBlock(md, options = {}) {
|
|
|
10474
10474
|
const lines = content.split(/\r?\n/).filter((line) => line.trim().length > 0);
|
|
10475
10475
|
if (lines.length === 1 && !looksLikeCode(lines[0] ?? "")) {
|
|
10476
10476
|
const textContent = lines[0] ?? "";
|
|
10477
|
+
const level = token.level ?? 0;
|
|
10477
10478
|
tokens.splice(i, 1, {
|
|
10478
10479
|
type: "paragraph_open",
|
|
10479
10480
|
tag: "p",
|
|
10480
10481
|
nesting: 1,
|
|
10481
|
-
level
|
|
10482
|
+
level
|
|
10482
10483
|
}, {
|
|
10483
10484
|
type: "inline",
|
|
10484
10485
|
tag: "",
|
|
10485
10486
|
nesting: 0,
|
|
10486
|
-
level
|
|
10487
|
+
level,
|
|
10487
10488
|
content: textContent,
|
|
10488
10489
|
children: [{
|
|
10489
10490
|
type: "text",
|
|
10490
10491
|
content: textContent,
|
|
10491
|
-
level:
|
|
10492
|
+
level: level + 1,
|
|
10493
|
+
raw: textContent
|
|
10492
10494
|
}],
|
|
10493
10495
|
block: true
|
|
10494
10496
|
}, {
|
|
10495
10497
|
type: "paragraph_close",
|
|
10496
10498
|
tag: "p",
|
|
10497
10499
|
nesting: -1,
|
|
10498
|
-
level
|
|
10500
|
+
level
|
|
10499
10501
|
});
|
|
10500
10502
|
i += 2;
|
|
10501
10503
|
}
|
|
@@ -10722,7 +10724,7 @@ function firstIndexOfAny(input, chars) {
|
|
|
10722
10724
|
return first;
|
|
10723
10725
|
}
|
|
10724
10726
|
function getHrefFromLinkOpen(token) {
|
|
10725
|
-
const href = token
|
|
10727
|
+
const href = token.attrs?.find((attr) => attr?.[0] === "href")?.[1];
|
|
10726
10728
|
return typeof href === "string" ? href : "";
|
|
10727
10729
|
}
|
|
10728
10730
|
function setHrefOnLinkOpen(token, href) {
|
|
@@ -10963,7 +10965,7 @@ function fixLinkToken(tokens) {
|
|
|
10963
10965
|
count += 1;
|
|
10964
10966
|
}
|
|
10965
10967
|
}
|
|
10966
|
-
|
|
10968
|
+
const linkToken = {
|
|
10967
10969
|
type: "link",
|
|
10968
10970
|
loading: false,
|
|
10969
10971
|
href,
|
|
@@ -10975,7 +10977,8 @@ function fixLinkToken(tokens) {
|
|
|
10975
10977
|
raw: text$1
|
|
10976
10978
|
}],
|
|
10977
10979
|
raw: String(`[${text$1}](${href})`)
|
|
10978
|
-
}
|
|
10980
|
+
};
|
|
10981
|
+
replacerTokens.push(linkToken);
|
|
10979
10982
|
if (emphasisMatch) {
|
|
10980
10983
|
const type = emphasisMatch[1].length;
|
|
10981
10984
|
pushEmClose(replacerTokens, type);
|
|
@@ -11342,10 +11345,50 @@ function mergeBrokenStrongAroundMathInline(tokens) {
|
|
|
11342
11345
|
continue;
|
|
11343
11346
|
}
|
|
11344
11347
|
}
|
|
11348
|
+
if (t0?.type === "strong_open" && t1?.type === "text" && t2?.type === "strong_close" && t3?.type === "strong_open" && t4?.type === "math_inline" && t5?.type === "strong_close") {
|
|
11349
|
+
const close = findTrailingTextStrongClose(tokens, i + 6);
|
|
11350
|
+
if (close) {
|
|
11351
|
+
out.push(t0);
|
|
11352
|
+
out.push(t1);
|
|
11353
|
+
out.push(t4);
|
|
11354
|
+
for (let j = i + 6; j < close.index; j++) out.push(tokens[j]);
|
|
11355
|
+
if (close.beforeClose) out.push({
|
|
11356
|
+
...tokens[close.index],
|
|
11357
|
+
type: "text",
|
|
11358
|
+
content: close.beforeClose,
|
|
11359
|
+
raw: close.beforeClose
|
|
11360
|
+
});
|
|
11361
|
+
out.push(t5);
|
|
11362
|
+
if (close.afterClose) out.push({
|
|
11363
|
+
...tokens[close.index],
|
|
11364
|
+
type: "text",
|
|
11365
|
+
content: close.afterClose,
|
|
11366
|
+
raw: close.afterClose
|
|
11367
|
+
});
|
|
11368
|
+
i = close.index;
|
|
11369
|
+
continue;
|
|
11370
|
+
}
|
|
11371
|
+
}
|
|
11345
11372
|
out.push(t0);
|
|
11346
11373
|
}
|
|
11347
11374
|
return out;
|
|
11348
11375
|
}
|
|
11376
|
+
function findTrailingTextStrongClose(tokens, startIndex) {
|
|
11377
|
+
for (let i = startIndex; i < tokens.length; i++) {
|
|
11378
|
+
const token = tokens[i];
|
|
11379
|
+
if (token?.type === "strong_open") return null;
|
|
11380
|
+
if (token?.type !== "text") continue;
|
|
11381
|
+
const content = String(token.content ?? "");
|
|
11382
|
+
const closeIdx = content.indexOf("**");
|
|
11383
|
+
if (closeIdx === -1) continue;
|
|
11384
|
+
return {
|
|
11385
|
+
index: i,
|
|
11386
|
+
beforeClose: content.slice(0, closeIdx),
|
|
11387
|
+
afterClose: content.slice(closeIdx + 2)
|
|
11388
|
+
};
|
|
11389
|
+
}
|
|
11390
|
+
return null;
|
|
11391
|
+
}
|
|
11349
11392
|
|
|
11350
11393
|
//#endregion
|
|
11351
11394
|
//#region src/plugins/fixTableTokens.ts
|
|
@@ -11353,7 +11396,7 @@ function applyFixTableTokens(md) {
|
|
|
11353
11396
|
md.core.ruler.after("block", "fix_table_tokens", (state) => {
|
|
11354
11397
|
const s = state;
|
|
11355
11398
|
try {
|
|
11356
|
-
const fixed = fixTableTokens(s.tokens ?? []);
|
|
11399
|
+
const fixed = fixTableTokens(s.tokens ?? [], !!s.env?.__markstreamFinal, s.src ?? "");
|
|
11357
11400
|
if (Array.isArray(fixed)) s.tokens = fixed;
|
|
11358
11401
|
} catch (e) {
|
|
11359
11402
|
console.error("[applyFixTableTokens] failed to fix table tokens", e);
|
|
@@ -11459,10 +11502,7 @@ function getPipeRowCells(line, requireTrailingPipe) {
|
|
|
11459
11502
|
if (requireTrailingPipe && !line.endsWith("|")) return null;
|
|
11460
11503
|
const cells = line.slice(1).split("|");
|
|
11461
11504
|
if (cells.at(-1) === "") cells.pop();
|
|
11462
|
-
return cells.length > 0 && cells.every((cell) => cell.length > 0) ? cells : null;
|
|
11463
|
-
}
|
|
11464
|
-
function isSingleLineFallbackTable(line) {
|
|
11465
|
-
return getPipeRowCells(line, false) !== null;
|
|
11505
|
+
return cells.length > 0 && cells.every((cell) => cell.trim().length > 0) ? cells : null;
|
|
11466
11506
|
}
|
|
11467
11507
|
function hasTrailingPipeHeaderRow(line) {
|
|
11468
11508
|
return getPipeRowCells(line, true) !== null;
|
|
@@ -11476,6 +11516,16 @@ function isTableSeparatorRow(line) {
|
|
|
11476
11516
|
if (cells.at(-1) === "") cells.pop();
|
|
11477
11517
|
return cells.length > 0 && cells.every(isSeparatorCell);
|
|
11478
11518
|
}
|
|
11519
|
+
function isPartialSeparatorTail(cell) {
|
|
11520
|
+
return /^(?:[::]-*|:?-+:?)?$/.test(cell.trim());
|
|
11521
|
+
}
|
|
11522
|
+
function isTableSeparatorRowWithPartialTail(line) {
|
|
11523
|
+
if (line === "") return true;
|
|
11524
|
+
if (!line.startsWith("|")) return false;
|
|
11525
|
+
const cells = line.slice(1).split("|");
|
|
11526
|
+
const tail = cells.at(-1) ?? "";
|
|
11527
|
+
return cells.slice(0, -1).every(isSeparatorCell) && isPartialSeparatorTail(tail);
|
|
11528
|
+
}
|
|
11479
11529
|
function isTruncatedSeparatorRow(line) {
|
|
11480
11530
|
return line === "|" || line === "|:";
|
|
11481
11531
|
}
|
|
@@ -11483,7 +11533,7 @@ function hasTrailingPipeHeaderRowWithoutColon(line) {
|
|
|
11483
11533
|
const cells = getPipeRowCells(line, true);
|
|
11484
11534
|
return cells !== null && cells.every((cell) => !cell.includes(":"));
|
|
11485
11535
|
}
|
|
11486
|
-
function fixTableTokens(tokens) {
|
|
11536
|
+
function fixTableTokens(tokens, final = false, source = "") {
|
|
11487
11537
|
const fixedTokens = [...tokens];
|
|
11488
11538
|
if (tokens.length < 3) return fixedTokens;
|
|
11489
11539
|
const i = tokens.length - 2;
|
|
@@ -11492,8 +11542,9 @@ function fixTableTokens(tokens) {
|
|
|
11492
11542
|
const tcontent = String(token.content ?? "");
|
|
11493
11543
|
const headerContent = tcontent.split("\n")[0] ?? "";
|
|
11494
11544
|
const [headerLine = "", separatorLine = "", ...rest] = tcontent.split("\n");
|
|
11495
|
-
|
|
11496
|
-
|
|
11545
|
+
const hasTrailingNewlineSeparatorStart = !final && !tcontent.includes("\n") && /\r?\n$/.test(source) && hasTrailingPipeHeaderRow(tcontent);
|
|
11546
|
+
if (!final && (tcontent.includes("\n") && rest.length === 0 && hasTrailingPipeHeaderRow(headerLine) && isTableSeparatorRowWithPartialTail(separatorLine) || hasTrailingNewlineSeparatorStart)) {
|
|
11547
|
+
const body = headerContent.slice(1, -1).split("|").map((i$1) => i$1.trim()).flatMap((i$1) => createTh(i$1));
|
|
11497
11548
|
const insert = [
|
|
11498
11549
|
...createStart(),
|
|
11499
11550
|
...body,
|
|
@@ -12179,7 +12230,7 @@ function applyMath(md, mathOpts) {
|
|
|
12179
12230
|
}
|
|
12180
12231
|
foundAny = true;
|
|
12181
12232
|
if (!silent) {
|
|
12182
|
-
const before = src.slice(s.pos - s.pending.length, index);
|
|
12233
|
+
const before = src.slice(s.pos - (s.pending ?? "").length, index);
|
|
12183
12234
|
let toPushBefore = src.slice(0, searchPos) ? src.slice(preMathPos, index) : before;
|
|
12184
12235
|
const isStrongPrefix = countUnescapedStrong(toPushBefore) % 2 === 1;
|
|
12185
12236
|
if (index !== s.pos && isStrongPrefix) toPushBefore = s.pending + src.slice(s.pos, index);
|
|
@@ -12503,7 +12554,8 @@ function parseEmphasisToken(tokens, startIndex, options) {
|
|
|
12503
12554
|
let i = startIndex + 1;
|
|
12504
12555
|
const innerTokens = [];
|
|
12505
12556
|
while (i < tokens.length && tokens[i].type !== "em_close") {
|
|
12506
|
-
|
|
12557
|
+
const tokenText = tokens[i];
|
|
12558
|
+
emText += String(tokens[i].content ?? tokenText.text ?? "");
|
|
12507
12559
|
innerTokens.push(tokens[i]);
|
|
12508
12560
|
i++;
|
|
12509
12561
|
}
|
|
@@ -12712,8 +12764,8 @@ function normalizeStandardHtmlChildren(children) {
|
|
|
12712
12764
|
if (!text$1) return;
|
|
12713
12765
|
const last = normalized[normalized.length - 1];
|
|
12714
12766
|
if (last?.type === "text") {
|
|
12715
|
-
last.content =
|
|
12716
|
-
last.raw =
|
|
12767
|
+
last.content = `${last.content}${text$1}`;
|
|
12768
|
+
last.raw = `${last.raw}${text$1}`;
|
|
12717
12769
|
return;
|
|
12718
12770
|
}
|
|
12719
12771
|
normalized.push({
|
|
@@ -12728,10 +12780,10 @@ function normalizeStandardHtmlChildren(children) {
|
|
|
12728
12780
|
pushText(String(child.raw ?? ""));
|
|
12729
12781
|
continue;
|
|
12730
12782
|
}
|
|
12731
|
-
if (Array.isArray(child.children)) {
|
|
12783
|
+
if ("children" in child && Array.isArray(child.children)) {
|
|
12732
12784
|
normalized.push({
|
|
12733
12785
|
...child,
|
|
12734
|
-
children: normalizeStandardHtmlChildren(child.children
|
|
12786
|
+
children: normalizeStandardHtmlChildren(child.children)
|
|
12735
12787
|
});
|
|
12736
12788
|
continue;
|
|
12737
12789
|
}
|
|
@@ -12901,7 +12953,7 @@ function parseImageToken(token, loading = false) {
|
|
|
12901
12953
|
let attrs = token.attrs ?? [];
|
|
12902
12954
|
let childWithAttrs = null;
|
|
12903
12955
|
if ((!attrs || attrs.length === 0) && Array.isArray(token.children)) for (const child of token.children) {
|
|
12904
|
-
const childAttrs = child
|
|
12956
|
+
const childAttrs = child.attrs;
|
|
12905
12957
|
if (Array.isArray(childAttrs) && childAttrs.length > 0) {
|
|
12906
12958
|
attrs = childAttrs;
|
|
12907
12959
|
childWithAttrs = child;
|
|
@@ -13104,10 +13156,11 @@ function parseStrongToken(tokens, startIndex, raw, options) {
|
|
|
13104
13156
|
innerTokens.push(tokens[i]);
|
|
13105
13157
|
i++;
|
|
13106
13158
|
}
|
|
13107
|
-
|
|
13159
|
+
const innerOptions = {
|
|
13108
13160
|
...options,
|
|
13109
13161
|
__insideStrong: true
|
|
13110
|
-
}
|
|
13162
|
+
};
|
|
13163
|
+
children.push(...parseInlineTokens(innerTokens, resolveInnerRaw(raw, strongText), void 0, innerOptions));
|
|
13111
13164
|
return {
|
|
13112
13165
|
node: {
|
|
13113
13166
|
type: "strong",
|
|
@@ -13429,6 +13482,7 @@ function recoverTrailingMarkdownLinkLabel(raw, href) {
|
|
|
13429
13482
|
}
|
|
13430
13483
|
function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
13431
13484
|
if (!tokens || tokens.length === 0) return [];
|
|
13485
|
+
const internalOptions = options;
|
|
13432
13486
|
const result = [];
|
|
13433
13487
|
let currentTextNode = null;
|
|
13434
13488
|
let i = 0;
|
|
@@ -13864,7 +13918,7 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
13864
13918
|
return true;
|
|
13865
13919
|
}
|
|
13866
13920
|
function tryReparseCollapsedInlineText(rawContent) {
|
|
13867
|
-
const md =
|
|
13921
|
+
const md = internalOptions?.__markdownIt;
|
|
13868
13922
|
if (!md) return null;
|
|
13869
13923
|
if (tokens.length <= 1 || !tokens.some((token) => token?.type === "math_inline")) return null;
|
|
13870
13924
|
if (!INLINE_REPARSE_MARKER_RE.test(rawContent)) return null;
|
|
@@ -13901,9 +13955,28 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
13901
13955
|
result.push(currentTextNode);
|
|
13902
13956
|
}
|
|
13903
13957
|
}
|
|
13958
|
+
function pushInlineTextContent(content, token) {
|
|
13959
|
+
if (!content) return;
|
|
13960
|
+
const parsed = parseInlineTokens([{
|
|
13961
|
+
...token,
|
|
13962
|
+
type: "text",
|
|
13963
|
+
content,
|
|
13964
|
+
raw: content
|
|
13965
|
+
}], content, pPreToken, options);
|
|
13966
|
+
if (parsed.length === 1 && parsed[0]?.type === "text") {
|
|
13967
|
+
const text$1 = parsed[0];
|
|
13968
|
+
pushText(String(text$1.content ?? ""), String(text$1.raw ?? text$1.content ?? ""));
|
|
13969
|
+
return;
|
|
13970
|
+
}
|
|
13971
|
+
for (const node of parsed) pushNode(node);
|
|
13972
|
+
}
|
|
13904
13973
|
function hasEscapedMarkup(token, escapedPrefix) {
|
|
13905
13974
|
return String(token.markup ?? "").startsWith(escapedPrefix);
|
|
13906
13975
|
}
|
|
13976
|
+
function isMarkdownLinkBeforeLinkifiedUrl(content) {
|
|
13977
|
+
if (!content.endsWith("](")) return false;
|
|
13978
|
+
return tokens[i + 1]?.type === "link_open" && tokens[i + 1]?.markup === "linkify" && tokens[i + 2]?.type === "text" && tokens[i + 3]?.type === "link_close" && tokens[i + 4]?.type === "text" && String(tokens[i + 4]?.content ?? "").startsWith(")");
|
|
13979
|
+
}
|
|
13907
13980
|
function stripTrailingMidStateMarker(content, token) {
|
|
13908
13981
|
let nextContent = content;
|
|
13909
13982
|
const rawTokenContent = String(token.content ?? "");
|
|
@@ -14092,10 +14165,11 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
14092
14165
|
pushText(String(token.content ?? ""), String(token.content ?? ""));
|
|
14093
14166
|
i++;
|
|
14094
14167
|
break;
|
|
14095
|
-
default:
|
|
14096
|
-
|
|
14168
|
+
default: {
|
|
14169
|
+
const syntheticLink = token;
|
|
14170
|
+
if (token.type === "link" && syntheticLink.href != null && options?.validateLink && !options.validateLink(String(syntheticLink.href))) {
|
|
14097
14171
|
resetCurrentTextNode();
|
|
14098
|
-
const displayText = String(
|
|
14172
|
+
const displayText = String(syntheticLink.text ?? "");
|
|
14099
14173
|
pushText(displayText, displayText);
|
|
14100
14174
|
i++;
|
|
14101
14175
|
} else if (recoverOuterImageLinkFromSyntheticLinkToken(token)) i++;
|
|
@@ -14106,6 +14180,7 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
14106
14180
|
i++;
|
|
14107
14181
|
}
|
|
14108
14182
|
break;
|
|
14183
|
+
}
|
|
14109
14184
|
}
|
|
14110
14185
|
}
|
|
14111
14186
|
function commitTextNode(content, token, preToken, nextToken) {
|
|
@@ -14176,7 +14251,7 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
14176
14251
|
}
|
|
14177
14252
|
if (handleInlineCodeContent(rawContent, token)) return;
|
|
14178
14253
|
if (handleInlineImageContent(content)) return;
|
|
14179
|
-
if (tokens[i + 1]?.type !== "link_open" && handleInlineLinkContent(content, token)) return;
|
|
14254
|
+
if ((tokens[i + 1]?.type !== "link_open" || isMarkdownLinkBeforeLinkifiedUrl(content)) && handleInlineLinkContent(content, token)) return;
|
|
14180
14255
|
const reparsedNodes = tryReparseCollapsedInlineText(rawContent);
|
|
14181
14256
|
if (reparsedNodes) {
|
|
14182
14257
|
resetCurrentTextNode();
|
|
@@ -14381,7 +14456,8 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
14381
14456
|
if (outerOpenToken?.type === "text" && String(outerOpenToken.content ?? "").endsWith("[") && hasEscapedMarkup(outerOpenToken, "\\[")) return false;
|
|
14382
14457
|
const previous = result[result.length - 1];
|
|
14383
14458
|
if (previous?.type !== "image" && previous?.type !== "link") return false;
|
|
14384
|
-
const
|
|
14459
|
+
const previousWithChildren = previous;
|
|
14460
|
+
const previousLink = previous?.type === "link" && Array.isArray(previousWithChildren.children) && previousWithChildren.children.length === 1 && previousWithChildren.children[0]?.type === "image" ? result.pop() : null;
|
|
14385
14461
|
const imageNode = previousLink ? previousLink.children[0] : result.pop();
|
|
14386
14462
|
if (!imageNode || imageNode.type !== "image") return false;
|
|
14387
14463
|
const nextToken = tokens[i + 1];
|
|
@@ -14431,11 +14507,18 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
14431
14507
|
const last = tokens[i + 4];
|
|
14432
14508
|
let index = 4;
|
|
14433
14509
|
let loading$1 = true;
|
|
14434
|
-
if (last?.type === "text"
|
|
14435
|
-
|
|
14436
|
-
|
|
14437
|
-
|
|
14438
|
-
|
|
14510
|
+
if (last?.type === "text") {
|
|
14511
|
+
const lastContent = String(last.content ?? "");
|
|
14512
|
+
if (lastContent.startsWith(")")) {
|
|
14513
|
+
loading$1 = false;
|
|
14514
|
+
const trailing = lastContent.slice(1);
|
|
14515
|
+
if (trailing) {
|
|
14516
|
+
last.content = trailing;
|
|
14517
|
+
last.raw = trailing;
|
|
14518
|
+
} else index++;
|
|
14519
|
+
} else if (lastContent === ".") i++;
|
|
14520
|
+
}
|
|
14521
|
+
pushInlineTextContent(textNodeContent, _token);
|
|
14439
14522
|
const hrefFromToken = String(textToken$1.content ?? "");
|
|
14440
14523
|
if (options?.validateLink && !options.validateLink(hrefFromToken)) pushText(text$1, text$1);
|
|
14441
14524
|
else pushParsed({
|
|
@@ -14458,7 +14541,7 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
14458
14541
|
const loading = linkContentEnd === -1;
|
|
14459
14542
|
let emphasisMatch = textNodeContent.match(/\*+$/);
|
|
14460
14543
|
if (emphasisMatch) textNodeContent = textNodeContent.replace(/\*+$/, "");
|
|
14461
|
-
|
|
14544
|
+
pushInlineTextContent(textNodeContent, _token);
|
|
14462
14545
|
if (!emphasisMatch) emphasisMatch = text$1.match(/^\*+/);
|
|
14463
14546
|
if (!requireClosingStrong && emphasisMatch) {
|
|
14464
14547
|
const type = emphasisMatch[0].length;
|
|
@@ -14977,11 +15060,11 @@ function parseFootnote(tokens, index, options) {
|
|
|
14977
15060
|
let j = index + 1;
|
|
14978
15061
|
while (j < tokens.length && tokens[j].type !== "footnote_close") if (tokens[j].type === "paragraph_open") {
|
|
14979
15062
|
const contentToken = tokens[j + 1];
|
|
14980
|
-
const children = contentToken.children
|
|
15063
|
+
const children = contentToken.children ? [...contentToken.children] : [];
|
|
14981
15064
|
if (tokens[j + 2].type === "footnote_anchor") children.push(tokens[j + 2]);
|
|
14982
15065
|
footnoteChildren.push({
|
|
14983
15066
|
type: "paragraph",
|
|
14984
|
-
children: parseInlineTokens(
|
|
15067
|
+
children: parseInlineTokens(children, String(contentToken.content ?? ""), void 0, options),
|
|
14985
15068
|
raw: String(contentToken.content ?? "")
|
|
14986
15069
|
});
|
|
14987
15070
|
j += 3;
|
|
@@ -14998,7 +15081,7 @@ function parseFootnote(tokens, index, options) {
|
|
|
14998
15081
|
//#region src/parser/node-parsers/heading-parser.ts
|
|
14999
15082
|
function parseHeading(tokens, index, options) {
|
|
15000
15083
|
const token = tokens[index];
|
|
15001
|
-
const attrs = token
|
|
15084
|
+
const attrs = token.attrs;
|
|
15002
15085
|
const attrsRecord = Array.isArray(attrs) && attrs.length ? Object.fromEntries(attrs.filter((pair) => Array.isArray(pair) && pair.length >= 1 && pair[0]).map(([name, value]) => [String(name), value == null || value === "" ? true : String(value)])) : void 0;
|
|
15003
15086
|
const levelStr = String(token.tag?.substring(1) ?? "1");
|
|
15004
15087
|
const headingLevel = Number.parseInt(levelStr, 10);
|
|
@@ -15393,7 +15476,7 @@ function parseBasicBlockToken(tokens, index, options) {
|
|
|
15393
15476
|
const htmlBlockNode = parseHtmlBlock(token);
|
|
15394
15477
|
const tagSets = htmlBlockNode.tag ? getHtmlTagSets(options?.customHtmlTags) : null;
|
|
15395
15478
|
if (htmlBlockNode.tag && htmlBlockNode.loading && tagSets && !tagSets.allowedTagSet.has(htmlBlockNode.tag)) {
|
|
15396
|
-
const content = String(token
|
|
15479
|
+
const content = String(token.content ?? "").replace(/\n+$/, "");
|
|
15397
15480
|
return [{
|
|
15398
15481
|
type: "paragraph",
|
|
15399
15482
|
children: content ? [{
|
|
@@ -15410,7 +15493,7 @@ function parseBasicBlockToken(tokens, index, options) {
|
|
|
15410
15493
|
const cursor = Number(options?.__customHtmlBlockCursor ?? 0);
|
|
15411
15494
|
const mappedLineStart = Array.isArray(token.map) ? lineToIndex(source, Number(token.map?.[0] ?? 0)) : 0;
|
|
15412
15495
|
const fromSource = findNextCustomHtmlBlockFromSource(source, tag, Math.max(clampNonNegative(cursor), clampNonNegative(mappedLineStart)));
|
|
15413
|
-
if (fromSource) options.__customHtmlBlockCursor = fromSource.end;
|
|
15496
|
+
if (fromSource && options) options.__customHtmlBlockCursor = fromSource.end;
|
|
15414
15497
|
const rawHtml = String(fromSource?.raw ?? htmlBlockNode.raw ?? "");
|
|
15415
15498
|
const openEnd = findTagCloseIndexOutsideQuotes(rawHtml);
|
|
15416
15499
|
const openTag = openEnd !== -1 ? rawHtml.slice(0, openEnd + 1) : rawHtml;
|
|
@@ -15507,6 +15590,9 @@ function parseParagraph(tokens, index, options) {
|
|
|
15507
15590
|
|
|
15508
15591
|
//#endregion
|
|
15509
15592
|
//#region src/parser/index.ts
|
|
15593
|
+
function getNodeFields(node) {
|
|
15594
|
+
return node;
|
|
15595
|
+
}
|
|
15510
15596
|
function getCustomHtmlTagSet(options) {
|
|
15511
15597
|
const custom = options?.customHtmlTags;
|
|
15512
15598
|
if (!Array.isArray(custom) || custom.length === 0) return null;
|
|
@@ -15521,11 +15607,11 @@ function buildAllowedHtmlTagSet(options) {
|
|
|
15521
15607
|
return set;
|
|
15522
15608
|
}
|
|
15523
15609
|
function stringifyInlineNodeRaw(node) {
|
|
15524
|
-
const raw = node
|
|
15610
|
+
const raw = node.raw;
|
|
15525
15611
|
if (typeof raw === "string") return raw;
|
|
15526
|
-
const content = node
|
|
15612
|
+
const content = getNodeFields(node).content;
|
|
15527
15613
|
if (typeof content === "string") return content;
|
|
15528
|
-
if (node
|
|
15614
|
+
if (node.type === "hardbreak") return "<br>";
|
|
15529
15615
|
return "";
|
|
15530
15616
|
}
|
|
15531
15617
|
function buildParagraphFromInlineChildren(children) {
|
|
@@ -15537,7 +15623,8 @@ function buildParagraphFromInlineChildren(children) {
|
|
|
15537
15623
|
}
|
|
15538
15624
|
function maybePromoteCustomNodeFromParagraph(node, options) {
|
|
15539
15625
|
if (node.type !== "paragraph") return null;
|
|
15540
|
-
const
|
|
15626
|
+
const nodeChildren = getNodeFields(node).children;
|
|
15627
|
+
const children = Array.isArray(nodeChildren) ? nodeChildren : [];
|
|
15541
15628
|
if (children.length === 0) return null;
|
|
15542
15629
|
const customTagSet = getCustomHtmlTagSet(options);
|
|
15543
15630
|
if (!customTagSet?.size) return null;
|
|
@@ -15546,7 +15633,7 @@ function maybePromoteCustomNodeFromParagraph(node, options) {
|
|
|
15546
15633
|
const child = children[i];
|
|
15547
15634
|
if (!customTagSet.has(String(child?.type ?? "").toLowerCase())) continue;
|
|
15548
15635
|
const prefixChildren$1 = children.slice(0, i);
|
|
15549
|
-
if (!String(child
|
|
15636
|
+
if (!String(getNodeFields(child).content ?? "").trim()) continue;
|
|
15550
15637
|
if (!prefixChildren$1.some((prefixChild) => prefixChild?.type === "hardbreak")) continue;
|
|
15551
15638
|
customIndex = i;
|
|
15552
15639
|
break;
|
|
@@ -15577,15 +15664,15 @@ function parseStandaloneHtmlDocument(markdown) {
|
|
|
15577
15664
|
}];
|
|
15578
15665
|
}
|
|
15579
15666
|
function getMergeableNodeRaw(node) {
|
|
15580
|
-
const raw = node
|
|
15667
|
+
const raw = node.raw;
|
|
15581
15668
|
if (typeof raw === "string") return raw;
|
|
15582
|
-
const content = node
|
|
15669
|
+
const content = getNodeFields(node).content;
|
|
15583
15670
|
if (typeof content === "string") return content;
|
|
15584
15671
|
return "";
|
|
15585
15672
|
}
|
|
15586
15673
|
function isCloseOnlyHtmlBlockForTag(node, tag) {
|
|
15587
15674
|
if (node.type !== "html_block" || !tag) return false;
|
|
15588
|
-
const raw = String(node
|
|
15675
|
+
const raw = String(node.raw ?? node.content ?? "");
|
|
15589
15676
|
return new RegExp(String.raw`^\s*<\s*\/\s*${escapeTagForRegExp(tag)}\s*>\s*$`, "i").test(raw);
|
|
15590
15677
|
}
|
|
15591
15678
|
function findNextHtmlBlockFromSource(source, tag, startIndex) {
|
|
@@ -15743,7 +15830,8 @@ function shouldStructureGenericHtmlBlockChildren(innerRaw, children) {
|
|
|
15743
15830
|
if (children.some((child) => STRUCTURED_HTML_WRAPPER_BLOCK_TYPES.has(String(child?.type ?? "").toLowerCase()))) return true;
|
|
15744
15831
|
if (children.some((child) => {
|
|
15745
15832
|
if (child?.type !== "html_block") return false;
|
|
15746
|
-
|
|
15833
|
+
const childFields = getNodeFields(child);
|
|
15834
|
+
return Array.isArray(childFields.children) && childFields.children.length > 0;
|
|
15747
15835
|
})) return true;
|
|
15748
15836
|
if (!hasStructuredHtmlWrapperMarkers(innerRaw)) return false;
|
|
15749
15837
|
if (children.length > 1) return true;
|
|
@@ -15753,9 +15841,10 @@ function shouldStructureGenericHtmlBlockChildren(innerRaw, children) {
|
|
|
15753
15841
|
function structureGenericHtmlBlockChildren(nodes, md, options, final) {
|
|
15754
15842
|
return nodes.map((node) => {
|
|
15755
15843
|
if (node?.type !== "html_block") return node;
|
|
15756
|
-
const
|
|
15757
|
-
|
|
15758
|
-
|
|
15844
|
+
const fields = getNodeFields(node);
|
|
15845
|
+
const tag = String(fields.tag ?? "").toLowerCase();
|
|
15846
|
+
if (!tag || tag === "details" || NON_STRUCTURING_HTML_TAGS.has(tag) || Array.isArray(fields.children)) return node;
|
|
15847
|
+
const raw = String(node.raw ?? fields.content ?? "");
|
|
15759
15848
|
if (!raw) return node;
|
|
15760
15849
|
const openEnd = findTagCloseIndexOutsideQuotes(raw);
|
|
15761
15850
|
if (openEnd === -1) return node;
|
|
@@ -15850,7 +15939,7 @@ function combineStructuredDetailsHtmlBlocks(nodes, source, md, options, final, s
|
|
|
15850
15939
|
})() : openRaw;
|
|
15851
15940
|
const [children] = combineStructuredDetailsHtmlBlocks(selfContained ? [] : closeIndex === -1 ? nodes.slice(i + 1) : nodes.slice(i + 1, closeIndex), source, md, options, final, openStart + openRaw.length);
|
|
15852
15941
|
const prefixChildren = buildDetailsPrefixChildren(effectiveOpenRaw, md, buildDetailsChildParseOptions(options, final));
|
|
15853
|
-
const closeRaw = closeIndex === -1 ? "</details>" : String(nodes[closeIndex]
|
|
15942
|
+
const closeRaw = closeIndex === -1 ? "</details>" : String(nodes[closeIndex].raw ?? getMergeableNodeRaw(nodes[closeIndex]) ?? "</details>");
|
|
15854
15943
|
const explicitClose = selfContained || closeIndex !== -1 && exact?.closed === true;
|
|
15855
15944
|
const trimmedCloseRaw = closeRaw.replace(/[\t\r\n ]+$/, "");
|
|
15856
15945
|
const closeStart = explicitClose ? (() => {
|
|
@@ -15894,7 +15983,7 @@ function mergeSplitTopLevelHtmlBlocks(nodes, final, source) {
|
|
|
15894
15983
|
if (nodePos !== -1) sourceHtmlCursor = nodePos + nodeRaw.length;
|
|
15895
15984
|
continue;
|
|
15896
15985
|
}
|
|
15897
|
-
const tag = String(node
|
|
15986
|
+
const tag = String(node.tag ?? "").toLowerCase();
|
|
15898
15987
|
if (!tag) continue;
|
|
15899
15988
|
if (tag === "details") {
|
|
15900
15989
|
if (nodePos !== -1) sourceHtmlCursor = nodePos + nodeRaw.length;
|
|
@@ -15903,11 +15992,11 @@ function mergeSplitTopLevelHtmlBlocks(nodes, final, source) {
|
|
|
15903
15992
|
const exact = findNextHtmlBlockFromSource(source, tag, nodePos !== -1 ? nodePos : sourceHtmlCursor);
|
|
15904
15993
|
if (!exact) continue;
|
|
15905
15994
|
sourceHtmlCursor = exact.end;
|
|
15906
|
-
const currentContent = String(node
|
|
15907
|
-
const currentRaw = String(node
|
|
15995
|
+
const currentContent = String(node.content ?? nodeRaw);
|
|
15996
|
+
const currentRaw = String(node.raw ?? currentContent);
|
|
15908
15997
|
const nextContent = buildHtmlBlockContent(exact.raw, tag, exact.closed);
|
|
15909
15998
|
const desiredLoading = !final && !exact.closed;
|
|
15910
|
-
const needsExpansion = currentContent !== nextContent || currentRaw !== exact.raw || Boolean(node
|
|
15999
|
+
const needsExpansion = currentContent !== nextContent || currentRaw !== exact.raw || Boolean(node.loading) !== desiredLoading;
|
|
15911
16000
|
const exactOpenEnd = findTagCloseIndexOutsideQuotes(exact.raw);
|
|
15912
16001
|
const exactOpenTag = exactOpenEnd === -1 ? "" : exact.raw.slice(0, exactOpenEnd + 1);
|
|
15913
16002
|
const exactAttrs = exactOpenTag ? parseTagAttrs(exactOpenTag) : [];
|
|
@@ -17359,9 +17448,8 @@ function getMarkdown(msgId = `editor-${Date.now()}`, options = {}) {
|
|
|
17359
17448
|
if (Array.isArray(options.plugin)) for (const p of options.plugin) {
|
|
17360
17449
|
const pluginItem = p;
|
|
17361
17450
|
if (Array.isArray(pluginItem)) {
|
|
17362
|
-
const fn = pluginItem
|
|
17363
|
-
|
|
17364
|
-
if (typeof fn === "function") md.use(fn, opts);
|
|
17451
|
+
const [fn, ...params] = pluginItem;
|
|
17452
|
+
if (typeof fn === "function") md.use(fn, ...params);
|
|
17365
17453
|
} else if (typeof pluginItem === "function") md.use(pluginItem);
|
|
17366
17454
|
}
|
|
17367
17455
|
if (Array.isArray(options.apply)) for (const fn of options.apply) try {
|
|
@@ -17371,9 +17459,8 @@ function getMarkdown(msgId = `editor-${Date.now()}`, options = {}) {
|
|
|
17371
17459
|
}
|
|
17372
17460
|
if (_registeredMarkdownPlugins.length) {
|
|
17373
17461
|
for (const p of _registeredMarkdownPlugins) if (Array.isArray(p)) {
|
|
17374
|
-
const fn = p
|
|
17375
|
-
|
|
17376
|
-
if (typeof fn === "function") md.use(fn, opts);
|
|
17462
|
+
const [fn, ...params] = p;
|
|
17463
|
+
if (typeof fn === "function") md.use(fn, ...params);
|
|
17377
17464
|
} else if (typeof p === "function") md.use(p);
|
|
17378
17465
|
}
|
|
17379
17466
|
md.use(sub_plugin);
|