stream-markdown-parser 0.0.7 → 0.0.8

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.js CHANGED
@@ -36,40 +36,41 @@ function applyContainers(md) {
36
36
  } });
37
37
  });
38
38
  md.block.ruler.before("fence", "vmr_container_fallback", (state, startLine, endLine, silent) => {
39
- const startPos = state.bMarks[startLine] + state.tShift[startLine];
40
- const lineMax = state.eMarks[startLine];
41
- const markerMatch = state.src.slice(startPos, lineMax).match(/^:::\s*(\w+)/);
39
+ const s = state;
40
+ const startPos = s.bMarks[startLine] + s.tShift[startLine];
41
+ const lineMax = s.eMarks[startLine];
42
+ const markerMatch = s.src.slice(startPos, lineMax).match(/^:::\s*(\w+)/);
42
43
  if (!markerMatch) return false;
43
44
  if (silent) return true;
44
45
  const name = markerMatch[1];
45
46
  let nextLine = startLine + 1;
46
47
  let found = false;
47
48
  while (nextLine <= endLine) {
48
- const sPos = state.bMarks[nextLine] + state.tShift[nextLine];
49
- const ePos = state.eMarks[nextLine];
50
- if (state.src.slice(sPos, ePos).trim() === ":::") {
49
+ const sPos = s.bMarks[nextLine] + s.tShift[nextLine];
50
+ const ePos = s.eMarks[nextLine];
51
+ if (s.src.slice(sPos, ePos).trim() === ":::") {
51
52
  found = true;
52
53
  break;
53
54
  }
54
55
  nextLine++;
55
56
  }
56
57
  if (!found) return false;
57
- state.push("vmr_container_open", "div", 1).attrSet("class", `vmr-container vmr-container-${name}`);
58
+ s.push("vmr_container_open", "div", 1).attrSet("class", `vmr-container vmr-container-${name}`);
58
59
  const contentLines = [];
59
60
  for (let i = startLine + 1; i < nextLine; i++) {
60
- const sPos = state.bMarks[i] + state.tShift[i];
61
- const ePos = state.eMarks[i];
62
- contentLines.push(state.src.slice(sPos, ePos));
61
+ const sPos = s.bMarks[i] + s.tShift[i];
62
+ const ePos = s.eMarks[i];
63
+ contentLines.push(s.src.slice(sPos, ePos));
63
64
  }
64
- state.push("paragraph_open", "p", 1);
65
- const inlineToken = state.push("inline", "", 0);
65
+ s.push("paragraph_open", "p", 1);
66
+ const inlineToken = s.push("inline", "", 0);
66
67
  inlineToken.content = contentLines.join("\n");
67
68
  inlineToken.map = [startLine + 1, nextLine];
68
69
  inlineToken.children = [];
69
- state.md.inline.parse(inlineToken.content, state.md, state.env, inlineToken.children);
70
- state.push("paragraph_close", "p", -1);
71
- state.push("vmr_container_close", "div", -1);
72
- state.line = nextLine + 1;
70
+ s.md.inline.parse(inlineToken.content, s.md, s.env, inlineToken.children);
71
+ s.push("paragraph_close", "p", -1);
72
+ s.push("vmr_container_close", "div", -1);
73
+ s.line = nextLine + 1;
73
74
  return true;
74
75
  });
75
76
  }
@@ -278,7 +279,8 @@ function normalizeStandaloneBackslashT(s, opts) {
278
279
  }
