@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.dev.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 (rawDocumentIndex !== void 0 && documentIndex === void 0) {
|
|
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 (this.chunkOrder.length > 0) {
|
|
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) {
|
|
@@ -3914,7 +4198,12 @@ var createSmoothStreamController = (options = {}) => {
|
|
|
3914
4198
|
return;
|
|
3915
4199
|
}
|
|
3916
4200
|
tentativeEnd = ends[ends.length - 1];
|
|
3917
|
-
|
|
4201
|
+
let hold = 1;
|
|
4202
|
+
if (!finished && ends.length > 1) {
|
|
4203
|
+
const last = source.charCodeAt(source.length - 1);
|
|
4204
|
+
if (last >= 55296 && last <= 56319) hold = 2;
|
|
4205
|
+
}
|
|
4206
|
+
const confirmedEnds = finished ? ends : ends.slice(0, -hold);
|
|
3918
4207
|
for (const end of confirmedEnds) pending.push(end);
|
|
3919
4208
|
};
|
|
3920
4209
|
const snap = (next) => {
|
|
@@ -4037,10 +4326,17 @@ function lineIndentBefore(content, pos) {
|
|
|
4037
4326
|
function findClosingBacktickRun(content, start, n) {
|
|
4038
4327
|
let i = start;
|
|
4039
4328
|
while (i < content.length) {
|
|
4040
|
-
|
|
4329
|
+
const ch = content[i];
|
|
4330
|
+
if (ch === "`") {
|
|
4041
4331
|
const runLen = getRepeatedMarkerLength(content, i, "`");
|
|
4042
4332
|
if (runLen === n) return i;
|
|
4043
4333
|
i += runLen;
|
|
4334
|
+
} else if (ch === "\n" || ch === "\r") {
|
|
4335
|
+
let j = i + 1;
|
|
4336
|
+
if (ch === "\r" && content[j] === "\n") j += 1;
|
|
4337
|
+
while (j < content.length && (content[j] === " " || content[j] === " ")) j += 1;
|
|
4338
|
+
if (j >= content.length || content[j] === "\n" || content[j] === "\r") return -1;
|
|
4339
|
+
i += 1;
|
|
4044
4340
|
} else {
|
|
4045
4341
|
i += 1;
|
|
4046
4342
|
}
|
|
@@ -4140,47 +4436,85 @@ function escapeMhchemCommands(text) {
|
|
|
4140
4436
|
return text.replaceAll("$\\ce{", "$\\\\ce{").replaceAll("$\\pu{", "$\\\\pu{");
|
|
4141
4437
|
}
|
|
4142
4438
|
var CURRENCY_REGEX = /(?<![\\$])\$(?!\$)(?=\d+(?:,\d{3})*(?:\.\d+)?(?:[KMBkmb])?(?:\s|$|[^a-zA-Z\d]))/g;
|
|
4143
|
-
var NO_ESCAPED_DOLLAR_REGEX = /(?<![\\$])\$(?!\$)/g;
|
|
4144
4439
|
var DELIMITERS_REGEX = /(?<!!)\\\[([\S\s]*?[^\\])\\](?!\()|\\\((.*?)\\\)/g;
|
|
4145
4440
|
var ARRAY_COL_SPEC_OR_PIPE_REGEX = /(\\begin\{(?:array|tabular[x*]?)\}\{[^}]*\})|(?<!\\)\|/g;
|
|
4146
|
-
var
|
|
4441
|
+
var EVEN_BACKSLASHES = String.raw`(?<=(?:^|[^\\])(?:\\\\)*)`;
|
|
4442
|
+
var LATEX_BLOCK_REGEX = new RegExp(
|
|
4443
|
+
String.raw`${EVEN_BACKSLASHES}\$\$([\S\s]*?)${EVEN_BACKSLASHES}\$\$|(?<![\\$])\$(?!\$)((?:[^$\n]|\\\$)*?)(?<![\\` + "`" + String.raw`])\$(?!\$)`,
|
|
4444
|
+
"g"
|
|
4445
|
+
);
|
|
4147
4446
|
var TEXT_COMMAND = "\\text{";
|
|
4148
4447
|
var SINGLE_DOLLAR_REGEX = /(?<![\\$])\$(?!\$)((?:[^$\n]|\\[$])+?)(?<!\\)(?<!`)\$(?!\$)/g;
|
|
4448
|
+
function countBareDollars(str, from, to, prev, next) {
|
|
4449
|
+
let n = 0;
|
|
4450
|
+
for (let j = from; j < to; j++) {
|
|
4451
|
+
if (str.charCodeAt(j) !== 36) continue;
|
|
4452
|
+
const before = j > from ? str[j - 1] : prev;
|
|
4453
|
+
const after = j + 1 < to ? str[j + 1] : next;
|
|
4454
|
+
if (before !== "\\" && before !== "$" && after !== "$") n += 1;
|
|
4455
|
+
}
|
|
4456
|
+
return n;
|
|
4457
|
+
}
|
|
4149
4458
|
function escapeCurrencyDollarSigns(text) {
|
|
4150
4459
|
const parts = [];
|
|
4151
4460
|
let lastIndex = 0;
|
|
4152
4461
|
const currencyMatches = Array.from(text.matchAll(CURRENCY_REGEX));
|
|
4153
4462
|
let currentLineProcessed = "";
|
|
4463
|
+
let currentLineDollars = 0;
|
|
4464
|
+
const appendToLine = (piece) => {
|
|
4465
|
+
if (piece.length === 0) return;
|
|
4466
|
+
const prevLast = currentLineProcessed.length > 0 ? currentLineProcessed[currentLineProcessed.length - 1] : "";
|
|
4467
|
+
const prevBeforeLast = currentLineProcessed.length > 1 ? currentLineProcessed[currentLineProcessed.length - 2] : "";
|
|
4468
|
+
const prevLastCounted = prevLast === "$" && prevBeforeLast !== "\\" && prevBeforeLast !== "$";
|
|
4469
|
+
if (prevLastCounted && piece[0] === "$") currentLineDollars -= 1;
|
|
4470
|
+
currentLineDollars += countBareDollars(piece, 0, piece.length, prevLast, "");
|
|
4471
|
+
currentLineProcessed += piece;
|
|
4472
|
+
};
|
|
4473
|
+
const resetLine = (rest) => {
|
|
4474
|
+
currentLineProcessed = "";
|
|
4475
|
+
currentLineDollars = 0;
|
|
4476
|
+
appendToLine(rest);
|
|
4477
|
+
};
|
|
4154
4478
|
for (let i = 0; i < currencyMatches.length; i++) {
|
|
4155
4479
|
const match = currencyMatches[i];
|
|
4156
4480
|
const segment = text.substring(lastIndex, match.index);
|
|
4157
4481
|
parts.push(segment);
|
|
4158
4482
|
const newlineIdx = Math.max(segment.lastIndexOf("\n"), segment.lastIndexOf("\r"));
|
|
4159
4483
|
if (newlineIdx !== -1) {
|
|
4160
|
-
|
|
4484
|
+
resetLine(segment.substring(newlineIdx + 1));
|
|
4161
4485
|
} else {
|
|
4162
|
-
|
|
4486
|
+
appendToLine(segment);
|
|
4163
4487
|
}
|
|
4164
4488
|
let needEscape = true;
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4489
|
+
const restStart = match.index + 1;
|
|
4490
|
+
const restEnd = i < currencyMatches.length - 1 ? currencyMatches[i + 1].index : text.length;
|
|
4491
|
+
let firstLineBeforeNextMatch = "";
|
|
4492
|
+
if (restEnd - restStart > 0) {
|
|
4493
|
+
let eol = restEnd;
|
|
4494
|
+
for (let k = restStart; k < restEnd; k++) {
|
|
4495
|
+
const c = text.charCodeAt(k);
|
|
4496
|
+
if (c === 10 || c === 13) {
|
|
4497
|
+
eol = k;
|
|
4498
|
+
break;
|
|
4499
|
+
}
|
|
4170
4500
|
}
|
|
4171
|
-
|
|
4172
|
-
restBeforeNextMatchOrEnd = text.substring(match.index + 1);
|
|
4501
|
+
firstLineBeforeNextMatch = text.substring(restStart, eol);
|
|
4173
4502
|
}
|
|
4174
|
-
const
|
|
4175
|
-
if (
|
|
4176
|
-
const
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4503
|
+
const restDollars = countBareDollars(firstLineBeforeNextMatch, 0, firstLineBeforeNextMatch.length, "", "");
|
|
4504
|
+
if (restDollars % 2 !== 0) {
|
|
4505
|
+
const L = currentLineProcessed;
|
|
4506
|
+
const lLast = L.length > 0 ? L[L.length - 1] : "";
|
|
4507
|
+
const lBeforeLast = L.length > 1 ? L[L.length - 2] : "";
|
|
4508
|
+
const lLastCounted = lLast === "$" && lBeforeLast !== "\\" && lBeforeLast !== "$";
|
|
4509
|
+
const f0 = firstLineBeforeNextMatch[0];
|
|
4510
|
+
let whole = currentLineDollars + restDollars;
|
|
4511
|
+
if (lLastCounted && f0 === "$") whole -= 1;
|
|
4512
|
+
if (f0 === "$" && (lLast === "\\" || lLast === "$") && firstLineBeforeNextMatch[1] !== "$") whole -= 1;
|
|
4513
|
+
if (whole % 2 !== 0) needEscape = false;
|
|
4180
4514
|
}
|
|
4181
4515
|
const replacement = needEscape ? "\\$" : "$";
|
|
4182
4516
|
parts.push(replacement);
|
|
4183
|
-
|
|
4517
|
+
appendToLine(replacement);
|
|
4184
4518
|
lastIndex = match.index + 1;
|
|
4185
4519
|
}
|
|
4186
4520
|
parts.push(text.substring(lastIndex));
|
|
@@ -4248,8 +4582,7 @@ function escapeLatexPipesInUnclosed(text) {
|
|
|
4248
4582
|
const tail = text.substring(unclosedStart + delimLen);
|
|
4249
4583
|
return before + delim + replaceUnescapedPipes(tail);
|
|
4250
4584
|
}
|
|
4251
|
-
function truncateUnclosedLatexBlock(text) {
|
|
4252
|
-
const unclosedStart = findUnclosedDelimiterStart(text, "double-only");
|
|
4585
|
+
function truncateUnclosedLatexBlock(text, unclosedStart = findUnclosedDelimiterStart(text, "double-only")) {
|
|
4253
4586
|
if (unclosedStart === -1) return text;
|
|
4254
4587
|
return text.substring(0, unclosedStart).trimEnd();
|
|
4255
4588
|
}
|
|
@@ -4337,39 +4670,50 @@ function hasUnclosedTextCommand(text) {
|
|
|
4337
4670
|
return false;
|
|
4338
4671
|
}
|
|
4339
4672
|
var RESIDUAL_OPEN_BRACKET_RE = /(?<!!)\\\[/;
|
|
4340
|
-
|
|
4673
|
+
var LEADING_DOUBLE_DOLLAR_RE = /^\s*\$\$/;
|
|
4674
|
+
function processSliceInstrumented(slice, probe = true) {
|
|
4341
4675
|
const segments = splitByProtectedRegions(slice);
|
|
4342
|
-
|
|
4676
|
+
const parts = [];
|
|
4343
4677
|
let quiescent = true;
|
|
4344
4678
|
let truncatedAtSeamStart = false;
|
|
4345
4679
|
for (let index = 0; index < segments.length; index++) {
|
|
4346
4680
|
const segment = segments[index];
|
|
4347
4681
|
if (segment.isCode) {
|
|
4348
|
-
|
|
4682
|
+
parts.push(segment.text);
|
|
4349
4683
|
continue;
|
|
4350
4684
|
}
|
|
4351
4685
|
let text = segment.text;
|
|
4352
4686
|
text = escapeMhchemCommands(text);
|
|
4353
4687
|
text = escapeCurrencyDollarSigns(text);
|
|
4354
4688
|
text = convertLatexDelimiters(text);
|
|
4355
|
-
if (RESIDUAL_OPEN_BRACKET_RE.test(text)) quiescent = false;
|
|
4689
|
+
if (probe && RESIDUAL_OPEN_BRACKET_RE.test(text)) quiescent = false;
|
|
4356
4690
|
text = escapeLatexPipes(text);
|
|
4357
|
-
if (findUnclosedDelimiterStart(text, "both") !== -1) quiescent = false;
|
|
4691
|
+
if (probe && findUnclosedDelimiterStart(text, "both") !== -1) quiescent = false;
|
|
4358
4692
|
text = escapeLatexPipesInUnclosed(text);
|
|
4359
|
-
if (hasUnclosedTextCommand(text)) quiescent = false;
|
|
4693
|
+
if (probe && hasUnclosedTextCommand(text)) quiescent = false;
|
|
4360
4694
|
text = escapeTextUnderscores(text);
|
|
4361
4695
|
text = convertSingleToDoubleDollar(text);
|
|
4362
|
-
|
|
4363
|
-
if (
|
|
4364
|
-
|
|
4365
|
-
if (
|
|
4366
|
-
|
|
4696
|
+
let unclosedDouble;
|
|
4697
|
+
if (probe || index === 0 && LEADING_DOUBLE_DOLLAR_RE.test(text)) {
|
|
4698
|
+
unclosedDouble = findUnclosedDelimiterStart(text, "double-only");
|
|
4699
|
+
if (unclosedDouble !== -1) {
|
|
4700
|
+
quiescent = false;
|
|
4701
|
+
if (index === 0 && text.slice(0, unclosedDouble).trim() === "") {
|
|
4702
|
+
truncatedAtSeamStart = true;
|
|
4703
|
+
}
|
|
4367
4704
|
}
|
|
4368
4705
|
}
|
|
4369
|
-
text = truncateUnclosedLatexBlock(text);
|
|
4370
|
-
|
|
4706
|
+
text = truncateUnclosedLatexBlock(text, unclosedDouble);
|
|
4707
|
+
parts.push(text);
|
|
4371
4708
|
}
|
|
4372
|
-
return { out, quiescent, truncatedAtSeamStart };
|
|
4709
|
+
return { out: parts.join(""), quiescent, truncatedAtSeamStart };
|
|
4710
|
+
}
|
|
4711
|
+
function isBlankRawLine(text, from, to) {
|
|
4712
|
+
for (let i = from; i < to; i++) {
|
|
4713
|
+
const c = text.charCodeAt(i);
|
|
4714
|
+
if (c !== 32 && c !== 9 && c !== 13) return false;
|
|
4715
|
+
}
|
|
4716
|
+
return true;
|
|
4373
4717
|
}
|
|
4374
4718
|
function findRawSafeCut(active) {
|
|
4375
4719
|
const segments = splitByProtectedRegions(active);
|
|
@@ -4384,10 +4728,12 @@ function findRawSafeCut(active) {
|
|
|
4384
4728
|
continue;
|
|
4385
4729
|
}
|
|
4386
4730
|
const text = segment.text;
|
|
4731
|
+
let atLineStart = offset === 0 || active.charCodeAt(offset - 1) === 10;
|
|
4387
4732
|
let lineStart = 0;
|
|
4388
4733
|
while (lineStart <= text.length) {
|
|
4389
4734
|
const nl = text.indexOf("\n", lineStart);
|
|
4390
4735
|
const lineEnd = nl === -1 ? text.length : nl;
|
|
4736
|
+
if (atLineStart && nl !== -1 && isBlankRawLine(text, lineStart, lineEnd)) backtickHazard = false;
|
|
4391
4737
|
for (let i = lineStart; i < lineEnd; i++) {
|
|
4392
4738
|
const ch = text[i];
|
|
4393
4739
|
if (ch === "`") backtickHazard = true;
|
|
@@ -4400,6 +4746,7 @@ function findRawSafeCut(active) {
|
|
|
4400
4746
|
if (nl === -1) break;
|
|
4401
4747
|
if (!backtickHazard && !latentLt) lastCut = offset + nl + 1;
|
|
4402
4748
|
lineStart = nl + 1;
|
|
4749
|
+
atLineStart = true;
|
|
4403
4750
|
}
|
|
4404
4751
|
offset += text.length;
|
|
4405
4752
|
}
|
|
@@ -4408,11 +4755,14 @@ function findRawSafeCut(active) {
|
|
|
4408
4755
|
var DEFAULT_FREEZE_ATTEMPT_THRESHOLD = 512;
|
|
4409
4756
|
function createIncrementalLatexPreprocessor(options) {
|
|
4410
4757
|
const freezeThreshold = options?.freezeThreshold ?? DEFAULT_FREEZE_ATTEMPT_THRESHOLD;
|
|
4758
|
+
const onAttempt = options?.onAttempt;
|
|
4759
|
+
const backoff = options?.backoff ?? true;
|
|
4411
4760
|
let prevSource = "";
|
|
4412
4761
|
let prevOutput = "";
|
|
4413
4762
|
let frozenSrcEnd = 0;
|
|
4414
4763
|
let frozenOut = "";
|
|
4415
4764
|
let triggered = false;
|
|
4765
|
+
let nextAttemptLen = 0;
|
|
4416
4766
|
return function incrementalPreprocessLaTeX(source) {
|
|
4417
4767
|
if (source === prevSource) return prevOutput;
|
|
4418
4768
|
const isAppend = source.length > prevSource.length && source.startsWith(prevSource);
|
|
@@ -4420,6 +4770,7 @@ function createIncrementalLatexPreprocessor(options) {
|
|
|
4420
4770
|
frozenSrcEnd = 0;
|
|
4421
4771
|
frozenOut = "";
|
|
4422
4772
|
triggered = false;
|
|
4773
|
+
nextAttemptLen = 0;
|
|
4423
4774
|
}
|
|
4424
4775
|
if (!triggered) {
|
|
4425
4776
|
const checkFrom = isAppend ? Math.max(0, prevSource.length - 1) : 0;
|
|
@@ -4431,18 +4782,26 @@ function createIncrementalLatexPreprocessor(options) {
|
|
|
4431
4782
|
triggered = true;
|
|
4432
4783
|
}
|
|
4433
4784
|
let active = source.slice(frozenSrcEnd);
|
|
4434
|
-
if (active.length > freezeThreshold) {
|
|
4785
|
+
if (active.length > freezeThreshold && active.length >= nextAttemptLen) {
|
|
4786
|
+
const activeLength = active.length;
|
|
4787
|
+
let advanced = false;
|
|
4788
|
+
let frozenBytes = 0;
|
|
4789
|
+
const freeze = (cut2, slice) => {
|
|
4790
|
+
frozenOut += slice.out;
|
|
4791
|
+
frozenSrcEnd += cut2;
|
|
4792
|
+
active = source.slice(frozenSrcEnd);
|
|
4793
|
+
advanced = true;
|
|
4794
|
+
frozenBytes = cut2;
|
|
4795
|
+
};
|
|
4435
4796
|
const cut = findRawSafeCut(active);
|
|
4436
4797
|
if (cut > 0) {
|
|
4437
4798
|
const candidate = processSliceInstrumented(active.slice(0, cut));
|
|
4438
|
-
if (candidate.quiescent)
|
|
4439
|
-
frozenOut += candidate.out;
|
|
4440
|
-
frozenSrcEnd += cut;
|
|
4441
|
-
active = source.slice(frozenSrcEnd);
|
|
4442
|
-
}
|
|
4799
|
+
if (candidate.quiescent) freeze(cut, candidate);
|
|
4443
4800
|
}
|
|
4801
|
+
nextAttemptLen = advanced || !backoff ? 0 : active.length * 2;
|
|
4802
|
+
onAttempt?.({ activeLength, frozenBytes });
|
|
4444
4803
|
}
|
|
4445
|
-
const tail = processSliceInstrumented(active);
|
|
4804
|
+
const tail = processSliceInstrumented(active, false);
|
|
4446
4805
|
const head = tail.truncatedAtSeamStart ? frozenOut.replace(/\s+$/, "") : frozenOut;
|
|
4447
4806
|
const out = head + tail.out;
|
|
4448
4807
|
prevSource = source;
|
|
@@ -4473,7 +4832,6 @@ function createRemendPreprocessor(options) {
|
|
|
4473
4832
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4474
4833
|
0 && (module.exports = {
|
|
4475
4834
|
DEFAULT_PAYLOAD,
|
|
4476
|
-
DEF_LINE_START_RE,
|
|
4477
4835
|
PIPELINE_STAGES,
|
|
4478
4836
|
SENTINEL_FN_CONTENT,
|
|
4479
4837
|
SENTINEL_LINK_URL,
|
|
@@ -4508,7 +4866,6 @@ function createRemendPreprocessor(options) {
|
|
|
4508
4866
|
hasLoneSurrogate,
|
|
4509
4867
|
highlight,
|
|
4510
4868
|
isFootnoteSection,
|
|
4511
|
-
lastRegionStart,
|
|
4512
4869
|
measureStage,
|
|
4513
4870
|
mergeClassNameAllowlist,
|
|
4514
4871
|
normalizeForMatch,
|