@ai-react-markdown/engine 2.4.1 → 2.4.3

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.
@@ -295,6 +295,10 @@ var TAG_OR_COMMENT_RE = /<(\/?)([A-Za-z][A-Za-z0-9-]*)(?=[\s/>])([^>]*)>|<!--|--
295
295
  var TRUNCATED_TAG_RE = /<(\/?)([A-Za-z][A-Za-z0-9-]*)([^<>]*)$/;
296
296
  var REF_RE = /!?\[((?:[^[\]\\]|\\.)*)\]/g;
297
297
  var BACKTICK_RUN_RE = /`+/g;
298
+ var MD_BLANK_RE = /^[ \t\r]*$/;
299
+ var isMdBlank = (text) => MD_BLANK_RE.test(text);
300
+ var mdTrim = (text) => text.replace(/^[ \t\r]+|[ \t\r]+$/g, "");
301
+ var mdTrimStart = (text) => text.replace(/^[ \t\r]+/, "");
298
302
  function computeIndent(text) {
299
303
  let indent = 0;
300
304
  for (const ch of text) {
@@ -304,8 +308,25 @@ function computeIndent(text) {
304
308
  }
305
309
  return indent;
306
310
  }
311
+ function firstUnescaped(text, ch) {
312
+ for (let i = 0; i < text.length; i++) {
313
+ if (text[i] === "\\") i += 1;
314
+ else if (text[i] === ch) return i;
315
+ }
316
+ return -1;
317
+ }
318
+ function lastUnclosedBracket(text) {
319
+ let open = -1;
320
+ for (let i = 0; i < text.length; i++) {
321
+ const c = text[i];
322
+ if (c === "\\") i += 1;
323
+ else if (c === "[") open = i;
324
+ else if (c === "]") open = -1;
325
+ }
326
+ return open;
327
+ }
307
328
  function normalizeLabel(label) {
308
- const collapsed = label.trim().replace(/[ \t\r\n]+/g, " ");
329
+ const collapsed = label.replace(/[ \t\r\n]+/g, " ").replace(/^ | $/g, "");
309
330
  return collapsed ? (0, import_micromark_util_normalize_identifier.normalizeIdentifier)(collapsed) : "";
310
331
  }
311
332
  function canBecomeDdLine(text, confirmed) {
@@ -382,6 +403,7 @@ function freshCheckpoint(defListEnabled, mathFlow, referenceTaint) {
382
403
  prevLineWasText: false,
383
404
  prevLineWasValidDef: false,
384
405
  paragraphHasUnpairedRun: false,
406
+ openBracket: null,
385
407
  htmlFlowSinceBlank: false,
386
408
  htmlSeamPending: false,
387
409
  phasePoisonedAt: Infinity,
@@ -389,11 +411,11 @@ function freshCheckpoint(defListEnabled, mathFlow, referenceTaint) {
389
411
  };
390
412
  }
391
413
  function isPlausibleLinkDefRest(rest) {
392
- const t = rest.trim();
414
+ const t = mdTrim(rest);
393
415
  if (t === "") return false;
394
416
  const destEnd = linkDestinationEnd(t);
395
417
  if (destEnd === -1) return false;
396
- const after = t.slice(destEnd).trim();
418
+ const after = mdTrim(t.slice(destEnd));
397
419
  if (after === "") return true;
398
420
  const opener = after[0];
399
421
  if (opener !== '"' && opener !== "'" && opener !== "(") return false;
@@ -403,7 +425,7 @@ function isPlausibleLinkDefRest(rest) {
403
425
  i += 1;
404
426
  continue;
405
427
  }
406
- if (after[i] === closer) return after.slice(i + 1).trim() === "";
428
+ if (after[i] === closer) return isMdBlank(after.slice(i + 1));
407
429
  }
408
430
  return false;
409
431
  }
@@ -440,6 +462,36 @@ function linkDestinationEnd(t) {
440
462
  if (balance !== 0 || i === 0) return -1;
441
463
  return i;
442
464
  }
465
+ function inlineResourceEnd(text, openIdx) {
466
+ let i = openIdx + 1;
467
+ const skipWs = () => {
468
+ while (i < text.length && (text[i] === " " || text[i] === " ")) i += 1;
469
+ };
470
+ skipWs();
471
+ if (text[i] === ")") return i + 1;
472
+ const destEnd = linkDestinationEnd(text.slice(i));
473
+ if (destEnd === -1) return -1;
474
+ i += destEnd;
475
+ const beforeWs = i;
476
+ skipWs();
477
+ if (text[i] === ")") return i + 1;
478
+ if (i === beforeWs) return -1;
479
+ const opener = text[i];
480
+ if (opener !== '"' && opener !== "'" && opener !== "(") return -1;
481
+ const closer = opener === "(" ? ")" : opener;
482
+ for (i += 1; i < text.length; i++) {
483
+ if (text[i] === "\\") {
484
+ i += 1;
485
+ continue;
486
+ }
487
+ if (text[i] === closer) {
488
+ i += 1;
489
+ skipWs();
490
+ return text[i] === ")" ? i + 1 : -1;
491
+ }
492
+ }
493
+ return -1;
494
+ }
443
495
  function classifyBlockStart(text, indent, defListEnabled) {
444
496
  if (indent >= 4) return true;
445
497
  if (LIST_MARKER_RE.test(text) || FOOTNOTE_DEF_RE.test(text)) return true;
@@ -457,12 +509,13 @@ function computeFreezeBoundary(text, options, resume) {
457
509
  let end = text.indexOf("\n", start);
458
510
  if (end === -1) end = text.length;
459
511
  const confirmed = end < text.length;
460
- const lineText = text.slice(start, end);
512
+ const rawLine = text.slice(start, end);
513
+ const lineText = rawLine.endsWith("\r") ? rawLine.slice(0, -1) : rawLine;
461
514
  const ln = {
462
515
  start,
463
516
  end,
464
517
  text: lineText,
465
- blank: confirmed && lineText.trim() === "",
518
+ blank: confirmed && isMdBlank(lineText),
466
519
  indent: computeIndent(lineText)
467
520
  };
468
521
  if (!confirmed) {
@@ -551,7 +604,7 @@ function processConfirmedLine(cp, ln, text) {
551
604
  const isBlockStart = cp.prevLineBlank;
552
605
  if (cp.htmlSeamPending && !ln.blank && !cp.htmlFlowSinceBlank && !(cp.commentOpen || cp.piOpen || cp.declOpen || cp.cdataOpen)) {
553
606
  const defShapedLine = DEF_RE.test(ln.text) || FOOTNOTE_DEF_RE.test(ln.text);
554
- const commentOnly = ln.text.replace(/<!--[\s\S]*?-->/g, " ").replace(/<!--[\s\S]*$/, " ").trim() === "";
607
+ const commentOnly = ln.text.replace(/<!--[\s\S]*?-->/g, " ").replace(/<!--[\s\S]*$/, " ").replace(/[ \t\r]/g, "") === "";
555
608
  if (!defShapedLine && !commentOnly) {
556
609
  cp.htmlSeamPending = false;
557
610
  }
@@ -572,13 +625,14 @@ function processConfirmedLine(cp, ln, text) {
572
625
  const rawOpenAtLineStart = cp.commentOpen || cp.piOpen || cp.declOpen || cp.cdataOpen;
573
626
  if (cp.inFence) {
574
627
  const close = FENCE_RE.exec(ln.text);
575
- if (close && close[1][0] === cp.fenceChar && close[1].length >= cp.fenceLen && ln.text.trim() === close[1]) {
628
+ if (close && close[1][0] === cp.fenceChar && close[1].length >= cp.fenceLen && isMdBlank(ln.text.slice(close[0].length))) {
576
629
  cp.inFence = false;
577
630
  cp.fenceChar = "";
578
631
  cp.fenceLen = 0;
579
632
  }
580
633
  cp.blankRun = 0;
581
634
  cp.paragraphHasUnpairedRun = false;
635
+ cp.openBracket = null;
582
636
  cp.prevLineBlank = false;
583
637
  cp.prevLineWasText = false;
584
638
  cp.prevLineWasValidDef = false;
@@ -600,6 +654,7 @@ function processConfirmedLine(cp, ln, text) {
600
654
  cp.openIndent = ln.indent;
601
655
  cp.blankRun = 0;
602
656
  cp.paragraphHasUnpairedRun = false;
657
+ cp.openBracket = null;
603
658
  cp.prevLineBlank = false;
604
659
  cp.prevLineWasText = false;
605
660
  cp.prevLineWasValidDef = false;
@@ -608,12 +663,13 @@ function processConfirmedLine(cp, ln, text) {
608
663
  }
609
664
  if (cp.inMath) {
610
665
  const close = MATH_RUN_RE.exec(ln.text);
611
- if (close && close[1].length >= cp.mathFenceLen && ln.text.trim() === close[1]) {
666
+ if (close && close[1].length >= cp.mathFenceLen && isMdBlank(ln.text.slice(close[0].length))) {
612
667
  cp.inMath = false;
613
668
  cp.mathFenceLen = 0;
614
669
  }
615
670
  cp.blankRun = 0;
616
671
  cp.paragraphHasUnpairedRun = false;
672
+ cp.openBracket = null;
617
673
  cp.prevLineBlank = false;
618
674
  cp.prevLineWasText = false;
619
675
  cp.prevLineWasValidDef = false;
@@ -635,6 +691,7 @@ function processConfirmedLine(cp, ln, text) {
635
691
  cp.openIndent = ln.indent;
636
692
  cp.blankRun = 0;
637
693
  cp.paragraphHasUnpairedRun = false;
694
+ cp.openBracket = null;
638
695
  cp.prevLineBlank = false;
639
696
  cp.prevLineWasText = false;
640
697
  cp.prevLineWasValidDef = false;
@@ -658,6 +715,7 @@ function processConfirmedLine(cp, ln, text) {
658
715
  defListSettled: null
659
716
  });
660
717
  cp.paragraphHasUnpairedRun = false;
718
+ cp.openBracket = null;
661
719
  cp.htmlFlowSinceBlank = false;
662
720
  cp.prevLineBlank = true;
663
721
  cp.prevLineWasText = false;
@@ -670,13 +728,13 @@ function processConfirmedLine(cp, ln, text) {
670
728
  } else if (LIST_MARKER_RE.test(ln.text) || FOOTNOTE_DEF_RE.test(ln.text) || cp.defListEnabled && DEF_LIST_DD_RE.test(ln.text) || ln.indent >= 4) {
671
729
  cp.hazardVerdict = true;
672
730
  }
673
- const tagStart = ln.indent <= 3 ? /^<\/?([A-Za-z][A-Za-z0-9-]*)/.exec(ln.text.trimStart()) : null;
731
+ const tagStart = ln.indent <= 3 ? /^<\/?([A-Za-z][A-Za-z0-9-]*)/.exec(mdTrimStart(ln.text)) : null;
674
732
  if (tagStart) {
675
733
  cp.htmlFlowSinceBlank = true;
676
734
  if (!TYPE6_NAMES.has(tagStart[1].toLowerCase())) cp.hazardVerdict = true;
677
735
  }
678
736
  const inRawText = cp.htmlFlowSinceBlank || rawOpenAtLineStart;
679
- const rawFlowStart = ln.indent <= 3 && /^<(?:!--|\?|![A-Za-z]|!\[CDATA\[)/.test(ln.text.trimStart());
737
+ const rawFlowStart = ln.indent <= 3 && /^<(?:!--|\?|![A-Za-z]|!\[CDATA\[)/.test(mdTrimStart(ln.text));
680
738
  const { masked, unpaired } = inRawText ? { masked: null, unpaired: false } : maskIntraLineCodeSpans(ln.text, cp.paragraphHasUnpairedRun);
681
739
  if (unpaired) cp.paragraphHasUnpairedRun = true;
682
740
  const scanText = masked ?? ln.text;
@@ -694,28 +752,50 @@ function processConfirmedLine(cp, ln, text) {
694
752
  if (key && !cp.defs.has(key)) cp.defs.set(key, ln.end);
695
753
  }
696
754
  }
697
- if (cp.referenceTaint && scanText.includes("[")) {
698
- const defBracket = validDef ? def.index + def[0].indexOf("[") : -1;
699
- REF_RE.lastIndex = 0;
700
- let m;
701
- while ((m = REF_RE.exec(scanText)) !== null) {
702
- const follow = scanText[m.index + m[0].length];
703
- if (follow === "(") continue;
704
- if (follow === ":" && m.index === defBracket) continue;
705
- const inner = m[1];
755
+ if (cp.referenceTaint) {
756
+ const pushRef = (offset, inner, followAt) => {
757
+ const follow = scanText[followAt];
758
+ if (follow === "(" && inlineResourceEnd(scanText, followAt) !== -1) return;
706
759
  let label;
707
760
  let footnote = false;
708
761
  if (inner.startsWith("^")) {
709
762
  footnote = true;
710
763
  label = normalizeLabel(inner.slice(1));
711
764
  } else if (follow === "[") {
712
- const explicit = /^\[((?:[^[\]\\]|\\.)*)\]/.exec(scanText.slice(m.index + m[0].length));
765
+ const explicit = /^\[((?:[^[\]\\]|\\.)*)\]/.exec(scanText.slice(followAt));
713
766
  label = normalizeLabel(explicit && explicit[1] ? explicit[1] : inner);
714
767
  } else {
715
768
  label = normalizeLabel(inner);
716
769
  }
717
- if (!label) continue;
718
- cp.unresolvedRefs.push({ offset: ln.start + m.index, label, footnote });
770
+ if (label) cp.unresolvedRefs.push({ offset, label, footnote });
771
+ };
772
+ const pending = cp.openBracket;
773
+ cp.openBracket = null;
774
+ if (pending) {
775
+ const close = firstUnescaped(scanText, "]");
776
+ const open = firstUnescaped(scanText, "[");
777
+ const cont = (t) => t.replace(/^ {0,3}>[ \t]?/, "");
778
+ if (close !== -1 && (open === -1 || close < open)) {
779
+ pushRef(pending.offset, `${pending.text}
780
+ ${cont(scanText.slice(0, close))}`, close + 1);
781
+ } else if (close === -1 && open === -1) {
782
+ cp.openBracket = { offset: pending.offset, text: `${pending.text}
783
+ ${cont(scanText)}` };
784
+ }
785
+ }
786
+ if (scanText.includes("[")) {
787
+ const defBracket = validDef ? def.index + def[0].indexOf("[") : -1;
788
+ REF_RE.lastIndex = 0;
789
+ let m;
790
+ while ((m = REF_RE.exec(scanText)) !== null) {
791
+ const followAt = m.index + m[0].length;
792
+ if (scanText[followAt] === ":" && m.index === defBracket) continue;
793
+ pushRef(ln.start + m.index, m[1], followAt);
794
+ }
795
+ const trailingOpen = lastUnclosedBracket(scanText);
796
+ if (trailingOpen !== -1) {
797
+ cp.openBracket = { offset: ln.start + trailingOpen, text: scanText.slice(trailingOpen + 1) };
798
+ }
719
799
  }
720
800
  }
721
801
  const rawSpans = [];
@@ -776,7 +856,7 @@ function processConfirmedLine(cp, ln, text) {
776
856
  if (scanText[pi + 2] === ">") {
777
857
  rawSpans.push([pi, pi + 3]);
778
858
  pos = pi + 3;
779
- if (scanText.slice(0, pi).trim() !== "" || ln.indent > 3) poisonRawDivergence();
859
+ if (!isMdBlank(scanText.slice(0, pi)) || ln.indent > 3) poisonRawDivergence();
780
860
  continue;
781
861
  }
782
862
  rawSpans.push([pi, pi + 2]);
@@ -827,7 +907,7 @@ function processConfirmedLine(cp, ln, text) {
827
907
  applyTag(tag, closing);
828
908
  }
829
909
  if (cp.commentOpen && lastCommentOpenerIdx !== -1 && !inRawText) {
830
- if (tagText.slice(0, lastCommentOpenerIdx).trim() !== "") {
910
+ if (!isMdBlank(tagText.slice(0, lastCommentOpenerIdx))) {
831
911
  cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + lastCommentOpenerIdx);
832
912
  }
833
913
  }
@@ -1053,13 +1133,14 @@ function rebaseDualWalk(node, segments, maxEnd, offsetDelta, lineDelta) {
1053
1133
  const position = node.position;
1054
1134
  if (position) {
1055
1135
  for (const point of [position.start, position.end]) {
1136
+ if (!point) continue;
1056
1137
  const seg = point.offset !== void 0 && point.offset <= maxEnd ? segments.find((s) => point.offset >= s.injStart && point.offset <= s.injEnd) : void 0;
1057
1138
  if (seg) {
1058
1139
  point.offset += seg.offsetDelta;
1059
- point.line += seg.lineDelta;
1140
+ if (typeof point.line === "number") point.line += seg.lineDelta;
1060
1141
  } else {
1061
1142
  if (point.offset !== void 0) point.offset += offsetDelta;
1062
- point.line += lineDelta;
1143
+ if (typeof point.line === "number") point.line += lineDelta;
1063
1144
  }
1064
1145
  }
1065
1146
  }
@@ -1068,6 +1149,8 @@ function rebaseDualWalk(node, segments, maxEnd, offsetDelta, lineDelta) {
1068
1149
  for (const child of children) rebaseDualWalk(child, segments, maxEnd, offsetDelta, lineDelta);
1069
1150
  }
1070
1151
  }
1152
+ var TABLE_PART_TAG_RE = /<(?:td|th|tr|tbody|thead|tfoot|caption|col|colgroup)\b/i;
1153
+ var STRAY_SYNTHESIZED_END_TAG_RE = /<\/(?:br|p)\b/i;
1071
1154
  function spliceTrees(input) {
1072
1155
  const { prevMdast, prevHast, tailMdast, tailHast, content, boundary, injectionPrefix, injectedSegments } = input;
1073
1156
  const injectedLen = injectionPrefix.length;
@@ -1124,6 +1207,12 @@ function spliceTrees(input) {
1124
1207
  return !(start !== void 0 && start < injectedLen);
1125
1208
  });
1126
1209
  const tailWrapVisible = tailMdastChildren.some((child) => !isWrapInvisible(child));
1210
+ if (prefixMdast.some((c) => c.type === "html" && TABLE_PART_TAG_RE.test(c.value))) return null;
1211
+ for (const child of tailMdastChildren) {
1212
+ if (isWrapInvisible(child)) continue;
1213
+ if (child.type !== "html") break;
1214
+ if (STRAY_SYNTHESIZED_END_TAG_RE.test(child.value) || TABLE_PART_TAG_RE.test(child.value)) return null;
1215
+ }
1127
1216
  const aligned = alignPrefixCut(prefixMdast, cutRegion, tailWrapVisible);
1128
1217
  if (aligned === null) return null;
1129
1218
  const hastChildren = aligned.children;
@@ -1226,6 +1315,9 @@ function alignPrefixCut(prefixMdast, cutRegion, tailWrapVisible) {
1226
1315
  nextIdx = pairIdx + 1 + stripped;
1227
1316
  const candidate = visibles[nextIdx];
1228
1317
  if (!candidate) return null;
1318
+ if (start === void 0 && sepBuffer.some((sep) => sep.type !== "text" || sep.value !== "\n")) {
1319
+ return null;
1320
+ }
1229
1321
  if (start !== void 0) {
1230
1322
  const cStart = candidate.position?.start?.offset;
1231
1323
  const cEnd = candidate.position?.end?.offset;
@@ -1242,7 +1334,13 @@ function alignPrefixCut(prefixMdast, cutRegion, tailWrapVisible) {
1242
1334
  const trailingGaps = sawContent ? trailingStripped : Math.max(0, visibles.length - 1);
1243
1335
  const seam = visibles.length > 0 && tailWrapVisible ? 1 : 0;
1244
1336
  const last = out[out.length - 1];
1337
+ if (last !== void 0 && last.type === "text" && last.position !== void 0 && last.value.trim() === "") {
1338
+ return null;
1339
+ }
1245
1340
  const lastIsLiteral = last !== void 0 && last.type === "text" && last.value.trim() !== "";
1341
+ if (lastIsLiteral && pairIdx >= 0 && visibles[pairIdx].type !== "html") {
1342
+ return null;
1343
+ }
1246
1344
  const litOwnerEnd = pairIdx >= 0 ? visibles[pairIdx].position?.end?.offset : void 0;
1247
1345
  const litEnd = lastIsLiteral ? last.position?.end?.offset : void 0;
1248
1346
  if (lastIsLiteral && last.position !== void 0 && (litEnd === void 0 || litOwnerEnd === void 0)) {
@@ -1279,8 +1377,16 @@ function alignPrefixCut(prefixMdast, cutRegion, tailWrapVisible) {
1279
1377
  const v = lastPaired.value;
1280
1378
  const lastLt = v.lastIndexOf("<");
1281
1379
  if (lastLt !== -1 && /^<[!?]/.test(v.slice(lastLt))) return null;
1380
+ const lastOut = out[out.length - 1];
1381
+ const outEnd = lastOut?.type === "element" ? lastOut.position?.end?.offset : void 0;
1382
+ const blockEnd = lastPaired.position?.end?.offset;
1383
+ if (outEnd !== void 0 && blockEnd !== void 0 && outEnd < blockEnd) return null;
1282
1384
  }
1283
1385
  if (sepBuffer.length !== trailingGaps && sepBuffer.length !== trailingGaps + 1) return null;
1386
+ for (let j = pairIdx + 1; j < visibles.length; j++) {
1387
+ const v = visibles[j];
1388
+ if (v.type === "html" && !/^\s*<[!?]/.test(v.value)) return null;
1389
+ }
1284
1390
  for (let i = 0; i < trailingGaps + seam; i++) {
1285
1391
  out.push({ type: "text", value: "\n" });
1286
1392
  }
@@ -1323,8 +1429,9 @@ function stripInjectedHast(tailMdast, tailHast, injectedLen, tailWrapVisible) {
1323
1429
  }
1324
1430
  function tailLeadingTextIsHoist(tailMdastChildren, tailHastChildren) {
1325
1431
  const firstText = tailHastChildren[0];
1326
- if (!firstText) return false;
1327
1432
  const firstVisible = tailMdastChildren.find((c) => !isWrapInvisible(c));
1433
+ if (firstVisible?.type === "html" && STRAY_SYNTHESIZED_END_TAG_RE.test(firstVisible.value)) return null;
1434
+ if (!firstText) return false;
1328
1435
  if (!isSeparatorText(firstText)) {
1329
1436
  if (firstText.type === "text" && firstText.position === void 0 && firstVisible?.type === "html") {
1330
1437
  if (/^\s*<\/[A-Za-z][A-Za-z0-9-]*\s*>/.test(firstVisible.value)) return true;
@@ -1765,17 +1872,8 @@ function phantomSuffixCloser(content) {
1765
1872
  }
1766
1873
 
1767
1874
  // src/components/extractContributions.ts
1768
- function fakeAnchorElement(url) {
1769
- return { type: "element", tagName: "a", properties: { href: url }, children: [] };
1770
- }
1771
- function sanitizeDefUrl(url, urlTransform) {
1772
- if (!urlTransform) return url;
1773
- const result = urlTransform(url, "href", fakeAnchorElement(url));
1774
- return result == null ? "" : String(result);
1775
- }
1776
1875
  function* extractContributions(mdast, options = {}) {
1777
1876
  const phantomFn = options.phantomFootnoteLabels;
1778
- const urlTransform = options.urlTransform;
1779
1877
  const out = [];
1780
1878
  (0, import_unist_util_visit3.visit)(mdast, (n) => {
1781
1879
  if (n.type === "footnoteReference") {
@@ -1803,7 +1901,7 @@ function* extractContributions(mdast, options = {}) {
1803
1901
  out.push({
1804
1902
  kind: "linkDef",
1805
1903
  label: normalizeId(d.identifier),
1806
- url: sanitizeDefUrl(d.url, urlTransform),
1904
+ url: d.url,
1807
1905
  title: d.title
1808
1906
  });
1809
1907
  }
@@ -1875,6 +1973,7 @@ function createRegistry(onEmpty) {
1875
1973
  }
1876
1974
  },
1877
1975
  contributeLabels(symbol, footnotes, links) {
1976
+ if (!this.chunkOrder.includes(symbol)) return;
1878
1977
  const data = this.chunkData.get(symbol);
1879
1978
  if (data) {
1880
1979
  data.ownFootnoteLabels = footnotes;
@@ -1899,6 +1998,7 @@ function createRegistry(onEmpty) {
1899
1998
  this._notify();
1900
1999
  },
1901
2000
  contributeChunkData(symbol, data) {
2001
+ if (!this.chunkOrder.includes(symbol)) return;
1902
2002
  this.chunkData.set(symbol, data);
1903
2003
  this.labelSet.footnoteLabels = /* @__PURE__ */ new Set();
1904
2004
  this.labelSet.linkLabels = /* @__PURE__ */ new Set();
@@ -2004,14 +2104,16 @@ var import_rehype_unwrap_images = __toESM(require("rehype-unwrap-images"), 1);
2004
2104
  var import_unist_util_visit4 = require("unist-util-visit");
2005
2105
  var IMAGE_TAGS = /* @__PURE__ */ new Set(["img", "cross-chunk-image"]);
2006
2106
  var LINK_TAGS = /* @__PURE__ */ new Set(["a", "cross-chunk-link"]);
2007
- function applicable(node, inLink) {
2107
+ function applicable(node, inLink, seen) {
2008
2108
  let image = 0 /* Unknown */;
2009
2109
  for (const child of node.children) {
2010
2110
  if (child.type === "text" && /^\s*$/.test(child.value)) continue;
2011
2111
  if (child.type === "element" && IMAGE_TAGS.has(child.tagName)) {
2112
+ if (child.tagName !== "img") seen.placeholder = true;
2012
2113
  image = 1 /* ContainsImage */;
2013
2114
  } else if (!inLink && child.type === "element" && LINK_TAGS.has(child.tagName)) {
2014
- const inner = applicable(child, true);
2115
+ if (child.tagName !== "a") seen.placeholder = true;
2116
+ const inner = applicable(child, true, seen);
2015
2117
  if (inner === 2 /* ContainsOther */) return 2 /* ContainsOther */;
2016
2118
  if (inner === 1 /* ContainsImage */) image = 1 /* ContainsImage */;
2017
2119
  } else {
@@ -2023,9 +2125,9 @@ function applicable(node, inLink) {
2023
2125
  function rehypeUnwrapCrossChunkImages() {
2024
2126
  return function transform(tree) {
2025
2127
  (0, import_unist_util_visit4.visit)(tree, "element", (node, index, parent) => {
2026
- if (node.tagName === "p" && parent && typeof index === "number" && applicable(node, false) === 1 /* ContainsImage */ && // Only paragraphs that actually hold a placeholder — plain <img>
2027
- // paragraphs were already unwrapped by rehype-unwrap-images.
2028
- JSON.stringify(node.children).includes('"cross-chunk-image"')) {
2128
+ if (node.tagName !== "p" || !parent || typeof index !== "number") return;
2129
+ const seen = { placeholder: false };
2130
+ if (applicable(node, false, seen) === 1 /* ContainsImage */ && seen.placeholder) {
2029
2131
  parent.children.splice(index, 1, ...node.children);
2030
2132
  return [import_unist_util_visit4.SKIP, index];
2031
2133
  }
@@ -3513,14 +3615,11 @@ function isProtocolAllowed(url, allowed) {
3513
3615
  }
3514
3616
  function sanitizeCrossChunkUrl(rawUrl, key, tagName, urlTransform, schema) {
3515
3617
  rawUrl = (0, import_micromark_util_sanitize_uri2.normalizeUri)(rawUrl);
3618
+ const allowed = Object.hasOwn(schema, "protocols") ? schema.protocols?.[key] : sanitizeSchema.protocols?.[key];
3619
+ if (allowed && allowed.length > 0 && !isProtocolAllowed(rawUrl, allowed)) return null;
3516
3620
  const transformed = urlTransform(rawUrl, key, fakeElement(tagName, key, rawUrl));
3517
- if (transformed == null) return "";
3518
- const stringUrl = String(transformed);
3519
- if (stringUrl === "") return "";
3520
- const callerProtocols = schema.protocols;
3521
- const allowed = callerProtocols === void 0 || callerProtocols === null ? sanitizeSchema.protocols?.[key] : callerProtocols[key];
3522
- if (!allowed || allowed.length === 0) return stringUrl;
3523
- return isProtocolAllowed(stringUrl, allowed) ? stringUrl : "";
3621
+ if (transformed == null) return null;
3622
+ return String(transformed);
3524
3623
  }
3525
3624
 
3526
3625
  // src/plugins/defs.ts
@@ -3912,15 +4011,28 @@ var LITERAL_CONTENT_CLOSE_REGEX = {
3912
4011
  math: /<\/math\s*>/gi,
3913
4012
  svg: /<\/svg\s*>/gi
3914
4013
  };
3915
- function isAtLineStart(content, pos) {
4014
+ function restOfLineIsBlank(content, pos) {
4015
+ for (let i = pos; i < content.length; i++) {
4016
+ const c = content[i];
4017
+ if (c === "\n") return true;
4018
+ if (c !== " " && c !== " " && c !== "\r") return false;
4019
+ }
4020
+ return true;
4021
+ }
4022
+ function lineHasBacktick(content, pos) {
4023
+ for (let i = pos; i < content.length && content[i] !== "\n"; i++) {
4024
+ if (content[i] === "`") return true;
4025
+ }
4026
+ return false;
4027
+ }
4028
+ function lineIndentBefore(content, pos) {
3916
4029
  let i = pos - 1;
3917
- let spaces = 0;
3918
- while (i >= 0 && content[i] === " ") {
3919
- spaces++;
3920
- if (spaces > 3) return false;
4030
+ let indent = 0;
4031
+ while (i >= 0 && (content[i] === " " || content[i] === " ")) {
4032
+ indent += content[i] === " " ? 4 : 1;
3921
4033
  i--;
3922
4034
  }
3923
- return i < 0 || content[i] === "\n" || content[i] === "\r";
4035
+ return i < 0 || content[i] === "\n" || content[i] === "\r" ? indent : -1;
3924
4036
  }
3925
4037
  function findClosingBacktickRun(content, start, n) {
3926
4038
  let i = start;
@@ -3941,6 +4053,7 @@ function splitByProtectedRegions(content) {
3941
4053
  let multilineStart = -1;
3942
4054
  let multilineFenceMarker = null;
3943
4055
  let multilineFenceLength = 0;
4056
+ let multilineFenceIndent = 0;
3944
4057
  function pushProtected(start, end) {
3945
4058
  if (start > lastIndex) {
3946
4059
  segments.push({ text: content.substring(lastIndex, start), isCode: false });
@@ -3954,7 +4067,8 @@ function splitByProtectedRegions(content) {
3954
4067
  if (multilineStart !== -1) {
3955
4068
  if (char === multilineFenceMarker) {
3956
4069
  const runLen = getRepeatedMarkerLength(content, i, multilineFenceMarker);
3957
- if (runLen >= multilineFenceLength && isAtLineStart(content, i)) {
4070
+ const closerIndent = lineIndentBefore(content, i);
4071
+ if (runLen >= multilineFenceLength && closerIndent !== -1 && closerIndent <= multilineFenceIndent + 3 && restOfLineIsBlank(content, i + runLen)) {
3958
4072
  pushProtected(multilineStart, i + runLen);
3959
4073
  multilineStart = -1;
3960
4074
  multilineFenceMarker = null;
@@ -3970,10 +4084,12 @@ function splitByProtectedRegions(content) {
3970
4084
  }
3971
4085
  if (char === "`" || char === "~") {
3972
4086
  const runLen = getRepeatedMarkerLength(content, i, char);
3973
- if (runLen >= 3 && isAtLineStart(content, i)) {
4087
+ const openerIndent = lineIndentBefore(content, i);
4088
+ if (runLen >= 3 && openerIndent !== -1 && !(char === "`" && lineHasBacktick(content, i + runLen))) {
3974
4089
  multilineStart = i;
3975
4090
  multilineFenceMarker = char;
3976
4091
  multilineFenceLength = runLen;
4092
+ multilineFenceIndent = openerIndent;
3977
4093
  i += runLen;
3978
4094
  continue;
3979
4095
  }