@ai-react-markdown/engine 2.4.2 → 2.4.5
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 +142 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +77 -41
- package/dist/index.d.ts +77 -41
- package/dist/index.dev.cjs +142 -54
- package/dist/index.dev.cjs.map +1 -1
- package/dist/index.dev.js +142 -54
- package/dist/index.dev.js.map +1 -1
- package/dist/index.js +142 -54
- package/dist/index.js.map +1 -1
- package/package.json +12 -2
package/dist/index.dev.cjs
CHANGED
|
@@ -269,6 +269,11 @@ var defaultUrlTransform = (value) => {
|
|
|
269
269
|
var import_micromark_util_html_tag_name = require("micromark-util-html-tag-name");
|
|
270
270
|
var import_micromark_util_normalize_identifier = require("micromark-util-normalize-identifier");
|
|
271
271
|
var TYPE6_NAMES = new Set(import_micromark_util_html_tag_name.htmlBlockNames);
|
|
272
|
+
var TABLE_PART_NAMES = /* @__PURE__ */ new Set(["td", "th", "tr", "tbody", "thead", "tfoot", "caption", "col", "colgroup"]);
|
|
273
|
+
var TYPE1_NAMES = /* @__PURE__ */ new Set(["script", "pre", "style", "textarea"]);
|
|
274
|
+
var TYPE6_START_RE = /^<\/?([A-Za-z][A-Za-z0-9-]*)(?:[ \t\r]|\/?>|$)/;
|
|
275
|
+
var TYPE1_START_RE = /^<(script|pre|style|textarea)(?:[ \t\r]|>|$)/i;
|
|
276
|
+
var TYPE7_LINE_RE = /^<(\/?)([A-Za-z][A-Za-z0-9-]*)(?:[ \t\r][^>]*|\/)?>[ \t\r]*$/;
|
|
272
277
|
var VOID_TAGS = /* @__PURE__ */ new Set([
|
|
273
278
|
"area",
|
|
274
279
|
"base",
|
|
@@ -407,7 +412,11 @@ function freshCheckpoint(defListEnabled, mathFlow, referenceTaint) {
|
|
|
407
412
|
htmlFlowSinceBlank: false,
|
|
408
413
|
htmlSeamPending: false,
|
|
409
414
|
phasePoisonedAt: Infinity,
|
|
410
|
-
pendingTruncatedTags: []
|
|
415
|
+
pendingTruncatedTags: [],
|
|
416
|
+
pendingTruncatedCloses: [],
|
|
417
|
+
tagAcrossLines: false,
|
|
418
|
+
tagAcrossLinesIndent: 0,
|
|
419
|
+
htmlFlowReal: false
|
|
411
420
|
};
|
|
412
421
|
}
|
|
413
422
|
function isPlausibleLinkDefRest(rest) {
|
|
@@ -704,6 +713,8 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
704
713
|
for (const tag of cp.pendingTruncatedTags) applyTag(tag, true);
|
|
705
714
|
cp.pendingTruncatedTags = [];
|
|
706
715
|
}
|
|
716
|
+
cp.pendingTruncatedCloses = [];
|
|
717
|
+
cp.tagAcrossLines = false;
|
|
707
718
|
cp.blankRun += 1;
|
|
708
719
|
cp.lastBlankStart = ln.start;
|
|
709
720
|
cp.candidates.push({
|
|
@@ -717,6 +728,7 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
717
728
|
cp.paragraphHasUnpairedRun = false;
|
|
718
729
|
cp.openBracket = null;
|
|
719
730
|
cp.htmlFlowSinceBlank = false;
|
|
731
|
+
cp.htmlFlowReal = false;
|
|
720
732
|
cp.prevLineBlank = true;
|
|
721
733
|
cp.prevLineWasText = false;
|
|
722
734
|
cp.prevLineWasValidDef = false;
|
|
@@ -732,6 +744,16 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
732
744
|
if (tagStart) {
|
|
733
745
|
cp.htmlFlowSinceBlank = true;
|
|
734
746
|
if (!TYPE6_NAMES.has(tagStart[1].toLowerCase())) cp.hazardVerdict = true;
|
|
747
|
+
if (!cp.htmlFlowReal) {
|
|
748
|
+
const t = mdTrimStart(ln.text);
|
|
749
|
+
const t6 = TYPE6_START_RE.exec(t);
|
|
750
|
+
const t7 = TYPE7_LINE_RE.exec(t);
|
|
751
|
+
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
|
|
752
|
+
// names (those are type 1 as start tags, paragraph as end tags).
|
|
753
|
+
t7 !== null && !cp.prevLineWasText && !TYPE1_NAMES.has(t7[2].toLowerCase())) {
|
|
754
|
+
cp.htmlFlowReal = true;
|
|
755
|
+
}
|
|
756
|
+
}
|
|
735
757
|
}
|
|
736
758
|
const inRawText = cp.htmlFlowSinceBlank || rawOpenAtLineStart;
|
|
737
759
|
const rawFlowStart = ln.indent <= 3 && /^<(?:!--|\?|![A-Za-z]|!\[CDATA\[)/.test(mdTrimStart(ln.text));
|
|
@@ -872,7 +894,21 @@ ${cont(scanText)}` };
|
|
|
872
894
|
for (const [from, to] of rawSpans) {
|
|
873
895
|
tagText = tagText.slice(0, from) + " ".repeat(to - from) + tagText.slice(to);
|
|
874
896
|
}
|
|
875
|
-
|
|
897
|
+
let skipTagScan = false;
|
|
898
|
+
if (cp.tagAcrossLines) {
|
|
899
|
+
if (ln.indent < cp.tagAcrossLinesIndent) poisonRawDivergence();
|
|
900
|
+
const gt = ln.text.indexOf(">");
|
|
901
|
+
if (gt === -1) {
|
|
902
|
+
skipTagScan = true;
|
|
903
|
+
} else {
|
|
904
|
+
if (/["']/.test(ln.text.slice(0, gt))) poisonRawDivergence();
|
|
905
|
+
for (const tag of cp.pendingTruncatedCloses) applyTag(tag, true);
|
|
906
|
+
cp.pendingTruncatedCloses = [];
|
|
907
|
+
cp.tagAcrossLines = false;
|
|
908
|
+
tagText = " ".repeat(gt + 1) + tagText.slice(gt + 1);
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
if (!skipTagScan) {
|
|
876
912
|
TAG_OR_COMMENT_RE.lastIndex = 0;
|
|
877
913
|
let m;
|
|
878
914
|
let lastCommentOpenerIdx = -1;
|
|
@@ -902,6 +938,7 @@ ${cont(scanText)}` };
|
|
|
902
938
|
if (cp.commentOpen) continue;
|
|
903
939
|
const closing = m[1] === "/";
|
|
904
940
|
const tag = m[2].toLowerCase();
|
|
941
|
+
if (TABLE_PART_NAMES.has(tag)) cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + m.index);
|
|
905
942
|
const selfClosing = m[3] !== void 0 && /\/\s*$/.test(m[3]);
|
|
906
943
|
if (VOID_TAGS.has(tag) || selfClosing) continue;
|
|
907
944
|
applyTag(tag, closing);
|
|
@@ -922,6 +959,7 @@ ${cont(scanText)}` };
|
|
|
922
959
|
if (startMasked || wholeVisible || inRaw(mr.index) || cp.commentOpen) continue;
|
|
923
960
|
const closing = mr[1] === "/";
|
|
924
961
|
const tag = mr[2].toLowerCase();
|
|
962
|
+
if (TABLE_PART_NAMES.has(tag)) cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + mr.index);
|
|
925
963
|
const selfClosing = mr[3] !== void 0 && /\/\s*$/.test(mr[3]);
|
|
926
964
|
if (VOID_TAGS.has(tag) || selfClosing) continue;
|
|
927
965
|
applyTag(tag, closing);
|
|
@@ -937,7 +975,14 @@ ${cont(scanText)}` };
|
|
|
937
975
|
if (m2) {
|
|
938
976
|
const closing = m2[1] === "/";
|
|
939
977
|
const tag = m2[2].toLowerCase();
|
|
940
|
-
if (
|
|
978
|
+
if (TABLE_PART_NAMES.has(tag)) cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + lastLt);
|
|
979
|
+
if (cp.htmlFlowReal) {
|
|
980
|
+
cp.tagAcrossLines = true;
|
|
981
|
+
cp.tagAcrossLinesIndent = ln.indent;
|
|
982
|
+
}
|
|
983
|
+
if (closing) {
|
|
984
|
+
if (!VOID_TAGS.has(tag) && cp.htmlFlowReal) cp.pendingTruncatedCloses.push(tag);
|
|
985
|
+
} else if (!VOID_TAGS.has(tag)) {
|
|
941
986
|
applyTag(tag, closing);
|
|
942
987
|
const rawLastLt = ln.text.lastIndexOf("<");
|
|
943
988
|
const rawTruncated = rawLastLt !== -1 && !ln.text.includes(">", rawLastLt);
|
|
@@ -1149,6 +1194,8 @@ function rebaseDualWalk(node, segments, maxEnd, offsetDelta, lineDelta) {
|
|
|
1149
1194
|
for (const child of children) rebaseDualWalk(child, segments, maxEnd, offsetDelta, lineDelta);
|
|
1150
1195
|
}
|
|
1151
1196
|
}
|
|
1197
|
+
var TABLE_PART_TAG_RE = /<(?:td|th|tr|tbody|thead|tfoot|caption|col|colgroup)\b/i;
|
|
1198
|
+
var STRAY_SYNTHESIZED_END_TAG_RE = /<\/(?:br|p)\b/i;
|
|
1152
1199
|
function spliceTrees(input) {
|
|
1153
1200
|
const { prevMdast, prevHast, tailMdast, tailHast, content, boundary, injectionPrefix, injectedSegments } = input;
|
|
1154
1201
|
const injectedLen = injectionPrefix.length;
|
|
@@ -1205,6 +1252,12 @@ function spliceTrees(input) {
|
|
|
1205
1252
|
return !(start !== void 0 && start < injectedLen);
|
|
1206
1253
|
});
|
|
1207
1254
|
const tailWrapVisible = tailMdastChildren.some((child) => !isWrapInvisible(child));
|
|
1255
|
+
if (prefixMdast.some((c) => c.type === "html" && TABLE_PART_TAG_RE.test(c.value))) return null;
|
|
1256
|
+
for (const child of tailMdastChildren) {
|
|
1257
|
+
if (isWrapInvisible(child)) continue;
|
|
1258
|
+
if (child.type !== "html") break;
|
|
1259
|
+
if (STRAY_SYNTHESIZED_END_TAG_RE.test(child.value) || TABLE_PART_TAG_RE.test(child.value)) return null;
|
|
1260
|
+
}
|
|
1208
1261
|
const aligned = alignPrefixCut(prefixMdast, cutRegion, tailWrapVisible);
|
|
1209
1262
|
if (aligned === null) return null;
|
|
1210
1263
|
const hastChildren = aligned.children;
|
|
@@ -1330,6 +1383,9 @@ function alignPrefixCut(prefixMdast, cutRegion, tailWrapVisible) {
|
|
|
1330
1383
|
return null;
|
|
1331
1384
|
}
|
|
1332
1385
|
const lastIsLiteral = last !== void 0 && last.type === "text" && last.value.trim() !== "";
|
|
1386
|
+
if (lastIsLiteral && pairIdx >= 0 && visibles[pairIdx].type !== "html") {
|
|
1387
|
+
return null;
|
|
1388
|
+
}
|
|
1333
1389
|
const litOwnerEnd = pairIdx >= 0 ? visibles[pairIdx].position?.end?.offset : void 0;
|
|
1334
1390
|
const litEnd = lastIsLiteral ? last.position?.end?.offset : void 0;
|
|
1335
1391
|
if (lastIsLiteral && last.position !== void 0 && (litEnd === void 0 || litOwnerEnd === void 0)) {
|
|
@@ -1418,8 +1474,9 @@ function stripInjectedHast(tailMdast, tailHast, injectedLen, tailWrapVisible) {
|
|
|
1418
1474
|
}
|
|
1419
1475
|
function tailLeadingTextIsHoist(tailMdastChildren, tailHastChildren) {
|
|
1420
1476
|
const firstText = tailHastChildren[0];
|
|
1421
|
-
if (!firstText) return false;
|
|
1422
1477
|
const firstVisible = tailMdastChildren.find((c) => !isWrapInvisible(c));
|
|
1478
|
+
if (firstVisible?.type === "html" && STRAY_SYNTHESIZED_END_TAG_RE.test(firstVisible.value)) return null;
|
|
1479
|
+
if (!firstText) return false;
|
|
1423
1480
|
if (!isSeparatorText(firstText)) {
|
|
1424
1481
|
if (firstText.type === "text" && firstText.position === void 0 && firstVisible?.type === "html") {
|
|
1425
1482
|
if (/^\s*<\/[A-Za-z][A-Za-z0-9-]*\s*>/.test(firstVisible.value)) return true;
|
|
@@ -1468,6 +1525,9 @@ function countTrailingNewlines(value) {
|
|
|
1468
1525
|
function countNewlines(text, end = text.length) {
|
|
1469
1526
|
let count = 0;
|
|
1470
1527
|
for (let i = text.indexOf("\n"); i !== -1 && i < end; i = text.indexOf("\n", i + 1)) count += 1;
|
|
1528
|
+
for (let i = text.indexOf("\r"); i !== -1 && i < end; i = text.indexOf("\r", i + 1)) {
|
|
1529
|
+
if (text.charCodeAt(i + 1) !== 10) count += 1;
|
|
1530
|
+
}
|
|
1471
1531
|
return count;
|
|
1472
1532
|
}
|
|
1473
1533
|
|
|
@@ -1587,7 +1647,7 @@ function normalizeId(s) {
|
|
|
1587
1647
|
return (0, import_micromark_util_normalize_identifier3.normalizeIdentifier)(s);
|
|
1588
1648
|
}
|
|
1589
1649
|
function normalizeForMatch(s) {
|
|
1590
|
-
return (0, import_micromark_util_normalize_identifier3.normalizeIdentifier)(s.replace(/\\(
|
|
1650
|
+
return (0, import_micromark_util_normalize_identifier3.normalizeIdentifier)(s.replace(/\\([!-/:-@[-`{-~])/g, "$1"));
|
|
1591
1651
|
}
|
|
1592
1652
|
|
|
1593
1653
|
// src/components/collectDefLabels.ts
|
|
@@ -1860,17 +1920,8 @@ function phantomSuffixCloser(content) {
|
|
|
1860
1920
|
}
|
|
1861
1921
|
|
|
1862
1922
|
// src/components/extractContributions.ts
|
|
1863
|
-
function fakeAnchorElement(url) {
|
|
1864
|
-
return { type: "element", tagName: "a", properties: { href: url }, children: [] };
|
|
1865
|
-
}
|
|
1866
|
-
function sanitizeDefUrl(url, urlTransform) {
|
|
1867
|
-
if (!urlTransform) return url;
|
|
1868
|
-
const result = urlTransform(url, "href", fakeAnchorElement(url));
|
|
1869
|
-
return result == null ? "" : String(result);
|
|
1870
|
-
}
|
|
1871
1923
|
function* extractContributions(mdast, options = {}) {
|
|
1872
1924
|
const phantomFn = options.phantomFootnoteLabels;
|
|
1873
|
-
const urlTransform = options.urlTransform;
|
|
1874
1925
|
const out = [];
|
|
1875
1926
|
(0, import_unist_util_visit3.visit)(mdast, (n) => {
|
|
1876
1927
|
if (n.type === "footnoteReference") {
|
|
@@ -1898,7 +1949,7 @@ function* extractContributions(mdast, options = {}) {
|
|
|
1898
1949
|
out.push({
|
|
1899
1950
|
kind: "linkDef",
|
|
1900
1951
|
label: normalizeId(d.identifier),
|
|
1901
|
-
url:
|
|
1952
|
+
url: d.url,
|
|
1902
1953
|
title: d.title
|
|
1903
1954
|
});
|
|
1904
1955
|
}
|
|
@@ -3612,8 +3663,7 @@ function isProtocolAllowed(url, allowed) {
|
|
|
3612
3663
|
}
|
|
3613
3664
|
function sanitizeCrossChunkUrl(rawUrl, key, tagName, urlTransform, schema) {
|
|
3614
3665
|
rawUrl = (0, import_micromark_util_sanitize_uri2.normalizeUri)(rawUrl);
|
|
3615
|
-
const
|
|
3616
|
-
const allowed = callerProtocols === void 0 || callerProtocols === null ? sanitizeSchema.protocols?.[key] : callerProtocols[key];
|
|
3666
|
+
const allowed = Object.hasOwn(schema, "protocols") ? schema.protocols?.[key] : sanitizeSchema.protocols?.[key];
|
|
3617
3667
|
if (allowed && allowed.length > 0 && !isProtocolAllowed(rawUrl, allowed)) return null;
|
|
3618
3668
|
const transformed = urlTransform(rawUrl, key, fakeElement(tagName, key, rawUrl));
|
|
3619
3669
|
if (transformed == null) return null;
|
|
@@ -4023,23 +4073,28 @@ function lineHasBacktick(content, pos) {
|
|
|
4023
4073
|
}
|
|
4024
4074
|
return false;
|
|
4025
4075
|
}
|
|
4026
|
-
function
|
|
4076
|
+
function lineIndentBefore(content, pos) {
|
|
4027
4077
|
let i = pos - 1;
|
|
4028
|
-
let
|
|
4029
|
-
while (i >= 0 && content[i] === " ") {
|
|
4030
|
-
|
|
4031
|
-
if (spaces > 3) return false;
|
|
4078
|
+
let indent = 0;
|
|
4079
|
+
while (i >= 0 && (content[i] === " " || content[i] === " ")) {
|
|
4080
|
+
indent += content[i] === " " ? 4 : 1;
|
|
4032
4081
|
i--;
|
|
4033
4082
|
}
|
|
4034
|
-
return i < 0 || content[i] === "\n" || content[i] === "\r";
|
|
4083
|
+
return i < 0 || content[i] === "\n" || content[i] === "\r" ? indent : -1;
|
|
4035
4084
|
}
|
|
4036
4085
|
function findClosingBacktickRun(content, start, n) {
|
|
4037
4086
|
let i = start;
|
|
4038
4087
|
while (i < content.length) {
|
|
4039
|
-
|
|
4088
|
+
const ch = content[i];
|
|
4089
|
+
if (ch === "`") {
|
|
4040
4090
|
const runLen = getRepeatedMarkerLength(content, i, "`");
|
|
4041
4091
|
if (runLen === n) return i;
|
|
4042
4092
|
i += runLen;
|
|
4093
|
+
} else if (ch === "\n") {
|
|
4094
|
+
let j = i + 1;
|
|
4095
|
+
while (j < content.length && (content[j] === " " || content[j] === " " || content[j] === "\r")) j += 1;
|
|
4096
|
+
if (j >= content.length || content[j] === "\n") return -1;
|
|
4097
|
+
i += 1;
|
|
4043
4098
|
} else {
|
|
4044
4099
|
i += 1;
|
|
4045
4100
|
}
|
|
@@ -4052,6 +4107,7 @@ function splitByProtectedRegions(content) {
|
|
|
4052
4107
|
let multilineStart = -1;
|
|
4053
4108
|
let multilineFenceMarker = null;
|
|
4054
4109
|
let multilineFenceLength = 0;
|
|
4110
|
+
let multilineFenceIndent = 0;
|
|
4055
4111
|
function pushProtected(start, end) {
|
|
4056
4112
|
if (start > lastIndex) {
|
|
4057
4113
|
segments.push({ text: content.substring(lastIndex, start), isCode: false });
|
|
@@ -4065,7 +4121,8 @@ function splitByProtectedRegions(content) {
|
|
|
4065
4121
|
if (multilineStart !== -1) {
|
|
4066
4122
|
if (char === multilineFenceMarker) {
|
|
4067
4123
|
const runLen = getRepeatedMarkerLength(content, i, multilineFenceMarker);
|
|
4068
|
-
|
|
4124
|
+
const closerIndent = lineIndentBefore(content, i);
|
|
4125
|
+
if (runLen >= multilineFenceLength && closerIndent !== -1 && closerIndent <= multilineFenceIndent + 3 && restOfLineIsBlank(content, i + runLen)) {
|
|
4069
4126
|
pushProtected(multilineStart, i + runLen);
|
|
4070
4127
|
multilineStart = -1;
|
|
4071
4128
|
multilineFenceMarker = null;
|
|
@@ -4081,10 +4138,12 @@ function splitByProtectedRegions(content) {
|
|
|
4081
4138
|
}
|
|
4082
4139
|
if (char === "`" || char === "~") {
|
|
4083
4140
|
const runLen = getRepeatedMarkerLength(content, i, char);
|
|
4084
|
-
|
|
4141
|
+
const openerIndent = lineIndentBefore(content, i);
|
|
4142
|
+
if (runLen >= 3 && openerIndent !== -1 && !(char === "`" && lineHasBacktick(content, i + runLen))) {
|
|
4085
4143
|
multilineStart = i;
|
|
4086
4144
|
multilineFenceMarker = char;
|
|
4087
4145
|
multilineFenceLength = runLen;
|
|
4146
|
+
multilineFenceIndent = openerIndent;
|
|
4088
4147
|
i += runLen;
|
|
4089
4148
|
continue;
|
|
4090
4149
|
}
|
|
@@ -4157,16 +4216,20 @@ function escapeCurrencyDollarSigns(text) {
|
|
|
4157
4216
|
currentLineProcessed += segment;
|
|
4158
4217
|
}
|
|
4159
4218
|
let needEscape = true;
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4219
|
+
const restStart = match.index + 1;
|
|
4220
|
+
const restEnd = i < currencyMatches.length - 1 ? currencyMatches[i + 1].index : text.length;
|
|
4221
|
+
let firstLineBeforeNextMatch = "";
|
|
4222
|
+
if (restEnd - restStart > 0) {
|
|
4223
|
+
let eol = restEnd;
|
|
4224
|
+
for (let k = restStart; k < restEnd; k++) {
|
|
4225
|
+
const c = text.charCodeAt(k);
|
|
4226
|
+
if (c === 10 || c === 13) {
|
|
4227
|
+
eol = k;
|
|
4228
|
+
break;
|
|
4229
|
+
}
|
|
4165
4230
|
}
|
|
4166
|
-
|
|
4167
|
-
restBeforeNextMatchOrEnd = text.substring(match.index + 1);
|
|
4231
|
+
firstLineBeforeNextMatch = text.substring(restStart, eol);
|
|
4168
4232
|
}
|
|
4169
|
-
const firstLineBeforeNextMatch = restBeforeNextMatchOrEnd.split(/\r\n|\r|\n/g)[0];
|
|
4170
4233
|
if (Array.from(firstLineBeforeNextMatch.matchAll(NO_ESCAPED_DOLLAR_REGEX)).length % 2 !== 0) {
|
|
4171
4234
|
const wholeLineBeforeNextMatchWithoutCurrentDollar = currentLineProcessed + firstLineBeforeNextMatch;
|
|
4172
4235
|
if (Array.from(wholeLineBeforeNextMatchWithoutCurrentDollar.matchAll(NO_ESCAPED_DOLLAR_REGEX)).length % 2 !== 0) {
|
|
@@ -4332,39 +4395,49 @@ function hasUnclosedTextCommand(text) {
|
|
|
4332
4395
|
return false;
|
|
4333
4396
|
}
|
|
4334
4397
|
var RESIDUAL_OPEN_BRACKET_RE = /(?<!!)\\\[/;
|
|
4335
|
-
|
|
4398
|
+
var LEADING_DOUBLE_DOLLAR_RE = /^\s*\$\$/;
|
|
4399
|
+
function processSliceInstrumented(slice, probe = true) {
|
|
4336
4400
|
const segments = splitByProtectedRegions(slice);
|
|
4337
|
-
|
|
4401
|
+
const parts = [];
|
|
4338
4402
|
let quiescent = true;
|
|
4339
4403
|
let truncatedAtSeamStart = false;
|
|
4340
4404
|
for (let index = 0; index < segments.length; index++) {
|
|
4341
4405
|
const segment = segments[index];
|
|
4342
4406
|
if (segment.isCode) {
|
|
4343
|
-
|
|
4407
|
+
parts.push(segment.text);
|
|
4344
4408
|
continue;
|
|
4345
4409
|
}
|
|
4346
4410
|
let text = segment.text;
|
|
4347
4411
|
text = escapeMhchemCommands(text);
|
|
4348
4412
|
text = escapeCurrencyDollarSigns(text);
|
|
4349
4413
|
text = convertLatexDelimiters(text);
|
|
4350
|
-
if (RESIDUAL_OPEN_BRACKET_RE.test(text)) quiescent = false;
|
|
4414
|
+
if (probe && RESIDUAL_OPEN_BRACKET_RE.test(text)) quiescent = false;
|
|
4351
4415
|
text = escapeLatexPipes(text);
|
|
4352
|
-
if (findUnclosedDelimiterStart(text, "both") !== -1) quiescent = false;
|
|
4416
|
+
if (probe && findUnclosedDelimiterStart(text, "both") !== -1) quiescent = false;
|
|
4353
4417
|
text = escapeLatexPipesInUnclosed(text);
|
|
4354
|
-
if (hasUnclosedTextCommand(text)) quiescent = false;
|
|
4418
|
+
if (probe && hasUnclosedTextCommand(text)) quiescent = false;
|
|
4355
4419
|
text = escapeTextUnderscores(text);
|
|
4356
4420
|
text = convertSingleToDoubleDollar(text);
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4421
|
+
if (probe || index === 0 && LEADING_DOUBLE_DOLLAR_RE.test(text)) {
|
|
4422
|
+
const unclosedDouble = findUnclosedDelimiterStart(text, "double-only");
|
|
4423
|
+
if (unclosedDouble !== -1) {
|
|
4424
|
+
quiescent = false;
|
|
4425
|
+
if (index === 0 && text.slice(0, unclosedDouble).trim() === "") {
|
|
4426
|
+
truncatedAtSeamStart = true;
|
|
4427
|
+
}
|
|
4362
4428
|
}
|
|
4363
4429
|
}
|
|
4364
4430
|
text = truncateUnclosedLatexBlock(text);
|
|
4365
|
-
|
|
4431
|
+
parts.push(text);
|
|
4366
4432
|
}
|
|
4367
|
-
return { out, quiescent, truncatedAtSeamStart };
|
|
4433
|
+
return { out: parts.join(""), quiescent, truncatedAtSeamStart };
|
|
4434
|
+
}
|
|
4435
|
+
function isBlankRawLine(text, from, to) {
|
|
4436
|
+
for (let i = from; i < to; i++) {
|
|
4437
|
+
const c = text.charCodeAt(i);
|
|
4438
|
+
if (c !== 32 && c !== 9 && c !== 13) return false;
|
|
4439
|
+
}
|
|
4440
|
+
return true;
|
|
4368
4441
|
}
|
|
4369
4442
|
function findRawSafeCut(active) {
|
|
4370
4443
|
const segments = splitByProtectedRegions(active);
|
|
@@ -4379,10 +4452,12 @@ function findRawSafeCut(active) {
|
|
|
4379
4452
|
continue;
|
|
4380
4453
|
}
|
|
4381
4454
|
const text = segment.text;
|
|
4455
|
+
let atLineStart = offset === 0 || active.charCodeAt(offset - 1) === 10;
|
|
4382
4456
|
let lineStart = 0;
|
|
4383
4457
|
while (lineStart <= text.length) {
|
|
4384
4458
|
const nl = text.indexOf("\n", lineStart);
|
|
4385
4459
|
const lineEnd = nl === -1 ? text.length : nl;
|
|
4460
|
+
if (atLineStart && nl !== -1 && isBlankRawLine(text, lineStart, lineEnd)) backtickHazard = false;
|
|
4386
4461
|
for (let i = lineStart; i < lineEnd; i++) {
|
|
4387
4462
|
const ch = text[i];
|
|
4388
4463
|
if (ch === "`") backtickHazard = true;
|
|
@@ -4395,6 +4470,7 @@ function findRawSafeCut(active) {
|
|
|
4395
4470
|
if (nl === -1) break;
|
|
4396
4471
|
if (!backtickHazard && !latentLt) lastCut = offset + nl + 1;
|
|
4397
4472
|
lineStart = nl + 1;
|
|
4473
|
+
atLineStart = true;
|
|
4398
4474
|
}
|
|
4399
4475
|
offset += text.length;
|
|
4400
4476
|
}
|
|
@@ -4403,11 +4479,14 @@ function findRawSafeCut(active) {
|
|
|
4403
4479
|
var DEFAULT_FREEZE_ATTEMPT_THRESHOLD = 512;
|
|
4404
4480
|
function createIncrementalLatexPreprocessor(options) {
|
|
4405
4481
|
const freezeThreshold = options?.freezeThreshold ?? DEFAULT_FREEZE_ATTEMPT_THRESHOLD;
|
|
4482
|
+
const onAttempt = options?.onAttempt;
|
|
4483
|
+
const backoff = options?.backoff ?? true;
|
|
4406
4484
|
let prevSource = "";
|
|
4407
4485
|
let prevOutput = "";
|
|
4408
4486
|
let frozenSrcEnd = 0;
|
|
4409
4487
|
let frozenOut = "";
|
|
4410
4488
|
let triggered = false;
|
|
4489
|
+
let nextAttemptLen = 0;
|
|
4411
4490
|
return function incrementalPreprocessLaTeX(source) {
|
|
4412
4491
|
if (source === prevSource) return prevOutput;
|
|
4413
4492
|
const isAppend = source.length > prevSource.length && source.startsWith(prevSource);
|
|
@@ -4415,6 +4494,7 @@ function createIncrementalLatexPreprocessor(options) {
|
|
|
4415
4494
|
frozenSrcEnd = 0;
|
|
4416
4495
|
frozenOut = "";
|
|
4417
4496
|
triggered = false;
|
|
4497
|
+
nextAttemptLen = 0;
|
|
4418
4498
|
}
|
|
4419
4499
|
if (!triggered) {
|
|
4420
4500
|
const checkFrom = isAppend ? Math.max(0, prevSource.length - 1) : 0;
|
|
@@ -4426,18 +4506,26 @@ function createIncrementalLatexPreprocessor(options) {
|
|
|
4426
4506
|
triggered = true;
|
|
4427
4507
|
}
|
|
4428
4508
|
let active = source.slice(frozenSrcEnd);
|
|
4429
|
-
if (active.length > freezeThreshold) {
|
|
4509
|
+
if (active.length > freezeThreshold && active.length >= nextAttemptLen) {
|
|
4510
|
+
const activeLength = active.length;
|
|
4511
|
+
let advanced = false;
|
|
4512
|
+
let frozenBytes = 0;
|
|
4513
|
+
const freeze = (cut2, slice) => {
|
|
4514
|
+
frozenOut += slice.out;
|
|
4515
|
+
frozenSrcEnd += cut2;
|
|
4516
|
+
active = source.slice(frozenSrcEnd);
|
|
4517
|
+
advanced = true;
|
|
4518
|
+
frozenBytes = cut2;
|
|
4519
|
+
};
|
|
4430
4520
|
const cut = findRawSafeCut(active);
|
|
4431
4521
|
if (cut > 0) {
|
|
4432
4522
|
const candidate = processSliceInstrumented(active.slice(0, cut));
|
|
4433
|
-
if (candidate.quiescent)
|
|
4434
|
-
frozenOut += candidate.out;
|
|
4435
|
-
frozenSrcEnd += cut;
|
|
4436
|
-
active = source.slice(frozenSrcEnd);
|
|
4437
|
-
}
|
|
4523
|
+
if (candidate.quiescent) freeze(cut, candidate);
|
|
4438
4524
|
}
|
|
4525
|
+
nextAttemptLen = advanced || !backoff ? 0 : active.length * 2;
|
|
4526
|
+
onAttempt?.({ activeLength, frozenBytes });
|
|
4439
4527
|
}
|
|
4440
|
-
const tail = processSliceInstrumented(active);
|
|
4528
|
+
const tail = processSliceInstrumented(active, false);
|
|
4441
4529
|
const head = tail.truncatedAtSeamStart ? frozenOut.replace(/\s+$/, "") : frozenOut;
|
|
4442
4530
|
const out = head + tail.out;
|
|
4443
4531
|
prevSource = source;
|