@ai-react-markdown/engine 2.4.3 → 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 +95 -0
- package/dist/index.cjs +440 -83
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +109 -58
- package/dist/index.d.ts +109 -58
- package/dist/index.dev.cjs +440 -83
- package/dist/index.dev.cjs.map +1 -1
- package/dist/index.dev.js +440 -81
- package/dist/index.dev.js.map +1 -1
- package/dist/index.js +440 -81
- package/dist/index.js.map +1 -1
- package/package.json +12 -2
package/dist/index.cjs
CHANGED
|
@@ -31,7 +31,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var src_exports = {};
|
|
32
32
|
__export(src_exports, {
|
|
33
33
|
DEFAULT_PAYLOAD: () => DEFAULT_PAYLOAD,
|
|
34
|
-
DEF_LINE_START_RE: () => DEF_LINE_START_RE,
|
|
35
34
|
PIPELINE_STAGES: () => PIPELINE_STAGES,
|
|
36
35
|
SENTINEL_FN_CONTENT: () => SENTINEL_FN_CONTENT,
|
|
37
36
|
SENTINEL_LINK_URL: () => SENTINEL_LINK_URL,
|
|
@@ -66,7 +65,6 @@ __export(src_exports, {
|
|
|
66
65
|
hasLoneSurrogate: () => hasLoneSurrogate,
|
|
67
66
|
highlight: () => highlight,
|
|
68
67
|
isFootnoteSection: () => isFootnoteSection,
|
|
69
|
-
lastRegionStart: () => lastRegionStart,
|
|
70
68
|
measureStage: () => measureStage,
|
|
71
69
|
mergeClassNameAllowlist: () => mergeClassNameAllowlist,
|
|
72
70
|
normalizeForMatch: () => normalizeForMatch,
|
|
@@ -269,6 +267,74 @@ var defaultUrlTransform = (value) => {
|
|
|
269
267
|
var import_micromark_util_html_tag_name = require("micromark-util-html-tag-name");
|
|
270
268
|
var import_micromark_util_normalize_identifier = require("micromark-util-normalize-identifier");
|
|
271
269
|
var TYPE6_NAMES = new Set(import_micromark_util_html_tag_name.htmlBlockNames);
|
|
270
|
+
var TABLE_PART_NAMES = /* @__PURE__ */ new Set(["td", "th", "tr", "tbody", "thead", "tfoot", "caption", "col", "colgroup"]);
|
|
271
|
+
var HTML_BREAKOUT_TAGS = /* @__PURE__ */ new Set([
|
|
272
|
+
"b",
|
|
273
|
+
"big",
|
|
274
|
+
"blockquote",
|
|
275
|
+
"body",
|
|
276
|
+
"br",
|
|
277
|
+
"center",
|
|
278
|
+
"code",
|
|
279
|
+
"dd",
|
|
280
|
+
"div",
|
|
281
|
+
"dl",
|
|
282
|
+
"dt",
|
|
283
|
+
"em",
|
|
284
|
+
"embed",
|
|
285
|
+
"h1",
|
|
286
|
+
"h2",
|
|
287
|
+
"h3",
|
|
288
|
+
"h4",
|
|
289
|
+
"h5",
|
|
290
|
+
"h6",
|
|
291
|
+
"head",
|
|
292
|
+
"hr",
|
|
293
|
+
"i",
|
|
294
|
+
"img",
|
|
295
|
+
"li",
|
|
296
|
+
"listing",
|
|
297
|
+
"menu",
|
|
298
|
+
"meta",
|
|
299
|
+
"nobr",
|
|
300
|
+
"ol",
|
|
301
|
+
"p",
|
|
302
|
+
"pre",
|
|
303
|
+
"ruby",
|
|
304
|
+
"s",
|
|
305
|
+
"small",
|
|
306
|
+
"span",
|
|
307
|
+
"strong",
|
|
308
|
+
"strike",
|
|
309
|
+
"sub",
|
|
310
|
+
"sup",
|
|
311
|
+
"table",
|
|
312
|
+
"tt",
|
|
313
|
+
"u",
|
|
314
|
+
"ul",
|
|
315
|
+
"var"
|
|
316
|
+
]);
|
|
317
|
+
var HTML_INTEGRATION_POINTS = ["foreignobject", "desc", "mi", "mo", "mn", "ms", "mtext", "annotation-xml"];
|
|
318
|
+
var TYPE1_NAMES = /* @__PURE__ */ new Set(["script", "pre", "style", "textarea"]);
|
|
319
|
+
var RAW_TEXT_ELEMENTS = /* @__PURE__ */ new Set([
|
|
320
|
+
"script",
|
|
321
|
+
"style",
|
|
322
|
+
"textarea",
|
|
323
|
+
"title",
|
|
324
|
+
"xmp",
|
|
325
|
+
"iframe",
|
|
326
|
+
"noembed",
|
|
327
|
+
"noframes",
|
|
328
|
+
// NOT `noscript`: hast-util-raw constructs parse5 with
|
|
329
|
+
// `scriptingEnabled: false`, under which `<noscript>` content is ordinary
|
|
330
|
+
// HTML — modelling it as raw text ignored a `<b>` inside and under-blocked
|
|
331
|
+
// (oracle review of the r2 batch; regression caught before release).
|
|
332
|
+
"plaintext"
|
|
333
|
+
]);
|
|
334
|
+
var TYPE6_START_RE = /^<\/?([A-Za-z][A-Za-z0-9-]*)(?:[ \t\r]|\/?>|$)/;
|
|
335
|
+
var TYPE1_START_RE = /^<(script|pre|style|textarea)(?:[ \t\r]|>|$)/i;
|
|
336
|
+
var TYPE7_LINE_RE = /^(?:<[A-Za-z][A-Za-z0-9-]*(?:[ \t\r][^>]*|\/)?>|<\/[A-Za-z][A-Za-z0-9-]*[ \t\r]*>)[ \t\r]*$/;
|
|
337
|
+
var t7Name = (line) => /^<\/?([A-Za-z][A-Za-z0-9-]*)/.exec(line)[1];
|
|
272
338
|
var VOID_TAGS = /* @__PURE__ */ new Set([
|
|
273
339
|
"area",
|
|
274
340
|
"base",
|
|
@@ -292,7 +358,35 @@ var DEF_RE = /^ {0,3}\[((?:[^[\]\\]|\\.)+)\]:/;
|
|
|
292
358
|
var FENCE_RE = /^ {0,3}(`{3,}|~{3,})/;
|
|
293
359
|
var MATH_RUN_RE = /^ {0,3}(\$\$+)/;
|
|
294
360
|
var TAG_OR_COMMENT_RE = /<(\/?)([A-Za-z][A-Za-z0-9-]*)(?=[\s/>])([^>]*)>|<!--|-->|--!>/g;
|
|
295
|
-
var TRUNCATED_TAG_RE = /<(\/?)([A-Za-z][A-Za-z0-9-]*)([
|
|
361
|
+
var TRUNCATED_TAG_RE = /<(\/?)([A-Za-z][A-Za-z0-9-]*)([^>]*)$/;
|
|
362
|
+
var TAG_START_LT_RE = /<\/?[A-Za-z]/g;
|
|
363
|
+
function scanTagAttrs(text, from, to, out) {
|
|
364
|
+
let st = out.state;
|
|
365
|
+
for (let i = from; i < to; i++) {
|
|
366
|
+
const c = text[i];
|
|
367
|
+
if (st === '"' || st === "'") {
|
|
368
|
+
if (c === st) st = "outside";
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
const ws = c === " " || c === " " || c === "\n" || c === "\r" || c === "\f";
|
|
372
|
+
if (st === "afterEq") {
|
|
373
|
+
if (ws) continue;
|
|
374
|
+
if (c === '"' || c === "'") st = c;
|
|
375
|
+
else if (c === ">") return i;
|
|
376
|
+
else st = "unquoted";
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
if (st === "unquoted") {
|
|
380
|
+
if (ws) st = "outside";
|
|
381
|
+
else if (c === ">") return i;
|
|
382
|
+
continue;
|
|
383
|
+
}
|
|
384
|
+
if (c === "=") st = "afterEq";
|
|
385
|
+
else if (c === ">") return i;
|
|
386
|
+
}
|
|
387
|
+
out.state = st;
|
|
388
|
+
return -1;
|
|
389
|
+
}
|
|
296
390
|
var REF_RE = /!?\[((?:[^[\]\\]|\\.)*)\]/g;
|
|
297
391
|
var BACKTICK_RUN_RE = /`+/g;
|
|
298
392
|
var MD_BLANK_RE = /^[ \t\r]*$/;
|
|
@@ -387,6 +481,8 @@ function freshCheckpoint(defListEnabled, mathFlow, referenceTaint) {
|
|
|
387
481
|
openTotal: 0,
|
|
388
482
|
commentOpen: false,
|
|
389
483
|
piOpen: false,
|
|
484
|
+
bogusOpen: false,
|
|
485
|
+
rawTextOpen: null,
|
|
390
486
|
declOpen: false,
|
|
391
487
|
cdataOpen: false,
|
|
392
488
|
inFence: false,
|
|
@@ -407,7 +503,12 @@ function freshCheckpoint(defListEnabled, mathFlow, referenceTaint) {
|
|
|
407
503
|
htmlFlowSinceBlank: false,
|
|
408
504
|
htmlSeamPending: false,
|
|
409
505
|
phasePoisonedAt: Infinity,
|
|
410
|
-
pendingTruncatedTags: []
|
|
506
|
+
pendingTruncatedTags: [],
|
|
507
|
+
pendingTruncatedCloses: [],
|
|
508
|
+
tagAcrossLines: false,
|
|
509
|
+
tagAcrossLinesIndent: 0,
|
|
510
|
+
tagAcrossLinesState: "outside",
|
|
511
|
+
htmlFlowReal: false
|
|
411
512
|
};
|
|
412
513
|
}
|
|
413
514
|
function isPlausibleLinkDefRest(rest) {
|
|
@@ -506,11 +607,21 @@ function computeFreezeBoundary(text, options, resume) {
|
|
|
506
607
|
let start = cp.confirmedOffset;
|
|
507
608
|
let tailLine = null;
|
|
508
609
|
while (start < text.length) {
|
|
509
|
-
let end = text.
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
610
|
+
let end = text.length;
|
|
611
|
+
let textEnd = text.length;
|
|
612
|
+
{
|
|
613
|
+
const nl = text.indexOf("\n", start);
|
|
614
|
+
const cr = text.indexOf("\r", start);
|
|
615
|
+
if (cr !== -1 && (nl === -1 || cr < nl)) {
|
|
616
|
+
textEnd = cr;
|
|
617
|
+
end = text.charCodeAt(cr + 1) === 10 ? cr + 1 : cr;
|
|
618
|
+
} else if (nl !== -1) {
|
|
619
|
+
textEnd = nl;
|
|
620
|
+
end = nl;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
const confirmed = end < text.length && !(end === text.length - 1 && text.charCodeAt(end) === 13);
|
|
624
|
+
const lineText = text.slice(start, textEnd);
|
|
514
625
|
const ln = {
|
|
515
626
|
start,
|
|
516
627
|
end,
|
|
@@ -602,14 +713,33 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
602
713
|
newest.defListSettled = ln.blank ? true : !canBecomeDdLine(ln.text, true);
|
|
603
714
|
}
|
|
604
715
|
const isBlockStart = cp.prevLineBlank;
|
|
605
|
-
if (cp.htmlSeamPending && !ln.blank && !cp.htmlFlowSinceBlank && !(cp.commentOpen || cp.piOpen || cp.declOpen || cp.cdataOpen)) {
|
|
716
|
+
if (cp.htmlSeamPending && !ln.blank && !cp.htmlFlowSinceBlank && !(cp.commentOpen || cp.piOpen || cp.declOpen || cp.cdataOpen || cp.bogusOpen)) {
|
|
606
717
|
const defShapedLine = DEF_RE.test(ln.text) || FOOTNOTE_DEF_RE.test(ln.text);
|
|
607
718
|
const commentOnly = ln.text.replace(/<!--[\s\S]*?-->/g, " ").replace(/<!--[\s\S]*$/, " ").replace(/[ \t\r]/g, "") === "";
|
|
608
719
|
if (!defShapedLine && !commentOnly) {
|
|
609
720
|
cp.htmlSeamPending = false;
|
|
610
721
|
}
|
|
611
722
|
}
|
|
723
|
+
const inForeignContent = () => (cp.tagBalance.get("svg") ?? 0) > 0 || (cp.tagBalance.get("math") ?? 0) > 0;
|
|
724
|
+
const honoursSelfClosing = (tag) => {
|
|
725
|
+
if (tag === "svg" || tag === "math") return true;
|
|
726
|
+
if (!inForeignContent() || HTML_BREAKOUT_TAGS.has(tag)) return false;
|
|
727
|
+
for (const ip of HTML_INTEGRATION_POINTS) if ((cp.tagBalance.get(ip) ?? 0) > 0) return false;
|
|
728
|
+
return true;
|
|
729
|
+
};
|
|
730
|
+
const htmlRulesApply = () => {
|
|
731
|
+
if (!inForeignContent()) return true;
|
|
732
|
+
for (const ip of HTML_INTEGRATION_POINTS) if ((cp.tagBalance.get(ip) ?? 0) > 0) return true;
|
|
733
|
+
return false;
|
|
734
|
+
};
|
|
612
735
|
const applyTag = (tag, closing) => {
|
|
736
|
+
if (cp.rawTextOpen !== null) {
|
|
737
|
+
if (!(closing && tag === cp.rawTextOpen)) return;
|
|
738
|
+
cp.rawTextOpen = null;
|
|
739
|
+
} else if (!closing && RAW_TEXT_ELEMENTS.has(tag) && htmlRulesApply()) {
|
|
740
|
+
cp.rawTextOpen = tag;
|
|
741
|
+
if (tag === "plaintext") cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
|
|
742
|
+
}
|
|
613
743
|
if (closing) {
|
|
614
744
|
const count = cp.tagBalance.get(tag) ?? 0;
|
|
615
745
|
if (count > 0) {
|
|
@@ -622,7 +752,7 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
622
752
|
}
|
|
623
753
|
};
|
|
624
754
|
const commentOpenAtLineStart = cp.commentOpen;
|
|
625
|
-
const rawOpenAtLineStart = cp.commentOpen || cp.piOpen || cp.declOpen || cp.cdataOpen;
|
|
755
|
+
const rawOpenAtLineStart = cp.commentOpen || cp.piOpen || cp.declOpen || cp.cdataOpen || cp.bogusOpen;
|
|
626
756
|
if (cp.inFence) {
|
|
627
757
|
const close = FENCE_RE.exec(ln.text);
|
|
628
758
|
if (close && close[1][0] === cp.fenceChar && close[1].length >= cp.fenceLen && isMdBlank(ln.text.slice(close[0].length))) {
|
|
@@ -704,12 +834,22 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
704
834
|
for (const tag of cp.pendingTruncatedTags) applyTag(tag, true);
|
|
705
835
|
cp.pendingTruncatedTags = [];
|
|
706
836
|
}
|
|
837
|
+
cp.pendingTruncatedCloses = [];
|
|
838
|
+
if (cp.tagAcrossLines && (cp.tagAcrossLinesState === '"' || cp.tagAcrossLinesState === "'")) {
|
|
839
|
+
cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
|
|
840
|
+
}
|
|
841
|
+
cp.tagAcrossLines = false;
|
|
842
|
+
cp.tagAcrossLinesState = "outside";
|
|
843
|
+
if (cp.bogusOpen) {
|
|
844
|
+
cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
|
|
845
|
+
cp.bogusOpen = false;
|
|
846
|
+
}
|
|
707
847
|
cp.blankRun += 1;
|
|
708
848
|
cp.lastBlankStart = ln.start;
|
|
709
849
|
cp.candidates.push({
|
|
710
850
|
offset: Math.min(ln.end + 1, text.length),
|
|
711
851
|
blankRun: cp.blankRun,
|
|
712
|
-
htmlBalanced: cp.openTotal === 0 && !cp.commentOpen && !cp.piOpen && !cp.declOpen && !cp.cdataOpen,
|
|
852
|
+
htmlBalanced: cp.openTotal === 0 && !cp.commentOpen && !cp.piOpen && !cp.declOpen && !cp.cdataOpen && !cp.bogusOpen,
|
|
713
853
|
hazard: cp.hazardVerdict,
|
|
714
854
|
seamRisk: cp.htmlSeamPending,
|
|
715
855
|
defListSettled: null
|
|
@@ -717,6 +857,7 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
717
857
|
cp.paragraphHasUnpairedRun = false;
|
|
718
858
|
cp.openBracket = null;
|
|
719
859
|
cp.htmlFlowSinceBlank = false;
|
|
860
|
+
cp.htmlFlowReal = false;
|
|
720
861
|
cp.prevLineBlank = true;
|
|
721
862
|
cp.prevLineWasText = false;
|
|
722
863
|
cp.prevLineWasValidDef = false;
|
|
@@ -732,6 +873,16 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
732
873
|
if (tagStart) {
|
|
733
874
|
cp.htmlFlowSinceBlank = true;
|
|
734
875
|
if (!TYPE6_NAMES.has(tagStart[1].toLowerCase())) cp.hazardVerdict = true;
|
|
876
|
+
if (!cp.htmlFlowReal) {
|
|
877
|
+
const t = mdTrimStart(ln.text);
|
|
878
|
+
const t6 = TYPE6_START_RE.exec(t);
|
|
879
|
+
const t7 = TYPE7_LINE_RE.exec(t);
|
|
880
|
+
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
|
|
881
|
+
// names (those are type 1 as start tags, paragraph as end tags).
|
|
882
|
+
t7 !== null && !cp.prevLineWasText && !TYPE1_NAMES.has(t7Name(t).toLowerCase())) {
|
|
883
|
+
cp.htmlFlowReal = true;
|
|
884
|
+
}
|
|
885
|
+
}
|
|
735
886
|
}
|
|
736
887
|
const inRawText = cp.htmlFlowSinceBlank || rawOpenAtLineStart;
|
|
737
888
|
const rawFlowStart = ln.indent <= 3 && /^<(?:!--|\?|![A-Za-z]|!\[CDATA\[)/.test(mdTrimStart(ln.text));
|
|
@@ -830,7 +981,7 @@ ${cont(scanText)}` };
|
|
|
830
981
|
pos = c + 3;
|
|
831
982
|
continue;
|
|
832
983
|
}
|
|
833
|
-
if (cp.declOpen) {
|
|
984
|
+
if (cp.declOpen || cp.bogusOpen) {
|
|
834
985
|
const c = scanText.indexOf(">", pos);
|
|
835
986
|
if (c === -1) {
|
|
836
987
|
rawSpans.push([pos, scanText.length]);
|
|
@@ -838,6 +989,7 @@ ${cont(scanText)}` };
|
|
|
838
989
|
}
|
|
839
990
|
rawSpans.push([pos, c + 1]);
|
|
840
991
|
cp.declOpen = false;
|
|
992
|
+
cp.bogusOpen = false;
|
|
841
993
|
pos = c + 1;
|
|
842
994
|
continue;
|
|
843
995
|
}
|
|
@@ -845,10 +997,16 @@ ${cont(scanText)}` };
|
|
|
845
997
|
const cd = scanText.indexOf("<![CDATA[", pos);
|
|
846
998
|
const dm = scanText.slice(pos).search(/<![A-Za-z]/);
|
|
847
999
|
const decl = dm === -1 ? -1 : pos + dm;
|
|
848
|
-
const
|
|
1000
|
+
const bm = cp.htmlFlowReal ? scanText.slice(pos).search(/<!(?!--|[A-Za-z]|\[CDATA\[)|<\/(?![A-Za-z])/) : -1;
|
|
1001
|
+
const bogus = bm === -1 ? -1 : pos + bm;
|
|
1002
|
+
const starts = [pi, cd, decl, bogus].filter((x) => x !== -1);
|
|
849
1003
|
if (starts.length === 0) break;
|
|
850
1004
|
const first = Math.min(...starts);
|
|
851
|
-
if (first ===
|
|
1005
|
+
if (first === bogus) {
|
|
1006
|
+
rawSpans.push([bogus, bogus + 2]);
|
|
1007
|
+
cp.bogusOpen = true;
|
|
1008
|
+
pos = bogus + 2;
|
|
1009
|
+
} else if (first === cd) {
|
|
852
1010
|
rawSpans.push([cd, cd + 9]);
|
|
853
1011
|
cp.cdataOpen = true;
|
|
854
1012
|
pos = cd + 9;
|
|
@@ -872,11 +1030,30 @@ ${cont(scanText)}` };
|
|
|
872
1030
|
for (const [from, to] of rawSpans) {
|
|
873
1031
|
tagText = tagText.slice(0, from) + " ".repeat(to - from) + tagText.slice(to);
|
|
874
1032
|
}
|
|
875
|
-
|
|
1033
|
+
let skipTagScan = false;
|
|
1034
|
+
if (cp.tagAcrossLines) {
|
|
1035
|
+
if (ln.indent < cp.tagAcrossLinesIndent) poisonRawDivergence();
|
|
1036
|
+
const attrs = { state: cp.tagAcrossLinesState };
|
|
1037
|
+
const gt = scanTagAttrs(ln.text, 0, ln.text.length, attrs);
|
|
1038
|
+
if (gt === -1) {
|
|
1039
|
+
scanTagAttrs("\n", 0, 1, attrs);
|
|
1040
|
+
cp.tagAcrossLinesState = attrs.state;
|
|
1041
|
+
skipTagScan = true;
|
|
1042
|
+
} else {
|
|
1043
|
+
for (const tag of cp.pendingTruncatedCloses) applyTag(tag, true);
|
|
1044
|
+
cp.pendingTruncatedCloses = [];
|
|
1045
|
+
cp.tagAcrossLines = false;
|
|
1046
|
+
cp.tagAcrossLinesState = "outside";
|
|
1047
|
+
tagText = " ".repeat(gt + 1) + tagText.slice(gt + 1);
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
let tagHandledAsTruncated = false;
|
|
1051
|
+
if (!skipTagScan) {
|
|
876
1052
|
TAG_OR_COMMENT_RE.lastIndex = 0;
|
|
877
1053
|
let m;
|
|
878
1054
|
let lastCommentOpenerIdx = -1;
|
|
879
1055
|
while ((m = TAG_OR_COMMENT_RE.exec(tagText)) !== null) {
|
|
1056
|
+
if (cp.rawTextOpen !== null && (m[0] === "<!--" || m[0] === "-->" || m[0] === "--!>")) continue;
|
|
880
1057
|
if (m[0] === "<!--") {
|
|
881
1058
|
const next = tagText.slice(m.index + 4, m.index + 6);
|
|
882
1059
|
if (cp.commentOpen) {
|
|
@@ -902,8 +1079,32 @@ ${cont(scanText)}` };
|
|
|
902
1079
|
if (cp.commentOpen) continue;
|
|
903
1080
|
const closing = m[1] === "/";
|
|
904
1081
|
const tag = m[2].toLowerCase();
|
|
905
|
-
|
|
906
|
-
|
|
1082
|
+
if (TABLE_PART_NAMES.has(tag)) cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + m.index);
|
|
1083
|
+
let attrs = m[3] ?? "";
|
|
1084
|
+
if (cp.htmlFlowReal && (cp.rawTextOpen === null || closing && tag === cp.rawTextOpen)) {
|
|
1085
|
+
const attrStart = m.index + 1 + (closing ? 1 : 0) + m[2].length;
|
|
1086
|
+
const st = { state: "outside" };
|
|
1087
|
+
const gt = scanTagAttrs(tagText, attrStart, tagText.length, st);
|
|
1088
|
+
if (gt === -1) {
|
|
1089
|
+
if (!VOID_TAGS.has(tag)) {
|
|
1090
|
+
if (closing) cp.pendingTruncatedCloses.push(tag);
|
|
1091
|
+
else applyTag(tag, false);
|
|
1092
|
+
}
|
|
1093
|
+
scanTagAttrs("\n", 0, 1, st);
|
|
1094
|
+
cp.tagAcrossLines = true;
|
|
1095
|
+
cp.tagAcrossLinesIndent = ln.indent;
|
|
1096
|
+
cp.tagAcrossLinesState = st.state;
|
|
1097
|
+
tagHandledAsTruncated = true;
|
|
1098
|
+
break;
|
|
1099
|
+
}
|
|
1100
|
+
if (gt + 1 !== m.index + m[0].length) {
|
|
1101
|
+
attrs = tagText.slice(attrStart, gt);
|
|
1102
|
+
TAG_OR_COMMENT_RE.lastIndex = gt + 1;
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
if (closing && !cp.htmlFlowReal && !/^\s*$/.test(attrs)) continue;
|
|
1106
|
+
const selfClosing = /\/\s*$/.test(attrs);
|
|
1107
|
+
if (VOID_TAGS.has(tag) || selfClosing && honoursSelfClosing(tag)) continue;
|
|
907
1108
|
applyTag(tag, closing);
|
|
908
1109
|
}
|
|
909
1110
|
if (cp.commentOpen && lastCommentOpenerIdx !== -1 && !inRawText) {
|
|
@@ -922,22 +1123,44 @@ ${cont(scanText)}` };
|
|
|
922
1123
|
if (startMasked || wholeVisible || inRaw(mr.index) || cp.commentOpen) continue;
|
|
923
1124
|
const closing = mr[1] === "/";
|
|
924
1125
|
const tag = mr[2].toLowerCase();
|
|
1126
|
+
if (TABLE_PART_NAMES.has(tag)) cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + mr.index);
|
|
1127
|
+
if (closing && mr[3] !== void 0 && !/^\s*$/.test(mr[3])) continue;
|
|
925
1128
|
const selfClosing = mr[3] !== void 0 && /\/\s*$/.test(mr[3]);
|
|
926
|
-
if (VOID_TAGS.has(tag) || selfClosing) continue;
|
|
1129
|
+
if (VOID_TAGS.has(tag) || selfClosing && honoursSelfClosing(tag)) continue;
|
|
927
1130
|
applyTag(tag, closing);
|
|
928
1131
|
}
|
|
929
1132
|
}
|
|
930
1133
|
if (cp.pendingTruncatedTags.length > 0 && ln.text.includes(">")) {
|
|
1134
|
+
if (cp.pendingTruncatedTags.some((t) => TABLE_PART_NAMES.has(t))) {
|
|
1135
|
+
cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
|
|
1136
|
+
}
|
|
931
1137
|
cp.pendingTruncatedTags = [];
|
|
932
1138
|
}
|
|
933
|
-
if (!cp.commentOpen) {
|
|
934
|
-
|
|
1139
|
+
if (!cp.commentOpen && !tagHandledAsTruncated) {
|
|
1140
|
+
let lastLt = -1;
|
|
1141
|
+
TAG_START_LT_RE.lastIndex = 0;
|
|
1142
|
+
for (let ms = TAG_START_LT_RE.exec(tagText); ms !== null; ms = TAG_START_LT_RE.exec(tagText)) {
|
|
1143
|
+
lastLt = ms.index;
|
|
1144
|
+
TAG_START_LT_RE.lastIndex = ms.index + 1;
|
|
1145
|
+
}
|
|
935
1146
|
if (lastLt !== -1 && !tagText.includes(">", lastLt)) {
|
|
936
1147
|
const m2 = TRUNCATED_TAG_RE.exec(tagText.slice(lastLt));
|
|
937
1148
|
if (m2) {
|
|
938
1149
|
const closing = m2[1] === "/";
|
|
939
1150
|
const tag = m2[2].toLowerCase();
|
|
940
|
-
if (
|
|
1151
|
+
if (TABLE_PART_NAMES.has(tag) && cp.htmlFlowReal) {
|
|
1152
|
+
cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + lastLt);
|
|
1153
|
+
}
|
|
1154
|
+
if (cp.htmlFlowReal) {
|
|
1155
|
+
cp.tagAcrossLines = true;
|
|
1156
|
+
cp.tagAcrossLinesIndent = ln.indent;
|
|
1157
|
+
const attrs = { state: "outside" };
|
|
1158
|
+
scanTagAttrs(m2[3] + "\n", 0, m2[3].length + 1, attrs);
|
|
1159
|
+
cp.tagAcrossLinesState = attrs.state;
|
|
1160
|
+
}
|
|
1161
|
+
if (closing) {
|
|
1162
|
+
if (!VOID_TAGS.has(tag) && cp.htmlFlowReal) cp.pendingTruncatedCloses.push(tag);
|
|
1163
|
+
} else if (!VOID_TAGS.has(tag)) {
|
|
941
1164
|
applyTag(tag, closing);
|
|
942
1165
|
const rawLastLt = ln.text.lastIndexOf("<");
|
|
943
1166
|
const rawTruncated = rawLastLt !== -1 && !ln.text.includes(">", rawLastLt);
|
|
@@ -1480,6 +1703,9 @@ function countTrailingNewlines(value) {
|
|
|
1480
1703
|
function countNewlines(text, end = text.length) {
|
|
1481
1704
|
let count = 0;
|
|
1482
1705
|
for (let i = text.indexOf("\n"); i !== -1 && i < end; i = text.indexOf("\n", i + 1)) count += 1;
|
|
1706
|
+
for (let i = text.indexOf("\r"); i !== -1 && i < end; i = text.indexOf("\r", i + 1)) {
|
|
1707
|
+
if (text.charCodeAt(i + 1) !== 10) count += 1;
|
|
1708
|
+
}
|
|
1483
1709
|
return count;
|
|
1484
1710
|
}
|
|
1485
1711
|
|
|
@@ -1599,7 +1825,7 @@ function normalizeId(s) {
|
|
|
1599
1825
|
return (0, import_micromark_util_normalize_identifier3.normalizeIdentifier)(s);
|
|
1600
1826
|
}
|
|
1601
1827
|
function normalizeForMatch(s) {
|
|
1602
|
-
return (0, import_micromark_util_normalize_identifier3.normalizeIdentifier)(s
|
|
1828
|
+
return (0, import_micromark_util_normalize_identifier3.normalizeIdentifier)(s);
|
|
1603
1829
|
}
|
|
1604
1830
|
|
|
1605
1831
|
// src/components/collectDefLabels.ts
|
|
@@ -1917,22 +2143,68 @@ function createRegistry(onEmpty) {
|
|
|
1917
2143
|
labelSet: { footnoteLabels: /* @__PURE__ */ new Set(), linkLabels: /* @__PURE__ */ new Set() },
|
|
1918
2144
|
version: 0,
|
|
1919
2145
|
_reactIdMap: /* @__PURE__ */ new Map(),
|
|
2146
|
+
/** Symbol → its `documentIndex`, for chunks that supplied one. */
|
|
2147
|
+
_chunkIndex: /* @__PURE__ */ new Map(),
|
|
1920
2148
|
_subscribers: /* @__PURE__ */ new Set(),
|
|
1921
2149
|
_notifyScheduled: false,
|
|
1922
|
-
allocateSymbol(reactId) {
|
|
2150
|
+
allocateSymbol(reactId, rawDocumentIndex) {
|
|
2151
|
+
const documentIndex = rawDocumentIndex !== void 0 && Number.isFinite(rawDocumentIndex) ? rawDocumentIndex : void 0;
|
|
2152
|
+
if (false) {
|
|
2153
|
+
console.warn(
|
|
2154
|
+
`[ai-react-markdown] documentIndex must be a finite number \u2014 received ${String(rawDocumentIndex)}; ignoring it for this chunk.`
|
|
2155
|
+
);
|
|
2156
|
+
}
|
|
1923
2157
|
const existing = this._reactIdMap.get(reactId);
|
|
1924
2158
|
if (existing) {
|
|
1925
2159
|
existing.refcount++;
|
|
2160
|
+
const moved = documentIndex !== void 0 ? this._chunkIndex.get(existing.symbol) !== documentIndex : this._chunkIndex.has(existing.symbol);
|
|
2161
|
+
if (moved) {
|
|
2162
|
+
const at = this.chunkOrder.indexOf(existing.symbol);
|
|
2163
|
+
if (at !== -1) this.chunkOrder.splice(at, 1);
|
|
2164
|
+
this._placeChunk(existing.symbol, documentIndex);
|
|
2165
|
+
this._notify();
|
|
2166
|
+
}
|
|
1926
2167
|
return existing.symbol;
|
|
1927
2168
|
}
|
|
1928
2169
|
const sym = Symbol(reactId);
|
|
1929
2170
|
this._reactIdMap.set(reactId, { symbol: sym, refcount: 1 });
|
|
1930
|
-
this.
|
|
2171
|
+
this._placeChunk(sym, documentIndex);
|
|
1931
2172
|
this._notify();
|
|
1932
2173
|
return sym;
|
|
1933
2174
|
},
|
|
1934
|
-
|
|
1935
|
-
|
|
2175
|
+
/** Put `sym` into `chunkOrder` at its document position. Without an index
|
|
2176
|
+
* it goes last (mount order — the historical behaviour); with one it
|
|
2177
|
+
* sorts before the first chunk that sits later, where a chunk WITHOUT an
|
|
2178
|
+
* index counts as "later" so an indexed chunk never lands behind one
|
|
2179
|
+
* whose position is unknown. */
|
|
2180
|
+
_placeChunk(sym, documentIndex) {
|
|
2181
|
+
if (false) {
|
|
2182
|
+
const anyIndexed = documentIndex !== void 0 || this.chunkOrder.some((s) => this._chunkIndex.has(s));
|
|
2183
|
+
const anyPlain = documentIndex === void 0 || this.chunkOrder.some((s) => !this._chunkIndex.has(s));
|
|
2184
|
+
if (anyIndexed && anyPlain) {
|
|
2185
|
+
console.warn(
|
|
2186
|
+
"[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."
|
|
2187
|
+
);
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
if (documentIndex === void 0) {
|
|
2191
|
+
this._chunkIndex.delete(sym);
|
|
2192
|
+
this.chunkOrder.push(sym);
|
|
2193
|
+
return;
|
|
2194
|
+
}
|
|
2195
|
+
this._chunkIndex.set(sym, documentIndex);
|
|
2196
|
+
let at = this.chunkOrder.length;
|
|
2197
|
+
for (let i = 0; i < this.chunkOrder.length; i++) {
|
|
2198
|
+
const other = this._chunkIndex.get(this.chunkOrder[i]);
|
|
2199
|
+
if (other === void 0 || other > documentIndex) {
|
|
2200
|
+
at = i;
|
|
2201
|
+
break;
|
|
2202
|
+
}
|
|
2203
|
+
}
|
|
2204
|
+
this.chunkOrder.splice(at, 0, sym);
|
|
2205
|
+
},
|
|
2206
|
+
registerChunk(reactId, footnotes, links, documentIndex) {
|
|
2207
|
+
const sym = this.allocateSymbol(reactId, documentIndex);
|
|
1936
2208
|
this.contributeLabels(sym, footnotes, links);
|
|
1937
2209
|
return sym;
|
|
1938
2210
|
},
|
|
@@ -1955,6 +2227,7 @@ function createRegistry(onEmpty) {
|
|
|
1955
2227
|
this._reactIdMap.delete(reactId);
|
|
1956
2228
|
const idx = this.chunkOrder.indexOf(entry.symbol);
|
|
1957
2229
|
if (idx !== -1) this.chunkOrder.splice(idx, 1);
|
|
2230
|
+
this._chunkIndex.delete(entry.symbol);
|
|
1958
2231
|
this.chunkData.delete(entry.symbol);
|
|
1959
2232
|
const nextFn = /* @__PURE__ */ new Set();
|
|
1960
2233
|
const nextLink = /* @__PURE__ */ new Set();
|
|
@@ -3581,17 +3854,28 @@ function mergeClassNameAllowlist(existing, extraClassNames) {
|
|
|
3581
3854
|
return entries;
|
|
3582
3855
|
}
|
|
3583
3856
|
var crossChunkTags = ["cross-chunk-link", "cross-chunk-image", "footnote-sup"];
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3857
|
+
function deepFreeze(value) {
|
|
3858
|
+
if (value !== null && typeof value === "object" && !Object.isFrozen(value)) {
|
|
3859
|
+
Object.freeze(value);
|
|
3860
|
+
for (const key of Object.keys(value)) deepFreeze(value[key]);
|
|
3861
|
+
}
|
|
3862
|
+
return value;
|
|
3863
|
+
}
|
|
3864
|
+
var STRIPPED_TAGS = ["script", "style", "title", "textarea", "noframes", "noembed", "xmp", "iframe", "plaintext"];
|
|
3865
|
+
var sanitizeSchema = deepFreeze(
|
|
3866
|
+
cloneDeep_default({
|
|
3867
|
+
...import_rehype_sanitize2.defaultSchema,
|
|
3868
|
+
tagNames: [...import_rehype_sanitize2.defaultSchema.tagNames || [], "mark", ...crossChunkTags],
|
|
3869
|
+
attributes: {
|
|
3870
|
+
...import_rehype_sanitize2.defaultSchema.attributes,
|
|
3871
|
+
code: mergeClassNameAllowlist(import_rehype_sanitize2.defaultSchema.attributes?.code, ["math-inline", "math-display"]),
|
|
3872
|
+
"cross-chunk-link": ["label", "referenceType", "documentId", "localUrl", "localTitle"],
|
|
3873
|
+
"cross-chunk-image": ["label", "referenceType", "documentId", "alt", "localUrl", "localTitle"],
|
|
3874
|
+
"footnote-sup": ["label", "localOccurrence", "localNumber", "documentId"]
|
|
3875
|
+
},
|
|
3876
|
+
strip: [.../* @__PURE__ */ new Set([...import_rehype_sanitize2.defaultSchema.strip || [], ...STRIPPED_TAGS])]
|
|
3877
|
+
})
|
|
3878
|
+
);
|
|
3595
3879
|
|
|
3596
3880
|
// src/components/crossChunkUrlSanitize.ts
|
|
3597
3881
|
function fakeElement(tagName, key, url) {
|
|
@@ -3902,7 +4186,12 @@ var createSmoothStreamController = (options = {}) => {
|
|
|
3902
4186
|
return;
|
|
3903
4187
|
}
|
|
3904
4188
|
tentativeEnd = ends[ends.length - 1];
|
|
3905
|
-
|
|
4189
|
+
let hold = 1;
|
|
4190
|
+
if (!finished && ends.length > 1) {
|
|
4191
|
+
const last = source.charCodeAt(source.length - 1);
|
|
4192
|
+
if (last >= 55296 && last <= 56319) hold = 2;
|
|
4193
|
+
}
|
|
4194
|
+
const confirmedEnds = finished ? ends : ends.slice(0, -hold);
|
|
3906
4195
|
for (const end of confirmedEnds) pending.push(end);
|
|
3907
4196
|
};
|
|
3908
4197
|
const snap = (next) => {
|
|
@@ -4025,10 +4314,17 @@ function lineIndentBefore(content, pos) {
|
|
|
4025
4314
|
function findClosingBacktickRun(content, start, n) {
|
|
4026
4315
|
let i = start;
|
|
4027
4316
|
while (i < content.length) {
|
|
4028
|
-
|
|
4317
|
+
const ch = content[i];
|
|
4318
|
+
if (ch === "`") {
|
|
4029
4319
|
const runLen = getRepeatedMarkerLength(content, i, "`");
|
|
4030
4320
|
if (runLen === n) return i;
|
|
4031
4321
|
i += runLen;
|
|
4322
|
+
} else if (ch === "\n" || ch === "\r") {
|
|
4323
|
+
let j = i + 1;
|
|
4324
|
+
if (ch === "\r" && content[j] === "\n") j += 1;
|
|
4325
|
+
while (j < content.length && (content[j] === " " || content[j] === " ")) j += 1;
|
|
4326
|
+
if (j >= content.length || content[j] === "\n" || content[j] === "\r") return -1;
|
|
4327
|
+
i += 1;
|
|
4032
4328
|
} else {
|
|
4033
4329
|
i += 1;
|
|
4034
4330
|
}
|
|
@@ -4128,47 +4424,85 @@ function escapeMhchemCommands(text) {
|
|
|
4128
4424
|
return text.replaceAll("$\\ce{", "$\\\\ce{").replaceAll("$\\pu{", "$\\\\pu{");
|
|
4129
4425
|
}
|
|
4130
4426
|
var CURRENCY_REGEX = /(?<![\\$])\$(?!\$)(?=\d+(?:,\d{3})*(?:\.\d+)?(?:[KMBkmb])?(?:\s|$|[^a-zA-Z\d]))/g;
|
|
4131
|
-
var NO_ESCAPED_DOLLAR_REGEX = /(?<![\\$])\$(?!\$)/g;
|
|
4132
4427
|
var DELIMITERS_REGEX = /(?<!!)\\\[([\S\s]*?[^\\])\\](?!\()|\\\((.*?)\\\)/g;
|
|
4133
4428
|
var ARRAY_COL_SPEC_OR_PIPE_REGEX = /(\\begin\{(?:array|tabular[x*]?)\}\{[^}]*\})|(?<!\\)\|/g;
|
|
4134
|
-
var
|
|
4429
|
+
var EVEN_BACKSLASHES = String.raw`(?<=(?:^|[^\\])(?:\\\\)*)`;
|
|
4430
|
+
var LATEX_BLOCK_REGEX = new RegExp(
|
|
4431
|
+
String.raw`${EVEN_BACKSLASHES}\$\$([\S\s]*?)${EVEN_BACKSLASHES}\$\$|(?<![\\$])\$(?!\$)((?:[^$\n]|\\\$)*?)(?<![\\` + "`" + String.raw`])\$(?!\$)`,
|
|
4432
|
+
"g"
|
|
4433
|
+
);
|
|
4135
4434
|
var TEXT_COMMAND = "\\text{";
|
|
4136
4435
|
var SINGLE_DOLLAR_REGEX = /(?<![\\$])\$(?!\$)((?:[^$\n]|\\[$])+?)(?<!\\)(?<!`)\$(?!\$)/g;
|
|
4436
|
+
function countBareDollars(str, from, to, prev, next) {
|
|
4437
|
+
let n = 0;
|
|
4438
|
+
for (let j = from; j < to; j++) {
|
|
4439
|
+
if (str.charCodeAt(j) !== 36) continue;
|
|
4440
|
+
const before = j > from ? str[j - 1] : prev;
|
|
4441
|
+
const after = j + 1 < to ? str[j + 1] : next;
|
|
4442
|
+
if (before !== "\\" && before !== "$" && after !== "$") n += 1;
|
|
4443
|
+
}
|
|
4444
|
+
return n;
|
|
4445
|
+
}
|
|
4137
4446
|
function escapeCurrencyDollarSigns(text) {
|
|
4138
4447
|
const parts = [];
|
|
4139
4448
|
let lastIndex = 0;
|
|
4140
4449
|
const currencyMatches = Array.from(text.matchAll(CURRENCY_REGEX));
|
|
4141
4450
|
let currentLineProcessed = "";
|
|
4451
|
+
let currentLineDollars = 0;
|
|
4452
|
+
const appendToLine = (piece) => {
|
|
4453
|
+
if (piece.length === 0) return;
|
|
4454
|
+
const prevLast = currentLineProcessed.length > 0 ? currentLineProcessed[currentLineProcessed.length - 1] : "";
|
|
4455
|
+
const prevBeforeLast = currentLineProcessed.length > 1 ? currentLineProcessed[currentLineProcessed.length - 2] : "";
|
|
4456
|
+
const prevLastCounted = prevLast === "$" && prevBeforeLast !== "\\" && prevBeforeLast !== "$";
|
|
4457
|
+
if (prevLastCounted && piece[0] === "$") currentLineDollars -= 1;
|
|
4458
|
+
currentLineDollars += countBareDollars(piece, 0, piece.length, prevLast, "");
|
|
4459
|
+
currentLineProcessed += piece;
|
|
4460
|
+
};
|
|
4461
|
+
const resetLine = (rest) => {
|
|
4462
|
+
currentLineProcessed = "";
|
|
4463
|
+
currentLineDollars = 0;
|
|
4464
|
+
appendToLine(rest);
|
|
4465
|
+
};
|
|
4142
4466
|
for (let i = 0; i < currencyMatches.length; i++) {
|
|
4143
4467
|
const match = currencyMatches[i];
|
|
4144
4468
|
const segment = text.substring(lastIndex, match.index);
|
|
4145
4469
|
parts.push(segment);
|
|
4146
4470
|
const newlineIdx = Math.max(segment.lastIndexOf("\n"), segment.lastIndexOf("\r"));
|
|
4147
4471
|
if (newlineIdx !== -1) {
|
|
4148
|
-
|
|
4472
|
+
resetLine(segment.substring(newlineIdx + 1));
|
|
4149
4473
|
} else {
|
|
4150
|
-
|
|
4474
|
+
appendToLine(segment);
|
|
4151
4475
|
}
|
|
4152
4476
|
let needEscape = true;
|
|
4153
|
-
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4477
|
+
const restStart = match.index + 1;
|
|
4478
|
+
const restEnd = i < currencyMatches.length - 1 ? currencyMatches[i + 1].index : text.length;
|
|
4479
|
+
let firstLineBeforeNextMatch = "";
|
|
4480
|
+
if (restEnd - restStart > 0) {
|
|
4481
|
+
let eol = restEnd;
|
|
4482
|
+
for (let k = restStart; k < restEnd; k++) {
|
|
4483
|
+
const c = text.charCodeAt(k);
|
|
4484
|
+
if (c === 10 || c === 13) {
|
|
4485
|
+
eol = k;
|
|
4486
|
+
break;
|
|
4487
|
+
}
|
|
4158
4488
|
}
|
|
4159
|
-
|
|
4160
|
-
restBeforeNextMatchOrEnd = text.substring(match.index + 1);
|
|
4489
|
+
firstLineBeforeNextMatch = text.substring(restStart, eol);
|
|
4161
4490
|
}
|
|
4162
|
-
const
|
|
4163
|
-
if (
|
|
4164
|
-
const
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4491
|
+
const restDollars = countBareDollars(firstLineBeforeNextMatch, 0, firstLineBeforeNextMatch.length, "", "");
|
|
4492
|
+
if (restDollars % 2 !== 0) {
|
|
4493
|
+
const L = currentLineProcessed;
|
|
4494
|
+
const lLast = L.length > 0 ? L[L.length - 1] : "";
|
|
4495
|
+
const lBeforeLast = L.length > 1 ? L[L.length - 2] : "";
|
|
4496
|
+
const lLastCounted = lLast === "$" && lBeforeLast !== "\\" && lBeforeLast !== "$";
|
|
4497
|
+
const f0 = firstLineBeforeNextMatch[0];
|
|
4498
|
+
let whole = currentLineDollars + restDollars;
|
|
4499
|
+
if (lLastCounted && f0 === "$") whole -= 1;
|
|
4500
|
+
if (f0 === "$" && (lLast === "\\" || lLast === "$") && firstLineBeforeNextMatch[1] !== "$") whole -= 1;
|
|
4501
|
+
if (whole % 2 !== 0) needEscape = false;
|
|
4168
4502
|
}
|
|
4169
4503
|
const replacement = needEscape ? "\\$" : "$";
|
|
4170
4504
|
parts.push(replacement);
|
|
4171
|
-
|
|
4505
|
+
appendToLine(replacement);
|
|
4172
4506
|
lastIndex = match.index + 1;
|
|
4173
4507
|
}
|
|
4174
4508
|
parts.push(text.substring(lastIndex));
|
|
@@ -4236,8 +4570,7 @@ function escapeLatexPipesInUnclosed(text) {
|
|
|
4236
4570
|
const tail = text.substring(unclosedStart + delimLen);
|
|
4237
4571
|
return before + delim + replaceUnescapedPipes(tail);
|
|
4238
4572
|
}
|
|
4239
|
-
function truncateUnclosedLatexBlock(text) {
|
|
4240
|
-
const unclosedStart = findUnclosedDelimiterStart(text, "double-only");
|
|
4573
|
+
function truncateUnclosedLatexBlock(text, unclosedStart = findUnclosedDelimiterStart(text, "double-only")) {
|
|
4241
4574
|
if (unclosedStart === -1) return text;
|
|
4242
4575
|
return text.substring(0, unclosedStart).trimEnd();
|
|
4243
4576
|
}
|
|
@@ -4325,39 +4658,50 @@ function hasUnclosedTextCommand(text) {
|
|
|
4325
4658
|
return false;
|
|
4326
4659
|
}
|
|
4327
4660
|
var RESIDUAL_OPEN_BRACKET_RE = /(?<!!)\\\[/;
|
|
4328
|
-
|
|
4661
|
+
var LEADING_DOUBLE_DOLLAR_RE = /^\s*\$\$/;
|
|
4662
|
+
function processSliceInstrumented(slice, probe = true) {
|
|
4329
4663
|
const segments = splitByProtectedRegions(slice);
|
|
4330
|
-
|
|
4664
|
+
const parts = [];
|
|
4331
4665
|
let quiescent = true;
|
|
4332
4666
|
let truncatedAtSeamStart = false;
|
|
4333
4667
|
for (let index = 0; index < segments.length; index++) {
|
|
4334
4668
|
const segment = segments[index];
|
|
4335
4669
|
if (segment.isCode) {
|
|
4336
|
-
|
|
4670
|
+
parts.push(segment.text);
|
|
4337
4671
|
continue;
|
|
4338
4672
|
}
|
|
4339
4673
|
let text = segment.text;
|
|
4340
4674
|
text = escapeMhchemCommands(text);
|
|
4341
4675
|
text = escapeCurrencyDollarSigns(text);
|
|
4342
4676
|
text = convertLatexDelimiters(text);
|
|
4343
|
-
if (RESIDUAL_OPEN_BRACKET_RE.test(text)) quiescent = false;
|
|
4677
|
+
if (probe && RESIDUAL_OPEN_BRACKET_RE.test(text)) quiescent = false;
|
|
4344
4678
|
text = escapeLatexPipes(text);
|
|
4345
|
-
if (findUnclosedDelimiterStart(text, "both") !== -1) quiescent = false;
|
|
4679
|
+
if (probe && findUnclosedDelimiterStart(text, "both") !== -1) quiescent = false;
|
|
4346
4680
|
text = escapeLatexPipesInUnclosed(text);
|
|
4347
|
-
if (hasUnclosedTextCommand(text)) quiescent = false;
|
|
4681
|
+
if (probe && hasUnclosedTextCommand(text)) quiescent = false;
|
|
4348
4682
|
text = escapeTextUnderscores(text);
|
|
4349
4683
|
text = convertSingleToDoubleDollar(text);
|
|
4350
|
-
|
|
4351
|
-
if (
|
|
4352
|
-
|
|
4353
|
-
if (
|
|
4354
|
-
|
|
4684
|
+
let unclosedDouble;
|
|
4685
|
+
if (probe || index === 0 && LEADING_DOUBLE_DOLLAR_RE.test(text)) {
|
|
4686
|
+
unclosedDouble = findUnclosedDelimiterStart(text, "double-only");
|
|
4687
|
+
if (unclosedDouble !== -1) {
|
|
4688
|
+
quiescent = false;
|
|
4689
|
+
if (index === 0 && text.slice(0, unclosedDouble).trim() === "") {
|
|
4690
|
+
truncatedAtSeamStart = true;
|
|
4691
|
+
}
|
|
4355
4692
|
}
|
|
4356
4693
|
}
|
|
4357
|
-
text = truncateUnclosedLatexBlock(text);
|
|
4358
|
-
|
|
4694
|
+
text = truncateUnclosedLatexBlock(text, unclosedDouble);
|
|
4695
|
+
parts.push(text);
|
|
4359
4696
|
}
|
|
4360
|
-
return { out, quiescent, truncatedAtSeamStart };
|
|
4697
|
+
return { out: parts.join(""), quiescent, truncatedAtSeamStart };
|
|
4698
|
+
}
|
|
4699
|
+
function isBlankRawLine(text, from, to) {
|
|
4700
|
+
for (let i = from; i < to; i++) {
|
|
4701
|
+
const c = text.charCodeAt(i);
|
|
4702
|
+
if (c !== 32 && c !== 9 && c !== 13) return false;
|
|
4703
|
+
}
|
|
4704
|
+
return true;
|
|
4361
4705
|
}
|
|
4362
4706
|
function findRawSafeCut(active) {
|
|
4363
4707
|
const segments = splitByProtectedRegions(active);
|
|
@@ -4372,10 +4716,12 @@ function findRawSafeCut(active) {
|
|
|
4372
4716
|
continue;
|
|
4373
4717
|
}
|
|
4374
4718
|
const text = segment.text;
|
|
4719
|
+
let atLineStart = offset === 0 || active.charCodeAt(offset - 1) === 10;
|
|
4375
4720
|
let lineStart = 0;
|
|
4376
4721
|
while (lineStart <= text.length) {
|
|
4377
4722
|
const nl = text.indexOf("\n", lineStart);
|
|
4378
4723
|
const lineEnd = nl === -1 ? text.length : nl;
|
|
4724
|
+
if (atLineStart && nl !== -1 && isBlankRawLine(text, lineStart, lineEnd)) backtickHazard = false;
|
|
4379
4725
|
for (let i = lineStart; i < lineEnd; i++) {
|
|
4380
4726
|
const ch = text[i];
|
|
4381
4727
|
if (ch === "`") backtickHazard = true;
|
|
@@ -4388,6 +4734,7 @@ function findRawSafeCut(active) {
|
|
|
4388
4734
|
if (nl === -1) break;
|
|
4389
4735
|
if (!backtickHazard && !latentLt) lastCut = offset + nl + 1;
|
|
4390
4736
|
lineStart = nl + 1;
|
|
4737
|
+
atLineStart = true;
|
|
4391
4738
|
}
|
|
4392
4739
|
offset += text.length;
|
|
4393
4740
|
}
|
|
@@ -4396,11 +4743,14 @@ function findRawSafeCut(active) {
|
|
|
4396
4743
|
var DEFAULT_FREEZE_ATTEMPT_THRESHOLD = 512;
|
|
4397
4744
|
function createIncrementalLatexPreprocessor(options) {
|
|
4398
4745
|
const freezeThreshold = options?.freezeThreshold ?? DEFAULT_FREEZE_ATTEMPT_THRESHOLD;
|
|
4746
|
+
const onAttempt = options?.onAttempt;
|
|
4747
|
+
const backoff = options?.backoff ?? true;
|
|
4399
4748
|
let prevSource = "";
|
|
4400
4749
|
let prevOutput = "";
|
|
4401
4750
|
let frozenSrcEnd = 0;
|
|
4402
4751
|
let frozenOut = "";
|
|
4403
4752
|
let triggered = false;
|
|
4753
|
+
let nextAttemptLen = 0;
|
|
4404
4754
|
return function incrementalPreprocessLaTeX(source) {
|
|
4405
4755
|
if (source === prevSource) return prevOutput;
|
|
4406
4756
|
const isAppend = source.length > prevSource.length && source.startsWith(prevSource);
|
|
@@ -4408,6 +4758,7 @@ function createIncrementalLatexPreprocessor(options) {
|
|
|
4408
4758
|
frozenSrcEnd = 0;
|
|
4409
4759
|
frozenOut = "";
|
|
4410
4760
|
triggered = false;
|
|
4761
|
+
nextAttemptLen = 0;
|
|
4411
4762
|
}
|
|
4412
4763
|
if (!triggered) {
|
|
4413
4764
|
const checkFrom = isAppend ? Math.max(0, prevSource.length - 1) : 0;
|
|
@@ -4419,18 +4770,26 @@ function createIncrementalLatexPreprocessor(options) {
|
|
|
4419
4770
|
triggered = true;
|
|
4420
4771
|
}
|
|
4421
4772
|
let active = source.slice(frozenSrcEnd);
|
|
4422
|
-
if (active.length > freezeThreshold) {
|
|
4773
|
+
if (active.length > freezeThreshold && active.length >= nextAttemptLen) {
|
|
4774
|
+
const activeLength = active.length;
|
|
4775
|
+
let advanced = false;
|
|
4776
|
+
let frozenBytes = 0;
|
|
4777
|
+
const freeze = (cut2, slice) => {
|
|
4778
|
+
frozenOut += slice.out;
|
|
4779
|
+
frozenSrcEnd += cut2;
|
|
4780
|
+
active = source.slice(frozenSrcEnd);
|
|
4781
|
+
advanced = true;
|
|
4782
|
+
frozenBytes = cut2;
|
|
4783
|
+
};
|
|
4423
4784
|
const cut = findRawSafeCut(active);
|
|
4424
4785
|
if (cut > 0) {
|
|
4425
4786
|
const candidate = processSliceInstrumented(active.slice(0, cut));
|
|
4426
|
-
if (candidate.quiescent)
|
|
4427
|
-
frozenOut += candidate.out;
|
|
4428
|
-
frozenSrcEnd += cut;
|
|
4429
|
-
active = source.slice(frozenSrcEnd);
|
|
4430
|
-
}
|
|
4787
|
+
if (candidate.quiescent) freeze(cut, candidate);
|
|
4431
4788
|
}
|
|
4789
|
+
nextAttemptLen = advanced || !backoff ? 0 : active.length * 2;
|
|
4790
|
+
onAttempt?.({ activeLength, frozenBytes });
|
|
4432
4791
|
}
|
|
4433
|
-
const tail = processSliceInstrumented(active);
|
|
4792
|
+
const tail = processSliceInstrumented(active, false);
|
|
4434
4793
|
const head = tail.truncatedAtSeamStart ? frozenOut.replace(/\s+$/, "") : frozenOut;
|
|
4435
4794
|
const out = head + tail.out;
|
|
4436
4795
|
prevSource = source;
|
|
@@ -4461,7 +4820,6 @@ function createRemendPreprocessor(options) {
|
|
|
4461
4820
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4462
4821
|
0 && (module.exports = {
|
|
4463
4822
|
DEFAULT_PAYLOAD,
|
|
4464
|
-
DEF_LINE_START_RE,
|
|
4465
4823
|
PIPELINE_STAGES,
|
|
4466
4824
|
SENTINEL_FN_CONTENT,
|
|
4467
4825
|
SENTINEL_LINK_URL,
|
|
@@ -4496,7 +4854,6 @@ function createRemendPreprocessor(options) {
|
|
|
4496
4854
|
hasLoneSurrogate,
|
|
4497
4855
|
highlight,
|
|
4498
4856
|
isFootnoteSection,
|
|
4499
|
-
lastRegionStart,
|
|
4500
4857
|
measureStage,
|
|
4501
4858
|
mergeClassNameAllowlist,
|
|
4502
4859
|
normalizeForMatch,
|