279
280
  function applyMath(md, mathOpts) {
280
281
  const mathInline = (state, silent) => {
281
- if (/^\*[^*]+/.test(state.src)) return false;
282
+ const s = state;
283
+ if (/^\*[^*]+/.test(s.src)) return false;
282
284
  const delimiters = [
283
285
  ["$$", "$$"],
284
286
  ["\\(", "\\)"],
@@ -287,28 +289,28 @@ function applyMath(md, mathOpts) {
287
289
  let searchPos = 0;
288
290
  let preMathPos = 0;
289
291
  for (const [open, close] of delimiters) {
290
- const src = state.src;
292
+ const src = s.src;
291
293
  let foundAny = false;
292
294
  const pushText = (text) => {
293
295
  if (text === "undefined" || text == null) text = "";
294
296
  if (text === "\\") {
295
- state.pos = state.pos + text.length;
296
- searchPos = state.pos;
297
+ s.pos = s.pos + text.length;
298
+ searchPos = s.pos;
297
299
  return;
298
300
  }
299
301
  if (text === "\\)" || text === "\\(") {
300
- const t$1 = state.push("text_special", "", 0);
302
+ const t$1 = s.push("text_special", "", 0);
301
303
  t$1.content = text === "\\)" ? ")" : "(";
302
304
  t$1.markup = text;
303
- state.pos = state.pos + text.length;
304
- searchPos = state.pos;
305
+ s.pos = s.pos + text.length;
306
+ searchPos = s.pos;
305
307
  return;
306
308
  }
307
309
  if (!text) return;
308
- const t = state.push("text", "", 0);
310
+ const t = s.push("text", "", 0);
309
311
  t.content = text;
310
- state.pos = state.pos + text.length;
311
- searchPos = state.pos;
312
+ s.pos = s.pos + text.length;
313
+ searchPos = s.pos;
312
314
  };
313
315
  while (true) {
314
316
  if (searchPos >= src.length) break;
@@ -326,28 +328,28 @@ function applyMath(md, mathOpts) {
326
328
  searchPos = index + open.length;
327
329
  foundAny = true;
328
330
  if (!silent) {
329
- state.pending = "";
331
+ s.pending = "";
330
332
  const isStrongPrefix = countUnescapedStrong(preMathPos ? src.slice(preMathPos, searchPos) : src.slice(0, searchPos)) % 2 === 1;
331
333
  if (preMathPos) pushText(src.slice(preMathPos, searchPos));
332
334
  else pushText(src.slice(0, searchPos));
333
335
  if (isStrongPrefix) {
334
- const strongToken = state.push("strong_open", "", 0);
336
+ const strongToken = s.push("strong_open", "", 0);
335
337
  strongToken.markup = src.slice(0, index + 2);
336
- const token = state.push("math_inline", "math", 0);
338
+ const token = s.push("math_inline", "math", 0);
337
339
  token.content = normalizeStandaloneBackslashT(content$1, mathOpts);
338
340
  token.markup = open === "$$" ? "$$" : open === "\\(" ? "\\(\\)" : open === "$" ? "$" : "()";
339
341
  token.raw = `${open}${content$1}${close}`;
340
342
  token.loading = true;
341
343
  strongToken.content = content$1;
342
- state.push("strong_close", "", 0);
344
+ s.push("strong_close", "", 0);
343
345
  } else {
344
- const token = state.push("math_inline", "math", 0);
346
+ const token = s.push("math_inline", "math", 0);
345
347
  token.content = normalizeStandaloneBackslashT(content$1, mathOpts);
346
348
  token.markup = open === "$$" ? "$$" : open === "\\(" ? "\\(\\)" : open === "$" ? "$" : "()";
347
349
  token.raw = `${open}${content$1}${close}`;
348
350
  token.loading = true;
349
351
  }
350
- state.pos = src.length;
352
+ s.pos = src.length;
351
353
  }
352
354
  searchPos = src.length;
353
355
  preMathPos = searchPos;
@@ -357,8 +359,8 @@ function applyMath(md, mathOpts) {
357
359
  const content = src.slice(index + open.length, endIdx);
358
360
  if (!isMathLike(content)) {
359
361
  searchPos = endIdx + close.length;
360
- const text = src.slice(state.pos, searchPos);
361
- if (!state.pending) pushText(text);
362
+ const text = src.slice(s.pos, searchPos);
363
+ if (!s.pending) pushText(text);
362
364
  continue;
363
365
  }
364
366
  foundAny = true;
@@ -366,42 +368,42 @@ function applyMath(md, mathOpts) {
366
368
  const before = src.slice(0, index);
367
369
  let toPushBefore = src.slice(0, searchPos) ? src.slice(preMathPos, index) : before;
368
370
  const isStrongPrefix = countUnescapedStrong(toPushBefore) % 2 === 1;
369
- if (index !== state.pos && isStrongPrefix) toPushBefore = state.pending + src.slice(state.pos, index);
370
- if (state.pending !== toPushBefore) {
371
- state.pending = "";
371
+ if (index !== s.pos && isStrongPrefix) toPushBefore = s.pending + src.slice(s.pos, index);
372
+ if (s.pending !== toPushBefore) {
373
+ s.pending = "";
372
374
  if (isStrongPrefix) {
373
375
  const _match = toPushBefore.match(/(\*+)/);
374
376
  const after = toPushBefore.slice(_match.index + _match[0].length);
375
377
  pushText(toPushBefore.slice(0, _match.index));
376
- const strongToken = state.push("strong_open", "", 0);
378
+ const strongToken = s.push("strong_open", "", 0);
377
379
  strongToken.markup = _match[0];
378
- const textToken = state.push("text", "", 0);
380
+ const textToken = s.push("text", "", 0);
379
381
  textToken.content = after;
380
- state.push("strong_close", "", 0);
382
+ s.push("strong_close", "", 0);
381
383
  } else pushText(toPushBefore);
382
384
  }
383
385
  if (isStrongPrefix) {
384
- const strongToken = state.push("strong_open", "", 0);
386
+ const strongToken = s.push("strong_open", "", 0);
385
387
  strongToken.markup = "**";
386
- const token = state.push("math_inline", "math", 0);
388
+ const token = s.push("math_inline", "math", 0);
387
389
  token.content = normalizeStandaloneBackslashT(content, mathOpts);
388
390
  token.markup = open === "$$" ? "$$" : open === "\\(" ? "\\(\\)" : open === "$" ? "$" : "()";
389
391
  token.raw = `${open}${content}${close}`;
390
392
  token.loading = false;
391
393
  const raw = src.slice(endIdx + close.length);
392
394
  const isBeforeClose = raw.startsWith("*");
393
- if (isBeforeClose) state.push("strong_close", "", 0);
395
+ if (isBeforeClose) s.push("strong_close", "", 0);
394
396
  if (raw) {
395
- const textContentToken = state.push("text", "", 0);
397
+ const textContentToken = s.push("text", "", 0);
396
398
  textContentToken.content = (raw == null ? "" : String(raw)).replace(/^\*+/, "");
397
399
  }
398
- if (!isBeforeClose) state.push("strong_close", "", 0);
399
- state.pos = src.length;
400
+ if (!isBeforeClose) s.push("strong_close", "", 0);
401
+ s.pos = src.length;
400
402
  searchPos = src.length;
401
403
  preMathPos = searchPos;
402
404
  continue;
403
405
  } else {
404
- const token = state.push("math_inline", "math", 0);
406
+ const token = s.push("math_inline", "math", 0);
405
407
  token.content = normalizeStandaloneBackslashT(content, mathOpts);
406
408
  token.markup = open === "$$" ? "$$" : open === "\\(" ? "\\(\\)" : open === "$" ? "$" : "()";
407
409
  token.raw = `${open}${content}${close}`;
@@ -410,26 +412,27 @@ function applyMath(md, mathOpts) {
410
412
  }
411
413
  searchPos = endIdx + close.length;
412
414
  preMathPos = searchPos;
413
- state.pos = searchPos;
415
+ s.pos = searchPos;
414
416
  }
415
417
  if (foundAny) {
416
418
  if (!silent) {
417
419
  if (searchPos < src.length) pushText(src.slice(searchPos));
418
- state.pos = src.length;
419
- } else state.pos = searchPos;
420
+ s.pos = src.length;
421
+ } else s.pos = searchPos;
420
422
  return true;
421
423
  }
422
424
  }
423
425
  return false;
424
426
  };
425
427
  const mathBlock = (state, startLine, endLine, silent) => {
428
+ const s = state;
426
429
  const delimiters = [
427
430
  ["\\[", "\\]"],
428
431
  ["[", "]"],
429
432
  ["$$", "$$"]
430
433
  ];
431
- const startPos = state.bMarks[startLine] + state.tShift[startLine];
432
- const lineText = state.src.slice(startPos, state.eMarks[startLine]).trim();
434
+ const startPos = s.bMarks[startLine] + s.tShift[startLine];
435
+ const lineText = s.src.slice(startPos, s.eMarks[startLine]).trim();
433
436
  let matched = false;
434
437
  let openDelim = "";
435
438
  let closeDelim = "";
@@ -455,14 +458,14 @@ function applyMath(md, mathOpts) {
455
458
  const startDelimIndex = lineText.indexOf(openDelim);
456
459
  const endDelimIndex = lineText.indexOf(closeDelim, startDelimIndex + openDelim.length);
457
460
  const content$1 = lineText.slice(startDelimIndex + openDelim.length, endDelimIndex);
458
- const token$1 = state.push("math_block", "math", 0);
461
+ const token$1 = s.push("math_block", "math", 0);
459
462
  token$1.content = normalizeStandaloneBackslashT(content$1);
460
463
  token$1.markup = openDelim === "$$" ? "$$" : openDelim === "[" ? "[]" : "\\[\\]";
461
464
  token$1.map = [startLine, startLine + 1];
462
465
  token$1.raw = `${openDelim}${content$1}${closeDelim}`;
463
466
  token$1.block = true;
464
467
  token$1.loading = false;
465
- state.line = startLine + 1;
468
+ s.line = startLine + 1;
466
469
  return true;
467
470
  }
468
471
  let nextLine = startLine;
@@ -477,9 +480,9 @@ function applyMath(md, mathOpts) {
477
480
  } else {
478
481
  if (firstLineContent) content = firstLineContent;
479
482
  for (nextLine = startLine + 1; nextLine < endLine; nextLine++) {
480
- const lineStart = state.bMarks[nextLine] + state.tShift[nextLine];
481
- const lineEnd = state.eMarks[nextLine];
482
- const currentLine = state.src.slice(lineStart - 1, lineEnd);
483
+ const lineStart = s.bMarks[nextLine] + s.tShift[nextLine];
484
+ const lineEnd = s.eMarks[nextLine];
485
+ const currentLine = s.src.slice(lineStart - 1, lineEnd);
483
486
  if (currentLine.trim() === closeDelim) {
484
487
  found = true;
485
488
  break;
@@ -492,14 +495,14 @@ function applyMath(md, mathOpts) {
492
495
  content += (content ? "\n" : "") + currentLine;
493
496
  }
494
497
  }
495
- const token = state.push("math_block", "math", 0);
498
+ const token = s.push("math_block", "math", 0);
496
499
  token.content = normalizeStandaloneBackslashT(content);
497
500
  token.markup = openDelim === "$$" ? "$$" : openDelim === "[" ? "[]" : "\\[\\]";
498
501
  token.raw = `${openDelim}${content}${content.startsWith("\n") ? "\n" : ""}${closeDelim}`;
499
502
  token.map = [startLine, nextLine + 1];
500
503
  token.block = true;
501
504
  token.loading = !found;
502
- state.line = nextLine + 1;
505
+ s.line = nextLine + 1;
503
506
  return true;
504
507
  };
505
508
  md.inline.ruler.before("escape", "math", mathInline);
@@ -515,16 +518,19 @@ function applyMath(md, mathOpts) {
515
518
  //#region src/renderers/index.ts
516
519
  function applyRenderRules(md) {
517
520
  const defaultImage = md.renderer.rules.image || function(tokens, idx, options, env, self) {
518
- return self.renderToken(tokens, idx, options);
521
+ const tokensAny = tokens;
522
+ const selfShape = self;
523
+ return selfShape.renderToken ? selfShape.renderToken(tokensAny, idx, options) : "";
519
524
  };
520
525
  md.renderer.rules.image = (tokens, idx, options, env, self) => {
521
- tokens[idx].attrSet?.("loading", "lazy");
522
- return defaultImage(tokens, idx, options, env, self);
526
+ const tokensAny = tokens;
527
+ tokensAny[idx].attrSet?.("loading", "lazy");
528
+ return defaultImage(tokensAny, idx, options, env, self);
523
529
  };
524
530
  md.renderer.rules.fence = md.renderer.rules.fence || ((tokens, idx) => {
525
- const token = tokens[idx];
526
- const info = token.info ? token.info.trim() : "";
527
- return `<pre class="${info ? `language-${md.utils.escapeHtml(info.split(/\s+/g)[0])}` : ""}"><code>${md.utils.escapeHtml(token.content)}</code></pre>`;
531
+ const tokenShape = tokens[idx];
532
+ const info = String(tokenShape.info ?? "").trim();
533
+ return `<pre class="${info ? `language-${md.utils.escapeHtml(info.split(/\s+/g)[0])}` : ""}"><code>${md.utils.escapeHtml(String(tokenShape.content ?? ""))}</code></pre>`;
528
534
  });
529
535
  }
530
536
 
@@ -654,24 +660,26 @@ function fixTableTokens(tokens) {
654
660
  const i = tokens.length - 2;
655
661
  const token = tokens[i];
656
662
  if (token.type === "inline") {
657
- if (/^\|(?:[^|\n]+\|?)+/.test(token.content)) {
658
- const body = token.children[0].content.slice(1).split("|").map((i$1) => i$1.trim()).filter(Boolean).flatMap((i$1) => createTh(i$1));
663
+ const tcontent = String(token.content ?? "");
664
+ const childContent = String(token.children?.[0]?.content ?? "");
665
+ if (/^\|(?:[^|\n]+\|?)+/.test(tcontent)) {
666
+ const body = childContent.slice(1).split("|").map((i$1) => i$1.trim()).filter(Boolean).flatMap((i$1) => createTh(i$1));
659
667
  const insert = [
660
668
  ...createStart(),
661
669
  ...body,
662
670
  ...createEnd()
663
671
  ];
664
672
  fixedTokens.splice(i - 1, 3, ...insert);
665
- } else if (/^\|(?:[^|\n]+\|)+\n\|:?-/.test(token.content)) {
666
- const body = token.children[0].content.slice(1, -1).split("|").map((i$1) => i$1.trim()).flatMap((i$1) => createTh(i$1));
673
+ } else if (/^\|(?:[^|\n]+\|)+\n\|:?-/.test(tcontent)) {
674
+ const body = childContent.slice(1, -1).split("|").map((i$1) => i$1.trim()).flatMap((i$1) => createTh(i$1));
667
675
  const insert = [
668
676
  ...createStart(),
669
677
  ...body,
670
678
  ...createEnd()
671
679
  ];
672
680
  fixedTokens.splice(i - 1, 3, ...insert);
673
- } else if (/^\|(?:[^|\n:]+\|)+\n\|:?$/.test(token.content)) {
674
- token.content = token.content.slice(0, -2);
681
+ } else if (/^\|(?:[^|\n:]+\|)+\n\|:?$/.test(tcontent)) {
682
+ token.content = tcontent.slice(0, -2);
675
683
  token.children.splice(2, 1);
676
684
  }
677
685
  }
@@ -681,28 +689,33 @@ function fixTableTokens(tokens) {
681
689
  //#endregion
682
690
  //#region src/parser/inline-parsers/checkbox-parser.ts
683
691
  function parseCheckboxToken(token) {
692
+ const tokenMeta = token.meta ?? {};
684
693
  return {
685
694
  type: "checkbox",
686
- checked: token.meta?.checked === true,
687
- raw: token.meta?.checked ? "[x]" : "[ ]"
695
+ checked: tokenMeta.checked === true,
696
+ raw: tokenMeta.checked ? "[x]" : "[ ]"
688
697
  };
689
698
  }
690
699
  function parseCheckboxInputToken(token) {
700
+ const tokenAny = token;
701
+ const rawAttr = tokenAny.attrGet ? tokenAny.attrGet("checked") : void 0;
702
+ const checked = rawAttr === "" || rawAttr === "true";
691
703
  return {
692
704
  type: "checkbox_input",
693
- checked: token.attrGet("checked") === "" || token.attrGet("checked") === "true",
694
- raw: token.attrGet("checked") === "" || token.attrGet("checked") === "true" ? "[x]" : "[ ]"
705
+ checked,
706
+ raw: checked ? "[x]" : "[ ]"
695
707
  };
696
708
  }
697
709
 
698
710
  //#endregion
699
711
  //#region src/parser/inline-parsers/emoji-parser.ts
700
712
  function parseEmojiToken(token) {
713
+ const name = String(token.content ?? "");
701
714
  return {
702
715
  type: "emoji",
703
- name: token.content || "",
704
- markup: token.markup || "",
705
- raw: `:${token.content || ""}:`
716
+ name,
717
+ markup: String(token.markup ?? ""),
718
+ raw: `:${name}:`
706
719
  };
707
720
  }
708
721
 
@@ -714,7 +727,7 @@ function parseEmphasisToken(tokens, startIndex) {
714
727
  let i = startIndex + 1;
715
728
  const innerTokens = [];
716
729
  while (i < tokens.length && tokens[i].type !== "em_close") {
717
- emText += tokens[i].content || "";
730
+ emText += String(tokens[i].content ?? "");
718
731
  innerTokens.push(tokens[i]);
719
732
  i++;
720
733
  }
@@ -751,11 +764,12 @@ function splitUnifiedDiff(content) {
751
764
  }
752
765
  function parseFenceToken(token) {
753
766
  const hasMap = Array.isArray(token.map) && token.map.length === 2;
754
- const meta = token.meta;
755
- const closed = typeof meta?.closed === "boolean" ? meta.closed : void 0;
756
- const diff = token.info?.startsWith("diff") || false;
757
- const language = diff ? token.info?.split(" ")[1] || "" : token.info || "";
758
- let content = token.content || "";
767
+ const tokenMeta = token.meta ?? {};
768
+ const closed = typeof tokenMeta.closed === "boolean" ? tokenMeta.closed : void 0;
769
+ const info = String(token.info ?? "");
770
+ const diff = info.startsWith("diff");
771
+ const language = diff ? String(info.split(" ")[1] ?? "") : info;
772
+ let content = String(token.content ?? "");
759
773
  const trailingFenceLine = /\r?\n[ \t]*`+\s*$/;
760
774
  if (trailingFenceLine.test(content)) content = content.replace(trailingFenceLine, "");
761
775
  if (diff) {
@@ -763,8 +777,8 @@ function parseFenceToken(token) {
763
777
  return {
764
778
  type: "code_block",
765
779
  language,
766
- code: updated || "",
767
- raw: content,
780
+ code: String(updated ?? ""),
781
+ raw: String(content ?? ""),
768
782
  diff,
769
783
  loading: closed === true ? false : closed === false ? true : !hasMap,
770
784
  originalCode: original,
@@ -774,8 +788,8 @@ function parseFenceToken(token) {
774
788
  return {
775
789
  type: "code_block",
776
790
  language,
777
- code: content || "",
778
- raw: content || "",
791
+ code: String(content ?? ""),
792
+ raw: String(content ?? ""),
779
793
  diff,
780
794
  loading: closed === true ? false : closed === false ? true : !hasMap
781
795
  };
@@ -787,26 +801,31 @@ function isTextToken(t) {
787
801
  return !!t && t.type === "text" && typeof t.content === "string";
788
802
  }
789
803
  function fixLinkToken(tokens) {
804
+ const tokensAny = tokens;
790
805
  tokens = fixLinkToken4(fixLinkToken3(tokens));
791
806
  if (tokens.length < 5) return tokens;
792
807
  const first = tokens[tokens.length - 5];
793
- if (first.type !== "text" || !first.content?.endsWith("[")) return fixLinkTokens2(tokens);
808
+ const firstAny = first;
809
+ const firstContent = String(firstAny.content ?? "");
810
+ if (first.type !== "text" || !firstContent.endsWith("[")) return fixLinkTokens2(tokens);
794
811
  if (tokens[tokens.length - 4].tag !== "em") return fixLinkTokens2(tokens);
795
812
  const last = tokens[tokens.length - 1];
796
- if (last?.type === "text" && !last.content?.startsWith("]")) return fixLinkTokens2(tokens);
797
- const third = tokens[tokens.length - 3];
798
- const lastContent = last.content ?? "";
813
+ const lastAny = last;
814
+ const lastContent = String(lastAny.content ?? "");
815
+ if (last?.type === "text" && !lastContent.startsWith("]")) return fixLinkTokens2(tokens);
816
+ const thirdAny = tokens[tokens.length - 3];
817
+ const thirdContent = String(thirdAny.content ?? "");
799
818
  const href = lastContent.replace(/^\]\(*/, "");
800
819
  const loading = !lastContent.includes(")");
801
- first.content = first.content?.replace(/\[$/, "");
820
+ tokensAny[tokens.length - 5].content = firstContent.replace(/\[$/, "");
802
821
  tokens.splice(tokens.length - 3, 1, {
803
822
  type: "link",
804
823
  href,
805
- text: third.content,
824
+ text: thirdContent,
806
825
  children: [{
807
826
  type: "text",
808
- content: third.content,
809
- raw: third.content
827
+ content: thirdContent,
828
+ raw: thirdContent
810
829
  }],
811
830
  loading
812
831
  });
@@ -814,6 +833,7 @@ function fixLinkToken(tokens) {
814
833
  return tokens;
815
834
  }
816
835
  function fixLinkTokens2(tokens) {
836
+ const tokensAny = tokens;
817
837
  if (tokens.length < 8) return tokens;
818
838
  let length = tokens.length;
819
839
  let last = tokens[length - 1];
@@ -826,16 +846,18 @@ function fixLinkTokens2(tokens) {
826
846
  const third = tokens[length - 6];
827
847
  const first = tokens[length - 8];
828
848
  if (first.type !== "text") return tokens;
829
- let href = tokens[length - 2].content ?? "";
849
+ let href = String(tokensAny[length - 2]?.content ?? "");
830
850
  let count = 4;
831
851
  if (length !== tokens.length) {
832
- href += last.content || "";
852
+ href += String(last.content ?? "");
833
853
  count++;
834
854
  }
835
855
  tokens.splice(length - 4, count);
836
- const content = third.content;
856
+ const thirdAny = third;
857
+ const content = String(thirdAny.content ?? "");
837
858
  length -= 4;
838
- first.content = first.content?.replace(/\[$/, "");
859
+ const firstAny = first;
860
+ tokensAny[length - 8].content = String(firstAny.content ?? "").replace(/\[$/, "");
839
861
  tokens.splice(length - 2, 1, {
840
862
  type: "link",
841
863
  href,
@@ -850,13 +872,16 @@ function fixLinkTokens2(tokens) {
850
872
  return tokens;
851
873
  }
852
874
  function fixLinkToken3(tokens) {
875
+ const tokensAny = tokens;
853
876
  const last = tokens[tokens.length - 1];
854
877
  const preLast = tokens[tokens.length - 2];
855
878
  const fixedTokens = [...tokens];
856
879
  if (last.type !== "text" || !last.content?.startsWith(")")) return tokens;
857
880
  if (preLast.type !== "link_close") return tokens;
858
- if (isTextToken(tokens[tokens.length - 5]) && tokens[tokens.length - 5].content?.endsWith("(")) {
859
- const content = tokens[tokens.length - 5].content + tokens[tokens.length - 3].content + last.content;
881
+ if (isTextToken(tokens[tokens.length - 5]) && String(tokens[tokens.length - 5].content ?? "").endsWith("(")) {
882
+ const a = tokensAny[tokens.length - 5];
883
+ const b = tokensAny[tokens.length - 3];
884
+ const content = String(a.content ?? "") + String(b.content ?? "") + String(last.content ?? "");
860
885
  fixedTokens.splice(tokens.length - 5, 5, {
861
886
  type: "text",
862
887
  content,
@@ -872,13 +897,17 @@ function fixLinkToken3(tokens) {
872
897
  return fixedTokens;
873
898
  }
874
899
  function fixLinkToken4(tokens) {
900
+ const tokensAny = tokens;
875
901
  const fixedTokens = [...tokens];
876
902
  for (let i = tokens.length - 1; i >= 3; i--) if (tokens[i].type === "link_close") {
877
903
  if (tokens[i - 3]?.content?.endsWith("(")) {
878
904
  const nextToken = tokens[i + 1];
879
905
  if (nextToken?.type === "text") {
880
906
  if (tokens[i - 1].type === "text" && tokens[i - 3].type === "text") {
881
- const content = tokens[i - 3].content + tokens[i - 1].content + nextToken.content;
907
+ const nextTokenContent = String(nextToken.content ?? "");
908
+ const a = tokensAny[i - 3];
909
+ const b = tokensAny[i - 1];
910
+ const content = String(a.content ?? "") + String(b.content ?? "") + nextTokenContent;
882
911
  fixedTokens.splice(i - 3, 5, {
883
912
  type: "text",
884
913
  content,
@@ -888,7 +917,9 @@ function fixLinkToken4(tokens) {
888
917
  }
889
918
  } else {
890
919
  if (tokens[i - 1].type === "text" && tokens[i - 3].type === "text") {
891
- const content = tokens[i - 3].content + tokens[i - 1].content;
920
+ const a = tokensAny[i - 3];
921
+ const b = tokensAny[i - 1];
922
+ const content = String(a.content ?? "") + String(b.content ?? "");
892
923
  fixedTokens.splice(i - 3, 4, {
893
924
  type: "text",
894
925
  content,
@@ -906,7 +937,8 @@ function fixLinkToken4(tokens) {
906
937
  //#region src/parser/inline-parsers/fixListItem.ts
907
938
  function fixListItem(tokens) {
908
939
  const last = tokens[tokens.length - 1];
909
- if (last?.type === "text" && /^\s*\d+\.\s*$/.test(last.content || "") && tokens[tokens.length - 2]?.tag === "br") tokens.splice(tokens.length - 1, 1);
940
+ const lastContent = String(last?.content ?? "");
941
+ if (last?.type === "text" && /^\s*\d+\.\s*$/.test(lastContent) && tokens[tokens.length - 2]?.tag === "br") tokens.splice(tokens.length - 1, 1);
910
942
  return tokens;
911
943
  }
912
944
 
@@ -918,7 +950,8 @@ function fixStrongTokens(tokens) {
918
950
  const i = tokens.length - 4;
919
951
  const token = tokens[i];
920
952
  const nextToken = tokens[i + 1];
921
- if (token.type === "text" && token.content?.endsWith("*") && nextToken.type === "em_open") {
953
+ const tokenContent = String(token.content ?? "");
954
+ if (token.type === "text" && tokenContent.endsWith("*") && nextToken.type === "em_open") {
922
955
  const _nextToken = tokens[i + 2];
923
956
  const count = _nextToken?.type === "text" ? 4 : 3;
924
957
  const insert = [
@@ -935,7 +968,7 @@ function fixStrongTokens(tokens) {
935
968
  },
936
969
  {
937
970
  type: "text",
938
- content: _nextToken?.type === "text" ? _nextToken.content : ""
971
+ content: _nextToken?.type === "text" ? String(_nextToken.content ?? "") : ""
939
972
  },
940
973
  {
941
974
  type: "strong_close",
@@ -949,7 +982,7 @@ function fixStrongTokens(tokens) {
949
982
  meta: null
950
983
  }
951
984
  ];
952
- const beforeText = token.content?.slice(0, -1);
985
+ const beforeText = tokenContent.slice(0, -1);
953
986
  if (beforeText) insert.unshift({
954
987
  type: "text",
955
988
  content: beforeText,
@@ -964,10 +997,11 @@ function fixStrongTokens(tokens) {
964
997
  //#endregion
965
998
  //#region src/parser/inline-parsers/footnote-ref-parser.ts
966
999
  function parseFootnoteRefToken(token) {
1000
+ const tokenMeta = token.meta ?? {};
967
1001
  return {
968
1002
  type: "footnote_reference",
969
- id: token.meta?.label || "",
970
- raw: `[^${token.meta?.label || ""}]`
1003
+ id: String(tokenMeta.label ?? ""),
1004
+ raw: `[^${String(tokenMeta.label ?? "")}]`
971
1005
  };
972
1006
  }
973
1007
 
@@ -988,7 +1022,7 @@ function parseHighlightToken(tokens, startIndex) {
988
1022
  let i = startIndex + 1;
989
1023
  const innerTokens = [];
990
1024
  while (i < tokens.length && tokens[i].type !== "mark_close") {
991
- markText += tokens[i].content || "";
1025
+ markText += String(tokens[i].content ?? "");
992
1026
  innerTokens.push(tokens[i]);
993
1027
  i++;
994
1028
  }
@@ -1006,12 +1040,33 @@ function parseHighlightToken(tokens, startIndex) {
1006
1040
  //#endregion
1007
1041
  //#region src/parser/inline-parsers/image-parser.ts
1008
1042
  function parseImageToken(token, loading = false) {
1043
+ let attrs = token.attrs ?? [];
1044
+ let childWithAttrs = null;
1045
+ if ((!attrs || attrs.length === 0) && Array.isArray(token.children)) for (const child of token.children) {
1046
+ const childAttrs = child?.attrs;
1047
+ if (Array.isArray(childAttrs) && childAttrs.length > 0) {
1048
+ attrs = childAttrs;
1049
+ childWithAttrs = child;
1050
+ break;
1051
+ }
1052
+ }
1053
+ const src = String(attrs.find((attr) => attr[0] === "src")?.[1] ?? "");
1054
+ const altAttr = attrs.find((attr) => attr[0] === "alt")?.[1];
1055
+ let alt = "";
1056
+ if (altAttr != null && String(altAttr).length > 0) alt = String(altAttr);
1057
+ else if (childWithAttrs?.content != null && String(childWithAttrs.content).length > 0) alt = String(childWithAttrs.content);
1058
+ else if (Array.isArray(childWithAttrs?.children) && childWithAttrs.children[0]?.content) alt = String(childWithAttrs.children[0].content);
1059
+ else if (Array.isArray(token.children) && token.children[0]?.content) alt = String(token.children[0].content);
1060
+ else if (token.content != null && String(token.content).length > 0) alt = String(token.content);
1061
+ const _title = attrs.find((attr) => attr[0] === "title")?.[1] ?? null;
1062
+ const title = _title === null ? null : String(_title);
1063
+ const raw = String(token.content ?? "");
1009
1064
  return {
1010
1065
  type: "image",
1011
- src: token.attrs?.find((attr) => attr[0] === "src")?.[1] || "",
1012
- alt: token.attrs?.find((attr) => attr[0] === "alt")?.[1] || "",
1013
- title: token.attrs?.find((attr) => attr[0] === "title")?.[1] || null,
1014
- raw: token.content || "",
1066
+ src,
1067
+ alt,
1068
+ title,
1069
+ raw,
1015
1070
  loading
1016
1071
  };
1017
1072
  }
@@ -1019,10 +1074,11 @@ function parseImageToken(token, loading = false) {
1019
1074
  //#endregion
1020
1075
  //#region src/parser/inline-parsers/inline-code-parser.ts
1021
1076
  function parseInlineCodeToken(token) {
1077
+ const code = String(token.content ?? "");
1022
1078
  return {
1023
1079
  type: "inline_code",
1024
- code: token.content || "",
1025
- raw: token.content || ""
1080
+ code,
1081
+ raw: code
1026
1082
  };
1027
1083
  }
1028
1084
 
@@ -1034,7 +1090,7 @@ function parseInsertToken(tokens, startIndex) {
1034
1090
  let i = startIndex + 1;
1035
1091
  const innerTokens = [];
1036
1092
  while (i < tokens.length && tokens[i].type !== "ins_close") {
1037
- insText += tokens[i].content || "";
1093
+ insText += String(tokens[i].content ?? "");
1038
1094
  innerTokens.push(tokens[i]);
1039
1095
  i++;
1040
1096
  }
@@ -1043,7 +1099,7 @@ function parseInsertToken(tokens, startIndex) {
1043
1099
  node: {
1044
1100
  type: "insert",
1045
1101
  children,
1046
- raw: `++${insText}++`
1102
+ raw: `++${String(insText)}++`
1047
1103
  },
1048
1104
  nextIndex: i < tokens.length ? i + 1 : tokens.length
1049
1105
  };
@@ -1052,9 +1108,10 @@ function parseInsertToken(tokens, startIndex) {
1052
1108
  //#endregion
1053
1109
  //#region src/parser/inline-parsers/link-parser.ts
1054
1110
  function parseLinkToken(tokens, startIndex) {
1055
- const openToken = tokens[startIndex];
1056
- const href = openToken.attrs?.find((attr) => attr[0] === "href")?.[1] || "";
1057
- const title = openToken.attrs?.find((attr) => attr[0] === "title")?.[1] || null;
1111
+ const attrs = tokens[startIndex].attrs ?? [];
1112
+ const href = String(attrs.find((attr) => attr[0] === "href")?.[1] ?? "");
1113
+ const _title = attrs.find((attr) => attr[0] === "title")?.[1] ?? null;
1114
+ const title = _title === null ? null : String(_title);
1058
1115
  let i = startIndex + 1;
1059
1116
  const linkTokens = [];
1060
1117
  const loading = true;
@@ -1064,8 +1121,9 @@ function parseLinkToken(tokens, startIndex) {
1064
1121
  }
1065
1122
  const children = parseInlineTokens(linkTokens);
1066
1123
  const linkText = children.map((node) => {
1067
- if ("content" in node) return node.content;
1068
- return node.raw;
1124
+ const nodeAny = node;
1125
+ if ("content" in node) return String(nodeAny.content ?? "");
1126
+ return String(nodeAny.raw ?? "");
1069
1127
  }).join("");
1070
1128
  return {
1071
1129
  node: {
@@ -1074,7 +1132,7 @@ function parseLinkToken(tokens, startIndex) {
1074
1132
  title,
1075
1133
  text: linkText,
1076
1134
  children,
1077
- raw: `[${linkText}](${href}${title ? ` "${title}"` : ""})`,
1135
+ raw: String(`[${linkText}](${href}${title ? ` "${title}"` : ""})`),
1078
1136
  loading
1079
1137
  },
1080
1138
  nextIndex: i < tokens.length ? i + 1 : tokens.length
@@ -1086,7 +1144,7 @@ function parseLinkToken(tokens, startIndex) {
1086
1144
  function parseMathInlineToken(token) {
1087
1145
  return {
1088
1146
  type: "math_inline",
1089
- content: token.content || "",
1147
+ content: String(token.content ?? ""),
1090
1148
  loading: !!token.loading,
1091
1149
  raw: token.raw
1092
1150
  };
@@ -1097,8 +1155,8 @@ function parseMathInlineToken(token) {
1097
1155
  function parseReferenceToken(token) {
1098
1156
  return {
1099
1157
  type: "reference",
1100
- id: token.content || "",
1101
- raw: token.markup || `[${token.content}]`
1158
+ id: String(token.content ?? ""),
1159
+ raw: String(token.markup ?? `[${token.content ?? ""}]`)
1102
1160
  };
1103
1161
  }
1104
1162
 
@@ -1110,7 +1168,7 @@ function parseStrikethroughToken(tokens, startIndex) {
1110
1168
  let i = startIndex + 1;
1111
1169
  const innerTokens = [];
1112
1170
  while (i < tokens.length && tokens[i].type !== "s_close") {
1113
- sText += tokens[i].content || "";
1171
+ sText += String(tokens[i].content ?? "");
1114
1172
  innerTokens.push(tokens[i]);
1115
1173
  i++;
1116
1174
  }
@@ -1133,7 +1191,7 @@ function parseStrongToken(tokens, startIndex, raw) {
1133
1191
  let i = startIndex + 1;
1134
1192
  const innerTokens = [];
1135
1193
  while (i < tokens.length && tokens[i].type !== "strong_close") {
1136
- strongText += tokens[i].content || "";
1194
+ strongText += String(tokens[i].content ?? "");
1137
1195
  innerTokens.push(tokens[i]);
1138
1196
  i++;
1139
1197
  }
@@ -1142,7 +1200,7 @@ function parseStrongToken(tokens, startIndex, raw) {
1142
1200
  node: {
1143
1201
  type: "strong",
1144
1202
  children,
1145
- raw: `**${strongText}**`
1203
+ raw: `**${String(strongText)}**`
1146
1204
  },
1147
1205
  nextIndex: i < tokens.length ? i + 1 : tokens.length
1148
1206
  };
@@ -1156,20 +1214,22 @@ function parseSubscriptToken(tokens, startIndex) {
1156
1214
  let i = startIndex + 1;
1157
1215
  const innerTokens = [];
1158
1216
  while (i < tokens.length && tokens[i].type !== "sub_close") {
1159
- subText += tokens[i].content || "";
1217
+ subText += String(tokens[i].content ?? "");
1160
1218
  innerTokens.push(tokens[i]);
1161
1219
  i++;
1162
1220
  }
1163
1221
  children.push(...parseInlineTokens(innerTokens));
1222
+ const startContent = String(tokens[startIndex].content ?? "");
1223
+ const display = subText || startContent;
1164
1224
  return {
1165
1225
  node: {
1166
1226
  type: "subscript",
1167
1227
  children: children.length > 0 ? children : [{
1168
1228
  type: "text",
1169
- content: subText || tokens[startIndex].content || "",
1170
- raw: subText || tokens[startIndex].content || ""
1229
+ content: display,
1230
+ raw: display
1171
1231
  }],
1172
- raw: `~${subText || tokens[startIndex].content || ""}~`
1232
+ raw: `~${display}~`
1173
1233
  },
1174
1234
  nextIndex: i < tokens.length ? i + 1 : tokens.length
1175
1235
  };
@@ -1183,7 +1243,7 @@ function parseSuperscriptToken(tokens, startIndex) {
1183
1243
  let i = startIndex + 1;
1184
1244
  const innerTokens = [];
1185
1245
  while (i < tokens.length && tokens[i].type !== "sup_close") {
1186
- supText += tokens[i].content || "";
1246
+ supText += String(tokens[i].content ?? "");
1187
1247
  innerTokens.push(tokens[i]);
1188
1248
  i++;
1189
1249
  }
@@ -1193,10 +1253,10 @@ function parseSuperscriptToken(tokens, startIndex) {
1193
1253
  type: "superscript",
1194
1254
  children: children.length > 0 ? children : [{
1195
1255
  type: "text",
1196
- content: supText || tokens[startIndex].content || "",
1197
- raw: supText || tokens[startIndex].content || ""
1256
+ content: supText || String(tokens[startIndex].content ?? ""),
1257
+ raw: supText || String(tokens[startIndex].content ?? "")
1198
1258
  }],
1199
- raw: `^${supText || tokens[startIndex].content || ""}^`
1259
+ raw: `^${supText || String(tokens[startIndex].content ?? "")}^`
1200
1260
  },
1201
1261
  nextIndex: i < tokens.length ? i + 1 : tokens.length
1202
1262
  };
@@ -1205,10 +1265,11 @@ function parseSuperscriptToken(tokens, startIndex) {
1205
1265
  //#endregion
1206
1266
  //#region src/parser/inline-parsers/text-parser.ts
1207
1267
  function parseTextToken(token) {
1268
+ const content = String(token.content ?? "");
1208
1269
  return {
1209
1270
  type: "text",
1210
- content: token.content || "",
1211
- raw: token.content || ""
1271
+ content,
1272
+ raw: content
1212
1273
  };
1213
1274
  }
1214
1275
 
@@ -1222,314 +1283,232 @@ function parseInlineTokens(tokens, raw, pPreToken) {
1222
1283
  tokens = fixStrongTokens(tokens);
1223
1284
  tokens = fixListItem(tokens);
1224
1285
  tokens = fixLinkToken(tokens);
1286
+ function resetCurrentTextNode() {
1287
+ currentTextNode = null;
1288
+ }
1289
+ function handleEmphasisAndStrikethrough(content, token) {
1290
+ if (/[^~]*~{2,}[^~]+/.test(content)) {
1291
+ let idx = content.indexOf("~~");
1292
+ if (idx === -1) idx = 0;
1293
+ const _text = content.slice(0, idx);
1294
+ if (_text) if (currentTextNode) {
1295
+ currentTextNode.content += _text;
1296
+ currentTextNode.raw += _text;
1297
+ } else {
1298
+ currentTextNode = {
1299
+ type: "text",
1300
+ content: String(_text ?? ""),
1301
+ raw: String(token.content ?? "")
1302
+ };
1303
+ result.push(currentTextNode);
1304
+ }
1305
+ const { node } = parseStrikethroughToken([
1306
+ {
1307
+ type: "s_open",
1308
+ tag: "s",
1309
+ content: "",
1310
+ markup: "*",
1311
+ info: "",
1312
+ meta: null
1313
+ },
1314
+ {
1315
+ type: "text",
1316
+ tag: "",
1317
+ content: content.slice(idx).replace(/~/g, ""),
1318
+ markup: "",
1319
+ info: "",
1320
+ meta: null
1321
+ },
1322
+ {
1323
+ type: "s_close",
1324
+ tag: "s",
1325
+ content: "",
1326
+ markup: "*",
1327
+ info: "",
1328
+ meta: null
1329
+ }
1330
+ ], 0);
1331
+ resetCurrentTextNode();
1332
+ pushNode(node);
1333
+ i++;
1334
+ return true;
1335
+ }
1336
+ if (/\*\*/.test(content)) {
1337
+ const openIdx = content.indexOf("**");
1338
+ const beforeText = openIdx > -1 ? content.slice(0, openIdx) : "";
1339
+ if (beforeText) pushText(beforeText, beforeText);
1340
+ if (openIdx === -1) {
1341
+ i++;
1342
+ return true;
1343
+ }
1344
+ const exec = /\*\*([\s\S]*?)\*\*/.exec(content);
1345
+ let inner = "";
1346
+ let after = "";
1347
+ if (exec && typeof exec.index === "number") {
1348
+ inner = exec[1];
1349
+ after = content.slice(exec.index + exec[0].length);
1350
+ } else {
1351
+ inner = content.slice(openIdx + 2);
1352
+ after = "";
1353
+ }
1354
+ const { node } = parseStrongToken([
1355
+ {
1356
+ type: "strong_open",
1357
+ tag: "strong",
1358
+ content: "",
1359
+ markup: "*",
1360
+ info: "",
1361
+ meta: null
1362
+ },
1363
+ {
1364
+ type: "text",
1365
+ tag: "",
1366
+ content: inner,
1367
+ markup: "",
1368
+ info: "",
1369
+ meta: null
1370
+ },
1371
+ {
1372
+ type: "strong_close",
1373
+ tag: "strong",
1374
+ content: "",
1375
+ markup: "*",
1376
+ info: "",
1377
+ meta: null
1378
+ }
1379
+ ], 0, raw);
1380
+ resetCurrentTextNode();
1381
+ pushNode(node);
1382
+ if (after) {
1383
+ handleToken({
1384
+ type: "text",
1385
+ content: after,
1386
+ raw: after
1387
+ });
1388
+ i--;
1389
+ }
1390
+ i++;
1391
+ return true;
1392
+ }
1393
+ if (/[^*]*\*[^*]+/.test(content)) {
1394
+ let idx = content.indexOf("*");
1395
+ if (idx === -1) idx = 0;
1396
+ const _text = content.slice(0, idx);
1397
+ if (_text) if (currentTextNode) {
1398
+ currentTextNode.content += _text;
1399
+ currentTextNode.raw += _text;
1400
+ } else {
1401
+ currentTextNode = {
1402
+ type: "text",
1403
+ content: String(_text ?? ""),
1404
+ raw: String(token.content ?? "")
1405
+ };
1406
+ result.push(currentTextNode);
1407
+ }
1408
+ const { node } = parseEmphasisToken([
1409
+ {
1410
+ type: "em_open",
1411
+ tag: "em",
1412
+ content: "",
1413
+ markup: "*",
1414
+ info: "",
1415
+ meta: null
1416
+ },
1417
+ {
1418
+ type: "text",
1419
+ tag: "",
1420
+ content: content.slice(idx).replace(/\*/g, ""),
1421
+ markup: "",
1422
+ info: "",
1423
+ meta: null
1424
+ },
1425
+ {
1426
+ type: "em_close",
1427
+ tag: "em",
1428
+ content: "",
1429
+ markup: "*",
1430
+ info: "",
1431
+ meta: null
1432
+ }
1433
+ ], 0);
1434
+ resetCurrentTextNode();
1435
+ pushNode(node);
1436
+ i++;
1437
+ return true;
1438
+ }
1439
+ return false;
1440
+ }
1441
+ function handleInlineCodeContent(content, _token) {
1442
+ if (!/`[^`]*/.test(content)) return false;
1443
+ resetCurrentTextNode();
1444
+ const code_start = content.indexOf("`");
1445
+ const code_end = content.indexOf("`", code_start + 1);
1446
+ const _text = content.slice(0, code_start);
1447
+ const codeContent = code_end === -1 ? content.slice(code_start) : content.slice(code_start, code_end);
1448
+ const after = code_end === -1 ? "" : content.slice(code_end + 1);
1449
+ if (_text) if (!handleEmphasisAndStrikethrough(_text, _token)) pushText(_text, _text);
1450
+ else i--;
1451
+ const code = codeContent.replace(/`/g, "");
1452
+ pushParsed({
1453
+ type: "inline_code",
1454
+ code,
1455
+ raw: String(code ?? "")
1456
+ });
1457
+ if (after) {
1458
+ handleToken({
1459
+ type: "text",
1460
+ content: after,
1461
+ raw: String(after ?? "")
1462
+ });
1463
+ i--;
1464
+ } else if (code_end === -1) {
1465
+ if (tokens[i + 1]) {
1466
+ let fixedAfter = after;
1467
+ for (let j = i + 1; j < tokens.length; j++) fixedAfter += String((tokens[j].content ?? "") + (tokens[j].markup ?? ""));
1468
+ i = tokens.length - 1;
1469
+ handleToken({
1470
+ type: "text",
1471
+ content: fixedAfter,
1472
+ raw: String(fixedAfter ?? "")
1473
+ });
1474
+ }
1475
+ }
1476
+ i++;
1477
+ return true;
1478
+ }
1479
+ function pushParsed(node) {
1480
+ resetCurrentTextNode();
1481
+ result.push(node);
1482
+ }
1483
+ function pushToken(token) {
1484
+ resetCurrentTextNode();
1485
+ result.push(token);
1486
+ }
1487
+ function pushNode(node) {
1488
+ pushParsed(node);
1489
+ }
1490
+ function pushText(content, raw$1) {
1491
+ if (currentTextNode) {
1492
+ currentTextNode.content += content;
1493
+ currentTextNode.raw += raw$1 ?? content;
1494
+ } else {
1495
+ currentTextNode = {
1496
+ type: "text",
1497
+ content: String(content ?? ""),
1498
+ raw: String(raw$1 ?? content ?? "")
1499
+ };
1500
+ result.push(currentTextNode);
1501
+ }
1502
+ }
1225
1503
  while (i < tokens.length) {
1226
1504
  const token = tokens[i];
1227
1505
  handleToken(token);
1228
1506
  }
1229
1507
  function handleToken(token) {
1230
1508
  switch (token.type) {
1231
- case "text": {
1232
- let index = result.length - 1;
1233
- let content = token.content.replace(/\\/g, "") || "";
1234
- if (content.startsWith(")") && result[result.length - 1]?.type === "link") content = content.slice(1);
1235
- for (; index >= 0; index--) {
1236
- const item = result[index];
1237
- if (item.type === "text") {
1238
- currentTextNode = null;
1239
- content = item.content + content;
1240
- continue;
1241
- }
1242
- break;
1243
- }
1244
- if (index < result.length - 1) result.splice(index + 1);
1245
- const nextToken = tokens[i + 1];
1246
- if (content === "`" || content === "|" || content === "$" || content === "1" || /^\*+$/.test(content) || /^\d$/.test(content)) {
1247
- i++;
1248
- break;
1249
- }
1250
- if (!nextToken && /[^\]]\s*\(\s*$/.test(content)) content = content.replace(/\(\s*$/, "");
1251
- if (raw?.startsWith("[") && pPreToken?.type === "list_item_open") {
1252
- const w = content.slice(1).match(/[^\s\]]/);
1253
- if (w === null) {
1254
- i++;
1255
- break;
1256
- }
1257
- if (w && /x/i.test(w[0]) || !w) {
1258
- const checked = w ? w[0] === "x" || w[0] === "X" : false;
1259
- result.push({
1260
- type: "checkbox_input",
1261
- checked,
1262
- raw: checked ? "[x]" : "[ ]"
1263
- });
1264
- i++;
1265
- break;
1266
- }
1267
- }
1268
- if (/`[^`]*/.test(content)) {
1269
- currentTextNode = null;
1270
- const index$1 = content.indexOf("`");
1271
- const _text = content.slice(0, index$1);
1272
- const codeContent = content.slice(index$1);
1273
- if (_text) result.push({
1274
- type: "text",
1275
- content: _text || "",
1276
- raw: _text || ""
1277
- });
1278
- result.push({
1279
- type: "inline_code",
1280
- code: codeContent.replace(/`/g, ""),
1281
- raw: codeContent || ""
1282
- });
1283
- i++;
1284
- break;
1285
- }
1286
- if (content === "[") {
1287
- i++;
1288
- break;
1289
- }
1290
- if (/[^~]*~{2,}[^~]+/.test(content)) {
1291
- const index$1 = content.indexOf("~~") || 0;
1292
- const _text = content.slice(0, index$1);
1293
- if (_text) if (currentTextNode) {
1294
- currentTextNode.content += _text;
1295
- currentTextNode.raw += _text;
1296
- } else {
1297
- currentTextNode = {
1298
- type: "text",
1299
- content: _text || "",
1300
- raw: token.content || ""
1301
- };
1302
- result.push(currentTextNode);
1303
- }
1304
- const strikethroughContent = content.slice(index$1);
1305
- currentTextNode = null;
1306
- const { node } = parseStrikethroughToken([
1307
- {
1308
- type: "s_open",
1309
- tag: "s",
1310
- content: "",
1311
- markup: "*",
1312
- info: "",
1313
- meta: null
1314
- },
1315
- {
1316
- type: "text",
1317
- tag: "",
1318
- content: strikethroughContent.replace(/~/g, ""),
1319
- markup: "",
1320
- info: "",
1321
- meta: null
1322
- },
1323
- {
1324
- type: "s_close",
1325
- tag: "s",
1326
- content: "",
1327
- markup: "*",
1328
- info: "",
1329
- meta: null
1330
- }
1331
- ], 0);
1332
- result.push(node);
1333
- i++;
1334
- break;
1335
- }
1336
- if (/[^*]*\*\*[^*]+/.test(content)) {
1337
- const index$1 = content.indexOf("*") || 0;
1338
- const _text = content.slice(0, index$1);
1339
- if (_text) if (currentTextNode) {
1340
- currentTextNode.content += _text;
1341
- currentTextNode.raw += _text;
1342
- } else {
1343
- currentTextNode = {
1344
- type: "text",
1345
- content: _text || "",
1346
- raw: token.content || ""
1347
- };
1348
- result.push(currentTextNode);
1349
- }
1350
- const strongContent = content.slice(index$1);
1351
- currentTextNode = null;
1352
- const { node } = parseStrongToken([
1353
- {
1354
- type: "strong_open",
1355
- tag: "strong",
1356
- content: "",
1357
- markup: "*",
1358
- info: "",
1359
- meta: null
1360
- },
1361
- {
1362
- type: "text",
1363
- tag: "",
1364
- content: strongContent.replace(/\*/g, ""),
1365
- markup: "",
1366
- info: "",
1367
- meta: null
1368
- },
1369
- {
1370
- type: "strong_close",
1371
- tag: "strong",
1372
- content: "",
1373
- markup: "*",
1374
- info: "",
1375
- meta: null
1376
- }
1377
- ], 0, raw);
1378
- result.push(node);
1379
- i++;
1380
- break;
1381
- } else if (/[^*]*\*[^*]+/.test(content)) {
1382
- const index$1 = content.indexOf("*") || 0;
1383
- const _text = content.slice(0, index$1);
1384
- if (_text) if (currentTextNode) {
1385
- currentTextNode.content += _text;
1386
- currentTextNode.raw += _text;
1387
- } else {
1388
- currentTextNode = {
1389
- type: "text",
1390
- content: _text || "",
1391
- raw: token.content || ""
1392
- };
1393
- result.push(currentTextNode);
1394
- }
1395
- const emphasisContent = content.slice(index$1);
1396
- currentTextNode = null;
1397
- const { node } = parseEmphasisToken([
1398
- {
1399
- type: "em_open",
1400
- tag: "em",
1401
- content: "",
1402
- markup: "*",
1403
- info: "",
1404
- meta: null
1405
- },
1406
- {
1407
- type: "text",
1408
- tag: "",
1409
- content: emphasisContent.replace(/\*/g, ""),
1410
- markup: "",
1411
- info: "",
1412
- meta: null
1413
- },
1414
- {
1415
- type: "em_close",
1416
- tag: "em",
1417
- content: "",
1418
- markup: "*",
1419
- info: "",
1420
- meta: null
1421
- }
1422
- ], 0);
1423
- result.push(node);
1424
- i++;
1425
- break;
1426
- }
1427
- const imageStart = content.indexOf("![");
1428
- if (imageStart !== -1) {
1429
- const textNodeContent = content.slice(0, imageStart);
1430
- if (!currentTextNode) currentTextNode = {
1431
- type: "text",
1432
- content: textNodeContent,
1433
- raw: textNodeContent
1434
- };
1435
- else currentTextNode.content += textNodeContent;
1436
- result.push(currentTextNode);
1437
- currentTextNode = null;
1438
- result.push(parseImageToken(token, true));
1439
- i++;
1440
- break;
1441
- }
1442
- let linkStart = content.indexOf("[");
1443
- if (content.endsWith("undefined") && !raw?.endsWith("undefined")) content = content.slice(0, -9);
1444
- const textNode = parseTextToken({
1445
- ...token,
1446
- content
1447
- });
1448
- if (linkStart !== -1) {
1449
- let textNodeContent = content.slice(0, linkStart);
1450
- const linkEnd = content.indexOf("](", linkStart);
1451
- if (linkEnd !== -1) {
1452
- const textToken = tokens[i + 2];
1453
- let text = content.slice(linkStart + 1, linkEnd);
1454
- if (text.includes("[")) {
1455
- const secondLinkStart = text.indexOf("[");
1456
- linkStart = linkStart + secondLinkStart + 1;
1457
- textNodeContent += content.slice(0, linkStart);
1458
- text = content.slice(linkStart + 1, linkEnd);
1459
- }
1460
- if (content.endsWith("](") && nextToken?.type === "link_open" && textToken) {
1461
- const last = tokens[i + 4];
1462
- let index$1 = 4;
1463
- let loading$1 = true;
1464
- if (last?.type === "text" && last.content === ")") {
1465
- index$1++;
1466
- loading$1 = false;
1467
- } else if (last?.type === "text" && last.content === ".") i++;
1468
- if (textNodeContent) result.push({
1469
- type: "text",
1470
- content: textNodeContent,
1471
- raw: textNodeContent
1472
- });
1473
- result.push({
1474
- type: "link",
1475
- href: textToken.content || "",
1476
- text,
1477
- children: [{
1478
- type: "text",
1479
- content: text,
1480
- raw: text
1481
- }],
1482
- loading: loading$1
1483
- });
1484
- i += index$1;
1485
- break;
1486
- }
1487
- const linkContentEnd = content.indexOf(")", linkEnd);
1488
- const href = linkContentEnd !== -1 ? content.slice(linkEnd + 2, linkContentEnd) : "";
1489
- const loading = linkContentEnd === -1;
1490
- if (textNodeContent) result.push({
1491
- type: "text",
1492
- content: textNodeContent,
1493
- raw: textNodeContent
1494
- });
1495
- result.push({
1496
- type: "link",
1497
- href,
1498
- text,
1499
- children: [{
1500
- type: "text",
1501
- content: text,
1502
- raw: text
1503
- }],
1504
- loading
1505
- });
1506
- const afterText = linkContentEnd !== -1 ? content.slice(linkContentEnd + 1) : "";
1507
- if (afterText) {
1508
- handleToken({
1509
- type: "text",
1510
- content: afterText,
1511
- raw: afterText
1512
- });
1513
- i--;
1514
- }
1515
- i++;
1516
- break;
1517
- }
1518
- }
1519
- const preToken = tokens[i - 1];
1520
- if (currentTextNode) {
1521
- currentTextNode.content += textNode.content.replace(/(\*+|\(|\\)$/, "");
1522
- currentTextNode.raw += textNode.raw;
1523
- } else {
1524
- const maybeMath = preToken?.tag === "br" && tokens[i - 2]?.content === "[";
1525
- if (!tokens[i + 1]) textNode.content = textNode.content.replace(/(\*+|\(|\\)$/, "");
1526
- currentTextNode = textNode;
1527
- currentTextNode.center = maybeMath;
1528
- result.push(currentTextNode);
1529
- }
1530
- i++;
1509
+ case "text":
1510
+ handleTextToken(token);
1531
1511
  break;
1532
- }
1533
1512
  case "softbreak":
1534
1513
  if (currentTextNode) {
1535
1514
  currentTextNode.content += "\n";
@@ -1538,193 +1517,358 @@ function parseInlineTokens(tokens, raw, pPreToken) {
1538
1517
  i++;
1539
1518
  break;
1540
1519
  case "code_inline":
1541
- currentTextNode = null;
1542
- result.push(parseInlineCodeToken(token));
1520
+ pushNode(parseInlineCodeToken(token));
1543
1521
  i++;
1544
1522
  break;
1545
- case "link_open": {
1546
- currentTextNode = null;
1547
- const href = token.attrs?.find((attr) => attr[0] === "href")?.[1];
1548
- if (raw && tokens[i + 1].type === "text") {
1549
- const text = tokens[i + 1]?.content || "";
1550
- if (!(/* @__PURE__ */ new RegExp(`\\[${text}\\s*\\]`)).test(raw)) {
1551
- result.push({
1552
- type: "text",
1553
- content: text,
1554
- raw: text
1555
- });
1556
- i += 3;
1557
- break;
1558
- }
1559
- }
1560
- if (raw && href) {
1561
- const loadingMath = /* @__PURE__ */ new RegExp(`\\(\\s*${href}\\s*\\)`);
1562
- const pre = result.length > 0 ? result[result.length - 1] : null;
1563
- const loading = !loadingMath.test(raw);
1564
- if (loading && pre) {
1565
- if ((/* @__PURE__ */ new RegExp(`\\[${pre.text}\\s*\\]\\(`)).test(raw)) {
1566
- const text = pre?.text || pre?.content?.slice(1, -1) || "";
1567
- result.splice(result.length - 1, 1, {
1568
- type: "link",
1569
- href: "",
1570
- text,
1571
- loading
1572
- });
1573
- i += 3;
1574
- if (tokens[i]?.content === ".") i++;
1575
- break;
1576
- }
1577
- }
1578
- }
1579
- const { node, nextIndex } = parseLinkToken(tokens, i);
1580
- i = nextIndex;
1581
- node.loading = false;
1582
- result.push(node);
1523
+ case "link_open":
1524
+ handleLinkOpen(token);
1583
1525
  break;
1584
- }
1585
1526
  case "image":
1586
- currentTextNode = null;
1587
- result.push(parseImageToken(token));
1527
+ resetCurrentTextNode();
1528
+ pushNode(parseImageToken(token));
1588
1529
  i++;
1589
1530
  break;
1590
1531
  case "strong_open": {
1591
- currentTextNode = null;
1532
+ resetCurrentTextNode();
1592
1533
  const { node, nextIndex } = parseStrongToken(tokens, i, token.content);
1593
- result.push(node);
1534
+ pushNode(node);
1594
1535
  i = nextIndex;
1595
1536
  break;
1596
1537
  }
1597
1538
  case "em_open": {
1598
- currentTextNode = null;
1539
+ resetCurrentTextNode();
1599
1540
  const { node, nextIndex } = parseEmphasisToken(tokens, i);
1600
- result.push(node);
1541
+ pushNode(node);
1601
1542
  i = nextIndex;
1602
1543
  break;
1603
1544
  }
1604
1545
  case "s_open": {
1605
- currentTextNode = null;
1546
+ resetCurrentTextNode();
1606
1547
  const { node, nextIndex } = parseStrikethroughToken(tokens, i);
1607
- result.push(node);
1548
+ pushNode(node);
1608
1549
  i = nextIndex;
1609
1550
  break;
1610
1551
  }
1611
1552
  case "mark_open": {
1612
- currentTextNode = null;
1553
+ resetCurrentTextNode();
1613
1554
  const { node, nextIndex } = parseHighlightToken(tokens, i);
1614
- result.push(node);
1555
+ pushNode(node);
1615
1556
  i = nextIndex;
1616
1557
  break;
1617
1558
  }
1618
1559
  case "ins_open": {
1619
- currentTextNode = null;
1560
+ resetCurrentTextNode();
1620
1561
  const { node, nextIndex } = parseInsertToken(tokens, i);
1621
- result.push(node);
1562
+ pushNode(node);
1622
1563
  i = nextIndex;
1623
1564
  break;
1624
1565
  }
1625
1566
  case "sub_open": {
1626
- currentTextNode = null;
1567
+ resetCurrentTextNode();
1627
1568
  const { node, nextIndex } = parseSubscriptToken(tokens, i);
1628
- result.push(node);
1569
+ pushNode(node);
1629
1570
  i = nextIndex;
1630
1571
  break;
1631
1572
  }
1632
1573
  case "sup_open": {
1633
- currentTextNode = null;
1574
+ resetCurrentTextNode();
1634
1575
  const { node, nextIndex } = parseSuperscriptToken(tokens, i);
1635
- result.push(node);
1576
+ pushNode(node);
1636
1577
  i = nextIndex;
1637
1578
  break;
1638
1579
  }
1639
1580
  case "sub":
1640
- currentTextNode = null;
1641
- result.push({
1581
+ resetCurrentTextNode();
1582
+ pushNode({
1642
1583
  type: "subscript",
1643
1584
  children: [{
1644
1585
  type: "text",
1645
- content: token.content || "",
1646
- raw: token.content || ""
1586
+ content: String(token.content ?? ""),
1587
+ raw: String(token.content ?? "")
1647
1588
  }],
1648
- raw: `~${token.content || ""}~`
1589
+ raw: `~${String(token.content ?? "")}~`
1649
1590
  });
1650
1591
  i++;
1651
1592
  break;
1652
1593
  case "sup":
1653
- currentTextNode = null;
1654
- result.push({
1594
+ resetCurrentTextNode();
1595
+ pushNode({
1655
1596
  type: "superscript",
1656
1597
  children: [{
1657
1598
  type: "text",
1658
- content: token.content || "",
1659
- raw: token.content || ""
1599
+ content: String(token.content ?? ""),
1600
+ raw: String(token.content ?? "")
1660
1601
  }],
1661
- raw: `^${token.content || ""}^`
1602
+ raw: `^${String(token.content ?? "")}^`
1662
1603
  });
1663
1604
  i++;
1664
1605
  break;
1665
1606
  case "emoji": {
1666
- currentTextNode = null;
1607
+ resetCurrentTextNode();
1667
1608
  const preToken = tokens[i - 1];
1668
- if (preToken?.type === "text" && /\|:-+/.test(preToken.content || "")) result.push({
1669
- type: "text",
1670
- content: "",
1671
- raw: ""
1672
- });
1673
- else result.push(parseEmojiToken(token));
1609
+ if (preToken?.type === "text" && /\|:-+/.test(String(preToken.content ?? ""))) pushText("", "");
1610
+ else pushNode(parseEmojiToken(token));
1674
1611
  i++;
1675
1612
  break;
1676
1613
  }
1677
1614
  case "checkbox":
1678
- currentTextNode = null;
1679
- result.push(parseCheckboxToken(token));
1615
+ resetCurrentTextNode();
1616
+ pushNode(parseCheckboxToken(token));
1680
1617
  i++;
1681
1618
  break;
1682
1619
  case "checkbox_input":
1683
- currentTextNode = null;
1684
- result.push(parseCheckboxInputToken(token));
1620
+ resetCurrentTextNode();
1621
+ pushNode(parseCheckboxInputToken(token));
1685
1622
  i++;
1686
1623
  break;
1687
1624
  case "footnote_ref":
1688
- currentTextNode = null;
1689
- result.push(parseFootnoteRefToken(token));
1625
+ resetCurrentTextNode();
1626
+ pushNode(parseFootnoteRefToken(token));
1690
1627
  i++;
1691
1628
  break;
1692
1629
  case "hardbreak":
1693
- currentTextNode = null;
1694
- result.push(parseHardbreakToken());
1630
+ resetCurrentTextNode();
1631
+ pushNode(parseHardbreakToken());
1695
1632
  i++;
1696
1633
  break;
1697
1634
  case "fence":
1698
- currentTextNode = null;
1699
- result.push(parseFenceToken(tokens[i]));
1635
+ resetCurrentTextNode();
1636
+ pushNode(parseFenceToken(tokens[i]));
1700
1637
  i++;
1701
1638
  break;
1702
1639
  case "math_inline":
1703
- currentTextNode = null;
1704
- result.push(parseMathInlineToken(token));
1640
+ resetCurrentTextNode();
1641
+ pushNode(parseMathInlineToken(token));
1705
1642
  i++;
1706
1643
  break;
1707
- case "reference": {
1708
- currentTextNode = null;
1709
- const nextToken = tokens[i + 1];
1710
- const preToken = tokens[i - 1];
1711
- const preResult = result[result.length - 1];
1712
- if (nextToken?.type === "text" && !nextToken.content?.startsWith("(") || preToken.type === "text" && /\]$|^\s*$/.test(preToken.content || "")) result.push(parseReferenceToken(token));
1713
- else if (nextToken && nextToken.type === "text") nextToken.content = token.markup + nextToken.content;
1714
- else if (preResult.type === "text") {
1715
- preResult.content = preResult.content + token.markup;
1716
- preResult.raw = preResult.raw + token.markup;
1717
- }
1718
- i++;
1644
+ case "reference":
1645
+ handleReference(token);
1719
1646
  break;
1720
- }
1721
1647
  default:
1722
- result.push(token);
1723
- currentTextNode = null;
1648
+ pushToken(token);
1724
1649
  i++;
1725
1650
  break;
1726
1651
  }
1727
1652
  }
1653
+ function handleTextToken(token) {
1654
+ let index = result.length - 1;
1655
+ let content = String(token.content ?? "").replace(/\\/g, "");
1656
+ if (content.startsWith(")") && result[result.length - 1]?.type === "link") content = content.slice(1);
1657
+ if (content.endsWith("undefined") && !raw?.endsWith("undefined")) content = content.slice(0, -9);
1658
+ for (; index >= 0; index--) {
1659
+ const item = result[index];
1660
+ if (item.type === "text") {
1661
+ currentTextNode = null;
1662
+ content = item.content + content;
1663
+ continue;
1664
+ }
1665
+ break;
1666
+ }
1667
+ if (index < result.length - 1) result.splice(index + 1);
1668
+ const nextToken = tokens[i + 1];
1669
+ if (content === "`" || content === "|" || content === "$" || content === "1" || /^\*+$/.test(content) || /^\d$/.test(content)) {
1670
+ i++;
1671
+ return;
1672
+ }
1673
+ if (!nextToken && /[^\]]\s*\(\s*$/.test(content)) content = content.replace(/\(\s*$/, "");
1674
+ if (handleCheckboxLike(content)) return;
1675
+ if (content === "[") {
1676
+ i++;
1677
+ return;
1678
+ }
1679
+ if (handleInlineCodeContent(content, token)) return;
1680
+ if (handleEmphasisAndStrikethrough(content, token)) return;
1681
+ if (handleInlineImageContent(content, token)) return;
1682
+ const textNode = parseTextToken({
1683
+ ...token,
1684
+ content
1685
+ });
1686
+ if (handleInlineLinkContent(content, token)) return;
1687
+ const preToken = tokens[i - 1];
1688
+ if (currentTextNode) {
1689
+ currentTextNode.content += textNode.content.replace(/(\*+|\(|\\)$/, "");
1690
+ currentTextNode.raw += textNode.raw;
1691
+ } else {
1692
+ const maybeMath = preToken?.tag === "br" && tokens[i - 2]?.content === "[";
1693
+ if (!tokens[i + 1]) textNode.content = textNode.content.replace(/(\*+|\(|\\)$/, "");
1694
+ currentTextNode = textNode;
1695
+ currentTextNode.center = maybeMath;
1696
+ result.push(currentTextNode);
1697
+ }
1698
+ i++;
1699
+ }
1700
+ function handleLinkOpen(token) {
1701
+ resetCurrentTextNode();
1702
+ const href = token.attrs?.find(([name]) => name === "href")?.[1];
1703
+ function escapeRegExp(str) {
1704
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1705
+ }
1706
+ if (raw && tokens[i + 1].type === "text") {
1707
+ const text = String(tokens[i + 1]?.content ?? "");
1708
+ const escText = escapeRegExp(text);
1709
+ if (!(/* @__PURE__ */ new RegExp(`\\[${escText}\\s*\\]`)).test(raw)) {
1710
+ pushText(text, text);
1711
+ i += 3;
1712
+ return;
1713
+ }
1714
+ }
1715
+ if (raw && href) {
1716
+ const loadingMath = /* @__PURE__ */ new RegExp(`\\(\\s*${escapeRegExp(href)}\\s*\\)`);
1717
+ const pre = result.length > 0 ? result[result.length - 1] : void 0;
1718
+ const loading = !loadingMath.test(raw);
1719
+ if (loading && pre) {
1720
+ let preText = "";
1721
+ if (pre) {
1722
+ if (pre.type === "link") preText = String(pre.text ?? "");
1723
+ else if (pre.type === "text") preText = String(pre.content ?? "");
1724
+ else if (pre.content && typeof pre.content === "string") preText = String(pre.content ?? "").slice(1, -1);
1725
+ }
1726
+ if ((/* @__PURE__ */ new RegExp(`\\[${escapeRegExp(preText)}\\s*\\]\\(`)).test(raw)) {
1727
+ const text = String(preText ?? "");
1728
+ resetCurrentTextNode();
1729
+ const node$1 = {
1730
+ type: "link",
1731
+ href: "",
1732
+ title: null,
1733
+ text,
1734
+ children: [{
1735
+ type: "text",
1736
+ content: text,
1737
+ raw: text
1738
+ }],
1739
+ loading
1740
+ };
1741
+ result.splice(result.length - 1, 1, node$1);
1742
+ i += 3;
1743
+ if (String(tokens[i]?.content ?? "") === ".") i++;
1744
+ return;
1745
+ }
1746
+ }
1747
+ }
1748
+ const { node, nextIndex } = parseLinkToken(tokens, i);
1749
+ i = nextIndex;
1750
+ node.loading = false;
1751
+ pushParsed(node);
1752
+ }
1753
+ function handleReference(token) {
1754
+ resetCurrentTextNode();
1755
+ const nextToken = tokens[i + 1];
1756
+ const preToken = tokens[i - 1];
1757
+ const preResult = result[result.length - 1];
1758
+ const nextIsTextNotStartingParens = nextToken?.type === "text" && !String(nextToken.content ?? "").startsWith("(");
1759
+ const preIsTextEndingBracketOrOnlySpace = preToken?.type === "text" && /\]$|^\s*$/.test(String(preToken.content ?? ""));
1760
+ if (nextIsTextNotStartingParens || preIsTextEndingBracketOrOnlySpace) pushNode(parseReferenceToken(token));
1761
+ else if (nextToken && nextToken.type === "text") nextToken.content = String(token.markup ?? "") + String(nextToken.content ?? "");
1762
+ else if (preResult && preResult.type === "text") {
1763
+ preResult.content = String(preResult.content ?? "") + String(token.markup ?? "");
1764
+ preResult.raw = String(preResult.raw ?? "") + String(token.markup ?? "");
1765
+ }
1766
+ i++;
1767
+ }
1768
+ function handleInlineLinkContent(content, _token) {
1769
+ const linkStart = content.indexOf("[");
1770
+ if (linkStart === -1) return false;
1771
+ let textNodeContent = content.slice(0, linkStart);
1772
+ const linkEnd = content.indexOf("](", linkStart);
1773
+ if (linkEnd !== -1) {
1774
+ const textToken = tokens[i + 2];
1775
+ let text = content.slice(linkStart + 1, linkEnd);
1776
+ if (text.includes("[")) {
1777
+ const secondLinkStart = text.indexOf("[");
1778
+ textNodeContent += content.slice(0, linkStart + secondLinkStart + 1);
1779
+ const newLinkStart = linkStart + secondLinkStart + 1;
1780
+ text = content.slice(newLinkStart + 1, linkEnd);
1781
+ }
1782
+ const nextToken = tokens[i + 1];
1783
+ if (content.endsWith("](") && nextToken?.type === "link_open" && textToken) {
1784
+ const last = tokens[i + 4];
1785
+ let index = 4;
1786
+ let loading$1 = true;
1787
+ if (last?.type === "text" && last.content === ")") {
1788
+ index++;
1789
+ loading$1 = false;
1790
+ } else if (last?.type === "text" && last.content === ".") i++;
1791
+ if (textNodeContent) pushText(textNodeContent, textNodeContent);
1792
+ pushParsed({
1793
+ type: "link",
1794
+ href: String(textToken.content ?? ""),
1795
+ title: null,
1796
+ text,
1797
+ children: [{
1798
+ type: "text",
1799
+ content: text,
1800
+ raw: text
1801
+ }],
1802
+ loading: loading$1
1803
+ });
1804
+ i += index;
1805
+ return true;
1806
+ }
1807
+ const linkContentEnd = content.indexOf(")", linkEnd);
1808
+ const href = linkContentEnd !== -1 ? content.slice(linkEnd + 2, linkContentEnd) : "";
1809
+ const loading = linkContentEnd === -1;
1810
+ if (textNodeContent) pushText(textNodeContent, textNodeContent);
1811
+ pushParsed({
1812
+ type: "link",
1813
+ href,
1814
+ title: null,
1815
+ text,
1816
+ children: [{
1817
+ type: "text",
1818
+ content: text,
1819
+ raw: text
1820
+ }],
1821
+ loading
1822
+ });
1823
+ const afterText = linkContentEnd !== -1 ? content.slice(linkContentEnd + 1) : "";
1824
+ if (afterText) {
1825
+ handleToken({
1826
+ type: "text",
1827
+ content: afterText,
1828
+ raw: afterText
1829
+ });
1830
+ i--;
1831
+ }
1832
+ i++;
1833
+ return true;
1834
+ }
1835
+ return false;
1836
+ }
1837
+ function handleInlineImageContent(content, token) {
1838
+ const imageStart = content.indexOf("![");
1839
+ if (imageStart === -1) return false;
1840
+ const textNodeContent = content.slice(0, imageStart);
1841
+ if (!currentTextNode) currentTextNode = {
1842
+ type: "text",
1843
+ content: textNodeContent,
1844
+ raw: textNodeContent
1845
+ };
1846
+ else currentTextNode.content += textNodeContent;
1847
+ result.push(currentTextNode);
1848
+ currentTextNode = null;
1849
+ pushParsed(parseImageToken(token, true));
1850
+ i++;
1851
+ return true;
1852
+ }
1853
+ function handleCheckboxLike(content) {
1854
+ if (!(content?.startsWith("[") && pPreToken?.type === "list_item_open")) return false;
1855
+ const w = content.slice(1).match(/[^\s\]]/);
1856
+ if (w === null) {
1857
+ i++;
1858
+ return true;
1859
+ }
1860
+ if (w && /x/i.test(w[0])) {
1861
+ const checked = w[0] === "x" || w[0] === "X";
1862
+ pushParsed({
1863
+ type: "checkbox_input",
1864
+ checked,
1865
+ raw: checked ? "[x]" : "[ ]"
1866
+ });
1867
+ i++;
1868
+ return true;
1869
+ }
1870
+ return false;
1871
+ }
1728
1872
  return result;
1729
1873
  }
1730
1874
 
@@ -1738,7 +1882,7 @@ function parseBlockquote(tokens, index) {
1738
1882
  blockquoteChildren.push({
1739
1883
  type: "paragraph",
1740
1884
  children: parseInlineTokens(contentToken.children || []),
1741
- raw: contentToken.content || ""
1885
+ raw: String(contentToken.content ?? "")
1742
1886
  });
1743
1887
  j += 3;
1744
1888
  } else if (tokens[j].type === "bullet_list_open" || tokens[j].type === "ordered_list_open") {
@@ -1757,14 +1901,15 @@ function parseBlockquote(tokens, index) {
1757
1901
  //#region src/parser/node-parsers/code-block-parser.ts
1758
1902
  function parseCodeBlock(token) {
1759
1903
  if (token.info?.startsWith("diff")) return parseFenceToken(token);
1760
- const match = token.content.match(/ type="application\/vnd\.ant\.([^"]+)"/);
1761
- if (match?.[1]) token.content = token.content.replace(/<antArtifact[^>]*>/g, "").replace(/<\/antArtifact>/g, "");
1904
+ const contentStr = String(token.content ?? "");
1905
+ const match = contentStr.match(/ type="application\/vnd\.ant\.([^"]+)"/);
1906
+ if (match?.[1]) token.content = contentStr.replace(/<antArtifact[^>]*>/g, "").replace(/<\/antArtifact>/g, "");
1762
1907
  const hasMap = Array.isArray(token.map) && token.map.length === 2;
1763
1908
  return {
1764
1909
  type: "code_block",
1765
- language: match ? match[1] : token.info || "",
1766
- code: token.content || "",
1767
- raw: token.content || "",
1910
+ language: match ? match[1] : String(token.info ?? ""),
1911
+ code: String(token.content ?? ""),
1912
+ raw: String(token.content ?? ""),
1768
1913
  loading: !hasMap
1769
1914
  };
1770
1915
  }
@@ -1787,8 +1932,8 @@ function parseDefinitionList(tokens, index) {
1787
1932
  const contentToken = tokens[k + 1];
1788
1933
  definitionNodes.push({
1789
1934
  type: "paragraph",
1790
- children: parseInlineTokens(contentToken.children || [], contentToken.content || ""),
1791
- raw: contentToken.content || ""
1935
+ children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? "")),
1936
+ raw: String(contentToken.content ?? "")
1792
1937
  });
1793
1938
  k += 3;
1794
1939
  } else k++;
@@ -1813,7 +1958,8 @@ function parseDefinitionList(tokens, index) {
1813
1958
  //#endregion
1814
1959
  //#region src/parser/node-parsers/footnote-parser.ts
1815
1960
  function parseFootnote(tokens, index) {
1816
- const id = tokens[index].meta?.label ?? 0;
1961
+ const meta = tokens[index].meta ?? {};
1962
+ const id = String(meta?.label ?? "0");
1817
1963
  const footnoteChildren = [];
1818
1964
  let j = index + 1;
1819
1965
  while (j < tokens.length && tokens[j].type !== "footnote_close") if (tokens[j].type === "paragraph_open") {
@@ -1821,7 +1967,7 @@ function parseFootnote(tokens, index) {
1821
1967
  footnoteChildren.push({
1822
1968
  type: "paragraph",
1823
1969
  children: parseInlineTokens(contentToken.children || []),
1824
- raw: contentToken.content || ""
1970
+ raw: String(contentToken.content ?? "")
1825
1971
  });
1826
1972
  j += 3;
1827
1973
  } else j++;
@@ -1837,9 +1983,10 @@ function parseFootnote(tokens, index) {
1837
1983
  //#region src/parser/node-parsers/heading-parser.ts
1838
1984
  function parseHeading(tokens, index) {
1839
1985
  const token = tokens[index];
1840
- const headingLevel = Number.parseInt(token.tag?.substring(1) || "1");
1986
+ const levelStr = String(token.tag?.substring(1) ?? "1");
1987
+ const headingLevel = Number.parseInt(levelStr, 10);
1841
1988
  const headingContentToken = tokens[index + 1];
1842
- const headingContent = headingContentToken.content || "";
1989
+ const headingContent = String(headingContentToken.content ?? "");
1843
1990
  return {
1844
1991
  type: "heading",
1845
1992
  level: headingLevel,
@@ -1854,9 +2001,9 @@ function parseHeading(tokens, index) {
1854
2001
  function parseMathBlock(token) {
1855
2002
  return {
1856
2003
  type: "math_block",
1857
- content: token.content || "",
2004
+ content: String(token.content ?? ""),
1858
2005
  loading: !!token.loading,
1859
- raw: token.raw || ""
2006
+ raw: String(token.raw ?? "")
1860
2007
  };
1861
2008
  }
1862
2009
 
@@ -1880,7 +2027,7 @@ function parseTable(tokens, index) {
1880
2027
  while (k < tokens.length && tokens[k].type !== "tr_close") if (tokens[k].type === "th_open" || tokens[k].type === "td_open") {
1881
2028
  const isHeaderCell = tokens[k].type === "th_open";
1882
2029
  const contentToken = tokens[k + 1];
1883
- const content = contentToken.content || "";
2030
+ const content = String(contentToken.content ?? "");
1884
2031
  cells.push({
1885
2032
  type: "table_cell",
1886
2033
  header: isHeaderCell || isHeader,
@@ -1907,7 +2054,7 @@ function parseTable(tokens, index) {
1907
2054
  type: "table",
1908
2055
  header: headerRow,
1909
2056
  rows,
1910
- loading: tokens[index].loading || false,
2057
+ loading: tokens[index].loading ?? false,
1911
2058
  raw: [headerRow, ...rows].map((row) => row.raw).join("\n")
1912
2059
  }, j + 1];
1913
2060
  }
@@ -1933,14 +2080,15 @@ function parseList(tokens, index) {
1933
2080
  while (k < tokens.length && tokens[k].type !== "list_item_close") if (tokens[k].type === "paragraph_open") {
1934
2081
  const contentToken = tokens[k + 1];
1935
2082
  const preToken = tokens[k - 1];
1936
- if (/\n\d+$/.test(contentToken.content || "")) {
1937
- contentToken.content = contentToken.content?.replace(/\n\d+$/, "");
2083
+ const contentStr = String(contentToken.content ?? "");
2084
+ if (/\n\d+$/.test(contentStr)) {
2085
+ contentToken.content = contentStr.replace(/\n\d+$/, "");
1938
2086
  contentToken.children?.splice(-1, 1);
1939
2087
  }
1940
2088
  itemChildren.push({
1941
2089
  type: "paragraph",
1942
- children: parseInlineTokens(contentToken.children || [], contentToken.content || "", preToken),
1943
- raw: contentToken.content || ""
2090
+ children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), preToken),
2091
+ raw: String(contentToken.content ?? "")
1944
2092
  });
1945
2093
  k += 3;
1946
2094
  } else if (tokens[k].type === "blockquote_open") {
@@ -1984,7 +2132,7 @@ function parseList(tokens, index) {
1984
2132
  itemChildren.push(parseThematicBreak());
1985
2133
  k += 1;
1986
2134
  } else if (tokens[k].type === "container_open") {
1987
- const match = /^::: ?(warning|info|note|tip|danger|caution) ?(.*)$/.exec(tokens[k].info || "");
2135
+ const match = /^::: ?(warning|info|note|tip|danger|caution) ?(.*)$/.exec(String(tokens[k].info ?? ""));
1988
2136
  if (match) {
1989
2137
  const [admonitionNode, newIndex] = parseAdmonition(tokens, k, match);
1990
2138
  itemChildren.push(admonitionNode);
@@ -2004,7 +2152,10 @@ function parseList(tokens, index) {
2004
2152
  start: (() => {
2005
2153
  if (token.attrs && token.attrs.length) {
2006
2154
  const found = token.attrs.find((a) => a[0] === "start");
2007
- if (found) return Number(found[1]) || 1;
2155
+ if (found) {
2156
+ const parsed = Number(found[1]);
2157
+ return Number.isFinite(parsed) && parsed !== 0 ? parsed : 1;
2158
+ }
2008
2159
  }
2009
2160
  })(),
2010
2161
  items: listItems,
@@ -2023,8 +2174,8 @@ function parseNestedList(tokens, index) {
2023
2174
  const preToken = tokens[k - 1];
2024
2175
  itemChildren.push({
2025
2176
  type: "paragraph",
2026
- children: parseInlineTokens(contentToken.children || [], contentToken.content || "", preToken),
2027
- raw: contentToken.content || ""
2177
+ children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), preToken),
2178
+ raw: String(contentToken.content ?? "")
2028
2179
  });
2029
2180
  k += 3;
2030
2181
  } else if (tokens[k].type === "bullet_list_open" || tokens[k].type === "ordered_list_open") {
@@ -2058,7 +2209,10 @@ function parseNestedList(tokens, index) {
2058
2209
  start: (() => {
2059
2210
  if (nestedToken.attrs && nestedToken.attrs.length) {
2060
2211
  const found = nestedToken.attrs.find((a) => a[0] === "start");
2061
- if (found) return Number(found[1]) || 1;
2212
+ if (found) {
2213
+ const parsed = Number(found[1]);
2214
+ return Number.isFinite(parsed) && parsed !== 0 ? parsed : 1;
2215
+ }
2062
2216
  }
2063
2217
  })(),
2064
2218
  items: nestedItems,
@@ -2069,8 +2223,8 @@ function parseNestedList(tokens, index) {
2069
2223
  //#endregion
2070
2224
  //#region src/parser/node-parsers/admonition-parser.ts
2071
2225
  function parseAdmonition(tokens, index, match) {
2072
- const kind = match[1] || "note";
2073
- const title = match[2] || kind.charAt(0).toUpperCase() + kind.slice(1);
2226
+ const kind = String(match[1] ?? "note");
2227
+ const title = String(match[2] ?? kind.charAt(0).toUpperCase() + kind.slice(1));
2074
2228
  const admonitionChildren = [];
2075
2229
  let j = index + 1;
2076
2230
  while (j < tokens.length && tokens[j].type !== "container_close") if (tokens[j].type === "paragraph_open") {
@@ -2078,7 +2232,7 @@ function parseAdmonition(tokens, index, match) {
2078
2232
  if (contentToken) admonitionChildren.push({
2079
2233
  type: "paragraph",
2080
2234
  children: parseInlineTokens(contentToken.children || []),
2081
- raw: contentToken.content || ""
2235
+ raw: String(contentToken.content ?? "")
2082
2236
  });
2083
2237
  j += 3;
2084
2238
  } else if (tokens[j].type === "bullet_list_open" || tokens[j].type === "ordered_list_open") {
@@ -2104,17 +2258,17 @@ function parseContainer(tokens, index) {
2104
2258
  const typeMatch = openToken.type.match(/^container_(\w+)_open$/);
2105
2259
  if (typeMatch) {
2106
2260
  kind = typeMatch[1];
2107
- const info = (openToken.info || "").trim();
2261
+ const info = String(openToken.info ?? "").trim();
2108
2262
  if (info && !info.startsWith(":::")) {
2109
2263
  const maybe = info.replace(/* @__PURE__ */ new RegExp(`^${kind}`), "").trim();
2110
2264
  if (maybe) title = maybe;
2111
2265
  }
2112
2266
  } else {
2113
- const info = (openToken.info || "").trim();
2267
+ const info = String(openToken.info ?? "").trim();
2114
2268
  const match = /^:{1,3}\s*(warning|info|note|tip|danger|caution)\s*(.*)$/i.exec(info);
2115
2269
  if (match) {
2116
2270
  kind = match[1];
2117
- title = match[2] || "";
2271
+ title = String(match[2] ?? "");
2118
2272
  }
2119
2273
  }
2120
2274
  if (!title) title = kind.charAt(0).toUpperCase() + kind.slice(1);
@@ -2124,12 +2278,20 @@ function parseContainer(tokens, index) {
2124
2278
  while (j < tokens.length && tokens[j].type !== "container_close" && !closeType.test(tokens[j].type)) if (tokens[j].type === "paragraph_open") {
2125
2279
  const contentToken = tokens[j + 1];
2126
2280
  if (contentToken) {
2127
- const i = contentToken.children.findLastIndex((t) => t.type === "text" && /:+/.test(t.content));
2128
- const _children = i !== -1 ? contentToken.children?.slice(0, i) : contentToken.children;
2281
+ const childrenArr = contentToken.children || [];
2282
+ let i = -1;
2283
+ for (let k = childrenArr.length - 1; k >= 0; k--) {
2284
+ const t = childrenArr[k];
2285
+ if (t.type === "text" && /:+/.test(t.content)) {
2286
+ i = k;
2287
+ break;
2288
+ }
2289
+ }
2290
+ const _children = i !== -1 ? childrenArr.slice(0, i) : childrenArr;
2129
2291
  children.push({
2130
2292
  type: "paragraph",
2131
2293
  children: parseInlineTokens(_children || []),
2132
- raw: contentToken.content?.replace(/\n:+$/, "").replace(/\n\s*:::\s*$/, "") || ""
2294
+ raw: String(contentToken.content ?? "").replace(/\n:+$/, "").replace(/\n\s*:::\s*$/, "")
2133
2295
  });
2134
2296
  }
2135
2297
  j += 3;
@@ -2160,7 +2322,7 @@ function parseHardBreak() {
2160
2322
  //#region src/parser/node-parsers/paragraph-parser.ts
2161
2323
  function parseParagraph(tokens, index) {
2162
2324
  const paragraphContentToken = tokens[index + 1];
2163
- const paragraphContent = paragraphContentToken.content || "";
2325
+ const paragraphContent = String(paragraphContentToken.content ?? "");
2164
2326
  return {
2165
2327
  type: "paragraph",
2166
2328
  children: parseInlineTokens(paragraphContentToken.children || [], paragraphContent),
@@ -2182,7 +2344,15 @@ function parseMarkdownToStructure(markdown, md, options = {}) {
2182
2344
  let transformedTokens = tokens;
2183
2345
  if (pre && typeof pre === "function") transformedTokens = pre(tokens) || tokens;
2184
2346
  let result = processTokens(transformedTokens);
2185
- if (post && typeof post === "function") result = post(transformedTokens) || transformedTokens;
2347
+ if (post && typeof post === "function") {
2348
+ const postResult = post(transformedTokens);
2349
+ if (Array.isArray(postResult)) {
2350
+ const first = postResult[0];
2351
+ const firstType = first?.type;
2352
+ if (first && typeof firstType === "string") result = processTokens(postResult);
2353
+ else result = postResult;
2354
+ }
2355
+ }
2186
2356
  return result;
2187
2357
  }
2188
2358
  function processTokens(tokens) {
@@ -2258,7 +2428,7 @@ function processTokens(tokens) {
2258
2428
  break;
2259
2429
  }
2260
2430
  case "container_open": {
2261
- const match = /^::: ?(warning|info|note|tip|danger|caution|error) ?(.*)$/.exec(token.info || "");
2431
+ const match = /^::: ?(warning|info|note|tip|danger|caution|error) ?(.*)$/.exec(String(token.info ?? ""));
2262
2432
  if (match) {
2263
2433
  const [admonitionNode, newIndex] = parseAdmonition(tokens, i, match);
2264
2434
  result.push(admonitionNode);
@@ -2293,8 +2463,14 @@ function getMarkdown(msgId = `editor-${Date.now()}`, options = {}) {
2293
2463
  const i18nMap = options.i18n;
2294
2464
  t = (key) => i18nMap[key] ?? defaultTranslations[key] ?? key;
2295
2465
  } else t = (key) => defaultTranslations[key] ?? key;
2296
- if (Array.isArray(options.plugin)) for (const p of options.plugin) if (Array.isArray(p)) md.use(p[0], p[1]);
2297
- else md.use(p);
2466
+ if (Array.isArray(options.plugin)) for (const p of options.plugin) {
2467
+ const pluginItem = p;
2468
+ if (Array.isArray(pluginItem)) {
2469
+ const fn = pluginItem[0];
2470
+ const opts = pluginItem[1];
2471
+ if (typeof fn === "function") md.use(fn, opts);
2472
+ } else if (typeof pluginItem === "function") md.use(pluginItem);
2473
+ }
2298
2474
  if (Array.isArray(options.apply)) for (const fn of options.apply) try {
2299
2475
  fn(md);
2300
2476
  } catch (e) {
@@ -2309,8 +2485,9 @@ function getMarkdown(msgId = `editor-${Date.now()}`, options = {}) {
2309
2485
  md.use(markdownItIns);
2310
2486
  md.use(markdownItFootnote);
2311
2487
  md.core.ruler.after("block", "mark_fence_closed", (state) => {
2312
- const lines = state.src.split(/\r?\n/);
2313
- for (const token of state.tokens) {
2488
+ const s = state;
2489
+ const lines = s.src.split(/\r?\n/);
2490
+ for (const token of s.tokens) {
2314
2491
  if (token.type !== "fence" || !token.map || !token.markup) continue;
2315
2492
  const openLine = token.map[0];
2316
2493
  const endLine = token.map[1];
@@ -2325,33 +2502,35 @@ function getMarkdown(msgId = `editor-${Date.now()}`, options = {}) {
2325
2502
  let j = i + count;
2326
2503
  while (j < line.length && (line[j] === " " || line[j] === " ")) j++;
2327
2504
  const closed = endLine > openLine + 1 && count >= minLen && j === line.length;
2328
- token.meta = token.meta || {};
2329
- token.meta.unclosed = !closed;
2330
- token.meta.closed = !!closed;
2505
+ const tokenShape = token;
2506
+ tokenShape.meta = tokenShape.meta ?? {};
2507
+ tokenShape.meta.unclosed = !closed;
2508
+ tokenShape.meta.closed = !!closed;
2331
2509
  }
2332
2510
  });
2333
2511
  const waveRule = (state, silent) => {
2334
- const start = state.pos;
2335
- if (state.src[start] !== "~") return false;
2336
- const prevChar = state.src[start - 1];
2337
- const nextChar = state.src[start + 1];
2512
+ const s = state;
2513
+ const start = s.pos;
2514
+ if (s.src[start] !== "~") return false;
2515
+ const prevChar = s.src[start - 1];
2516
+ const nextChar = s.src[start + 1];
2338
2517
  if (/\d/.test(prevChar) && /\d/.test(nextChar)) {
2339
2518
  if (!silent) {
2340
- const token = state.push("text", "", 0);
2519
+ const token = s.push("text", "", 0);
2341
2520
  token.content = "~";
2342
2521
  }
2343
- state.pos += 1;
2522
+ s.pos += 1;
2344
2523
  return true;
2345
2524
  }
2346
2525
  return false;
2347
2526
  };
2348
2527
  md.inline.ruler.before("sub", "wave", waveRule);
2349
2528
  md.renderer.rules.fence = (tokens, idx) => {
2350
- const token = tokens[idx];
2351
- const info = token.info ? token.info.trim() : "";
2352
- const str = token.content;
2529
+ const tokenShape = tokens[idx];
2530
+ const info = String(tokenShape.info ?? "").trim();
2531
+ const str = String(tokenShape.content ?? "");
2353
2532
  const encodedCode = btoa(unescape(encodeURIComponent(str)));
2354
- const language = info || "text";
2533
+ const language = String(info ?? "text");
2355
2534
  return `<div class="code-block" data-code="${encodedCode}" data-lang="${language}" id="${`editor-${msgId}-${idx}-${language}`}">
2356
2535
  <div class="code-header">
2357
2536
  <span class="code-lang">${language.toUpperCase()}</span>
@@ -2361,21 +2540,23 @@ function getMarkdown(msgId = `editor-${Date.now()}`, options = {}) {
2361
2540
  </div>`;
2362
2541
  };
2363
2542
  const referenceInline = (state, silent) => {
2364
- if (state.src[state.pos] !== "[") return false;
2365
- const match = /^\[(\d+)\]/.exec(state.src.slice(state.pos));
2543
+ const s = state;
2544
+ if (s.src[s.pos] !== "[") return false;
2545
+ const match = /^\[(\d+)\]/.exec(s.src.slice(s.pos));
2366
2546
  if (!match) return false;
2367
2547
  if (!silent) {
2368
2548
  const id = match[1];
2369
- const token = state.push("reference", "span", 0);
2549
+ const token = s.push("reference", "span", 0);
2370
2550
  token.content = id;
2371
2551
  token.markup = match[0];
2372
2552
  }
2373
- state.pos += match[0].length;
2553
+ s.pos += match[0].length;
2374
2554
  return true;
2375
2555
  };
2376
2556
  md.inline.ruler.before("escape", "reference", referenceInline);
2377
2557
  md.renderer.rules.reference = (tokens, idx) => {
2378
- const id = tokens[idx].content;
2558
+ const tokensAny = tokens;
2559
+ const id = String(tokensAny[idx].content ?? "");
2379
2560
  return `<span class="reference-link" data-reference-id="${id}" role="button" tabindex="0" title="Click to view reference">${id}</span>`;
2380
2561
  };
2381
2562
  return md;