stream-markdown-parser 0.0.46 → 0.0.48
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 +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +347 -260
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6751,10 +6751,28 @@ function applyContainers(md) {
|
|
|
6751
6751
|
const s = state;
|
|
6752
6752
|
const startPos = s.bMarks[startLine] + s.tShift[startLine];
|
|
6753
6753
|
const lineMax = s.eMarks[startLine];
|
|
6754
|
-
const
|
|
6755
|
-
|
|
6754
|
+
const line = s.src.slice(startPos, lineMax);
|
|
6755
|
+
const nameMatch = line.match(/^:::\s*(\S+)/);
|
|
6756
|
+
if (!nameMatch) return false;
|
|
6757
|
+
const name = nameMatch[1];
|
|
6758
|
+
if (!name.trim()) return false;
|
|
6759
|
+
const rest = line.slice(nameMatch[0].length);
|
|
6760
|
+
let jsonStr;
|
|
6761
|
+
const trimmedRest = rest.trim();
|
|
6762
|
+
if (trimmedRest.startsWith("{")) {
|
|
6763
|
+
let depth = 0;
|
|
6764
|
+
let jsonEnd = -1;
|
|
6765
|
+
for (let i = 0; i < trimmedRest.length; i++) {
|
|
6766
|
+
if (trimmedRest[i] === "{") depth++;
|
|
6767
|
+
else if (trimmedRest[i] === "}") depth--;
|
|
6768
|
+
if (depth === 0) {
|
|
6769
|
+
jsonEnd = i + 1;
|
|
6770
|
+
break;
|
|
6771
|
+
}
|
|
6772
|
+
}
|
|
6773
|
+
if (jsonEnd > 0) jsonStr = trimmedRest.slice(0, jsonEnd);
|
|
6774
|
+
}
|
|
6756
6775
|
if (silent) return true;
|
|
6757
|
-
const name = markerMatch[1];
|
|
6758
6776
|
let nextLine = startLine + 1;
|
|
6759
6777
|
let found = false;
|
|
6760
6778
|
while (nextLine <= endLine) {
|
|
@@ -6767,20 +6785,28 @@ function applyContainers(md) {
|
|
|
6767
6785
|
nextLine++;
|
|
6768
6786
|
}
|
|
6769
6787
|
if (!found) return false;
|
|
6770
|
-
s.push("vmr_container_open", "div", 1)
|
|
6788
|
+
const tokenOpen = s.push("vmr_container_open", "div", 1);
|
|
6789
|
+
tokenOpen.attrSet("class", `vmr-container vmr-container-${name}`);
|
|
6790
|
+
if (jsonStr) try {
|
|
6791
|
+
const attrs = JSON.parse(jsonStr);
|
|
6792
|
+
for (const [key, value] of Object.entries(attrs)) tokenOpen.attrSet(`data-${key}`, String(value));
|
|
6793
|
+
} catch {
|
|
6794
|
+
tokenOpen.attrSet("data-attrs", jsonStr);
|
|
6795
|
+
}
|
|
6771
6796
|
const contentLines = [];
|
|
6772
6797
|
for (let i = startLine + 1; i < nextLine; i++) {
|
|
6773
6798
|
const sPos = s.bMarks[i] + s.tShift[i];
|
|
6774
6799
|
const ePos = s.eMarks[i];
|
|
6775
6800
|
contentLines.push(s.src.slice(sPos, ePos));
|
|
6776
6801
|
}
|
|
6777
|
-
|
|
6778
|
-
|
|
6779
|
-
|
|
6780
|
-
|
|
6781
|
-
|
|
6782
|
-
|
|
6783
|
-
|
|
6802
|
+
if (contentLines.some((line$1) => line$1.trim().length > 0)) {
|
|
6803
|
+
let innerSrc = contentLines.join("\n");
|
|
6804
|
+
if (!innerSrc.endsWith("\n")) innerSrc += "\n";
|
|
6805
|
+
if (!innerSrc.endsWith("\n\n")) innerSrc += "\n";
|
|
6806
|
+
const innerTokens = [];
|
|
6807
|
+
s.md.block.parse(innerSrc, s.md, s.env, innerTokens);
|
|
6808
|
+
s.tokens.push(...innerTokens);
|
|
6809
|
+
}
|
|
6784
6810
|
s.push("vmr_container_close", "div", -1);
|
|
6785
6811
|
s.line = nextLine + 1;
|
|
6786
6812
|
return true;
|
|
@@ -10246,6 +10272,249 @@ function normalizeSingleLinkResult(raw, nodes) {
|
|
|
10246
10272
|
return nodes;
|
|
10247
10273
|
}
|
|
10248
10274
|
|
|
10275
|
+
//#endregion
|
|
10276
|
+
//#region src/parser/node-parsers/list-parser.ts
|
|
10277
|
+
function parseList(tokens, index, options) {
|
|
10278
|
+
const token = tokens[index];
|
|
10279
|
+
const listItems = [];
|
|
10280
|
+
let j = index + 1;
|
|
10281
|
+
while (j < tokens.length && tokens[j].type !== "bullet_list_close" && tokens[j].type !== "ordered_list_close") if (tokens[j].type === "list_item_open") {
|
|
10282
|
+
const itemChildren = [];
|
|
10283
|
+
let k = j + 1;
|
|
10284
|
+
while (k < tokens.length && tokens[k].type !== "list_item_close") if (tokens[k].type === "paragraph_open") {
|
|
10285
|
+
const contentToken = tokens[k + 1];
|
|
10286
|
+
const preToken = tokens[k - 1];
|
|
10287
|
+
const contentStr = String(contentToken.content ?? "");
|
|
10288
|
+
if (/\n\d+$/.test(contentStr)) {
|
|
10289
|
+
contentToken.content = contentStr.replace(/\n\d+$/, "");
|
|
10290
|
+
contentToken.children?.splice(-1, 1);
|
|
10291
|
+
}
|
|
10292
|
+
itemChildren.push({
|
|
10293
|
+
type: "paragraph",
|
|
10294
|
+
children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), preToken, {
|
|
10295
|
+
requireClosingStrong: options?.requireClosingStrong,
|
|
10296
|
+
customHtmlTags: options?.customHtmlTags
|
|
10297
|
+
}),
|
|
10298
|
+
raw: String(contentToken.content ?? "")
|
|
10299
|
+
});
|
|
10300
|
+
k += 3;
|
|
10301
|
+
} else if (tokens[k].type === "blockquote_open") {
|
|
10302
|
+
const [blockquoteNode, newIndex] = parseBlockquote(tokens, k, options);
|
|
10303
|
+
itemChildren.push(blockquoteNode);
|
|
10304
|
+
k = newIndex;
|
|
10305
|
+
} else if (tokens[k].type === "bullet_list_open" || tokens[k].type === "ordered_list_open") {
|
|
10306
|
+
const [nestedListNode, newIndex] = parseList(tokens, k, options);
|
|
10307
|
+
itemChildren.push(nestedListNode);
|
|
10308
|
+
k = newIndex;
|
|
10309
|
+
} else {
|
|
10310
|
+
const handled = parseCommonBlockToken(tokens, k, options, containerTokenHandlers);
|
|
10311
|
+
if (handled) {
|
|
10312
|
+
itemChildren.push(handled[0]);
|
|
10313
|
+
k = handled[1];
|
|
10314
|
+
} else k += 1;
|
|
10315
|
+
}
|
|
10316
|
+
listItems.push({
|
|
10317
|
+
type: "list_item",
|
|
10318
|
+
children: itemChildren,
|
|
10319
|
+
raw: itemChildren.map((child) => child.raw).join("")
|
|
10320
|
+
});
|
|
10321
|
+
j = k + 1;
|
|
10322
|
+
} else j += 1;
|
|
10323
|
+
return [{
|
|
10324
|
+
type: "list",
|
|
10325
|
+
ordered: token.type === "ordered_list_open",
|
|
10326
|
+
start: (() => {
|
|
10327
|
+
if (token.attrs && token.attrs.length) {
|
|
10328
|
+
const found = token.attrs.find((a) => a[0] === "start");
|
|
10329
|
+
if (found) {
|
|
10330
|
+
const parsed = Number(found[1]);
|
|
10331
|
+
return Number.isFinite(parsed) && parsed !== 0 ? parsed : 1;
|
|
10332
|
+
}
|
|
10333
|
+
}
|
|
10334
|
+
})(),
|
|
10335
|
+
items: listItems,
|
|
10336
|
+
raw: listItems.map((item) => item.raw).join("\n")
|
|
10337
|
+
}, j + 1];
|
|
10338
|
+
}
|
|
10339
|
+
|
|
10340
|
+
//#endregion
|
|
10341
|
+
//#region src/parser/node-parsers/admonition-parser.ts
|
|
10342
|
+
function parseAdmonition(tokens, index, match, options) {
|
|
10343
|
+
const kind = String(match[1] ?? "note");
|
|
10344
|
+
const title = String(match[2] ?? kind.charAt(0).toUpperCase() + kind.slice(1));
|
|
10345
|
+
const admonitionChildren = [];
|
|
10346
|
+
let j = index + 1;
|
|
10347
|
+
while (j < tokens.length && tokens[j].type !== "container_close") if (tokens[j].type === "paragraph_open") {
|
|
10348
|
+
const contentToken = tokens[j + 1];
|
|
10349
|
+
if (contentToken) admonitionChildren.push({
|
|
10350
|
+
type: "paragraph",
|
|
10351
|
+
children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, {
|
|
10352
|
+
requireClosingStrong: options?.requireClosingStrong,
|
|
10353
|
+
customHtmlTags: options?.customHtmlTags
|
|
10354
|
+
}),
|
|
10355
|
+
raw: String(contentToken.content ?? "")
|
|
10356
|
+
});
|
|
10357
|
+
j += 3;
|
|
10358
|
+
} else if (tokens[j].type === "bullet_list_open" || tokens[j].type === "ordered_list_open") {
|
|
10359
|
+
const [listNode, newIndex] = parseList(tokens, j, options);
|
|
10360
|
+
admonitionChildren.push(listNode);
|
|
10361
|
+
j = newIndex;
|
|
10362
|
+
} else if (tokens[j].type === "blockquote_open") {
|
|
10363
|
+
const [blockquoteNode, newIndex] = parseBlockquote(tokens, j, options);
|
|
10364
|
+
admonitionChildren.push(blockquoteNode);
|
|
10365
|
+
j = newIndex;
|
|
10366
|
+
} else {
|
|
10367
|
+
const handled = parseBasicBlockToken(tokens, j, options);
|
|
10368
|
+
if (handled) {
|
|
10369
|
+
admonitionChildren.push(handled[0]);
|
|
10370
|
+
j = handled[1];
|
|
10371
|
+
} else j++;
|
|
10372
|
+
}
|
|
10373
|
+
return [{
|
|
10374
|
+
type: "admonition",
|
|
10375
|
+
kind,
|
|
10376
|
+
title,
|
|
10377
|
+
children: admonitionChildren,
|
|
10378
|
+
raw: `:::${kind} ${title}\n${admonitionChildren.map((child) => child.raw).join("\n")}\n:::`
|
|
10379
|
+
}, j + 1];
|
|
10380
|
+
}
|
|
10381
|
+
|
|
10382
|
+
//#endregion
|
|
10383
|
+
//#region src/parser/node-parsers/container-parser.ts
|
|
10384
|
+
function parseContainer(tokens, index, options) {
|
|
10385
|
+
const openToken = tokens[index];
|
|
10386
|
+
let kind = "note";
|
|
10387
|
+
let title = "";
|
|
10388
|
+
const typeMatch = openToken.type.match(/^container_(\w+)_open$/);
|
|
10389
|
+
if (typeMatch) {
|
|
10390
|
+
kind = typeMatch[1];
|
|
10391
|
+
const info = String(openToken.info ?? "").trim();
|
|
10392
|
+
if (info && !info.startsWith(":::")) {
|
|
10393
|
+
const maybe = info.replace(/* @__PURE__ */ new RegExp(`^${kind}`), "").trim();
|
|
10394
|
+
if (maybe) title = maybe;
|
|
10395
|
+
}
|
|
10396
|
+
} else {
|
|
10397
|
+
const info = String(openToken.info ?? "").trim();
|
|
10398
|
+
const match = /^:{1,3}\s*(warning|info|note|tip|danger|caution)\s*(.*)$/i.exec(info);
|
|
10399
|
+
if (match) {
|
|
10400
|
+
kind = match[1];
|
|
10401
|
+
title = String(match[2] ?? "");
|
|
10402
|
+
}
|
|
10403
|
+
}
|
|
10404
|
+
if (!title) title = kind.charAt(0).toUpperCase() + kind.slice(1);
|
|
10405
|
+
const children = [];
|
|
10406
|
+
let j = index + 1;
|
|
10407
|
+
const closeType = /* @__PURE__ */ new RegExp(`^container_${kind}_close$`);
|
|
10408
|
+
while (j < tokens.length && tokens[j].type !== "container_close" && !closeType.test(tokens[j].type)) if (tokens[j].type === "paragraph_open") {
|
|
10409
|
+
const contentToken = tokens[j + 1];
|
|
10410
|
+
if (contentToken) {
|
|
10411
|
+
const childrenArr = contentToken.children || [];
|
|
10412
|
+
let i = -1;
|
|
10413
|
+
for (let k = childrenArr.length - 1; k >= 0; k--) {
|
|
10414
|
+
const t = childrenArr[k];
|
|
10415
|
+
if (t.type === "text" && /:+/.test(t.content)) {
|
|
10416
|
+
i = k;
|
|
10417
|
+
break;
|
|
10418
|
+
}
|
|
10419
|
+
}
|
|
10420
|
+
const _children = i !== -1 ? childrenArr.slice(0, i) : childrenArr;
|
|
10421
|
+
children.push({
|
|
10422
|
+
type: "paragraph",
|
|
10423
|
+
children: parseInlineTokens(_children || [], void 0, void 0, {
|
|
10424
|
+
requireClosingStrong: options?.requireClosingStrong,
|
|
10425
|
+
customHtmlTags: options?.customHtmlTags
|
|
10426
|
+
}),
|
|
10427
|
+
raw: String(contentToken.content ?? "").replace(/\n:+$/, "").replace(/\n\s*:::\s*$/, "")
|
|
10428
|
+
});
|
|
10429
|
+
}
|
|
10430
|
+
j += 3;
|
|
10431
|
+
} else if (tokens[j].type === "bullet_list_open" || tokens[j].type === "ordered_list_open") {
|
|
10432
|
+
const [listNode, newIndex] = parseList(tokens, j, options);
|
|
10433
|
+
children.push(listNode);
|
|
10434
|
+
j = newIndex;
|
|
10435
|
+
} else if (tokens[j].type === "blockquote_open") {
|
|
10436
|
+
const [blockquoteNode, newIndex] = parseBlockquote(tokens, j, options);
|
|
10437
|
+
children.push(blockquoteNode);
|
|
10438
|
+
j = newIndex;
|
|
10439
|
+
} else {
|
|
10440
|
+
const handled = parseBasicBlockToken(tokens, j, options);
|
|
10441
|
+
if (handled) {
|
|
10442
|
+
children.push(handled[0]);
|
|
10443
|
+
j = handled[1];
|
|
10444
|
+
} else j++;
|
|
10445
|
+
}
|
|
10446
|
+
return [{
|
|
10447
|
+
type: "admonition",
|
|
10448
|
+
kind,
|
|
10449
|
+
title,
|
|
10450
|
+
children,
|
|
10451
|
+
raw: `:::${kind} ${title}\n${children.map((c) => c.raw).join("\n")}\n:::`
|
|
10452
|
+
}, j + 1];
|
|
10453
|
+
}
|
|
10454
|
+
|
|
10455
|
+
//#endregion
|
|
10456
|
+
//#region src/parser/node-parsers/container-token-handlers.ts
|
|
10457
|
+
const CONTAINER_REGEX = /^::: ?(warning|info|note|tip|danger|caution|error) ?(.*)$/;
|
|
10458
|
+
function handleContainerOpen(tokens, index, options) {
|
|
10459
|
+
const token = tokens[index];
|
|
10460
|
+
if (token.type !== "container_open") return null;
|
|
10461
|
+
const match = CONTAINER_REGEX.exec(String(token.info ?? ""));
|
|
10462
|
+
if (!match) return null;
|
|
10463
|
+
return parseAdmonition(tokens, index, match, options);
|
|
10464
|
+
}
|
|
10465
|
+
const containerTokenHandlers = {
|
|
10466
|
+
parseContainer: (tokens, index, options) => parseContainer(tokens, index, options),
|
|
10467
|
+
matchAdmonition: handleContainerOpen
|
|
10468
|
+
};
|
|
10469
|
+
|
|
10470
|
+
//#endregion
|
|
10471
|
+
//#region src/parser/node-parsers/blockquote-parser.ts
|
|
10472
|
+
function parseBlockquote(tokens, index, options) {
|
|
10473
|
+
const blockquoteChildren = [];
|
|
10474
|
+
let j = index + 1;
|
|
10475
|
+
while (j < tokens.length && tokens[j].type !== "blockquote_close") switch (tokens[j].type) {
|
|
10476
|
+
case "paragraph_open": {
|
|
10477
|
+
const contentToken = tokens[j + 1];
|
|
10478
|
+
blockquoteChildren.push({
|
|
10479
|
+
type: "paragraph",
|
|
10480
|
+
children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, {
|
|
10481
|
+
requireClosingStrong: options?.requireClosingStrong,
|
|
10482
|
+
customHtmlTags: options?.customHtmlTags
|
|
10483
|
+
}),
|
|
10484
|
+
raw: String(contentToken.content ?? "")
|
|
10485
|
+
});
|
|
10486
|
+
j += 3;
|
|
10487
|
+
break;
|
|
10488
|
+
}
|
|
10489
|
+
case "bullet_list_open":
|
|
10490
|
+
case "ordered_list_open": {
|
|
10491
|
+
const [listNode, newIndex] = parseList(tokens, j, options);
|
|
10492
|
+
blockquoteChildren.push(listNode);
|
|
10493
|
+
j = newIndex;
|
|
10494
|
+
break;
|
|
10495
|
+
}
|
|
10496
|
+
case "blockquote_open": {
|
|
10497
|
+
const [nestedBlockquote, newIndex] = parseBlockquote(tokens, j, options);
|
|
10498
|
+
blockquoteChildren.push(nestedBlockquote);
|
|
10499
|
+
j = newIndex;
|
|
10500
|
+
break;
|
|
10501
|
+
}
|
|
10502
|
+
default: {
|
|
10503
|
+
const handled = parseCommonBlockToken(tokens, j, options, containerTokenHandlers);
|
|
10504
|
+
if (handled) {
|
|
10505
|
+
blockquoteChildren.push(handled[0]);
|
|
10506
|
+
j = handled[1];
|
|
10507
|
+
} else j++;
|
|
10508
|
+
break;
|
|
10509
|
+
}
|
|
10510
|
+
}
|
|
10511
|
+
return [{
|
|
10512
|
+
type: "blockquote",
|
|
10513
|
+
children: blockquoteChildren,
|
|
10514
|
+
raw: blockquoteChildren.map((child) => child.raw).join("\n")
|
|
10515
|
+
}, j + 1];
|
|
10516
|
+
}
|
|
10517
|
+
|
|
10249
10518
|
//#endregion
|
|
10250
10519
|
//#region src/parser/node-parsers/code-block-parser.ts
|
|
10251
10520
|
function parseCodeBlock(token) {
|
|
@@ -10508,12 +10777,72 @@ function parseThematicBreak() {
|
|
|
10508
10777
|
|
|
10509
10778
|
//#endregion
|
|
10510
10779
|
//#region src/parser/node-parsers/block-token-parser.ts
|
|
10511
|
-
function
|
|
10512
|
-
|
|
10513
|
-
let
|
|
10514
|
-
|
|
10515
|
-
|
|
10516
|
-
if (
|
|
10780
|
+
function parseVmrContainer(tokens, index, options) {
|
|
10781
|
+
const attrs = tokens[index].attrs;
|
|
10782
|
+
let name = "";
|
|
10783
|
+
const containerAttrs = {};
|
|
10784
|
+
if (attrs) {
|
|
10785
|
+
for (const [key, value] of attrs) if (key === "class") {
|
|
10786
|
+
const match = value.match(/(?:\s|^)vmr-container-(\S+)/);
|
|
10787
|
+
if (match) name = match[1];
|
|
10788
|
+
} else if (key.startsWith("data-")) {
|
|
10789
|
+
const attrName = key.slice(5);
|
|
10790
|
+
containerAttrs[attrName] = value;
|
|
10791
|
+
}
|
|
10792
|
+
}
|
|
10793
|
+
const children = [];
|
|
10794
|
+
let j = index + 1;
|
|
10795
|
+
while (j < tokens.length && tokens[j].type !== "vmr_container_close") if (tokens[j].type === "paragraph_open") {
|
|
10796
|
+
const contentToken = tokens[j + 1];
|
|
10797
|
+
if (contentToken) {
|
|
10798
|
+
const childrenArr = contentToken.children || [];
|
|
10799
|
+
children.push({
|
|
10800
|
+
type: "paragraph",
|
|
10801
|
+
children: parseInlineTokens(childrenArr || [], void 0, void 0, {
|
|
10802
|
+
requireClosingStrong: options?.requireClosingStrong,
|
|
10803
|
+
customHtmlTags: options?.customHtmlTags
|
|
10804
|
+
}),
|
|
10805
|
+
raw: String(contentToken.content ?? "")
|
|
10806
|
+
});
|
|
10807
|
+
}
|
|
10808
|
+
j += 3;
|
|
10809
|
+
} else if (tokens[j].type === "bullet_list_open" || tokens[j].type === "ordered_list_open") {
|
|
10810
|
+
const [listNode, newIndex] = parseList(tokens, j, options);
|
|
10811
|
+
children.push(listNode);
|
|
10812
|
+
j = newIndex;
|
|
10813
|
+
} else if (tokens[j].type === "blockquote_open") {
|
|
10814
|
+
const [blockquoteNode, newIndex] = parseBlockquote(tokens, j, options);
|
|
10815
|
+
children.push(blockquoteNode);
|
|
10816
|
+
j = newIndex;
|
|
10817
|
+
} else {
|
|
10818
|
+
const handled = parseBasicBlockToken(tokens, j, options);
|
|
10819
|
+
if (handled) {
|
|
10820
|
+
children.push(handled[0]);
|
|
10821
|
+
j = handled[1];
|
|
10822
|
+
} else j++;
|
|
10823
|
+
}
|
|
10824
|
+
let raw = `::: ${name}`;
|
|
10825
|
+
if (Object.keys(containerAttrs).length > 0) raw += ` ${JSON.stringify(containerAttrs)}`;
|
|
10826
|
+
raw += "\n";
|
|
10827
|
+
if (children.length > 0) {
|
|
10828
|
+
raw += children.map((c) => c.raw).join("\n");
|
|
10829
|
+
raw += "\n";
|
|
10830
|
+
}
|
|
10831
|
+
raw += ":::";
|
|
10832
|
+
return [{
|
|
10833
|
+
type: "vmr_container",
|
|
10834
|
+
name,
|
|
10835
|
+
attrs: Object.keys(containerAttrs).length > 0 ? containerAttrs : void 0,
|
|
10836
|
+
children,
|
|
10837
|
+
raw
|
|
10838
|
+
}, j + 1];
|
|
10839
|
+
}
|
|
10840
|
+
function findTagCloseIndexOutsideQuotes(input) {
|
|
10841
|
+
let inSingle = false;
|
|
10842
|
+
let inDouble = false;
|
|
10843
|
+
for (let i = 0; i < input.length; i++) {
|
|
10844
|
+
const ch = input[i];
|
|
10845
|
+
if (ch === "\\") {
|
|
10517
10846
|
i++;
|
|
10518
10847
|
continue;
|
|
10519
10848
|
}
|
|
@@ -10683,254 +11012,12 @@ function parseCommonBlockToken(tokens, index, options, handlers) {
|
|
|
10683
11012
|
if (result) return result;
|
|
10684
11013
|
}
|
|
10685
11014
|
break;
|
|
11015
|
+
case "vmr_container_open": return parseVmrContainer(tokens, index, options);
|
|
10686
11016
|
default: break;
|
|
10687
11017
|
}
|
|
10688
11018
|
return null;
|
|
10689
11019
|
}
|
|
10690
11020
|
|
|
10691
|
-
//#endregion
|
|
10692
|
-
//#region src/parser/node-parsers/list-parser.ts
|
|
10693
|
-
function parseList(tokens, index, options) {
|
|
10694
|
-
const token = tokens[index];
|
|
10695
|
-
const listItems = [];
|
|
10696
|
-
let j = index + 1;
|
|
10697
|
-
while (j < tokens.length && tokens[j].type !== "bullet_list_close" && tokens[j].type !== "ordered_list_close") if (tokens[j].type === "list_item_open") {
|
|
10698
|
-
const itemChildren = [];
|
|
10699
|
-
let k = j + 1;
|
|
10700
|
-
while (k < tokens.length && tokens[k].type !== "list_item_close") if (tokens[k].type === "paragraph_open") {
|
|
10701
|
-
const contentToken = tokens[k + 1];
|
|
10702
|
-
const preToken = tokens[k - 1];
|
|
10703
|
-
const contentStr = String(contentToken.content ?? "");
|
|
10704
|
-
if (/\n\d+$/.test(contentStr)) {
|
|
10705
|
-
contentToken.content = contentStr.replace(/\n\d+$/, "");
|
|
10706
|
-
contentToken.children?.splice(-1, 1);
|
|
10707
|
-
}
|
|
10708
|
-
itemChildren.push({
|
|
10709
|
-
type: "paragraph",
|
|
10710
|
-
children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), preToken, {
|
|
10711
|
-
requireClosingStrong: options?.requireClosingStrong,
|
|
10712
|
-
customHtmlTags: options?.customHtmlTags
|
|
10713
|
-
}),
|
|
10714
|
-
raw: String(contentToken.content ?? "")
|
|
10715
|
-
});
|
|
10716
|
-
k += 3;
|
|
10717
|
-
} else if (tokens[k].type === "blockquote_open") {
|
|
10718
|
-
const [blockquoteNode, newIndex] = parseBlockquote(tokens, k, options);
|
|
10719
|
-
itemChildren.push(blockquoteNode);
|
|
10720
|
-
k = newIndex;
|
|
10721
|
-
} else if (tokens[k].type === "bullet_list_open" || tokens[k].type === "ordered_list_open") {
|
|
10722
|
-
const [nestedListNode, newIndex] = parseList(tokens, k, options);
|
|
10723
|
-
itemChildren.push(nestedListNode);
|
|
10724
|
-
k = newIndex;
|
|
10725
|
-
} else {
|
|
10726
|
-
const handled = parseCommonBlockToken(tokens, k, options, containerTokenHandlers);
|
|
10727
|
-
if (handled) {
|
|
10728
|
-
itemChildren.push(handled[0]);
|
|
10729
|
-
k = handled[1];
|
|
10730
|
-
} else k += 1;
|
|
10731
|
-
}
|
|
10732
|
-
listItems.push({
|
|
10733
|
-
type: "list_item",
|
|
10734
|
-
children: itemChildren,
|
|
10735
|
-
raw: itemChildren.map((child) => child.raw).join("")
|
|
10736
|
-
});
|
|
10737
|
-
j = k + 1;
|
|
10738
|
-
} else j += 1;
|
|
10739
|
-
return [{
|
|
10740
|
-
type: "list",
|
|
10741
|
-
ordered: token.type === "ordered_list_open",
|
|
10742
|
-
start: (() => {
|
|
10743
|
-
if (token.attrs && token.attrs.length) {
|
|
10744
|
-
const found = token.attrs.find((a) => a[0] === "start");
|
|
10745
|
-
if (found) {
|
|
10746
|
-
const parsed = Number(found[1]);
|
|
10747
|
-
return Number.isFinite(parsed) && parsed !== 0 ? parsed : 1;
|
|
10748
|
-
}
|
|
10749
|
-
}
|
|
10750
|
-
})(),
|
|
10751
|
-
items: listItems,
|
|
10752
|
-
raw: listItems.map((item) => item.raw).join("\n")
|
|
10753
|
-
}, j + 1];
|
|
10754
|
-
}
|
|
10755
|
-
|
|
10756
|
-
//#endregion
|
|
10757
|
-
//#region src/parser/node-parsers/admonition-parser.ts
|
|
10758
|
-
function parseAdmonition(tokens, index, match, options) {
|
|
10759
|
-
const kind = String(match[1] ?? "note");
|
|
10760
|
-
const title = String(match[2] ?? kind.charAt(0).toUpperCase() + kind.slice(1));
|
|
10761
|
-
const admonitionChildren = [];
|
|
10762
|
-
let j = index + 1;
|
|
10763
|
-
while (j < tokens.length && tokens[j].type !== "container_close") if (tokens[j].type === "paragraph_open") {
|
|
10764
|
-
const contentToken = tokens[j + 1];
|
|
10765
|
-
if (contentToken) admonitionChildren.push({
|
|
10766
|
-
type: "paragraph",
|
|
10767
|
-
children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, {
|
|
10768
|
-
requireClosingStrong: options?.requireClosingStrong,
|
|
10769
|
-
customHtmlTags: options?.customHtmlTags
|
|
10770
|
-
}),
|
|
10771
|
-
raw: String(contentToken.content ?? "")
|
|
10772
|
-
});
|
|
10773
|
-
j += 3;
|
|
10774
|
-
} else if (tokens[j].type === "bullet_list_open" || tokens[j].type === "ordered_list_open") {
|
|
10775
|
-
const [listNode, newIndex] = parseList(tokens, j, options);
|
|
10776
|
-
admonitionChildren.push(listNode);
|
|
10777
|
-
j = newIndex;
|
|
10778
|
-
} else if (tokens[j].type === "blockquote_open") {
|
|
10779
|
-
const [blockquoteNode, newIndex] = parseBlockquote(tokens, j, options);
|
|
10780
|
-
admonitionChildren.push(blockquoteNode);
|
|
10781
|
-
j = newIndex;
|
|
10782
|
-
} else {
|
|
10783
|
-
const handled = parseBasicBlockToken(tokens, j, options);
|
|
10784
|
-
if (handled) {
|
|
10785
|
-
admonitionChildren.push(handled[0]);
|
|
10786
|
-
j = handled[1];
|
|
10787
|
-
} else j++;
|
|
10788
|
-
}
|
|
10789
|
-
return [{
|
|
10790
|
-
type: "admonition",
|
|
10791
|
-
kind,
|
|
10792
|
-
title,
|
|
10793
|
-
children: admonitionChildren,
|
|
10794
|
-
raw: `:::${kind} ${title}\n${admonitionChildren.map((child) => child.raw).join("\n")}\n:::`
|
|
10795
|
-
}, j + 1];
|
|
10796
|
-
}
|
|
10797
|
-
|
|
10798
|
-
//#endregion
|
|
10799
|
-
//#region src/parser/node-parsers/container-parser.ts
|
|
10800
|
-
function parseContainer(tokens, index, options) {
|
|
10801
|
-
const openToken = tokens[index];
|
|
10802
|
-
let kind = "note";
|
|
10803
|
-
let title = "";
|
|
10804
|
-
const typeMatch = openToken.type.match(/^container_(\w+)_open$/);
|
|
10805
|
-
if (typeMatch) {
|
|
10806
|
-
kind = typeMatch[1];
|
|
10807
|
-
const info = String(openToken.info ?? "").trim();
|
|
10808
|
-
if (info && !info.startsWith(":::")) {
|
|
10809
|
-
const maybe = info.replace(/* @__PURE__ */ new RegExp(`^${kind}`), "").trim();
|
|
10810
|
-
if (maybe) title = maybe;
|
|
10811
|
-
}
|
|
10812
|
-
} else {
|
|
10813
|
-
const info = String(openToken.info ?? "").trim();
|
|
10814
|
-
const match = /^:{1,3}\s*(warning|info|note|tip|danger|caution)\s*(.*)$/i.exec(info);
|
|
10815
|
-
if (match) {
|
|
10816
|
-
kind = match[1];
|
|
10817
|
-
title = String(match[2] ?? "");
|
|
10818
|
-
}
|
|
10819
|
-
}
|
|
10820
|
-
if (!title) title = kind.charAt(0).toUpperCase() + kind.slice(1);
|
|
10821
|
-
const children = [];
|
|
10822
|
-
let j = index + 1;
|
|
10823
|
-
const closeType = /* @__PURE__ */ new RegExp(`^container_${kind}_close$`);
|
|
10824
|
-
while (j < tokens.length && tokens[j].type !== "container_close" && !closeType.test(tokens[j].type)) if (tokens[j].type === "paragraph_open") {
|
|
10825
|
-
const contentToken = tokens[j + 1];
|
|
10826
|
-
if (contentToken) {
|
|
10827
|
-
const childrenArr = contentToken.children || [];
|
|
10828
|
-
let i = -1;
|
|
10829
|
-
for (let k = childrenArr.length - 1; k >= 0; k--) {
|
|
10830
|
-
const t = childrenArr[k];
|
|
10831
|
-
if (t.type === "text" && /:+/.test(t.content)) {
|
|
10832
|
-
i = k;
|
|
10833
|
-
break;
|
|
10834
|
-
}
|
|
10835
|
-
}
|
|
10836
|
-
const _children = i !== -1 ? childrenArr.slice(0, i) : childrenArr;
|
|
10837
|
-
children.push({
|
|
10838
|
-
type: "paragraph",
|
|
10839
|
-
children: parseInlineTokens(_children || [], void 0, void 0, {
|
|
10840
|
-
requireClosingStrong: options?.requireClosingStrong,
|
|
10841
|
-
customHtmlTags: options?.customHtmlTags
|
|
10842
|
-
}),
|
|
10843
|
-
raw: String(contentToken.content ?? "").replace(/\n:+$/, "").replace(/\n\s*:::\s*$/, "")
|
|
10844
|
-
});
|
|
10845
|
-
}
|
|
10846
|
-
j += 3;
|
|
10847
|
-
} else if (tokens[j].type === "bullet_list_open" || tokens[j].type === "ordered_list_open") {
|
|
10848
|
-
const [listNode, newIndex] = parseList(tokens, j, options);
|
|
10849
|
-
children.push(listNode);
|
|
10850
|
-
j = newIndex;
|
|
10851
|
-
} else if (tokens[j].type === "blockquote_open") {
|
|
10852
|
-
const [blockquoteNode, newIndex] = parseBlockquote(tokens, j, options);
|
|
10853
|
-
children.push(blockquoteNode);
|
|
10854
|
-
j = newIndex;
|
|
10855
|
-
} else {
|
|
10856
|
-
const handled = parseBasicBlockToken(tokens, j, options);
|
|
10857
|
-
if (handled) {
|
|
10858
|
-
children.push(handled[0]);
|
|
10859
|
-
j = handled[1];
|
|
10860
|
-
} else j++;
|
|
10861
|
-
}
|
|
10862
|
-
return [{
|
|
10863
|
-
type: "admonition",
|
|
10864
|
-
kind,
|
|
10865
|
-
title,
|
|
10866
|
-
children,
|
|
10867
|
-
raw: `:::${kind} ${title}\n${children.map((c) => c.raw).join("\n")}\n:::`
|
|
10868
|
-
}, j + 1];
|
|
10869
|
-
}
|
|
10870
|
-
|
|
10871
|
-
//#endregion
|
|
10872
|
-
//#region src/parser/node-parsers/container-token-handlers.ts
|
|
10873
|
-
const CONTAINER_REGEX = /^::: ?(warning|info|note|tip|danger|caution|error) ?(.*)$/;
|
|
10874
|
-
function handleContainerOpen(tokens, index, options) {
|
|
10875
|
-
const token = tokens[index];
|
|
10876
|
-
if (token.type !== "container_open") return null;
|
|
10877
|
-
const match = CONTAINER_REGEX.exec(String(token.info ?? ""));
|
|
10878
|
-
if (!match) return null;
|
|
10879
|
-
return parseAdmonition(tokens, index, match, options);
|
|
10880
|
-
}
|
|
10881
|
-
const containerTokenHandlers = {
|
|
10882
|
-
parseContainer: (tokens, index, options) => parseContainer(tokens, index, options),
|
|
10883
|
-
matchAdmonition: handleContainerOpen
|
|
10884
|
-
};
|
|
10885
|
-
|
|
10886
|
-
//#endregion
|
|
10887
|
-
//#region src/parser/node-parsers/blockquote-parser.ts
|
|
10888
|
-
function parseBlockquote(tokens, index, options) {
|
|
10889
|
-
const blockquoteChildren = [];
|
|
10890
|
-
let j = index + 1;
|
|
10891
|
-
while (j < tokens.length && tokens[j].type !== "blockquote_close") switch (tokens[j].type) {
|
|
10892
|
-
case "paragraph_open": {
|
|
10893
|
-
const contentToken = tokens[j + 1];
|
|
10894
|
-
blockquoteChildren.push({
|
|
10895
|
-
type: "paragraph",
|
|
10896
|
-
children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, {
|
|
10897
|
-
requireClosingStrong: options?.requireClosingStrong,
|
|
10898
|
-
customHtmlTags: options?.customHtmlTags
|
|
10899
|
-
}),
|
|
10900
|
-
raw: String(contentToken.content ?? "")
|
|
10901
|
-
});
|
|
10902
|
-
j += 3;
|
|
10903
|
-
break;
|
|
10904
|
-
}
|
|
10905
|
-
case "bullet_list_open":
|
|
10906
|
-
case "ordered_list_open": {
|
|
10907
|
-
const [listNode, newIndex] = parseList(tokens, j, options);
|
|
10908
|
-
blockquoteChildren.push(listNode);
|
|
10909
|
-
j = newIndex;
|
|
10910
|
-
break;
|
|
10911
|
-
}
|
|
10912
|
-
case "blockquote_open": {
|
|
10913
|
-
const [nestedBlockquote, newIndex] = parseBlockquote(tokens, j, options);
|
|
10914
|
-
blockquoteChildren.push(nestedBlockquote);
|
|
10915
|
-
j = newIndex;
|
|
10916
|
-
break;
|
|
10917
|
-
}
|
|
10918
|
-
default: {
|
|
10919
|
-
const handled = parseCommonBlockToken(tokens, j, options, containerTokenHandlers);
|
|
10920
|
-
if (handled) {
|
|
10921
|
-
blockquoteChildren.push(handled[0]);
|
|
10922
|
-
j = handled[1];
|
|
10923
|
-
} else j++;
|
|
10924
|
-
break;
|
|
10925
|
-
}
|
|
10926
|
-
}
|
|
10927
|
-
return [{
|
|
10928
|
-
type: "blockquote",
|
|
10929
|
-
children: blockquoteChildren,
|
|
10930
|
-
raw: blockquoteChildren.map((child) => child.raw).join("\n")
|
|
10931
|
-
}, j + 1];
|
|
10932
|
-
}
|
|
10933
|
-
|
|
10934
11021
|
//#endregion
|
|
10935
11022
|
//#region src/parser/node-parsers/hardbreak-parser.ts
|
|
10936
11023
|
function parseHardBreak() {
|