@ai-react-markdown/engine 2.4.5 → 2.5.0
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/README.md +1 -1
- package/dist/index.cjs +334 -60
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +52 -58
- package/dist/index.d.ts +52 -58
- package/dist/index.dev.cjs +334 -60
- package/dist/index.dev.cjs.map +1 -1
- package/dist/index.dev.js +334 -58
- package/dist/index.dev.js.map +1 -1
- package/dist/index.js +334 -58
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -177,10 +177,73 @@ import { htmlBlockNames } from "micromark-util-html-tag-name";
|
|
|
177
177
|
import { normalizeIdentifier } from "micromark-util-normalize-identifier";
|
|
178
178
|
var TYPE6_NAMES = new Set(htmlBlockNames);
|
|
179
179
|
var TABLE_PART_NAMES = /* @__PURE__ */ new Set(["td", "th", "tr", "tbody", "thead", "tfoot", "caption", "col", "colgroup"]);
|
|
180
|
+
var HTML_BREAKOUT_TAGS = /* @__PURE__ */ new Set([
|
|
181
|
+
"b",
|
|
182
|
+
"big",
|
|
183
|
+
"blockquote",
|
|
184
|
+
"body",
|
|
185
|
+
"br",
|
|
186
|
+
"center",
|
|
187
|
+
"code",
|
|
188
|
+
"dd",
|
|
189
|
+
"div",
|
|
190
|
+
"dl",
|
|
191
|
+
"dt",
|
|
192
|
+
"em",
|
|
193
|
+
"embed",
|
|
194
|
+
"h1",
|
|
195
|
+
"h2",
|
|
196
|
+
"h3",
|
|
197
|
+
"h4",
|
|
198
|
+
"h5",
|
|
199
|
+
"h6",
|
|
200
|
+
"head",
|
|
201
|
+
"hr",
|
|
202
|
+
"i",
|
|
203
|
+
"img",
|
|
204
|
+
"li",
|
|
205
|
+
"listing",
|
|
206
|
+
"menu",
|
|
207
|
+
"meta",
|
|
208
|
+
"nobr",
|
|
209
|
+
"ol",
|
|
210
|
+
"p",
|
|
211
|
+
"pre",
|
|
212
|
+
"ruby",
|
|
213
|
+
"s",
|
|
214
|
+
"small",
|
|
215
|
+
"span",
|
|
216
|
+
"strong",
|
|
217
|
+
"strike",
|
|
218
|
+
"sub",
|
|
219
|
+
"sup",
|
|
220
|
+
"table",
|
|
221
|
+
"tt",
|
|
222
|
+
"u",
|
|
223
|
+
"ul",
|
|
224
|
+
"var"
|
|
225
|
+
]);
|
|
226
|
+
var HTML_INTEGRATION_POINTS = ["foreignobject", "desc", "mi", "mo", "mn", "ms", "mtext", "annotation-xml"];
|
|
180
227
|
var TYPE1_NAMES = /* @__PURE__ */ new Set(["script", "pre", "style", "textarea"]);
|
|
228
|
+
var RAW_TEXT_ELEMENTS = /* @__PURE__ */ new Set([
|
|
229
|
+
"script",
|
|
230
|
+
"style",
|
|
231
|
+
"textarea",
|
|
232
|
+
"title",
|
|
233
|
+
"xmp",
|
|
234
|
+
"iframe",
|
|
235
|
+
"noembed",
|
|
236
|
+
"noframes",
|
|
237
|
+
// NOT `noscript`: hast-util-raw constructs parse5 with
|
|
238
|
+
// `scriptingEnabled: false`, under which `<noscript>` content is ordinary
|
|
239
|
+
// HTML — modelling it as raw text ignored a `<b>` inside and under-blocked
|
|
240
|
+
// (oracle review of the r2 batch; regression caught before release).
|
|
241
|
+
"plaintext"
|
|
242
|
+
]);
|
|
181
243
|
var TYPE6_START_RE = /^<\/?([A-Za-z][A-Za-z0-9-]*)(?:[ \t\r]|\/?>|$)/;
|
|
182
244
|
var TYPE1_START_RE = /^<(script|pre|style|textarea)(?:[ \t\r]|>|$)/i;
|
|
183
|
-
var TYPE7_LINE_RE =
|
|
245
|
+
var TYPE7_LINE_RE = /^(?:<[A-Za-z][A-Za-z0-9-]*(?:[ \t\r][^>]*|\/)?>|<\/[A-Za-z][A-Za-z0-9-]*[ \t\r]*>)[ \t\r]*$/;
|
|
246
|
+
var t7Name = (line) => /^<\/?([A-Za-z][A-Za-z0-9-]*)/.exec(line)[1];
|
|
184
247
|
var VOID_TAGS = /* @__PURE__ */ new Set([
|
|
185
248
|
"area",
|
|
186
249
|
"base",
|
|
@@ -204,7 +267,35 @@ var DEF_RE = /^ {0,3}\[((?:[^[\]\\]|\\.)+)\]:/;
|
|
|
204
267
|
var FENCE_RE = /^ {0,3}(`{3,}|~{3,})/;
|
|
205
268
|
var MATH_RUN_RE = /^ {0,3}(\$\$+)/;
|
|
206
269
|
var TAG_OR_COMMENT_RE = /<(\/?)([A-Za-z][A-Za-z0-9-]*)(?=[\s/>])([^>]*)>|<!--|-->|--!>/g;
|
|
207
|
-
var TRUNCATED_TAG_RE = /<(\/?)([A-Za-z][A-Za-z0-9-]*)([
|
|
270
|
+
var TRUNCATED_TAG_RE = /<(\/?)([A-Za-z][A-Za-z0-9-]*)([^>]*)$/;
|
|
271
|
+
var TAG_START_LT_RE = /<\/?[A-Za-z]/g;
|
|
272
|
+
function scanTagAttrs(text, from, to, out) {
|
|
273
|
+
let st = out.state;
|
|
274
|
+
for (let i = from; i < to; i++) {
|
|
275
|
+
const c = text[i];
|
|
276
|
+
if (st === '"' || st === "'") {
|
|
277
|
+
if (c === st) st = "outside";
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
const ws = c === " " || c === " " || c === "\n" || c === "\r" || c === "\f";
|
|
281
|
+
if (st === "afterEq") {
|
|
282
|
+
if (ws) continue;
|
|
283
|
+
if (c === '"' || c === "'") st = c;
|
|
284
|
+
else if (c === ">") return i;
|
|
285
|
+
else st = "unquoted";
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
if (st === "unquoted") {
|
|
289
|
+
if (ws) st = "outside";
|
|
290
|
+
else if (c === ">") return i;
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
if (c === "=") st = "afterEq";
|
|
294
|
+
else if (c === ">") return i;
|
|
295
|
+
}
|
|
296
|
+
out.state = st;
|
|
297
|
+
return -1;
|
|
298
|
+
}
|
|
208
299
|
var REF_RE = /!?\[((?:[^[\]\\]|\\.)*)\]/g;
|
|
209
300
|
var BACKTICK_RUN_RE = /`+/g;
|
|
210
301
|
var MD_BLANK_RE = /^[ \t\r]*$/;
|
|
@@ -299,6 +390,8 @@ function freshCheckpoint(defListEnabled, mathFlow, referenceTaint) {
|
|
|
299
390
|
openTotal: 0,
|
|
300
391
|
commentOpen: false,
|
|
301
392
|
piOpen: false,
|
|
393
|
+
bogusOpen: false,
|
|
394
|
+
rawTextOpen: null,
|
|
302
395
|
declOpen: false,
|
|
303
396
|
cdataOpen: false,
|
|
304
397
|
inFence: false,
|
|
@@ -323,6 +416,7 @@ function freshCheckpoint(defListEnabled, mathFlow, referenceTaint) {
|
|
|
323
416
|
pendingTruncatedCloses: [],
|
|
324
417
|
tagAcrossLines: false,
|
|
325
418
|
tagAcrossLinesIndent: 0,
|
|
419
|
+
tagAcrossLinesState: "outside",
|
|
326
420
|
htmlFlowReal: false
|
|
327
421
|
};
|
|
328
422
|
}
|
|
@@ -422,11 +516,21 @@ function computeFreezeBoundary(text, options, resume) {
|
|
|
422
516
|
let start = cp.confirmedOffset;
|
|
423
517
|
let tailLine = null;
|
|
424
518
|
while (start < text.length) {
|
|
425
|
-
let end = text.
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
519
|
+
let end = text.length;
|
|
520
|
+
let textEnd = text.length;
|
|
521
|
+
{
|
|
522
|
+
const nl = text.indexOf("\n", start);
|
|
523
|
+
const cr = text.indexOf("\r", start);
|
|
524
|
+
if (cr !== -1 && (nl === -1 || cr < nl)) {
|
|
525
|
+
textEnd = cr;
|
|
526
|
+
end = text.charCodeAt(cr + 1) === 10 ? cr + 1 : cr;
|
|
527
|
+
} else if (nl !== -1) {
|
|
528
|
+
textEnd = nl;
|
|
529
|
+
end = nl;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
const confirmed = end < text.length && !(end === text.length - 1 && text.charCodeAt(end) === 13);
|
|
533
|
+
const lineText = text.slice(start, textEnd);
|
|
430
534
|
const ln = {
|
|
431
535
|
start,
|
|
432
536
|
end,
|
|
@@ -518,14 +622,33 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
518
622
|
newest.defListSettled = ln.blank ? true : !canBecomeDdLine(ln.text, true);
|
|
519
623
|
}
|
|
520
624
|
const isBlockStart = cp.prevLineBlank;
|
|
521
|
-
if (cp.htmlSeamPending && !ln.blank && !cp.htmlFlowSinceBlank && !(cp.commentOpen || cp.piOpen || cp.declOpen || cp.cdataOpen)) {
|
|
625
|
+
if (cp.htmlSeamPending && !ln.blank && !cp.htmlFlowSinceBlank && !(cp.commentOpen || cp.piOpen || cp.declOpen || cp.cdataOpen || cp.bogusOpen)) {
|
|
522
626
|
const defShapedLine = DEF_RE.test(ln.text) || FOOTNOTE_DEF_RE.test(ln.text);
|
|
523
627
|
const commentOnly = ln.text.replace(/<!--[\s\S]*?-->/g, " ").replace(/<!--[\s\S]*$/, " ").replace(/[ \t\r]/g, "") === "";
|
|
524
628
|
if (!defShapedLine && !commentOnly) {
|
|
525
629
|
cp.htmlSeamPending = false;
|
|
526
630
|
}
|
|
527
631
|
}
|
|
632
|
+
const inForeignContent = () => (cp.tagBalance.get("svg") ?? 0) > 0 || (cp.tagBalance.get("math") ?? 0) > 0;
|
|
633
|
+
const honoursSelfClosing = (tag) => {
|
|
634
|
+
if (tag === "svg" || tag === "math") return true;
|
|
635
|
+
if (!inForeignContent() || HTML_BREAKOUT_TAGS.has(tag)) return false;
|
|
636
|
+
for (const ip of HTML_INTEGRATION_POINTS) if ((cp.tagBalance.get(ip) ?? 0) > 0) return false;
|
|
637
|
+
return true;
|
|
638
|
+
};
|
|
639
|
+
const htmlRulesApply = () => {
|
|
640
|
+
if (!inForeignContent()) return true;
|
|
641
|
+
for (const ip of HTML_INTEGRATION_POINTS) if ((cp.tagBalance.get(ip) ?? 0) > 0) return true;
|
|
642
|
+
return false;
|
|
643
|
+
};
|
|
528
644
|
const applyTag = (tag, closing) => {
|
|
645
|
+
if (cp.rawTextOpen !== null) {
|
|
646
|
+
if (!(closing && tag === cp.rawTextOpen)) return;
|
|
647
|
+
cp.rawTextOpen = null;
|
|
648
|
+
} else if (!closing && RAW_TEXT_ELEMENTS.has(tag) && htmlRulesApply()) {
|
|
649
|
+
cp.rawTextOpen = tag;
|
|
650
|
+
if (tag === "plaintext") cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
|
|
651
|
+
}
|
|
529
652
|
if (closing) {
|
|
530
653
|
const count = cp.tagBalance.get(tag) ?? 0;
|
|
531
654
|
if (count > 0) {
|
|
@@ -538,7 +661,7 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
538
661
|
}
|
|
539
662
|
};
|
|
540
663
|
const commentOpenAtLineStart = cp.commentOpen;
|
|
541
|
-
const rawOpenAtLineStart = cp.commentOpen || cp.piOpen || cp.declOpen || cp.cdataOpen;
|
|
664
|
+
const rawOpenAtLineStart = cp.commentOpen || cp.piOpen || cp.declOpen || cp.cdataOpen || cp.bogusOpen;
|
|
542
665
|
if (cp.inFence) {
|
|
543
666
|
const close = FENCE_RE.exec(ln.text);
|
|
544
667
|
if (close && close[1][0] === cp.fenceChar && close[1].length >= cp.fenceLen && isMdBlank(ln.text.slice(close[0].length))) {
|
|
@@ -621,13 +744,21 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
621
744
|
cp.pendingTruncatedTags = [];
|
|
622
745
|
}
|
|
623
746
|
cp.pendingTruncatedCloses = [];
|
|
747
|
+
if (cp.tagAcrossLines && (cp.tagAcrossLinesState === '"' || cp.tagAcrossLinesState === "'")) {
|
|
748
|
+
cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
|
|
749
|
+
}
|
|
624
750
|
cp.tagAcrossLines = false;
|
|
751
|
+
cp.tagAcrossLinesState = "outside";
|
|
752
|
+
if (cp.bogusOpen) {
|
|
753
|
+
cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
|
|
754
|
+
cp.bogusOpen = false;
|
|
755
|
+
}
|
|
625
756
|
cp.blankRun += 1;
|
|
626
757
|
cp.lastBlankStart = ln.start;
|
|
627
758
|
cp.candidates.push({
|
|
628
759
|
offset: Math.min(ln.end + 1, text.length),
|
|
629
760
|
blankRun: cp.blankRun,
|
|
630
|
-
htmlBalanced: cp.openTotal === 0 && !cp.commentOpen && !cp.piOpen && !cp.declOpen && !cp.cdataOpen,
|
|
761
|
+
htmlBalanced: cp.openTotal === 0 && !cp.commentOpen && !cp.piOpen && !cp.declOpen && !cp.cdataOpen && !cp.bogusOpen,
|
|
631
762
|
hazard: cp.hazardVerdict,
|
|
632
763
|
seamRisk: cp.htmlSeamPending,
|
|
633
764
|
defListSettled: null
|
|
@@ -657,7 +788,7 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
657
788
|
const t7 = TYPE7_LINE_RE.exec(t);
|
|
658
789
|
if (t6 !== null && TYPE6_NAMES.has(t6[1].toLowerCase()) || TYPE1_START_RE.test(t) || // Type 7 cannot interrupt a paragraph, and excludes the raw-text
|
|
659
790
|
// names (those are type 1 as start tags, paragraph as end tags).
|
|
660
|
-
t7 !== null && !cp.prevLineWasText && !TYPE1_NAMES.has(
|
|
791
|
+
t7 !== null && !cp.prevLineWasText && !TYPE1_NAMES.has(t7Name(t).toLowerCase())) {
|
|
661
792
|
cp.htmlFlowReal = true;
|
|
662
793
|
}
|
|
663
794
|
}
|
|
@@ -759,7 +890,7 @@ ${cont(scanText)}` };
|
|
|
759
890
|
pos = c + 3;
|
|
760
891
|
continue;
|
|
761
892
|
}
|
|
762
|
-
if (cp.declOpen) {
|
|
893
|
+
if (cp.declOpen || cp.bogusOpen) {
|
|
763
894
|
const c = scanText.indexOf(">", pos);
|
|
764
895
|
if (c === -1) {
|
|
765
896
|
rawSpans.push([pos, scanText.length]);
|
|
@@ -767,6 +898,7 @@ ${cont(scanText)}` };
|
|
|
767
898
|
}
|
|
768
899
|
rawSpans.push([pos, c + 1]);
|
|
769
900
|
cp.declOpen = false;
|
|
901
|
+
cp.bogusOpen = false;
|
|
770
902
|
pos = c + 1;
|
|
771
903
|
continue;
|
|
772
904
|
}
|
|
@@ -774,10 +906,16 @@ ${cont(scanText)}` };
|
|
|
774
906
|
const cd = scanText.indexOf("<![CDATA[", pos);
|
|
775
907
|
const dm = scanText.slice(pos).search(/<![A-Za-z]/);
|
|
776
908
|
const decl = dm === -1 ? -1 : pos + dm;
|
|
777
|
-
const
|
|
909
|
+
const bm = cp.htmlFlowReal ? scanText.slice(pos).search(/<!(?!--|[A-Za-z]|\[CDATA\[)|<\/(?![A-Za-z])/) : -1;
|
|
910
|
+
const bogus = bm === -1 ? -1 : pos + bm;
|
|
911
|
+
const starts = [pi, cd, decl, bogus].filter((x) => x !== -1);
|
|
778
912
|
if (starts.length === 0) break;
|
|
779
913
|
const first = Math.min(...starts);
|
|
780
|
-
if (first ===
|
|
914
|
+
if (first === bogus) {
|
|
915
|
+
rawSpans.push([bogus, bogus + 2]);
|
|
916
|
+
cp.bogusOpen = true;
|
|
917
|
+
pos = bogus + 2;
|
|
918
|
+
} else if (first === cd) {
|
|
781
919
|
rawSpans.push([cd, cd + 9]);
|
|
782
920
|
cp.cdataOpen = true;
|
|
783
921
|
pos = cd + 9;
|
|
@@ -804,22 +942,27 @@ ${cont(scanText)}` };
|
|
|
804
942
|
let skipTagScan = false;
|
|
805
943
|
if (cp.tagAcrossLines) {
|
|
806
944
|
if (ln.indent < cp.tagAcrossLinesIndent) poisonRawDivergence();
|
|
807
|
-
const
|
|
945
|
+
const attrs = { state: cp.tagAcrossLinesState };
|
|
946
|
+
const gt = scanTagAttrs(ln.text, 0, ln.text.length, attrs);
|
|
808
947
|
if (gt === -1) {
|
|
948
|
+
scanTagAttrs("\n", 0, 1, attrs);
|
|
949
|
+
cp.tagAcrossLinesState = attrs.state;
|
|
809
950
|
skipTagScan = true;
|
|
810
951
|
} else {
|
|
811
|
-
if (/["']/.test(ln.text.slice(0, gt))) poisonRawDivergence();
|
|
812
952
|
for (const tag of cp.pendingTruncatedCloses) applyTag(tag, true);
|
|
813
953
|
cp.pendingTruncatedCloses = [];
|
|
814
954
|
cp.tagAcrossLines = false;
|
|
955
|
+
cp.tagAcrossLinesState = "outside";
|
|
815
956
|
tagText = " ".repeat(gt + 1) + tagText.slice(gt + 1);
|
|
816
957
|
}
|
|
817
958
|
}
|
|
959
|
+
let tagHandledAsTruncated = false;
|
|
818
960
|
if (!skipTagScan) {
|
|
819
961
|
TAG_OR_COMMENT_RE.lastIndex = 0;
|
|
820
962
|
let m;
|
|
821
963
|
let lastCommentOpenerIdx = -1;
|
|
822
964
|
while ((m = TAG_OR_COMMENT_RE.exec(tagText)) !== null) {
|
|
965
|
+
if (cp.rawTextOpen !== null && (m[0] === "<!--" || m[0] === "-->" || m[0] === "--!>")) continue;
|
|
823
966
|
if (m[0] === "<!--") {
|
|
824
967
|
const next = tagText.slice(m.index + 4, m.index + 6);
|
|
825
968
|
if (cp.commentOpen) {
|
|
@@ -846,8 +989,31 @@ ${cont(scanText)}` };
|
|
|
846
989
|
const closing = m[1] === "/";
|
|
847
990
|
const tag = m[2].toLowerCase();
|
|
848
991
|
if (TABLE_PART_NAMES.has(tag)) cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + m.index);
|
|
849
|
-
|
|
850
|
-
if (
|
|
992
|
+
let attrs = m[3] ?? "";
|
|
993
|
+
if (cp.htmlFlowReal && (cp.rawTextOpen === null || closing && tag === cp.rawTextOpen)) {
|
|
994
|
+
const attrStart = m.index + 1 + (closing ? 1 : 0) + m[2].length;
|
|
995
|
+
const st = { state: "outside" };
|
|
996
|
+
const gt = scanTagAttrs(tagText, attrStart, tagText.length, st);
|
|
997
|
+
if (gt === -1) {
|
|
998
|
+
if (!VOID_TAGS.has(tag)) {
|
|
999
|
+
if (closing) cp.pendingTruncatedCloses.push(tag);
|
|
1000
|
+
else applyTag(tag, false);
|
|
1001
|
+
}
|
|
1002
|
+
scanTagAttrs("\n", 0, 1, st);
|
|
1003
|
+
cp.tagAcrossLines = true;
|
|
1004
|
+
cp.tagAcrossLinesIndent = ln.indent;
|
|
1005
|
+
cp.tagAcrossLinesState = st.state;
|
|
1006
|
+
tagHandledAsTruncated = true;
|
|
1007
|
+
break;
|
|
1008
|
+
}
|
|
1009
|
+
if (gt + 1 !== m.index + m[0].length) {
|
|
1010
|
+
attrs = tagText.slice(attrStart, gt);
|
|
1011
|
+
TAG_OR_COMMENT_RE.lastIndex = gt + 1;
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
if (closing && !cp.htmlFlowReal && !/^\s*$/.test(attrs)) continue;
|
|
1015
|
+
const selfClosing = /\/\s*$/.test(attrs);
|
|
1016
|
+
if (VOID_TAGS.has(tag) || selfClosing && honoursSelfClosing(tag)) continue;
|
|
851
1017
|
applyTag(tag, closing);
|
|
852
1018
|
}
|
|
853
1019
|
if (cp.commentOpen && lastCommentOpenerIdx !== -1 && !inRawText) {
|
|
@@ -867,25 +1033,39 @@ ${cont(scanText)}` };
|
|
|
867
1033
|
const closing = mr[1] === "/";
|
|
868
1034
|
const tag = mr[2].toLowerCase();
|
|
869
1035
|
if (TABLE_PART_NAMES.has(tag)) cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + mr.index);
|
|
1036
|
+
if (closing && mr[3] !== void 0 && !/^\s*$/.test(mr[3])) continue;
|
|
870
1037
|
const selfClosing = mr[3] !== void 0 && /\/\s*$/.test(mr[3]);
|
|
871
|
-
if (VOID_TAGS.has(tag) || selfClosing) continue;
|
|
1038
|
+
if (VOID_TAGS.has(tag) || selfClosing && honoursSelfClosing(tag)) continue;
|
|
872
1039
|
applyTag(tag, closing);
|
|
873
1040
|
}
|
|
874
1041
|
}
|
|
875
1042
|
if (cp.pendingTruncatedTags.length > 0 && ln.text.includes(">")) {
|
|
1043
|
+
if (cp.pendingTruncatedTags.some((t) => TABLE_PART_NAMES.has(t))) {
|
|
1044
|
+
cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
|
|
1045
|
+
}
|
|
876
1046
|
cp.pendingTruncatedTags = [];
|
|
877
1047
|
}
|
|
878
|
-
if (!cp.commentOpen) {
|
|
879
|
-
|
|
1048
|
+
if (!cp.commentOpen && !tagHandledAsTruncated) {
|
|
1049
|
+
let lastLt = -1;
|
|
1050
|
+
TAG_START_LT_RE.lastIndex = 0;
|
|
1051
|
+
for (let ms = TAG_START_LT_RE.exec(tagText); ms !== null; ms = TAG_START_LT_RE.exec(tagText)) {
|
|
1052
|
+
lastLt = ms.index;
|
|
1053
|
+
TAG_START_LT_RE.lastIndex = ms.index + 1;
|
|
1054
|
+
}
|
|
880
1055
|
if (lastLt !== -1 && !tagText.includes(">", lastLt)) {
|
|
881
1056
|
const m2 = TRUNCATED_TAG_RE.exec(tagText.slice(lastLt));
|
|
882
1057
|
if (m2) {
|
|
883
1058
|
const closing = m2[1] === "/";
|
|
884
1059
|
const tag = m2[2].toLowerCase();
|
|
885
|
-
if (TABLE_PART_NAMES.has(tag)
|
|
1060
|
+
if (TABLE_PART_NAMES.has(tag) && cp.htmlFlowReal) {
|
|
1061
|
+
cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + lastLt);
|
|
1062
|
+
}
|
|
886
1063
|
if (cp.htmlFlowReal) {
|
|
887
1064
|
cp.tagAcrossLines = true;
|
|
888
1065
|
cp.tagAcrossLinesIndent = ln.indent;
|
|
1066
|
+
const attrs = { state: "outside" };
|
|
1067
|
+
scanTagAttrs(m2[3] + "\n", 0, m2[3].length + 1, attrs);
|
|
1068
|
+
cp.tagAcrossLinesState = attrs.state;
|
|
889
1069
|
}
|
|
890
1070
|
if (closing) {
|
|
891
1071
|
if (!VOID_TAGS.has(tag) && cp.htmlFlowReal) cp.pendingTruncatedCloses.push(tag);
|
|
@@ -1554,7 +1734,7 @@ function normalizeId(s) {
|
|
|
1554
1734
|
return normalizeIdentifier3(s);
|
|
1555
1735
|
}
|
|
1556
1736
|
function normalizeForMatch(s) {
|
|
1557
|
-
return normalizeIdentifier3(s
|
|
1737
|
+
return normalizeIdentifier3(s);
|
|
1558
1738
|
}
|
|
1559
1739
|
|
|
1560
1740
|
// src/components/collectDefLabels.ts
|
|
@@ -1872,22 +2052,68 @@ function createRegistry(onEmpty) {
|
|
|
1872
2052
|
labelSet: { footnoteLabels: /* @__PURE__ */ new Set(), linkLabels: /* @__PURE__ */ new Set() },
|
|
1873
2053
|
version: 0,
|
|
1874
2054
|
_reactIdMap: /* @__PURE__ */ new Map(),
|
|
2055
|
+
/** Symbol → its `documentIndex`, for chunks that supplied one. */
|
|
2056
|
+
_chunkIndex: /* @__PURE__ */ new Map(),
|
|
1875
2057
|
_subscribers: /* @__PURE__ */ new Set(),
|
|
1876
2058
|
_notifyScheduled: false,
|
|
1877
|
-
allocateSymbol(reactId) {
|
|
2059
|
+
allocateSymbol(reactId, rawDocumentIndex) {
|
|
2060
|
+
const documentIndex = rawDocumentIndex !== void 0 && Number.isFinite(rawDocumentIndex) ? rawDocumentIndex : void 0;
|
|
2061
|
+
if (false) {
|
|
2062
|
+
console.warn(
|
|
2063
|
+
`[ai-react-markdown] documentIndex must be a finite number \u2014 received ${String(rawDocumentIndex)}; ignoring it for this chunk.`
|
|
2064
|
+
);
|
|
2065
|
+
}
|
|
1878
2066
|
const existing = this._reactIdMap.get(reactId);
|
|
1879
2067
|
if (existing) {
|
|
1880
2068
|
existing.refcount++;
|
|
2069
|
+
const moved = documentIndex !== void 0 ? this._chunkIndex.get(existing.symbol) !== documentIndex : this._chunkIndex.has(existing.symbol);
|
|
2070
|
+
if (moved) {
|
|
2071
|
+
const at = this.chunkOrder.indexOf(existing.symbol);
|
|
2072
|
+
if (at !== -1) this.chunkOrder.splice(at, 1);
|
|
2073
|
+
this._placeChunk(existing.symbol, documentIndex);
|
|
2074
|
+
this._notify();
|
|
2075
|
+
}
|
|
1881
2076
|
return existing.symbol;
|
|
1882
2077
|
}
|
|
1883
2078
|
const sym = Symbol(reactId);
|
|
1884
2079
|
this._reactIdMap.set(reactId, { symbol: sym, refcount: 1 });
|
|
1885
|
-
this.
|
|
2080
|
+
this._placeChunk(sym, documentIndex);
|
|
1886
2081
|
this._notify();
|
|
1887
2082
|
return sym;
|
|
1888
2083
|
},
|
|
1889
|
-
|
|
1890
|
-
|
|
2084
|
+
/** Put `sym` into `chunkOrder` at its document position. Without an index
|
|
2085
|
+
* it goes last (mount order — the historical behaviour); with one it
|
|
2086
|
+
* sorts before the first chunk that sits later, where a chunk WITHOUT an
|
|
2087
|
+
* index counts as "later" so an indexed chunk never lands behind one
|
|
2088
|
+
* whose position is unknown. */
|
|
2089
|
+
_placeChunk(sym, documentIndex) {
|
|
2090
|
+
if (false) {
|
|
2091
|
+
const anyIndexed = documentIndex !== void 0 || this.chunkOrder.some((s) => this._chunkIndex.has(s));
|
|
2092
|
+
const anyPlain = documentIndex === void 0 || this.chunkOrder.some((s) => !this._chunkIndex.has(s));
|
|
2093
|
+
if (anyIndexed && anyPlain) {
|
|
2094
|
+
console.warn(
|
|
2095
|
+
"[ai-react-markdown] Some chunks of this document supply `documentIndex` and some do not. Indexed chunks always sort ahead of un-indexed ones, so footnote numbering and aggregate-footer placement will not follow document order. Pass `documentIndex` to every chunk, or to none."
|
|
2096
|
+
);
|
|
2097
|
+
}
|
|
2098
|
+
}
|
|
2099
|
+
if (documentIndex === void 0) {
|
|
2100
|
+
this._chunkIndex.delete(sym);
|
|
2101
|
+
this.chunkOrder.push(sym);
|
|
2102
|
+
return;
|
|
2103
|
+
}
|
|
2104
|
+
this._chunkIndex.set(sym, documentIndex);
|
|
2105
|
+
let at = this.chunkOrder.length;
|
|
2106
|
+
for (let i = 0; i < this.chunkOrder.length; i++) {
|
|
2107
|
+
const other = this._chunkIndex.get(this.chunkOrder[i]);
|
|
2108
|
+
if (other === void 0 || other > documentIndex) {
|
|
2109
|
+
at = i;
|
|
2110
|
+
break;
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
this.chunkOrder.splice(at, 0, sym);
|
|
2114
|
+
},
|
|
2115
|
+
registerChunk(reactId, footnotes, links, documentIndex) {
|
|
2116
|
+
const sym = this.allocateSymbol(reactId, documentIndex);
|
|
1891
2117
|
this.contributeLabels(sym, footnotes, links);
|
|
1892
2118
|
return sym;
|
|
1893
2119
|
},
|
|
@@ -1910,6 +2136,7 @@ function createRegistry(onEmpty) {
|
|
|
1910
2136
|
this._reactIdMap.delete(reactId);
|
|
1911
2137
|
const idx = this.chunkOrder.indexOf(entry.symbol);
|
|
1912
2138
|
if (idx !== -1) this.chunkOrder.splice(idx, 1);
|
|
2139
|
+
this._chunkIndex.delete(entry.symbol);
|
|
1913
2140
|
this.chunkData.delete(entry.symbol);
|
|
1914
2141
|
const nextFn = /* @__PURE__ */ new Set();
|
|
1915
2142
|
const nextLink = /* @__PURE__ */ new Set();
|
|
@@ -3536,17 +3763,28 @@ function mergeClassNameAllowlist(existing, extraClassNames) {
|
|
|
3536
3763
|
return entries;
|
|
3537
3764
|
}
|
|
3538
3765
|
var crossChunkTags = ["cross-chunk-link", "cross-chunk-image", "footnote-sup"];
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3766
|
+
function deepFreeze(value) {
|
|
3767
|
+
if (value !== null && typeof value === "object" && !Object.isFrozen(value)) {
|
|
3768
|
+
Object.freeze(value);
|
|
3769
|
+
for (const key of Object.keys(value)) deepFreeze(value[key]);
|
|
3770
|
+
}
|
|
3771
|
+
return value;
|
|
3772
|
+
}
|
|
3773
|
+
var STRIPPED_TAGS = ["script", "style", "title", "textarea", "noframes", "noembed", "xmp", "iframe", "plaintext"];
|
|
3774
|
+
var sanitizeSchema = deepFreeze(
|
|
3775
|
+
cloneDeep_default({
|
|
3776
|
+
...defaultSchema,
|
|
3777
|
+
tagNames: [...defaultSchema.tagNames || [], "mark", ...crossChunkTags],
|
|
3778
|
+
attributes: {
|
|
3779
|
+
...defaultSchema.attributes,
|
|
3780
|
+
code: mergeClassNameAllowlist(defaultSchema.attributes?.code, ["math-inline", "math-display"]),
|
|
3781
|
+
"cross-chunk-link": ["label", "referenceType", "documentId", "localUrl", "localTitle"],
|
|
3782
|
+
"cross-chunk-image": ["label", "referenceType", "documentId", "alt", "localUrl", "localTitle"],
|
|
3783
|
+
"footnote-sup": ["label", "localOccurrence", "localNumber", "documentId"]
|
|
3784
|
+
},
|
|
3785
|
+
strip: [.../* @__PURE__ */ new Set([...defaultSchema.strip || [], ...STRIPPED_TAGS])]
|
|
3786
|
+
})
|
|
3787
|
+
);
|
|
3550
3788
|
|
|
3551
3789
|
// src/components/crossChunkUrlSanitize.ts
|
|
3552
3790
|
function fakeElement(tagName, key, url) {
|
|
@@ -3857,7 +4095,12 @@ var createSmoothStreamController = (options = {}) => {
|
|
|
3857
4095
|
return;
|
|
3858
4096
|
}
|
|
3859
4097
|
tentativeEnd = ends[ends.length - 1];
|
|
3860
|
-
|
|
4098
|
+
let hold = 1;
|
|
4099
|
+
if (!finished && ends.length > 1) {
|
|
4100
|
+
const last = source.charCodeAt(source.length - 1);
|
|
4101
|
+
if (last >= 55296 && last <= 56319) hold = 2;
|
|
4102
|
+
}
|
|
4103
|
+
const confirmedEnds = finished ? ends : ends.slice(0, -hold);
|
|
3861
4104
|
for (const end of confirmedEnds) pending.push(end);
|
|
3862
4105
|
};
|
|
3863
4106
|
const snap = (next) => {
|
|
@@ -3985,10 +4228,11 @@ function findClosingBacktickRun(content, start, n) {
|
|
|
3985
4228
|
const runLen = getRepeatedMarkerLength(content, i, "`");
|
|
3986
4229
|
if (runLen === n) return i;
|
|
3987
4230
|
i += runLen;
|
|
3988
|
-
} else if (ch === "\n") {
|
|
4231
|
+
} else if (ch === "\n" || ch === "\r") {
|
|
3989
4232
|
let j = i + 1;
|
|
3990
|
-
|
|
3991
|
-
|
|
4233
|
+
if (ch === "\r" && content[j] === "\n") j += 1;
|
|
4234
|
+
while (j < content.length && (content[j] === " " || content[j] === " ")) j += 1;
|
|
4235
|
+
if (j >= content.length || content[j] === "\n" || content[j] === "\r") return -1;
|
|
3992
4236
|
i += 1;
|
|
3993
4237
|
} else {
|
|
3994
4238
|
i += 1;
|
|
@@ -4089,26 +4333,54 @@ function escapeMhchemCommands(text) {
|
|
|
4089
4333
|
return text.replaceAll("$\\ce{", "$\\\\ce{").replaceAll("$\\pu{", "$\\\\pu{");
|
|
4090
4334
|
}
|
|
4091
4335
|
var CURRENCY_REGEX = /(?<![\\$])\$(?!\$)(?=\d+(?:,\d{3})*(?:\.\d+)?(?:[KMBkmb])?(?:\s|$|[^a-zA-Z\d]))/g;
|
|
4092
|
-
var NO_ESCAPED_DOLLAR_REGEX = /(?<![\\$])\$(?!\$)/g;
|
|
4093
4336
|
var DELIMITERS_REGEX = /(?<!!)\\\[([\S\s]*?[^\\])\\](?!\()|\\\((.*?)\\\)/g;
|
|
4094
4337
|
var ARRAY_COL_SPEC_OR_PIPE_REGEX = /(\\begin\{(?:array|tabular[x*]?)\}\{[^}]*\})|(?<!\\)\|/g;
|
|
4095
|
-
var
|
|
4338
|
+
var EVEN_BACKSLASHES = String.raw`(?<=(?:^|[^\\])(?:\\\\)*)`;
|
|
4339
|
+
var LATEX_BLOCK_REGEX = new RegExp(
|
|
4340
|
+
String.raw`${EVEN_BACKSLASHES}\$\$([\S\s]*?)${EVEN_BACKSLASHES}\$\$|(?<![\\$])\$(?!\$)((?:[^$\n]|\\\$)*?)(?<![\\` + "`" + String.raw`])\$(?!\$)`,
|
|
4341
|
+
"g"
|
|
4342
|
+
);
|
|
4096
4343
|
var TEXT_COMMAND = "\\text{";
|
|
4097
4344
|
var SINGLE_DOLLAR_REGEX = /(?<![\\$])\$(?!\$)((?:[^$\n]|\\[$])+?)(?<!\\)(?<!`)\$(?!\$)/g;
|
|
4345
|
+
function countBareDollars(str, from, to, prev, next) {
|
|
4346
|
+
let n = 0;
|
|
4347
|
+
for (let j = from; j < to; j++) {
|
|
4348
|
+
if (str.charCodeAt(j) !== 36) continue;
|
|
4349
|
+
const before = j > from ? str[j - 1] : prev;
|
|
4350
|
+
const after = j + 1 < to ? str[j + 1] : next;
|
|
4351
|
+
if (before !== "\\" && before !== "$" && after !== "$") n += 1;
|
|
4352
|
+
}
|
|
4353
|
+
return n;
|
|
4354
|
+
}
|
|
4098
4355
|
function escapeCurrencyDollarSigns(text) {
|
|
4099
4356
|
const parts = [];
|
|
4100
4357
|
let lastIndex = 0;
|
|
4101
4358
|
const currencyMatches = Array.from(text.matchAll(CURRENCY_REGEX));
|
|
4102
4359
|
let currentLineProcessed = "";
|
|
4360
|
+
let currentLineDollars = 0;
|
|
4361
|
+
const appendToLine = (piece) => {
|
|
4362
|
+
if (piece.length === 0) return;
|
|
4363
|
+
const prevLast = currentLineProcessed.length > 0 ? currentLineProcessed[currentLineProcessed.length - 1] : "";
|
|
4364
|
+
const prevBeforeLast = currentLineProcessed.length > 1 ? currentLineProcessed[currentLineProcessed.length - 2] : "";
|
|
4365
|
+
const prevLastCounted = prevLast === "$" && prevBeforeLast !== "\\" && prevBeforeLast !== "$";
|
|
4366
|
+
if (prevLastCounted && piece[0] === "$") currentLineDollars -= 1;
|
|
4367
|
+
currentLineDollars += countBareDollars(piece, 0, piece.length, prevLast, "");
|
|
4368
|
+
currentLineProcessed += piece;
|
|
4369
|
+
};
|
|
4370
|
+
const resetLine = (rest) => {
|
|
4371
|
+
currentLineProcessed = "";
|
|
4372
|
+
currentLineDollars = 0;
|
|
4373
|
+
appendToLine(rest);
|
|
4374
|
+
};
|
|
4103
4375
|
for (let i = 0; i < currencyMatches.length; i++) {
|
|
4104
4376
|
const match = currencyMatches[i];
|
|
4105
4377
|
const segment = text.substring(lastIndex, match.index);
|
|
4106
4378
|
parts.push(segment);
|
|
4107
4379
|
const newlineIdx = Math.max(segment.lastIndexOf("\n"), segment.lastIndexOf("\r"));
|
|
4108
4380
|
if (newlineIdx !== -1) {
|
|
4109
|
-
|
|
4381
|
+
resetLine(segment.substring(newlineIdx + 1));
|
|
4110
4382
|
} else {
|
|
4111
|
-
|
|
4383
|
+
appendToLine(segment);
|
|
4112
4384
|
}
|
|
4113
4385
|
let needEscape = true;
|
|
4114
4386
|
const restStart = match.index + 1;
|
|
@@ -4125,15 +4397,21 @@ function escapeCurrencyDollarSigns(text) {
|
|
|
4125
4397
|
}
|
|
4126
4398
|
firstLineBeforeNextMatch = text.substring(restStart, eol);
|
|
4127
4399
|
}
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4400
|
+
const restDollars = countBareDollars(firstLineBeforeNextMatch, 0, firstLineBeforeNextMatch.length, "", "");
|
|
4401
|
+
if (restDollars % 2 !== 0) {
|
|
4402
|
+
const L = currentLineProcessed;
|
|
4403
|
+
const lLast = L.length > 0 ? L[L.length - 1] : "";
|
|
4404
|
+
const lBeforeLast = L.length > 1 ? L[L.length - 2] : "";
|
|
4405
|
+
const lLastCounted = lLast === "$" && lBeforeLast !== "\\" && lBeforeLast !== "$";
|
|
4406
|
+
const f0 = firstLineBeforeNextMatch[0];
|
|
4407
|
+
let whole = currentLineDollars + restDollars;
|
|
4408
|
+
if (lLastCounted && f0 === "$") whole -= 1;
|
|
4409
|
+
if (f0 === "$" && (lLast === "\\" || lLast === "$") && firstLineBeforeNextMatch[1] !== "$") whole -= 1;
|
|
4410
|
+
if (whole % 2 !== 0) needEscape = false;
|
|
4133
4411
|
}
|
|
4134
4412
|
const replacement = needEscape ? "\\$" : "$";
|
|
4135
4413
|
parts.push(replacement);
|
|
4136
|
-
|
|
4414
|
+
appendToLine(replacement);
|
|
4137
4415
|
lastIndex = match.index + 1;
|
|
4138
4416
|
}
|
|
4139
4417
|
parts.push(text.substring(lastIndex));
|
|
@@ -4201,8 +4479,7 @@ function escapeLatexPipesInUnclosed(text) {
|
|
|
4201
4479
|
const tail = text.substring(unclosedStart + delimLen);
|
|
4202
4480
|
return before + delim + replaceUnescapedPipes(tail);
|
|
4203
4481
|
}
|
|
4204
|
-
function truncateUnclosedLatexBlock(text) {
|
|
4205
|
-
const unclosedStart = findUnclosedDelimiterStart(text, "double-only");
|
|
4482
|
+
function truncateUnclosedLatexBlock(text, unclosedStart = findUnclosedDelimiterStart(text, "double-only")) {
|
|
4206
4483
|
if (unclosedStart === -1) return text;
|
|
4207
4484
|
return text.substring(0, unclosedStart).trimEnd();
|
|
4208
4485
|
}
|
|
@@ -4313,8 +4590,9 @@ function processSliceInstrumented(slice, probe = true) {
|
|
|
4313
4590
|
if (probe && hasUnclosedTextCommand(text)) quiescent = false;
|
|
4314
4591
|
text = escapeTextUnderscores(text);
|
|
4315
4592
|
text = convertSingleToDoubleDollar(text);
|
|
4593
|
+
let unclosedDouble;
|
|
4316
4594
|
if (probe || index === 0 && LEADING_DOUBLE_DOLLAR_RE.test(text)) {
|
|
4317
|
-
|
|
4595
|
+
unclosedDouble = findUnclosedDelimiterStart(text, "double-only");
|
|
4318
4596
|
if (unclosedDouble !== -1) {
|
|
4319
4597
|
quiescent = false;
|
|
4320
4598
|
if (index === 0 && text.slice(0, unclosedDouble).trim() === "") {
|
|
@@ -4322,7 +4600,7 @@ function processSliceInstrumented(slice, probe = true) {
|
|
|
4322
4600
|
}
|
|
4323
4601
|
}
|
|
4324
4602
|
}
|
|
4325
|
-
text = truncateUnclosedLatexBlock(text);
|
|
4603
|
+
text = truncateUnclosedLatexBlock(text, unclosedDouble);
|
|
4326
4604
|
parts.push(text);
|
|
4327
4605
|
}
|
|
4328
4606
|
return { out: parts.join(""), quiescent, truncatedAtSeamStart };
|
|
@@ -4450,7 +4728,6 @@ function createRemendPreprocessor(options) {
|
|
|
4450
4728
|
}
|
|
4451
4729
|
export {
|
|
4452
4730
|
DEFAULT_PAYLOAD,
|
|
4453
|
-
DEF_LINE_START_RE,
|
|
4454
4731
|
PIPELINE_STAGES,
|
|
4455
4732
|
SENTINEL_FN_CONTENT,
|
|
4456
4733
|
SENTINEL_LINK_URL,
|
|
@@ -4485,7 +4762,6 @@ export {
|
|
|
4485
4762
|
hasLoneSurrogate,
|
|
4486
4763
|
highlight,
|
|
4487
4764
|
isFootnoteSection,
|
|
4488
|
-
lastRegionStart,
|
|
4489
4765
|
measureStage,
|
|
4490
4766
|
mergeClassNameAllowlist,
|
|
4491
4767
|
normalizeForMatch,
|