@ai-react-markdown/engine 2.3.3 → 2.4.1
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.cjs +301 -53
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +93 -23
- package/dist/index.d.ts +93 -23
- package/dist/index.dev.cjs +301 -53
- package/dist/index.dev.cjs.map +1 -1
- package/dist/index.dev.js +299 -53
- package/dist/index.dev.js.map +1 -1
- package/dist/index.js +299 -53
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
package/dist/index.dev.js
CHANGED
|
@@ -198,7 +198,7 @@ var DEF_LIST_DD_RE = /^ {0,3}:[ \t]/;
|
|
|
198
198
|
var DEF_RE = /^ {0,3}\[((?:[^[\]\\]|\\.)+)\]:/;
|
|
199
199
|
var FENCE_RE = /^ {0,3}(`{3,}|~{3,})/;
|
|
200
200
|
var MATH_RUN_RE = /^ {0,3}(\$\$+)/;
|
|
201
|
-
var TAG_OR_COMMENT_RE = /<(\/?)([A-Za-z][A-Za-z0-9-]*)(?=[\s/>])([^>]*)
|
|
201
|
+
var TAG_OR_COMMENT_RE = /<(\/?)([A-Za-z][A-Za-z0-9-]*)(?=[\s/>])([^>]*)>|<!--|-->|--!>/g;
|
|
202
202
|
var TRUNCATED_TAG_RE = /<(\/?)([A-Za-z][A-Za-z0-9-]*)([^<>]*)$/;
|
|
203
203
|
var REF_RE = /!?\[((?:[^[\]\\]|\\.)*)\]/g;
|
|
204
204
|
var BACKTICK_RUN_RE = /`+/g;
|
|
@@ -280,6 +280,7 @@ function freshCheckpoint(defListEnabled, mathFlow, referenceTaint) {
|
|
|
280
280
|
fenceLen: 0,
|
|
281
281
|
inMath: false,
|
|
282
282
|
mathFenceLen: 0,
|
|
283
|
+
openIndent: 0,
|
|
283
284
|
blankRun: 0,
|
|
284
285
|
lastBlankStart: -1,
|
|
285
286
|
hazardVerdict: false,
|
|
@@ -290,21 +291,15 @@ function freshCheckpoint(defListEnabled, mathFlow, referenceTaint) {
|
|
|
290
291
|
paragraphHasUnpairedRun: false,
|
|
291
292
|
htmlFlowSinceBlank: false,
|
|
292
293
|
htmlSeamPending: false,
|
|
293
|
-
phasePoisonedAt: Infinity
|
|
294
|
+
phasePoisonedAt: Infinity,
|
|
295
|
+
pendingTruncatedTags: []
|
|
294
296
|
};
|
|
295
297
|
}
|
|
296
298
|
function isPlausibleLinkDefRest(rest) {
|
|
297
299
|
const t = rest.trim();
|
|
298
300
|
if (t === "") return false;
|
|
299
|
-
|
|
300
|
-
if (
|
|
301
|
-
const close = t.indexOf(">");
|
|
302
|
-
if (close === -1) return false;
|
|
303
|
-
destEnd = close + 1;
|
|
304
|
-
} else {
|
|
305
|
-
const ws = t.search(/[ \t]/);
|
|
306
|
-
destEnd = ws === -1 ? t.length : ws;
|
|
307
|
-
}
|
|
301
|
+
const destEnd = linkDestinationEnd(t);
|
|
302
|
+
if (destEnd === -1) return false;
|
|
308
303
|
const after = t.slice(destEnd).trim();
|
|
309
304
|
if (after === "") return true;
|
|
310
305
|
const opener = after[0];
|
|
@@ -319,6 +314,39 @@ function isPlausibleLinkDefRest(rest) {
|
|
|
319
314
|
}
|
|
320
315
|
return false;
|
|
321
316
|
}
|
|
317
|
+
function linkDestinationEnd(t) {
|
|
318
|
+
if (t.startsWith("<")) {
|
|
319
|
+
for (let i2 = 1; i2 < t.length; i2++) {
|
|
320
|
+
const ch = t[i2];
|
|
321
|
+
if (ch === "\\" && (t[i2 + 1] === "<" || t[i2 + 1] === ">" || t[i2 + 1] === "\\")) {
|
|
322
|
+
i2 += 1;
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
if (ch === ">") return i2 + 1;
|
|
326
|
+
if (ch === "<") return -1;
|
|
327
|
+
}
|
|
328
|
+
return -1;
|
|
329
|
+
}
|
|
330
|
+
let balance = 0;
|
|
331
|
+
let i = 0;
|
|
332
|
+
for (; i < t.length; i++) {
|
|
333
|
+
const code = t.charCodeAt(i);
|
|
334
|
+
if (code === 32 || code === 9) break;
|
|
335
|
+
if (code < 32 || code === 127) return -1;
|
|
336
|
+
const ch = t[i];
|
|
337
|
+
if (ch === "\\" && (t[i + 1] === "(" || t[i + 1] === ")" || t[i + 1] === "\\")) {
|
|
338
|
+
i += 1;
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
if (ch === "(") balance += 1;
|
|
342
|
+
else if (ch === ")") {
|
|
343
|
+
if (balance === 0) break;
|
|
344
|
+
balance -= 1;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
if (balance !== 0 || i === 0) return -1;
|
|
348
|
+
return i;
|
|
349
|
+
}
|
|
322
350
|
function classifyBlockStart(text, indent, defListEnabled) {
|
|
323
351
|
if (indent >= 4) return true;
|
|
324
352
|
if (LIST_MARKER_RE.test(text) || FOOTNOTE_DEF_RE.test(text)) return true;
|
|
@@ -380,6 +408,48 @@ function computeFreezeBoundary(text, options, resume) {
|
|
|
380
408
|
}
|
|
381
409
|
return { boundary, checkpoint: cp };
|
|
382
410
|
}
|
|
411
|
+
function floatingResidue(text, commentOpenAtStart) {
|
|
412
|
+
let out = "";
|
|
413
|
+
let open = commentOpenAtStart;
|
|
414
|
+
let last = 0;
|
|
415
|
+
TAG_OR_COMMENT_RE.lastIndex = 0;
|
|
416
|
+
let m;
|
|
417
|
+
while ((m = TAG_OR_COMMENT_RE.exec(text)) !== null) {
|
|
418
|
+
if (m[0] === "<!--") {
|
|
419
|
+
const next = text.slice(m.index + 4, m.index + 6);
|
|
420
|
+
const overlapLen = next.startsWith(">") ? 5 : next === "->" ? 6 : 0;
|
|
421
|
+
if (open) {
|
|
422
|
+
if (overlapLen) {
|
|
423
|
+
open = false;
|
|
424
|
+
last = m.index + overlapLen;
|
|
425
|
+
TAG_OR_COMMENT_RE.lastIndex = last;
|
|
426
|
+
}
|
|
427
|
+
continue;
|
|
428
|
+
}
|
|
429
|
+
out += text.slice(last, m.index);
|
|
430
|
+
if (overlapLen) {
|
|
431
|
+
last = m.index + overlapLen;
|
|
432
|
+
TAG_OR_COMMENT_RE.lastIndex = last;
|
|
433
|
+
continue;
|
|
434
|
+
}
|
|
435
|
+
open = true;
|
|
436
|
+
continue;
|
|
437
|
+
}
|
|
438
|
+
if (m[0] === "-->") {
|
|
439
|
+
if (open) {
|
|
440
|
+
open = false;
|
|
441
|
+
last = m.index + 3;
|
|
442
|
+
}
|
|
443
|
+
continue;
|
|
444
|
+
}
|
|
445
|
+
if (m[0] === "--!>") continue;
|
|
446
|
+
if (open) continue;
|
|
447
|
+
out += text.slice(last, m.index);
|
|
448
|
+
last = m.index + m[0].length;
|
|
449
|
+
}
|
|
450
|
+
if (!open) out += text.slice(last);
|
|
451
|
+
return out;
|
|
452
|
+
}
|
|
383
453
|
function processConfirmedLine(cp, ln, text) {
|
|
384
454
|
const newest = cp.candidates[cp.candidates.length - 1];
|
|
385
455
|
if (newest && newest.defListSettled === null) {
|
|
@@ -434,6 +504,7 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
434
504
|
cp.inFence = true;
|
|
435
505
|
cp.fenceChar = open[1][0];
|
|
436
506
|
cp.fenceLen = open[1].length;
|
|
507
|
+
cp.openIndent = ln.indent;
|
|
437
508
|
cp.blankRun = 0;
|
|
438
509
|
cp.paragraphHasUnpairedRun = false;
|
|
439
510
|
cp.prevLineBlank = false;
|
|
@@ -468,6 +539,7 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
468
539
|
}
|
|
469
540
|
cp.inMath = true;
|
|
470
541
|
cp.mathFenceLen = mathRun[1].length;
|
|
542
|
+
cp.openIndent = ln.indent;
|
|
471
543
|
cp.blankRun = 0;
|
|
472
544
|
cp.paragraphHasUnpairedRun = false;
|
|
473
545
|
cp.prevLineBlank = false;
|
|
@@ -478,6 +550,10 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
478
550
|
}
|
|
479
551
|
}
|
|
480
552
|
if (ln.blank) {
|
|
553
|
+
if (cp.pendingTruncatedTags.length > 0) {
|
|
554
|
+
for (const tag of cp.pendingTruncatedTags) applyTag(tag, true);
|
|
555
|
+
cp.pendingTruncatedTags = [];
|
|
556
|
+
}
|
|
481
557
|
cp.blankRun += 1;
|
|
482
558
|
cp.lastBlankStart = ln.start;
|
|
483
559
|
cp.candidates.push({
|
|
@@ -507,6 +583,7 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
507
583
|
if (!TYPE6_NAMES.has(tagStart[1].toLowerCase())) cp.hazardVerdict = true;
|
|
508
584
|
}
|
|
509
585
|
const inRawText = cp.htmlFlowSinceBlank || rawOpenAtLineStart;
|
|
586
|
+
const rawFlowStart = ln.indent <= 3 && /^<(?:!--|\?|![A-Za-z]|!\[CDATA\[)/.test(ln.text.trimStart());
|
|
510
587
|
const { masked, unpaired } = inRawText ? { masked: null, unpaired: false } : maskIntraLineCodeSpans(ln.text, cp.paragraphHasUnpairedRun);
|
|
511
588
|
if (unpaired) cp.paragraphHasUnpairedRun = true;
|
|
512
589
|
const scanText = masked ?? ln.text;
|
|
@@ -548,12 +625,16 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
548
625
|
cp.unresolvedRefs.push({ offset: ln.start + m.index, label, footnote });
|
|
549
626
|
}
|
|
550
627
|
}
|
|
551
|
-
const rawOpenAtStart = cp.piOpen || cp.declOpen || cp.cdataOpen;
|
|
552
628
|
const rawSpans = [];
|
|
553
629
|
let pos = 0;
|
|
630
|
+
const poisonRawDivergence = () => {
|
|
631
|
+
cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
|
|
632
|
+
};
|
|
554
633
|
while (pos < scanText.length) {
|
|
555
634
|
if (cp.piOpen) {
|
|
556
635
|
const c = scanText.indexOf("?>", pos);
|
|
636
|
+
const gt = scanText.indexOf(">", pos);
|
|
637
|
+
if (gt !== -1 && (c === -1 || gt !== c + 1)) poisonRawDivergence();
|
|
557
638
|
if (c === -1) {
|
|
558
639
|
rawSpans.push([pos, scanText.length]);
|
|
559
640
|
break;
|
|
@@ -565,6 +646,8 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
565
646
|
}
|
|
566
647
|
if (cp.cdataOpen) {
|
|
567
648
|
const c = scanText.indexOf("]]>", pos);
|
|
649
|
+
const gt = scanText.indexOf(">", pos);
|
|
650
|
+
if (gt !== -1 && (c === -1 || gt !== c + 2)) poisonRawDivergence();
|
|
568
651
|
if (c === -1) {
|
|
569
652
|
rawSpans.push([pos, scanText.length]);
|
|
570
653
|
break;
|
|
@@ -597,6 +680,12 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
597
680
|
cp.cdataOpen = true;
|
|
598
681
|
pos = cd + 9;
|
|
599
682
|
} else if (first === pi) {
|
|
683
|
+
if (scanText[pi + 2] === ">") {
|
|
684
|
+
rawSpans.push([pi, pi + 3]);
|
|
685
|
+
pos = pi + 3;
|
|
686
|
+
if (scanText.slice(0, pi).trim() !== "" || ln.indent > 3) poisonRawDivergence();
|
|
687
|
+
continue;
|
|
688
|
+
}
|
|
600
689
|
rawSpans.push([pi, pi + 2]);
|
|
601
690
|
cp.piOpen = true;
|
|
602
691
|
pos = pi + 2;
|
|
@@ -606,13 +695,25 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
606
695
|
pos = decl + 2;
|
|
607
696
|
}
|
|
608
697
|
}
|
|
609
|
-
|
|
610
|
-
|
|
698
|
+
let tagText = scanText;
|
|
699
|
+
for (const [from, to] of rawSpans) {
|
|
700
|
+
tagText = tagText.slice(0, from) + " ".repeat(to - from) + tagText.slice(to);
|
|
701
|
+
}
|
|
702
|
+
{
|
|
611
703
|
TAG_OR_COMMENT_RE.lastIndex = 0;
|
|
612
704
|
let m;
|
|
613
705
|
let lastCommentOpenerIdx = -1;
|
|
614
|
-
while ((m = TAG_OR_COMMENT_RE.exec(
|
|
706
|
+
while ((m = TAG_OR_COMMENT_RE.exec(tagText)) !== null) {
|
|
615
707
|
if (m[0] === "<!--") {
|
|
708
|
+
const next = tagText.slice(m.index + 4, m.index + 6);
|
|
709
|
+
if (cp.commentOpen) {
|
|
710
|
+
if (next.startsWith(">") || next === "->") cp.commentOpen = false;
|
|
711
|
+
else if (next === "!>" || next === "-!") poisonRawDivergence();
|
|
712
|
+
continue;
|
|
713
|
+
}
|
|
714
|
+
if (next.startsWith(">") || next === "->") {
|
|
715
|
+
continue;
|
|
716
|
+
}
|
|
616
717
|
cp.commentOpen = true;
|
|
617
718
|
lastCommentOpenerIdx = m.index;
|
|
618
719
|
continue;
|
|
@@ -621,6 +722,10 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
621
722
|
cp.commentOpen = false;
|
|
622
723
|
continue;
|
|
623
724
|
}
|
|
725
|
+
if (m[0] === "--!>") {
|
|
726
|
+
if (cp.commentOpen) poisonRawDivergence();
|
|
727
|
+
continue;
|
|
728
|
+
}
|
|
624
729
|
if (cp.commentOpen) continue;
|
|
625
730
|
const closing = m[1] === "/";
|
|
626
731
|
const tag = m[2].toLowerCase();
|
|
@@ -629,33 +734,56 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
629
734
|
applyTag(tag, closing);
|
|
630
735
|
}
|
|
631
736
|
if (cp.commentOpen && lastCommentOpenerIdx !== -1 && !inRawText) {
|
|
632
|
-
if (
|
|
737
|
+
if (tagText.slice(0, lastCommentOpenerIdx).trim() !== "") {
|
|
633
738
|
cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + lastCommentOpenerIdx);
|
|
634
739
|
}
|
|
635
740
|
}
|
|
741
|
+
if (masked !== null && masked !== ln.text) {
|
|
742
|
+
const inRaw = (i) => rawSpans.some(([from, to]) => i >= from && i < to);
|
|
743
|
+
TAG_OR_COMMENT_RE.lastIndex = 0;
|
|
744
|
+
let mr;
|
|
745
|
+
while ((mr = TAG_OR_COMMENT_RE.exec(ln.text)) !== null) {
|
|
746
|
+
if (mr[0] === "<!--" || mr[0] === "-->" || mr[0] === "--!>") continue;
|
|
747
|
+
const startMasked = masked[mr.index] !== ln.text[mr.index];
|
|
748
|
+
const wholeVisible = masked.slice(mr.index, mr.index + mr[0].length) === mr[0];
|
|
749
|
+
if (startMasked || wholeVisible || inRaw(mr.index) || cp.commentOpen) continue;
|
|
750
|
+
const closing = mr[1] === "/";
|
|
751
|
+
const tag = mr[2].toLowerCase();
|
|
752
|
+
const selfClosing = mr[3] !== void 0 && /\/\s*$/.test(mr[3]);
|
|
753
|
+
if (VOID_TAGS.has(tag) || selfClosing) continue;
|
|
754
|
+
applyTag(tag, closing);
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
if (cp.pendingTruncatedTags.length > 0 && ln.text.includes(">")) {
|
|
758
|
+
cp.pendingTruncatedTags = [];
|
|
759
|
+
}
|
|
636
760
|
if (!cp.commentOpen) {
|
|
637
|
-
const lastLt =
|
|
638
|
-
if (lastLt !== -1 && !
|
|
639
|
-
const m2 = TRUNCATED_TAG_RE.exec(
|
|
761
|
+
const lastLt = tagText.lastIndexOf("<");
|
|
762
|
+
if (lastLt !== -1 && !tagText.includes(">", lastLt)) {
|
|
763
|
+
const m2 = TRUNCATED_TAG_RE.exec(tagText.slice(lastLt));
|
|
640
764
|
if (m2) {
|
|
641
765
|
const closing = m2[1] === "/";
|
|
642
766
|
const tag = m2[2].toLowerCase();
|
|
643
|
-
if (!VOID_TAGS.has(tag))
|
|
767
|
+
if (!VOID_TAGS.has(tag)) {
|
|
768
|
+
applyTag(tag, closing);
|
|
769
|
+
const rawLastLt = ln.text.lastIndexOf("<");
|
|
770
|
+
const rawTruncated = rawLastLt !== -1 && !ln.text.includes(">", rawLastLt);
|
|
771
|
+
if (!closing && !inRawText && rawTruncated) cp.pendingTruncatedTags.push(tag);
|
|
772
|
+
}
|
|
644
773
|
}
|
|
645
774
|
}
|
|
646
775
|
}
|
|
647
776
|
}
|
|
648
|
-
|
|
649
|
-
|
|
777
|
+
const effectiveOpen = cp.openTotal - cp.pendingTruncatedTags.length;
|
|
778
|
+
if ((inRawText || rawFlowStart) && effectiveOpen <= 0) {
|
|
779
|
+
let masked2 = "";
|
|
780
|
+
let cursor = 0;
|
|
650
781
|
for (const [from, to] of rawSpans) {
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
residue = residue.replace(/<!--[\s\S]*?-->/g, " ");
|
|
654
|
-
if (commentOpenAtLineStart) {
|
|
655
|
-
residue = residue.includes("-->") ? residue.replace(/[\s\S]*?-->/, " ") : "";
|
|
782
|
+
masked2 += scanText.slice(cursor, from);
|
|
783
|
+
cursor = to;
|
|
656
784
|
}
|
|
657
|
-
|
|
658
|
-
if (
|
|
785
|
+
masked2 += scanText.slice(cursor);
|
|
786
|
+
if (floatingResidue(masked2, commentOpenAtLineStart).length > 0) {
|
|
659
787
|
cp.htmlSeamPending = true;
|
|
660
788
|
}
|
|
661
789
|
}
|
|
@@ -665,6 +793,9 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
665
793
|
cp.prevLineWasValidDef = validDef && !def[1].startsWith("^");
|
|
666
794
|
}
|
|
667
795
|
|
|
796
|
+
// src/components/incrementalParse/spliceParse.ts
|
|
797
|
+
import { normalizeIdentifier as normalizeIdentifier2 } from "micromark-util-normalize-identifier";
|
|
798
|
+
|
|
668
799
|
// src/components/hastPredicates.ts
|
|
669
800
|
function isFootnoteSection(node) {
|
|
670
801
|
if (node.tagName !== "section") return false;
|
|
@@ -715,7 +846,7 @@ function collectPrefixInjection(mdast, content, boundary, resume) {
|
|
|
715
846
|
if (last && last.kind === "refs") last.tokens.push(token);
|
|
716
847
|
else events.push({ kind: "refs", tokens: [token] });
|
|
717
848
|
};
|
|
718
|
-
const
|
|
849
|
+
const visit7 = (node, nested) => {
|
|
719
850
|
const type = node.type;
|
|
720
851
|
if (type === "definition") {
|
|
721
852
|
const start = node.position?.start?.offset;
|
|
@@ -756,20 +887,24 @@ function collectPrefixInjection(mdast, content, boundary, resume) {
|
|
|
756
887
|
}
|
|
757
888
|
const children = node.children;
|
|
758
889
|
if (children) {
|
|
759
|
-
for (const child of children)
|
|
890
|
+
for (const child of children) visit7(child, true);
|
|
760
891
|
}
|
|
761
892
|
};
|
|
893
|
+
let lastStart = -1;
|
|
762
894
|
for (const child of mdast.children) {
|
|
763
895
|
const start = child.position?.start?.offset;
|
|
896
|
+
if (start !== void 0) {
|
|
897
|
+
if (start < lastStart) return { events: [], uninjectable: true, cacheable: false };
|
|
898
|
+
lastStart = start;
|
|
899
|
+
}
|
|
764
900
|
if (start === void 0) {
|
|
765
901
|
if (resumeAt > 0) return collectPrefixInjection(mdast, content, boundary, null);
|
|
766
902
|
cacheable = false;
|
|
767
|
-
|
|
903
|
+
visit7(child, false);
|
|
768
904
|
continue;
|
|
769
905
|
}
|
|
770
|
-
if (start >= boundary)
|
|
771
|
-
|
|
772
|
-
visit6(child, false);
|
|
906
|
+
if (start >= boundary || start < resumeAt) continue;
|
|
907
|
+
visit7(child, false);
|
|
773
908
|
}
|
|
774
909
|
return { events, uninjectable, cacheable };
|
|
775
910
|
}
|
|
@@ -782,7 +917,7 @@ function cloneEventsForAppend(events) {
|
|
|
782
917
|
var TERMINATOR_LABEL = "__aimd_injection_terminator__";
|
|
783
918
|
var INJECTION_TERMINATOR = `[${TERMINATOR_LABEL}]: __aimd_sentinel_link__`;
|
|
784
919
|
function tailMentionsTerminator(tailSource) {
|
|
785
|
-
return tailSource.includes(`[${TERMINATOR_LABEL}`);
|
|
920
|
+
return normalizeIdentifier2(tailSource).replace(/\[ /g, "[").includes(`[${normalizeIdentifier2(TERMINATOR_LABEL)}`);
|
|
786
921
|
}
|
|
787
922
|
function buildInjectionPrefix(events) {
|
|
788
923
|
if (events.length === 0) return { text: "", segments: [] };
|
|
@@ -862,12 +997,25 @@ function spliceTrees(input) {
|
|
|
862
997
|
if (isTrailingLiteralText(node2)) {
|
|
863
998
|
const prev = i > 0 ? prevHast.children[i - 1] : void 0;
|
|
864
999
|
if (!prev || prev.type !== "element" || prev.position === void 0) return null;
|
|
1000
|
+
if (!ownsTrailingLiteral(prev, node2, prefixMdast))
|
|
1001
|
+
return null;
|
|
865
1002
|
}
|
|
866
1003
|
cutRegion.push(node2);
|
|
867
1004
|
continue;
|
|
868
1005
|
}
|
|
869
1006
|
const node = prevHast.children[i];
|
|
870
|
-
if (i > 0 && attrs[i - 1] < boundary && prevHast.children[i - 1].type === "element" && isTrailingLiteralText(node)
|
|
1007
|
+
if (i > 0 && attrs[i - 1] < boundary && prevHast.children[i - 1].type === "element" && isTrailingLiteralText(node) && // …and only when that element really IS an html block's output: a
|
|
1008
|
+
// raw literal can only trail an `html` mdast node. A position-less
|
|
1009
|
+
// text after a `<p>` is the NEXT block's remnant — a stray end tag
|
|
1010
|
+
// (`</t>\na`) parse5 dropped, whose text merged with the wrap
|
|
1011
|
+
// separator — owned by the tail, which re-parses it; freezing it
|
|
1012
|
+
// here duplicated it (v2.4.0 review P3). Falls through to the
|
|
1013
|
+
// remnant look-ahead below, which bails to a full parse. And the
|
|
1014
|
+
// literal must really be THAT block's trailing text: the block's raw
|
|
1015
|
+
// source ends with it. A dropped-tag block right after a frozen html
|
|
1016
|
+
// element (`</details>\n\n</t>\ntext`) puts its remnant in the same
|
|
1017
|
+
// position, and freezing it duplicated it (release soak of the fix).
|
|
1018
|
+
ownsTrailingLiteral(prevHast.children[i - 1], node, prefixMdast)) {
|
|
871
1019
|
cutRegion.push(node);
|
|
872
1020
|
break;
|
|
873
1021
|
}
|
|
@@ -1082,8 +1230,16 @@ function stripInjectedHast(tailMdast, tailHast, injectedLen, tailWrapVisible) {
|
|
|
1082
1230
|
}
|
|
1083
1231
|
function tailLeadingTextIsHoist(tailMdastChildren, tailHastChildren) {
|
|
1084
1232
|
const firstText = tailHastChildren[0];
|
|
1085
|
-
if (!firstText
|
|
1233
|
+
if (!firstText) return false;
|
|
1086
1234
|
const firstVisible = tailMdastChildren.find((c) => !isWrapInvisible(c));
|
|
1235
|
+
if (!isSeparatorText(firstText)) {
|
|
1236
|
+
if (firstText.type === "text" && firstText.position === void 0 && firstVisible?.type === "html") {
|
|
1237
|
+
if (/^\s*<\/[A-Za-z][A-Za-z0-9-]*\s*>/.test(firstVisible.value)) return true;
|
|
1238
|
+
if (isCompleteRawConstruct(firstVisible.value)) return false;
|
|
1239
|
+
return null;
|
|
1240
|
+
}
|
|
1241
|
+
return false;
|
|
1242
|
+
}
|
|
1087
1243
|
if (!firstVisible) return false;
|
|
1088
1244
|
const firstContent = tailHastChildren.find((c) => !isSeparatorText(c));
|
|
1089
1245
|
if (firstContent) {
|
|
@@ -1105,6 +1261,14 @@ function isCompleteRawConstruct(value) {
|
|
|
1105
1261
|
function isSeparatorText(node) {
|
|
1106
1262
|
return node.type === "text" && node.position === void 0 && node.value.trim() === "";
|
|
1107
1263
|
}
|
|
1264
|
+
function ownsTrailingLiteral(el, literal, prefixMdast) {
|
|
1265
|
+
const start = el.position?.start?.offset;
|
|
1266
|
+
if (start === void 0) return false;
|
|
1267
|
+
const owner = prefixMdast.find((c) => c.type === "html" && c.position?.start?.offset === start);
|
|
1268
|
+
if (!owner || owner.type !== "html") return false;
|
|
1269
|
+
const text = literal.value.trim();
|
|
1270
|
+
return text !== "" && owner.value.trimEnd().endsWith(text);
|
|
1271
|
+
}
|
|
1108
1272
|
function isTrailingLiteralText(node) {
|
|
1109
1273
|
return node.type === "text" && node.position === void 0 && node.value.trim() !== "";
|
|
1110
1274
|
}
|
|
@@ -1230,11 +1394,12 @@ import remarkGfm from "remark-gfm";
|
|
|
1230
1394
|
import { visit } from "unist-util-visit";
|
|
1231
1395
|
|
|
1232
1396
|
// src/components/normalizeId.ts
|
|
1397
|
+
import { normalizeIdentifier as normalizeIdentifier3 } from "micromark-util-normalize-identifier";
|
|
1233
1398
|
function normalizeId(s) {
|
|
1234
|
-
return
|
|
1399
|
+
return normalizeIdentifier3(s);
|
|
1235
1400
|
}
|
|
1236
1401
|
function normalizeForMatch(s) {
|
|
1237
|
-
return s.replace(/\\(.)/g, "$1")
|
|
1402
|
+
return normalizeIdentifier3(s.replace(/\\(.)/g, "$1"));
|
|
1238
1403
|
}
|
|
1239
1404
|
|
|
1240
1405
|
// src/components/collectDefLabels.ts
|
|
@@ -1338,7 +1503,11 @@ function createDefLabelScanner(parse = collectDefLabels) {
|
|
|
1338
1503
|
|
|
1339
1504
|
// src/components/extractDefBodiesFromHast.ts
|
|
1340
1505
|
import { SKIP, visit as visit2 } from "unist-util-visit";
|
|
1506
|
+
import { normalizeUri } from "micromark-util-sanitize-uri";
|
|
1341
1507
|
var FN_LI_ID_RE = /(?:^|-)user-content-fn-(.+)$/;
|
|
1508
|
+
function footnoteSafeId(identifier) {
|
|
1509
|
+
return normalizeUri(identifier.toLowerCase());
|
|
1510
|
+
}
|
|
1342
1511
|
function sourceIdFromFootnoteLiId(idProp, clobberPrefix) {
|
|
1343
1512
|
let raw = null;
|
|
1344
1513
|
if (clobberPrefix !== void 0) {
|
|
@@ -1489,6 +1658,18 @@ function buildPhantomSuffix(phantoms) {
|
|
|
1489
1658
|
}
|
|
1490
1659
|
return suffix;
|
|
1491
1660
|
}
|
|
1661
|
+
function phantomSuffixCloser(content) {
|
|
1662
|
+
if (content === "") return "";
|
|
1663
|
+
const endsWithNewline = content.endsWith("\n");
|
|
1664
|
+
const confirmed = endsWithNewline ? content : content + "\n";
|
|
1665
|
+
const { checkpoint } = computeFreezeBoundary(confirmed, { defListEnabled: false, referenceTaint: false });
|
|
1666
|
+
if (checkpoint.phasePoisonedAt !== Infinity) return "";
|
|
1667
|
+
if (checkpoint.openIndent !== 0) return "";
|
|
1668
|
+
const nl = endsWithNewline ? "" : "\n";
|
|
1669
|
+
if (checkpoint.inFence) return `${nl}${checkpoint.fenceChar.repeat(checkpoint.fenceLen)}`;
|
|
1670
|
+
if (checkpoint.inMath) return `${nl}${"$".repeat(checkpoint.mathFenceLen)}`;
|
|
1671
|
+
return "";
|
|
1672
|
+
}
|
|
1492
1673
|
|
|
1493
1674
|
// src/components/extractContributions.ts
|
|
1494
1675
|
function fakeAnchorElement(url) {
|
|
@@ -1567,6 +1748,14 @@ function createRegistry(onEmpty) {
|
|
|
1567
1748
|
releaseSymbol(reactId) {
|
|
1568
1749
|
const entry = this._reactIdMap.get(reactId);
|
|
1569
1750
|
if (!entry) return;
|
|
1751
|
+
if (entry.refcount <= 0) {
|
|
1752
|
+
if (true) {
|
|
1753
|
+
console.warn(
|
|
1754
|
+
`[ai-react-markdown] Registry.releaseSymbol("${reactId}") called with no matching allocateSymbol \u2014 ignoring (unbalanced release).`
|
|
1755
|
+
);
|
|
1756
|
+
}
|
|
1757
|
+
return;
|
|
1758
|
+
}
|
|
1570
1759
|
entry.refcount--;
|
|
1571
1760
|
if (entry.refcount === 0) {
|
|
1572
1761
|
queueMicrotask(() => {
|
|
@@ -1717,6 +1906,41 @@ function createRegistry(onEmpty) {
|
|
|
1717
1906
|
import rehypeKatex from "rehype-katex";
|
|
1718
1907
|
import rehypeRaw from "rehype-raw";
|
|
1719
1908
|
import rehypeUnwrapImages from "rehype-unwrap-images";
|
|
1909
|
+
|
|
1910
|
+
// src/components/rehypeUnwrapCrossChunkImages.ts
|
|
1911
|
+
import { SKIP as SKIP3, visit as visit4 } from "unist-util-visit";
|
|
1912
|
+
var IMAGE_TAGS = /* @__PURE__ */ new Set(["img", "cross-chunk-image"]);
|
|
1913
|
+
var LINK_TAGS = /* @__PURE__ */ new Set(["a", "cross-chunk-link"]);
|
|
1914
|
+
function applicable(node, inLink) {
|
|
1915
|
+
let image = 0 /* Unknown */;
|
|
1916
|
+
for (const child of node.children) {
|
|
1917
|
+
if (child.type === "text" && /^\s*$/.test(child.value)) continue;
|
|
1918
|
+
if (child.type === "element" && IMAGE_TAGS.has(child.tagName)) {
|
|
1919
|
+
image = 1 /* ContainsImage */;
|
|
1920
|
+
} else if (!inLink && child.type === "element" && LINK_TAGS.has(child.tagName)) {
|
|
1921
|
+
const inner = applicable(child, true);
|
|
1922
|
+
if (inner === 2 /* ContainsOther */) return 2 /* ContainsOther */;
|
|
1923
|
+
if (inner === 1 /* ContainsImage */) image = 1 /* ContainsImage */;
|
|
1924
|
+
} else {
|
|
1925
|
+
return 2 /* ContainsOther */;
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1928
|
+
return image;
|
|
1929
|
+
}
|
|
1930
|
+
function rehypeUnwrapCrossChunkImages() {
|
|
1931
|
+
return function transform(tree) {
|
|
1932
|
+
visit4(tree, "element", (node, index, parent) => {
|
|
1933
|
+
if (node.tagName === "p" && parent && typeof index === "number" && applicable(node, false) === 1 /* ContainsImage */ && // Only paragraphs that actually hold a placeholder — plain <img>
|
|
1934
|
+
// paragraphs were already unwrapped by rehype-unwrap-images.
|
|
1935
|
+
JSON.stringify(node.children).includes('"cross-chunk-image"')) {
|
|
1936
|
+
parent.children.splice(index, 1, ...node.children);
|
|
1937
|
+
return [SKIP3, index];
|
|
1938
|
+
}
|
|
1939
|
+
});
|
|
1940
|
+
};
|
|
1941
|
+
}
|
|
1942
|
+
|
|
1943
|
+
// src/components/pluginChain.ts
|
|
1720
1944
|
import rehypeSanitize from "rehype-sanitize";
|
|
1721
1945
|
import remarkBreaks from "remark-breaks";
|
|
1722
1946
|
import remarkCjkFriendly from "remark-cjk-friendly";
|
|
@@ -1732,13 +1956,13 @@ import remarkPangu from "remark-pangu";
|
|
|
1732
1956
|
import remarkRemoveComments from "remark-remove-comments";
|
|
1733
1957
|
|
|
1734
1958
|
// src/components/rehypeRebaseHashLinks.ts
|
|
1735
|
-
import { visit as
|
|
1959
|
+
import { visit as visit5 } from "unist-util-visit";
|
|
1736
1960
|
var DEFAULT_PREFIX = "user-content-";
|
|
1737
1961
|
var rehypeRebaseHashLinks = (options) => {
|
|
1738
1962
|
const prefix = options?.prefix ?? DEFAULT_PREFIX;
|
|
1739
1963
|
const hashPrefix = "#" + prefix;
|
|
1740
1964
|
return (tree) => {
|
|
1741
|
-
|
|
1965
|
+
visit5(tree, "element", (node) => {
|
|
1742
1966
|
if (node.tagName !== "a") return;
|
|
1743
1967
|
const href = node.properties?.href;
|
|
1744
1968
|
if (typeof href !== "string" || !href.startsWith("#")) return;
|
|
@@ -1750,7 +1974,7 @@ var rehypeRebaseHashLinks = (options) => {
|
|
|
1750
1974
|
var rehypeRebaseHashLinks_default = rehypeRebaseHashLinks;
|
|
1751
1975
|
|
|
1752
1976
|
// src/components/rehypeFooterAdorn.ts
|
|
1753
|
-
import { visit as
|
|
1977
|
+
import { visit as visit6 } from "unist-util-visit";
|
|
1754
1978
|
var FOOTNOTE_LABEL_ID_RE = /(?:^|-)footnote-label$/;
|
|
1755
1979
|
function isFootnoteLabelH2(node) {
|
|
1756
1980
|
if (node.type !== "element") return false;
|
|
@@ -1765,7 +1989,7 @@ function isHr(node) {
|
|
|
1765
1989
|
}
|
|
1766
1990
|
function rehypeFooterAdorn() {
|
|
1767
1991
|
return (tree) => {
|
|
1768
|
-
|
|
1992
|
+
visit6(tree, "element", (n) => {
|
|
1769
1993
|
const el = n;
|
|
1770
1994
|
if (el.tagName !== "section") return;
|
|
1771
1995
|
if (!(el.properties && "dataFootnotes" in el.properties)) return;
|
|
@@ -1843,7 +2067,10 @@ function buildCoreRehypePlugins(sanitizeSchema2, clobberPrefix) {
|
|
|
1843
2067
|
// above.
|
|
1844
2068
|
[rehypeRebaseHashLinks_default, { prefix: clobberPrefix }],
|
|
1845
2069
|
rehypeKatex,
|
|
1846
|
-
rehypeUnwrapImages
|
|
2070
|
+
rehypeUnwrapImages,
|
|
2071
|
+
// Same unwrap for `<cross-chunk-image>` placeholders (coordinated mode);
|
|
2072
|
+
// no-op on standalone documents.
|
|
2073
|
+
rehypeUnwrapCrossChunkImages
|
|
1847
2074
|
];
|
|
1848
2075
|
}
|
|
1849
2076
|
function buildCoreRemarkRehypeOptions(enableDefinitionList) {
|
|
@@ -1863,6 +2090,11 @@ function buildCoreRemarkRehypeOptions(enableDefinitionList) {
|
|
|
1863
2090
|
}
|
|
1864
2091
|
|
|
1865
2092
|
// src/components/customMdastHandlers.ts
|
|
2093
|
+
function localDefProps(s, id) {
|
|
2094
|
+
const def = s.definitionById.get(id);
|
|
2095
|
+
if (!def || typeof def.url !== "string" || def.url === SENTINEL_LINK_URL) return {};
|
|
2096
|
+
return def.title ? { localUrl: def.url, localTitle: def.title } : { localUrl: def.url };
|
|
2097
|
+
}
|
|
1866
2098
|
function buildCrossChunkHandlers() {
|
|
1867
2099
|
return {
|
|
1868
2100
|
footnoteDefinition: (state, node) => {
|
|
@@ -1895,7 +2127,8 @@ function buildCrossChunkHandlers() {
|
|
|
1895
2127
|
// internally, so cross-chunk case-insensitive matching still works.
|
|
1896
2128
|
label: node.label ?? node.identifier,
|
|
1897
2129
|
referenceType: node.referenceType,
|
|
1898
|
-
documentId: s.options.documentId
|
|
2130
|
+
documentId: s.options.documentId,
|
|
2131
|
+
...localDefProps(s, id)
|
|
1899
2132
|
},
|
|
1900
2133
|
children: s.all(node)
|
|
1901
2134
|
};
|
|
@@ -1912,7 +2145,8 @@ function buildCrossChunkHandlers() {
|
|
|
1912
2145
|
label: node.label ?? node.identifier,
|
|
1913
2146
|
referenceType: node.referenceType,
|
|
1914
2147
|
alt: node.alt ?? "",
|
|
1915
|
-
documentId: s.options.documentId
|
|
2148
|
+
documentId: s.options.documentId,
|
|
2149
|
+
...localDefProps(s, id)
|
|
1916
2150
|
},
|
|
1917
2151
|
children: []
|
|
1918
2152
|
};
|
|
@@ -1941,6 +2175,12 @@ function buildCrossChunkHandlers() {
|
|
|
1941
2175
|
properties: {
|
|
1942
2176
|
label: node.identifier,
|
|
1943
2177
|
localOccurrence,
|
|
2178
|
+
// The number mdast-util-to-hast would give this reference in a
|
|
2179
|
+
// standalone render (footnoteOrder position) — the placeholder's
|
|
2180
|
+
// fallback while the registry has no global number (server render /
|
|
2181
|
+
// first client frame), where the local synthetic footer is what
|
|
2182
|
+
// renders, so marks and footer agree (core-render-02).
|
|
2183
|
+
localNumber: s.footnoteOrder.indexOf(id) + 1,
|
|
1944
2184
|
documentId: s.options.documentId
|
|
1945
2185
|
},
|
|
1946
2186
|
children: []
|
|
@@ -1949,6 +2189,9 @@ function buildCrossChunkHandlers() {
|
|
|
1949
2189
|
};
|
|
1950
2190
|
}
|
|
1951
2191
|
|
|
2192
|
+
// src/components/crossChunkUrlSanitize.ts
|
|
2193
|
+
import { normalizeUri as normalizeUri2 } from "micromark-util-sanitize-uri";
|
|
2194
|
+
|
|
1952
2195
|
// ../../node_modules/.pnpm/lodash-es@4.18.1/node_modules/lodash-es/_listCacheClear.js
|
|
1953
2196
|
function listCacheClear() {
|
|
1954
2197
|
this.__data__ = [];
|
|
@@ -3149,9 +3392,9 @@ var sanitizeSchema = cloneDeep_default({
|
|
|
3149
3392
|
attributes: {
|
|
3150
3393
|
...defaultSchema.attributes,
|
|
3151
3394
|
code: mergeClassNameAllowlist(defaultSchema.attributes?.code, ["math-inline", "math-display"]),
|
|
3152
|
-
"cross-chunk-link": ["label", "referenceType", "documentId"],
|
|
3153
|
-
"cross-chunk-image": ["label", "referenceType", "documentId", "alt"],
|
|
3154
|
-
"footnote-sup": ["label", "localOccurrence", "documentId"]
|
|
3395
|
+
"cross-chunk-link": ["label", "referenceType", "documentId", "localUrl", "localTitle"],
|
|
3396
|
+
"cross-chunk-image": ["label", "referenceType", "documentId", "alt", "localUrl", "localTitle"],
|
|
3397
|
+
"footnote-sup": ["label", "localOccurrence", "localNumber", "documentId"]
|
|
3155
3398
|
}
|
|
3156
3399
|
});
|
|
3157
3400
|
|
|
@@ -3176,6 +3419,7 @@ function isProtocolAllowed(url, allowed) {
|
|
|
3176
3419
|
return allowed.some((p) => p === protocol);
|
|
3177
3420
|
}
|
|
3178
3421
|
function sanitizeCrossChunkUrl(rawUrl, key, tagName, urlTransform, schema) {
|
|
3422
|
+
rawUrl = normalizeUri2(rawUrl);
|
|
3179
3423
|
const transformed = urlTransform(rawUrl, key, fakeElement(tagName, key, rawUrl));
|
|
3180
3424
|
if (transformed == null) return "";
|
|
3181
3425
|
const stringUrl = String(transformed);
|
|
@@ -3532,9 +3776,9 @@ var createSmoothStreamController = (options = {}) => {
|
|
|
3532
3776
|
snap,
|
|
3533
3777
|
flush() {
|
|
3534
3778
|
disposed = false;
|
|
3535
|
-
|
|
3536
|
-
visibleEnd
|
|
3537
|
-
|
|
3779
|
+
const target = finished ? source.length : pending.length > 0 ? pending[pending.length - 1] : visibleEnd;
|
|
3780
|
+
if (target <= visibleEnd) return;
|
|
3781
|
+
visibleEnd = target;
|
|
3538
3782
|
pending = [];
|
|
3539
3783
|
credit = 0;
|
|
3540
3784
|
cancelScheduled();
|
|
@@ -4049,6 +4293,7 @@ export {
|
|
|
4049
4293
|
extendSanitizeSchema,
|
|
4050
4294
|
extractContributions,
|
|
4051
4295
|
extractDefBodiesFromHast,
|
|
4296
|
+
footnoteSafeId,
|
|
4052
4297
|
getEnginePluginInternals,
|
|
4053
4298
|
hasLoneSurrogate,
|
|
4054
4299
|
highlight,
|
|
@@ -4060,6 +4305,7 @@ export {
|
|
|
4060
4305
|
normalizeId,
|
|
4061
4306
|
pangu,
|
|
4062
4307
|
parseStage,
|
|
4308
|
+
phantomSuffixCloser,
|
|
4063
4309
|
preprocessAIMDContent,
|
|
4064
4310
|
preprocessLaTeX,
|
|
4065
4311
|
rehypeFooterAdorn,
|