@ai-react-markdown/engine 2.4.5 → 2.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.cjs +380 -65
- 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 +380 -65
- package/dist/index.dev.cjs.map +1 -1
- package/dist/index.dev.js +380 -63
- package/dist/index.dev.js.map +1 -1
- package/dist/index.js +380 -63
- 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) {
|
|
@@ -537,8 +660,9 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
537
660
|
cp.openTotal += 1;
|
|
538
661
|
}
|
|
539
662
|
};
|
|
663
|
+
const strayTablePart = (tag) => TABLE_PART_NAMES.has(tag) && (cp.tagBalance.get("table") ?? 0) === 0;
|
|
540
664
|
const commentOpenAtLineStart = cp.commentOpen;
|
|
541
|
-
const rawOpenAtLineStart = cp.commentOpen || cp.piOpen || cp.declOpen || cp.cdataOpen;
|
|
665
|
+
const rawOpenAtLineStart = cp.commentOpen || cp.piOpen || cp.declOpen || cp.cdataOpen || cp.bogusOpen;
|
|
542
666
|
if (cp.inFence) {
|
|
543
667
|
const close = FENCE_RE.exec(ln.text);
|
|
544
668
|
if (close && close[1][0] === cp.fenceChar && close[1].length >= cp.fenceLen && isMdBlank(ln.text.slice(close[0].length))) {
|
|
@@ -621,13 +745,21 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
621
745
|
cp.pendingTruncatedTags = [];
|
|
622
746
|
}
|
|
623
747
|
cp.pendingTruncatedCloses = [];
|
|
748
|
+
if (cp.tagAcrossLines && (cp.tagAcrossLinesState === '"' || cp.tagAcrossLinesState === "'")) {
|
|
749
|
+
cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
|
|
750
|
+
}
|
|
624
751
|
cp.tagAcrossLines = false;
|
|
752
|
+
cp.tagAcrossLinesState = "outside";
|
|
753
|
+
if (cp.bogusOpen) {
|
|
754
|
+
cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
|
|
755
|
+
cp.bogusOpen = false;
|
|
756
|
+
}
|
|
625
757
|
cp.blankRun += 1;
|
|
626
758
|
cp.lastBlankStart = ln.start;
|
|
627
759
|
cp.candidates.push({
|
|
628
760
|
offset: Math.min(ln.end + 1, text.length),
|
|
629
761
|
blankRun: cp.blankRun,
|
|
630
|
-
htmlBalanced: cp.openTotal === 0 && !cp.commentOpen && !cp.piOpen && !cp.declOpen && !cp.cdataOpen,
|
|
762
|
+
htmlBalanced: cp.openTotal === 0 && !cp.commentOpen && !cp.piOpen && !cp.declOpen && !cp.cdataOpen && !cp.bogusOpen,
|
|
631
763
|
hazard: cp.hazardVerdict,
|
|
632
764
|
seamRisk: cp.htmlSeamPending,
|
|
633
765
|
defListSettled: null
|
|
@@ -657,7 +789,7 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
657
789
|
const t7 = TYPE7_LINE_RE.exec(t);
|
|
658
790
|
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
791
|
// names (those are type 1 as start tags, paragraph as end tags).
|
|
660
|
-
t7 !== null && !cp.prevLineWasText && !TYPE1_NAMES.has(
|
|
792
|
+
t7 !== null && !cp.prevLineWasText && !TYPE1_NAMES.has(t7Name(t).toLowerCase())) {
|
|
661
793
|
cp.htmlFlowReal = true;
|
|
662
794
|
}
|
|
663
795
|
}
|
|
@@ -759,7 +891,7 @@ ${cont(scanText)}` };
|
|
|
759
891
|
pos = c + 3;
|
|
760
892
|
continue;
|
|
761
893
|
}
|
|
762
|
-
if (cp.declOpen) {
|
|
894
|
+
if (cp.declOpen || cp.bogusOpen) {
|
|
763
895
|
const c = scanText.indexOf(">", pos);
|
|
764
896
|
if (c === -1) {
|
|
765
897
|
rawSpans.push([pos, scanText.length]);
|
|
@@ -767,6 +899,7 @@ ${cont(scanText)}` };
|
|
|
767
899
|
}
|
|
768
900
|
rawSpans.push([pos, c + 1]);
|
|
769
901
|
cp.declOpen = false;
|
|
902
|
+
cp.bogusOpen = false;
|
|
770
903
|
pos = c + 1;
|
|
771
904
|
continue;
|
|
772
905
|
}
|
|
@@ -774,10 +907,16 @@ ${cont(scanText)}` };
|
|
|
774
907
|
const cd = scanText.indexOf("<![CDATA[", pos);
|
|
775
908
|
const dm = scanText.slice(pos).search(/<![A-Za-z]/);
|
|
776
909
|
const decl = dm === -1 ? -1 : pos + dm;
|
|
777
|
-
const
|
|
910
|
+
const bm = cp.htmlFlowReal ? scanText.slice(pos).search(/<!(?!--|[A-Za-z]|\[CDATA\[)|<\/(?![A-Za-z])/) : -1;
|
|
911
|
+
const bogus = bm === -1 ? -1 : pos + bm;
|
|
912
|
+
const starts = [pi, cd, decl, bogus].filter((x) => x !== -1);
|
|
778
913
|
if (starts.length === 0) break;
|
|
779
914
|
const first = Math.min(...starts);
|
|
780
|
-
if (first ===
|
|
915
|
+
if (first === bogus) {
|
|
916
|
+
rawSpans.push([bogus, bogus + 2]);
|
|
917
|
+
cp.bogusOpen = true;
|
|
918
|
+
pos = bogus + 2;
|
|
919
|
+
} else if (first === cd) {
|
|
781
920
|
rawSpans.push([cd, cd + 9]);
|
|
782
921
|
cp.cdataOpen = true;
|
|
783
922
|
pos = cd + 9;
|
|
@@ -804,22 +943,27 @@ ${cont(scanText)}` };
|
|
|
804
943
|
let skipTagScan = false;
|
|
805
944
|
if (cp.tagAcrossLines) {
|
|
806
945
|
if (ln.indent < cp.tagAcrossLinesIndent) poisonRawDivergence();
|
|
807
|
-
const
|
|
946
|
+
const attrs = { state: cp.tagAcrossLinesState };
|
|
947
|
+
const gt = scanTagAttrs(ln.text, 0, ln.text.length, attrs);
|
|
808
948
|
if (gt === -1) {
|
|
949
|
+
scanTagAttrs("\n", 0, 1, attrs);
|
|
950
|
+
cp.tagAcrossLinesState = attrs.state;
|
|
809
951
|
skipTagScan = true;
|
|
810
952
|
} else {
|
|
811
|
-
if (/["']/.test(ln.text.slice(0, gt))) poisonRawDivergence();
|
|
812
953
|
for (const tag of cp.pendingTruncatedCloses) applyTag(tag, true);
|
|
813
954
|
cp.pendingTruncatedCloses = [];
|
|
814
955
|
cp.tagAcrossLines = false;
|
|
956
|
+
cp.tagAcrossLinesState = "outside";
|
|
815
957
|
tagText = " ".repeat(gt + 1) + tagText.slice(gt + 1);
|
|
816
958
|
}
|
|
817
959
|
}
|
|
960
|
+
let tagHandledAsTruncated = false;
|
|
818
961
|
if (!skipTagScan) {
|
|
819
962
|
TAG_OR_COMMENT_RE.lastIndex = 0;
|
|
820
963
|
let m;
|
|
821
964
|
let lastCommentOpenerIdx = -1;
|
|
822
965
|
while ((m = TAG_OR_COMMENT_RE.exec(tagText)) !== null) {
|
|
966
|
+
if (cp.rawTextOpen !== null && (m[0] === "<!--" || m[0] === "-->" || m[0] === "--!>")) continue;
|
|
823
967
|
if (m[0] === "<!--") {
|
|
824
968
|
const next = tagText.slice(m.index + 4, m.index + 6);
|
|
825
969
|
if (cp.commentOpen) {
|
|
@@ -845,9 +989,32 @@ ${cont(scanText)}` };
|
|
|
845
989
|
if (cp.commentOpen) continue;
|
|
846
990
|
const closing = m[1] === "/";
|
|
847
991
|
const tag = m[2].toLowerCase();
|
|
848
|
-
if (
|
|
849
|
-
|
|
850
|
-
if (
|
|
992
|
+
if (strayTablePart(tag)) cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + m.index);
|
|
993
|
+
let attrs = m[3] ?? "";
|
|
994
|
+
if (cp.htmlFlowReal && (cp.rawTextOpen === null || closing && tag === cp.rawTextOpen)) {
|
|
995
|
+
const attrStart = m.index + 1 + (closing ? 1 : 0) + m[2].length;
|
|
996
|
+
const st = { state: "outside" };
|
|
997
|
+
const gt = scanTagAttrs(tagText, attrStart, tagText.length, st);
|
|
998
|
+
if (gt === -1) {
|
|
999
|
+
if (!VOID_TAGS.has(tag)) {
|
|
1000
|
+
if (closing) cp.pendingTruncatedCloses.push(tag);
|
|
1001
|
+
else applyTag(tag, false);
|
|
1002
|
+
}
|
|
1003
|
+
scanTagAttrs("\n", 0, 1, st);
|
|
1004
|
+
cp.tagAcrossLines = true;
|
|
1005
|
+
cp.tagAcrossLinesIndent = ln.indent;
|
|
1006
|
+
cp.tagAcrossLinesState = st.state;
|
|
1007
|
+
tagHandledAsTruncated = true;
|
|
1008
|
+
break;
|
|
1009
|
+
}
|
|
1010
|
+
if (gt + 1 !== m.index + m[0].length) {
|
|
1011
|
+
attrs = tagText.slice(attrStart, gt);
|
|
1012
|
+
TAG_OR_COMMENT_RE.lastIndex = gt + 1;
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
if (closing && !cp.htmlFlowReal && !/^\s*$/.test(attrs)) continue;
|
|
1016
|
+
const selfClosing = /\/\s*$/.test(attrs);
|
|
1017
|
+
if (VOID_TAGS.has(tag) || selfClosing && honoursSelfClosing(tag)) continue;
|
|
851
1018
|
applyTag(tag, closing);
|
|
852
1019
|
}
|
|
853
1020
|
if (cp.commentOpen && lastCommentOpenerIdx !== -1 && !inRawText) {
|
|
@@ -866,26 +1033,40 @@ ${cont(scanText)}` };
|
|
|
866
1033
|
if (startMasked || wholeVisible || inRaw(mr.index) || cp.commentOpen) continue;
|
|
867
1034
|
const closing = mr[1] === "/";
|
|
868
1035
|
const tag = mr[2].toLowerCase();
|
|
869
|
-
if (
|
|
1036
|
+
if (strayTablePart(tag)) cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + mr.index);
|
|
1037
|
+
if (closing && mr[3] !== void 0 && !/^\s*$/.test(mr[3])) continue;
|
|
870
1038
|
const selfClosing = mr[3] !== void 0 && /\/\s*$/.test(mr[3]);
|
|
871
|
-
if (VOID_TAGS.has(tag) || selfClosing) continue;
|
|
1039
|
+
if (VOID_TAGS.has(tag) || selfClosing && honoursSelfClosing(tag)) continue;
|
|
872
1040
|
applyTag(tag, closing);
|
|
873
1041
|
}
|
|
874
1042
|
}
|
|
875
1043
|
if (cp.pendingTruncatedTags.length > 0 && ln.text.includes(">")) {
|
|
1044
|
+
if (cp.pendingTruncatedTags.some((t) => strayTablePart(t))) {
|
|
1045
|
+
cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
|
|
1046
|
+
}
|
|
876
1047
|
cp.pendingTruncatedTags = [];
|
|
877
1048
|
}
|
|
878
|
-
if (!cp.commentOpen) {
|
|
879
|
-
|
|
1049
|
+
if (!cp.commentOpen && !tagHandledAsTruncated) {
|
|
1050
|
+
let lastLt = -1;
|
|
1051
|
+
TAG_START_LT_RE.lastIndex = 0;
|
|
1052
|
+
for (let ms = TAG_START_LT_RE.exec(tagText); ms !== null; ms = TAG_START_LT_RE.exec(tagText)) {
|
|
1053
|
+
lastLt = ms.index;
|
|
1054
|
+
TAG_START_LT_RE.lastIndex = ms.index + 1;
|
|
1055
|
+
}
|
|
880
1056
|
if (lastLt !== -1 && !tagText.includes(">", lastLt)) {
|
|
881
1057
|
const m2 = TRUNCATED_TAG_RE.exec(tagText.slice(lastLt));
|
|
882
1058
|
if (m2) {
|
|
883
1059
|
const closing = m2[1] === "/";
|
|
884
1060
|
const tag = m2[2].toLowerCase();
|
|
885
|
-
if (
|
|
1061
|
+
if (strayTablePart(tag) && cp.htmlFlowReal) {
|
|
1062
|
+
cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + lastLt);
|
|
1063
|
+
}
|
|
886
1064
|
if (cp.htmlFlowReal) {
|
|
887
1065
|
cp.tagAcrossLines = true;
|
|
888
1066
|
cp.tagAcrossLinesIndent = ln.indent;
|
|
1067
|
+
const attrs = { state: "outside" };
|
|
1068
|
+
scanTagAttrs(m2[3] + "\n", 0, m2[3].length + 1, attrs);
|
|
1069
|
+
cp.tagAcrossLinesState = attrs.state;
|
|
889
1070
|
}
|
|
890
1071
|
if (closing) {
|
|
891
1072
|
if (!VOID_TAGS.has(tag) && cp.htmlFlowReal) cp.pendingTruncatedCloses.push(tag);
|
|
@@ -1102,6 +1283,24 @@ function rebaseDualWalk(node, segments, maxEnd, offsetDelta, lineDelta) {
|
|
|
1102
1283
|
}
|
|
1103
1284
|
}
|
|
1104
1285
|
var TABLE_PART_TAG_RE = /<(?:td|th|tr|tbody|thead|tfoot|caption|col|colgroup)\b/i;
|
|
1286
|
+
var TABLE_TOKEN_RE = /<(\/?)(table|td|th|tr|tbody|thead|tfoot|caption|col|colgroup)\b/gi;
|
|
1287
|
+
function hasStrayTablePart(values) {
|
|
1288
|
+
let depth = 0;
|
|
1289
|
+
for (const value of values) {
|
|
1290
|
+
TABLE_TOKEN_RE.lastIndex = 0;
|
|
1291
|
+
let m;
|
|
1292
|
+
while ((m = TABLE_TOKEN_RE.exec(value)) !== null) {
|
|
1293
|
+
const closing = m[1] === "/";
|
|
1294
|
+
const tag = m[2].toLowerCase();
|
|
1295
|
+
if (tag === "table") {
|
|
1296
|
+
depth = closing ? Math.max(0, depth - 1) : depth + 1;
|
|
1297
|
+
continue;
|
|
1298
|
+
}
|
|
1299
|
+
if (depth === 0) return true;
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
return false;
|
|
1303
|
+
}
|
|
1105
1304
|
var STRAY_SYNTHESIZED_END_TAG_RE = /<\/(?:br|p)\b/i;
|
|
1106
1305
|
function spliceTrees(input) {
|
|
1107
1306
|
const { prevMdast, prevHast, tailMdast, tailHast, content, boundary, injectionPrefix, injectedSegments } = input;
|
|
@@ -1159,7 +1358,7 @@ function spliceTrees(input) {
|
|
|
1159
1358
|
return !(start !== void 0 && start < injectedLen);
|
|
1160
1359
|
});
|
|
1161
1360
|
const tailWrapVisible = tailMdastChildren.some((child) => !isWrapInvisible(child));
|
|
1162
|
-
if (prefixMdast.
|
|
1361
|
+
if (hasStrayTablePart(prefixMdast.flatMap((c) => c.type === "html" ? [c.value] : []))) return null;
|
|
1163
1362
|
for (const child of tailMdastChildren) {
|
|
1164
1363
|
if (isWrapInvisible(child)) continue;
|
|
1165
1364
|
if (child.type !== "html") break;
|
|
@@ -1554,7 +1753,7 @@ function normalizeId(s) {
|
|
|
1554
1753
|
return normalizeIdentifier3(s);
|
|
1555
1754
|
}
|
|
1556
1755
|
function normalizeForMatch(s) {
|
|
1557
|
-
return normalizeIdentifier3(s
|
|
1756
|
+
return normalizeIdentifier3(s);
|
|
1558
1757
|
}
|
|
1559
1758
|
|
|
1560
1759
|
// src/components/collectDefLabels.ts
|
|
@@ -1872,22 +2071,68 @@ function createRegistry(onEmpty) {
|
|
|
1872
2071
|
labelSet: { footnoteLabels: /* @__PURE__ */ new Set(), linkLabels: /* @__PURE__ */ new Set() },
|
|
1873
2072
|
version: 0,
|
|
1874
2073
|
_reactIdMap: /* @__PURE__ */ new Map(),
|
|
2074
|
+
/** Symbol → its `documentIndex`, for chunks that supplied one. */
|
|
2075
|
+
_chunkIndex: /* @__PURE__ */ new Map(),
|
|
1875
2076
|
_subscribers: /* @__PURE__ */ new Set(),
|
|
1876
2077
|
_notifyScheduled: false,
|
|
1877
|
-
allocateSymbol(reactId) {
|
|
2078
|
+
allocateSymbol(reactId, rawDocumentIndex) {
|
|
2079
|
+
const documentIndex = rawDocumentIndex !== void 0 && Number.isFinite(rawDocumentIndex) ? rawDocumentIndex : void 0;
|
|
2080
|
+
if (false) {
|
|
2081
|
+
console.warn(
|
|
2082
|
+
`[ai-react-markdown] documentIndex must be a finite number \u2014 received ${String(rawDocumentIndex)}; ignoring it for this chunk.`
|
|
2083
|
+
);
|
|
2084
|
+
}
|
|
1878
2085
|
const existing = this._reactIdMap.get(reactId);
|
|
1879
2086
|
if (existing) {
|
|
1880
2087
|
existing.refcount++;
|
|
2088
|
+
const moved = documentIndex !== void 0 ? this._chunkIndex.get(existing.symbol) !== documentIndex : this._chunkIndex.has(existing.symbol);
|
|
2089
|
+
if (moved) {
|
|
2090
|
+
const at = this.chunkOrder.indexOf(existing.symbol);
|
|
2091
|
+
if (at !== -1) this.chunkOrder.splice(at, 1);
|
|
2092
|
+
this._placeChunk(existing.symbol, documentIndex);
|
|
2093
|
+
this._notify();
|
|
2094
|
+
}
|
|
1881
2095
|
return existing.symbol;
|
|
1882
2096
|
}
|
|
1883
2097
|
const sym = Symbol(reactId);
|
|
1884
2098
|
this._reactIdMap.set(reactId, { symbol: sym, refcount: 1 });
|
|
1885
|
-
this.
|
|
2099
|
+
this._placeChunk(sym, documentIndex);
|
|
1886
2100
|
this._notify();
|
|
1887
2101
|
return sym;
|
|
1888
2102
|
},
|
|
1889
|
-
|
|
1890
|
-
|
|
2103
|
+
/** Put `sym` into `chunkOrder` at its document position. Without an index
|
|
2104
|
+
* it goes last (mount order — the historical behaviour); with one it
|
|
2105
|
+
* sorts before the first chunk that sits later, where a chunk WITHOUT an
|
|
2106
|
+
* index counts as "later" so an indexed chunk never lands behind one
|
|
2107
|
+
* whose position is unknown. */
|
|
2108
|
+
_placeChunk(sym, documentIndex) {
|
|
2109
|
+
if (false) {
|
|
2110
|
+
const anyIndexed = documentIndex !== void 0 || this.chunkOrder.some((s) => this._chunkIndex.has(s));
|
|
2111
|
+
const anyPlain = documentIndex === void 0 || this.chunkOrder.some((s) => !this._chunkIndex.has(s));
|
|
2112
|
+
if (anyIndexed && anyPlain) {
|
|
2113
|
+
console.warn(
|
|
2114
|
+
"[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."
|
|
2115
|
+
);
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2118
|
+
if (documentIndex === void 0) {
|
|
2119
|
+
this._chunkIndex.delete(sym);
|
|
2120
|
+
this.chunkOrder.push(sym);
|
|
2121
|
+
return;
|
|
2122
|
+
}
|
|
2123
|
+
this._chunkIndex.set(sym, documentIndex);
|
|
2124
|
+
let at = this.chunkOrder.length;
|
|
2125
|
+
for (let i = 0; i < this.chunkOrder.length; i++) {
|
|
2126
|
+
const other = this._chunkIndex.get(this.chunkOrder[i]);
|
|
2127
|
+
if (other === void 0 || other > documentIndex) {
|
|
2128
|
+
at = i;
|
|
2129
|
+
break;
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2132
|
+
this.chunkOrder.splice(at, 0, sym);
|
|
2133
|
+
},
|
|
2134
|
+
registerChunk(reactId, footnotes, links, documentIndex) {
|
|
2135
|
+
const sym = this.allocateSymbol(reactId, documentIndex);
|
|
1891
2136
|
this.contributeLabels(sym, footnotes, links);
|
|
1892
2137
|
return sym;
|
|
1893
2138
|
},
|
|
@@ -1910,6 +2155,7 @@ function createRegistry(onEmpty) {
|
|
|
1910
2155
|
this._reactIdMap.delete(reactId);
|
|
1911
2156
|
const idx = this.chunkOrder.indexOf(entry.symbol);
|
|
1912
2157
|
if (idx !== -1) this.chunkOrder.splice(idx, 1);
|
|
2158
|
+
this._chunkIndex.delete(entry.symbol);
|
|
1913
2159
|
this.chunkData.delete(entry.symbol);
|
|
1914
2160
|
const nextFn = /* @__PURE__ */ new Set();
|
|
1915
2161
|
const nextLink = /* @__PURE__ */ new Set();
|
|
@@ -3536,17 +3782,28 @@ function mergeClassNameAllowlist(existing, extraClassNames) {
|
|
|
3536
3782
|
return entries;
|
|
3537
3783
|
}
|
|
3538
3784
|
var crossChunkTags = ["cross-chunk-link", "cross-chunk-image", "footnote-sup"];
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3785
|
+
function deepFreeze(value) {
|
|
3786
|
+
if (value !== null && typeof value === "object" && !Object.isFrozen(value)) {
|
|
3787
|
+
Object.freeze(value);
|
|
3788
|
+
for (const key of Object.keys(value)) deepFreeze(value[key]);
|
|
3789
|
+
}
|
|
3790
|
+
return value;
|
|
3791
|
+
}
|
|
3792
|
+
var STRIPPED_TAGS = ["script", "style", "title", "textarea", "noframes", "noembed", "xmp", "iframe", "plaintext"];
|
|
3793
|
+
var sanitizeSchema = deepFreeze(
|
|
3794
|
+
cloneDeep_default({
|
|
3795
|
+
...defaultSchema,
|
|
3796
|
+
tagNames: [...defaultSchema.tagNames || [], "mark", ...crossChunkTags],
|
|
3797
|
+
attributes: {
|
|
3798
|
+
...defaultSchema.attributes,
|
|
3799
|
+
code: mergeClassNameAllowlist(defaultSchema.attributes?.code, ["math-inline", "math-display"]),
|
|
3800
|
+
"cross-chunk-link": ["label", "referenceType", "documentId", "localUrl", "localTitle"],
|
|
3801
|
+
"cross-chunk-image": ["label", "referenceType", "documentId", "alt", "localUrl", "localTitle"],
|
|
3802
|
+
"footnote-sup": ["label", "localOccurrence", "localNumber", "documentId"]
|
|
3803
|
+
},
|
|
3804
|
+
strip: [.../* @__PURE__ */ new Set([...defaultSchema.strip || [], ...STRIPPED_TAGS])]
|
|
3805
|
+
})
|
|
3806
|
+
);
|
|
3550
3807
|
|
|
3551
3808
|
// src/components/crossChunkUrlSanitize.ts
|
|
3552
3809
|
function fakeElement(tagName, key, url) {
|
|
@@ -3759,6 +4016,14 @@ var graphemeEnds = (text, base) => {
|
|
|
3759
4016
|
}
|
|
3760
4017
|
return ends;
|
|
3761
4018
|
};
|
|
4019
|
+
var RESUME_LOOKBACK = 64;
|
|
4020
|
+
var isMidSurrogatePair = (text, at) => at > 0 && at < text.length && (text.charCodeAt(at - 1) & 64512) === 55296 && (text.charCodeAt(at) & 64512) === 56320;
|
|
4021
|
+
var RI_FIRST = 127462;
|
|
4022
|
+
var RI_LAST = 127487;
|
|
4023
|
+
var isRegionalIndicatorAt = (text, at) => {
|
|
4024
|
+
const cp = text.codePointAt(at);
|
|
4025
|
+
return cp !== void 0 && cp >= RI_FIRST && cp <= RI_LAST;
|
|
4026
|
+
};
|
|
3762
4027
|
var createSmoothStreamController = (options = {}) => {
|
|
3763
4028
|
const now = options.now ?? defaultNow;
|
|
3764
4029
|
const schedule = options.schedule ?? defaultSchedule;
|
|
@@ -3767,6 +4032,7 @@ var createSmoothStreamController = (options = {}) => {
|
|
|
3767
4032
|
let pending = [];
|
|
3768
4033
|
let tentativeEnd = 0;
|
|
3769
4034
|
let finished = false;
|
|
4035
|
+
let seam;
|
|
3770
4036
|
let drainDeadlineAt;
|
|
3771
4037
|
let initialized = false;
|
|
3772
4038
|
let visibleCache = "";
|
|
@@ -3850,15 +4116,31 @@ var createSmoothStreamController = (options = {}) => {
|
|
|
3850
4116
|
if (!disposed && !cancelFrame && pending.length > 0) cancelFrame = schedule(tick);
|
|
3851
4117
|
};
|
|
3852
4118
|
const resegmentTail = () => {
|
|
4119
|
+
if (seam !== void 0 && seam < source.length && pending[pending.length - 1] === seam) {
|
|
4120
|
+
pending.pop();
|
|
4121
|
+
}
|
|
3853
4122
|
const from = pending.length > 0 ? pending[pending.length - 1] : visibleEnd;
|
|
3854
|
-
|
|
4123
|
+
let anchor = from;
|
|
4124
|
+
if (seam !== void 0 && from <= seam) {
|
|
4125
|
+
anchor = Math.max(0, from - RESUME_LOOKBACK);
|
|
4126
|
+
if (isMidSurrogatePair(source, anchor)) anchor -= 1;
|
|
4127
|
+
while (anchor >= 2 && isRegionalIndicatorAt(source, anchor - 2)) anchor -= 2;
|
|
4128
|
+
} else {
|
|
4129
|
+
seam = void 0;
|
|
4130
|
+
}
|
|
4131
|
+
const ends = graphemeEnds(source.slice(anchor), anchor);
|
|
3855
4132
|
if (ends.length === 0) {
|
|
3856
4133
|
tentativeEnd = from;
|
|
3857
4134
|
return;
|
|
3858
4135
|
}
|
|
3859
4136
|
tentativeEnd = ends[ends.length - 1];
|
|
3860
|
-
|
|
3861
|
-
|
|
4137
|
+
let hold = 1;
|
|
4138
|
+
if (!finished && ends.length > 1) {
|
|
4139
|
+
const last = source.charCodeAt(source.length - 1);
|
|
4140
|
+
if (last >= 55296 && last <= 56319) hold = 2;
|
|
4141
|
+
}
|
|
4142
|
+
const confirmedEnds = finished ? ends : ends.slice(0, -hold);
|
|
4143
|
+
for (const end of confirmedEnds) if (end > from) pending.push(end);
|
|
3862
4144
|
};
|
|
3863
4145
|
const snap = (next) => {
|
|
3864
4146
|
disposed = false;
|
|
@@ -3872,6 +4154,7 @@ var createSmoothStreamController = (options = {}) => {
|
|
|
3872
4154
|
visibleEnd = next.length;
|
|
3873
4155
|
tentativeEnd = next.length;
|
|
3874
4156
|
pending = [];
|
|
4157
|
+
seam = next.length;
|
|
3875
4158
|
credit = 0;
|
|
3876
4159
|
cancelScheduled();
|
|
3877
4160
|
if (visibleCache !== next) notify();
|
|
@@ -3906,6 +4189,7 @@ var createSmoothStreamController = (options = {}) => {
|
|
|
3906
4189
|
if (tentativeEnd > (pending.length > 0 ? pending[pending.length - 1] : visibleEnd)) {
|
|
3907
4190
|
pending.push(tentativeEnd);
|
|
3908
4191
|
}
|
|
4192
|
+
seam = source.length;
|
|
3909
4193
|
ensureScheduled();
|
|
3910
4194
|
},
|
|
3911
4195
|
snap,
|
|
@@ -3985,10 +4269,11 @@ function findClosingBacktickRun(content, start, n) {
|
|
|
3985
4269
|
const runLen = getRepeatedMarkerLength(content, i, "`");
|
|
3986
4270
|
if (runLen === n) return i;
|
|
3987
4271
|
i += runLen;
|
|
3988
|
-
} else if (ch === "\n") {
|
|
4272
|
+
} else if (ch === "\n" || ch === "\r") {
|
|
3989
4273
|
let j = i + 1;
|
|
3990
|
-
|
|
3991
|
-
|
|
4274
|
+
if (ch === "\r" && content[j] === "\n") j += 1;
|
|
4275
|
+
while (j < content.length && (content[j] === " " || content[j] === " ")) j += 1;
|
|
4276
|
+
if (j >= content.length || content[j] === "\n" || content[j] === "\r") return -1;
|
|
3992
4277
|
i += 1;
|
|
3993
4278
|
} else {
|
|
3994
4279
|
i += 1;
|
|
@@ -4089,26 +4374,54 @@ function escapeMhchemCommands(text) {
|
|
|
4089
4374
|
return text.replaceAll("$\\ce{", "$\\\\ce{").replaceAll("$\\pu{", "$\\\\pu{");
|
|
4090
4375
|
}
|
|
4091
4376
|
var CURRENCY_REGEX = /(?<![\\$])\$(?!\$)(?=\d+(?:,\d{3})*(?:\.\d+)?(?:[KMBkmb])?(?:\s|$|[^a-zA-Z\d]))/g;
|
|
4092
|
-
var NO_ESCAPED_DOLLAR_REGEX = /(?<![\\$])\$(?!\$)/g;
|
|
4093
4377
|
var DELIMITERS_REGEX = /(?<!!)\\\[([\S\s]*?[^\\])\\](?!\()|\\\((.*?)\\\)/g;
|
|
4094
4378
|
var ARRAY_COL_SPEC_OR_PIPE_REGEX = /(\\begin\{(?:array|tabular[x*]?)\}\{[^}]*\})|(?<!\\)\|/g;
|
|
4095
|
-
var
|
|
4379
|
+
var EVEN_BACKSLASHES = String.raw`(?<=(?:^|[^\\])(?:\\\\)*)`;
|
|
4380
|
+
var LATEX_BLOCK_REGEX = new RegExp(
|
|
4381
|
+
String.raw`${EVEN_BACKSLASHES}\$\$([\S\s]*?)${EVEN_BACKSLASHES}\$\$|(?<![\\$])\$(?!\$)((?:[^$\n]|\\\$)*?)(?<![\\` + "`" + String.raw`])\$(?!\$)`,
|
|
4382
|
+
"g"
|
|
4383
|
+
);
|
|
4096
4384
|
var TEXT_COMMAND = "\\text{";
|
|
4097
4385
|
var SINGLE_DOLLAR_REGEX = /(?<![\\$])\$(?!\$)((?:[^$\n]|\\[$])+?)(?<!\\)(?<!`)\$(?!\$)/g;
|
|
4386
|
+
function countBareDollars(str, from, to, prev, next) {
|
|
4387
|
+
let n = 0;
|
|
4388
|
+
for (let j = from; j < to; j++) {
|
|
4389
|
+
if (str.charCodeAt(j) !== 36) continue;
|
|
4390
|
+
const before = j > from ? str[j - 1] : prev;
|
|
4391
|
+
const after = j + 1 < to ? str[j + 1] : next;
|
|
4392
|
+
if (before !== "\\" && before !== "$" && after !== "$") n += 1;
|
|
4393
|
+
}
|
|
4394
|
+
return n;
|
|
4395
|
+
}
|
|
4098
4396
|
function escapeCurrencyDollarSigns(text) {
|
|
4099
4397
|
const parts = [];
|
|
4100
4398
|
let lastIndex = 0;
|
|
4101
4399
|
const currencyMatches = Array.from(text.matchAll(CURRENCY_REGEX));
|
|
4102
4400
|
let currentLineProcessed = "";
|
|
4401
|
+
let currentLineDollars = 0;
|
|
4402
|
+
const appendToLine = (piece) => {
|
|
4403
|
+
if (piece.length === 0) return;
|
|
4404
|
+
const prevLast = currentLineProcessed.length > 0 ? currentLineProcessed[currentLineProcessed.length - 1] : "";
|
|
4405
|
+
const prevBeforeLast = currentLineProcessed.length > 1 ? currentLineProcessed[currentLineProcessed.length - 2] : "";
|
|
4406
|
+
const prevLastCounted = prevLast === "$" && prevBeforeLast !== "\\" && prevBeforeLast !== "$";
|
|
4407
|
+
if (prevLastCounted && piece[0] === "$") currentLineDollars -= 1;
|
|
4408
|
+
currentLineDollars += countBareDollars(piece, 0, piece.length, prevLast, "");
|
|
4409
|
+
currentLineProcessed += piece;
|
|
4410
|
+
};
|
|
4411
|
+
const resetLine = (rest) => {
|
|
4412
|
+
currentLineProcessed = "";
|
|
4413
|
+
currentLineDollars = 0;
|
|
4414
|
+
appendToLine(rest);
|
|
4415
|
+
};
|
|
4103
4416
|
for (let i = 0; i < currencyMatches.length; i++) {
|
|
4104
4417
|
const match = currencyMatches[i];
|
|
4105
4418
|
const segment = text.substring(lastIndex, match.index);
|
|
4106
4419
|
parts.push(segment);
|
|
4107
4420
|
const newlineIdx = Math.max(segment.lastIndexOf("\n"), segment.lastIndexOf("\r"));
|
|
4108
4421
|
if (newlineIdx !== -1) {
|
|
4109
|
-
|
|
4422
|
+
resetLine(segment.substring(newlineIdx + 1));
|
|
4110
4423
|
} else {
|
|
4111
|
-
|
|
4424
|
+
appendToLine(segment);
|
|
4112
4425
|
}
|
|
4113
4426
|
let needEscape = true;
|
|
4114
4427
|
const restStart = match.index + 1;
|
|
@@ -4125,15 +4438,21 @@ function escapeCurrencyDollarSigns(text) {
|
|
|
4125
4438
|
}
|
|
4126
4439
|
firstLineBeforeNextMatch = text.substring(restStart, eol);
|
|
4127
4440
|
}
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4441
|
+
const restDollars = countBareDollars(firstLineBeforeNextMatch, 0, firstLineBeforeNextMatch.length, "", "");
|
|
4442
|
+
if (restDollars % 2 !== 0) {
|
|
4443
|
+
const L = currentLineProcessed;
|
|
4444
|
+
const lLast = L.length > 0 ? L[L.length - 1] : "";
|
|
4445
|
+
const lBeforeLast = L.length > 1 ? L[L.length - 2] : "";
|
|
4446
|
+
const lLastCounted = lLast === "$" && lBeforeLast !== "\\" && lBeforeLast !== "$";
|
|
4447
|
+
const f0 = firstLineBeforeNextMatch[0];
|
|
4448
|
+
let whole = currentLineDollars + restDollars;
|
|
4449
|
+
if (lLastCounted && f0 === "$") whole -= 1;
|
|
4450
|
+
if (f0 === "$" && (lLast === "\\" || lLast === "$") && firstLineBeforeNextMatch[1] !== "$") whole -= 1;
|
|
4451
|
+
if (whole % 2 !== 0) needEscape = false;
|
|
4133
4452
|
}
|
|
4134
4453
|
const replacement = needEscape ? "\\$" : "$";
|
|
4135
4454
|
parts.push(replacement);
|
|
4136
|
-
|
|
4455
|
+
appendToLine(replacement);
|
|
4137
4456
|
lastIndex = match.index + 1;
|
|
4138
4457
|
}
|
|
4139
4458
|
parts.push(text.substring(lastIndex));
|
|
@@ -4201,8 +4520,7 @@ function escapeLatexPipesInUnclosed(text) {
|
|
|
4201
4520
|
const tail = text.substring(unclosedStart + delimLen);
|
|
4202
4521
|
return before + delim + replaceUnescapedPipes(tail);
|
|
4203
4522
|
}
|
|
4204
|
-
function truncateUnclosedLatexBlock(text) {
|
|
4205
|
-
const unclosedStart = findUnclosedDelimiterStart(text, "double-only");
|
|
4523
|
+
function truncateUnclosedLatexBlock(text, unclosedStart = findUnclosedDelimiterStart(text, "double-only")) {
|
|
4206
4524
|
if (unclosedStart === -1) return text;
|
|
4207
4525
|
return text.substring(0, unclosedStart).trimEnd();
|
|
4208
4526
|
}
|
|
@@ -4313,8 +4631,9 @@ function processSliceInstrumented(slice, probe = true) {
|
|
|
4313
4631
|
if (probe && hasUnclosedTextCommand(text)) quiescent = false;
|
|
4314
4632
|
text = escapeTextUnderscores(text);
|
|
4315
4633
|
text = convertSingleToDoubleDollar(text);
|
|
4634
|
+
let unclosedDouble;
|
|
4316
4635
|
if (probe || index === 0 && LEADING_DOUBLE_DOLLAR_RE.test(text)) {
|
|
4317
|
-
|
|
4636
|
+
unclosedDouble = findUnclosedDelimiterStart(text, "double-only");
|
|
4318
4637
|
if (unclosedDouble !== -1) {
|
|
4319
4638
|
quiescent = false;
|
|
4320
4639
|
if (index === 0 && text.slice(0, unclosedDouble).trim() === "") {
|
|
@@ -4322,7 +4641,7 @@ function processSliceInstrumented(slice, probe = true) {
|
|
|
4322
4641
|
}
|
|
4323
4642
|
}
|
|
4324
4643
|
}
|
|
4325
|
-
text = truncateUnclosedLatexBlock(text);
|
|
4644
|
+
text = truncateUnclosedLatexBlock(text, unclosedDouble);
|
|
4326
4645
|
parts.push(text);
|
|
4327
4646
|
}
|
|
4328
4647
|
return { out: parts.join(""), quiescent, truncatedAtSeamStart };
|
|
@@ -4450,7 +4769,6 @@ function createRemendPreprocessor(options) {
|
|
|
4450
4769
|
}
|
|
4451
4770
|
export {
|
|
4452
4771
|
DEFAULT_PAYLOAD,
|
|
4453
|
-
DEF_LINE_START_RE,
|
|
4454
4772
|
PIPELINE_STAGES,
|
|
4455
4773
|
SENTINEL_FN_CONTENT,
|
|
4456
4774
|
SENTINEL_LINK_URL,
|
|
@@ -4485,7 +4803,6 @@ export {
|
|
|
4485
4803
|
hasLoneSurrogate,
|
|
4486
4804
|
highlight,
|
|
4487
4805
|
isFootnoteSection,
|
|
4488
|
-
lastRegionStart,
|
|
4489
4806
|
measureStage,
|
|
4490
4807
|
mergeClassNameAllowlist,
|
|
4491
4808
|
normalizeForMatch,
|