@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.js
CHANGED
|
@@ -176,6 +176,11 @@ var defaultUrlTransform = (value) => {
|
|
|
176
176
|
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
|
+
var TABLE_PART_NAMES = /* @__PURE__ */ new Set(["td", "th", "tr", "tbody", "thead", "tfoot", "caption", "col", "colgroup"]);
|
|
180
|
+
var TYPE1_NAMES = /* @__PURE__ */ new Set(["script", "pre", "style", "textarea"]);
|
|
181
|
+
var TYPE6_START_RE = /^<\/?([A-Za-z][A-Za-z0-9-]*)(?:[ \t\r]|\/?>|$)/;
|
|
182
|
+
var TYPE1_START_RE = /^<(script|pre|style|textarea)(?:[ \t\r]|>|$)/i;
|
|
183
|
+
var TYPE7_LINE_RE = /^<(\/?)([A-Za-z][A-Za-z0-9-]*)(?:[ \t\r][^>]*|\/)?>[ \t\r]*$/;
|
|
179
184
|
var VOID_TAGS = /* @__PURE__ */ new Set([
|
|
180
185
|
"area",
|
|
181
186
|
"base",
|
|
@@ -314,7 +319,11 @@ function freshCheckpoint(defListEnabled, mathFlow, referenceTaint) {
|
|
|
314
319
|
htmlFlowSinceBlank: false,
|
|
315
320
|
htmlSeamPending: false,
|
|
316
321
|
phasePoisonedAt: Infinity,
|
|
317
|
-
pendingTruncatedTags: []
|
|
322
|
+
pendingTruncatedTags: [],
|
|
323
|
+
pendingTruncatedCloses: [],
|
|
324
|
+
tagAcrossLines: false,
|
|
325
|
+
tagAcrossLinesIndent: 0,
|
|
326
|
+
htmlFlowReal: false
|
|
318
327
|
};
|
|
319
328
|
}
|
|
320
329
|
function isPlausibleLinkDefRest(rest) {
|
|
@@ -611,6 +620,8 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
611
620
|
for (const tag of cp.pendingTruncatedTags) applyTag(tag, true);
|
|
612
621
|
cp.pendingTruncatedTags = [];
|
|
613
622
|
}
|
|
623
|
+
cp.pendingTruncatedCloses = [];
|
|
624
|
+
cp.tagAcrossLines = false;
|
|
614
625
|
cp.blankRun += 1;
|
|
615
626
|
cp.lastBlankStart = ln.start;
|
|
616
627
|
cp.candidates.push({
|
|
@@ -624,6 +635,7 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
624
635
|
cp.paragraphHasUnpairedRun = false;
|
|
625
636
|
cp.openBracket = null;
|
|
626
637
|
cp.htmlFlowSinceBlank = false;
|
|
638
|
+
cp.htmlFlowReal = false;
|
|
627
639
|
cp.prevLineBlank = true;
|
|
628
640
|
cp.prevLineWasText = false;
|
|
629
641
|
cp.prevLineWasValidDef = false;
|
|
@@ -639,6 +651,16 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
639
651
|
if (tagStart) {
|
|
640
652
|
cp.htmlFlowSinceBlank = true;
|
|
641
653
|
if (!TYPE6_NAMES.has(tagStart[1].toLowerCase())) cp.hazardVerdict = true;
|
|
654
|
+
if (!cp.htmlFlowReal) {
|
|
655
|
+
const t = mdTrimStart(ln.text);
|
|
656
|
+
const t6 = TYPE6_START_RE.exec(t);
|
|
657
|
+
const t7 = TYPE7_LINE_RE.exec(t);
|
|
658
|
+
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
|
+
// names (those are type 1 as start tags, paragraph as end tags).
|
|
660
|
+
t7 !== null && !cp.prevLineWasText && !TYPE1_NAMES.has(t7[2].toLowerCase())) {
|
|
661
|
+
cp.htmlFlowReal = true;
|
|
662
|
+
}
|
|
663
|
+
}
|
|
642
664
|
}
|
|
643
665
|
const inRawText = cp.htmlFlowSinceBlank || rawOpenAtLineStart;
|
|
644
666
|
const rawFlowStart = ln.indent <= 3 && /^<(?:!--|\?|![A-Za-z]|!\[CDATA\[)/.test(mdTrimStart(ln.text));
|
|
@@ -779,7 +801,21 @@ ${cont(scanText)}` };
|
|
|
779
801
|
for (const [from, to] of rawSpans) {
|
|
780
802
|
tagText = tagText.slice(0, from) + " ".repeat(to - from) + tagText.slice(to);
|
|
781
803
|
}
|
|
782
|
-
|
|
804
|
+
let skipTagScan = false;
|
|
805
|
+
if (cp.tagAcrossLines) {
|
|
806
|
+
if (ln.indent < cp.tagAcrossLinesIndent) poisonRawDivergence();
|
|
807
|
+
const gt = ln.text.indexOf(">");
|
|
808
|
+
if (gt === -1) {
|
|
809
|
+
skipTagScan = true;
|
|
810
|
+
} else {
|
|
811
|
+
if (/["']/.test(ln.text.slice(0, gt))) poisonRawDivergence();
|
|
812
|
+
for (const tag of cp.pendingTruncatedCloses) applyTag(tag, true);
|
|
813
|
+
cp.pendingTruncatedCloses = [];
|
|
814
|
+
cp.tagAcrossLines = false;
|
|
815
|
+
tagText = " ".repeat(gt + 1) + tagText.slice(gt + 1);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
if (!skipTagScan) {
|
|
783
819
|
TAG_OR_COMMENT_RE.lastIndex = 0;
|
|
784
820
|
let m;
|
|
785
821
|
let lastCommentOpenerIdx = -1;
|
|
@@ -809,6 +845,7 @@ ${cont(scanText)}` };
|
|
|
809
845
|
if (cp.commentOpen) continue;
|
|
810
846
|
const closing = m[1] === "/";
|
|
811
847
|
const tag = m[2].toLowerCase();
|
|
848
|
+
if (TABLE_PART_NAMES.has(tag)) cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + m.index);
|
|
812
849
|
const selfClosing = m[3] !== void 0 && /\/\s*$/.test(m[3]);
|
|
813
850
|
if (VOID_TAGS.has(tag) || selfClosing) continue;
|
|
814
851
|
applyTag(tag, closing);
|
|
@@ -829,6 +866,7 @@ ${cont(scanText)}` };
|
|
|
829
866
|
if (startMasked || wholeVisible || inRaw(mr.index) || cp.commentOpen) continue;
|
|
830
867
|
const closing = mr[1] === "/";
|
|
831
868
|
const tag = mr[2].toLowerCase();
|
|
869
|
+
if (TABLE_PART_NAMES.has(tag)) cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + mr.index);
|
|
832
870
|
const selfClosing = mr[3] !== void 0 && /\/\s*$/.test(mr[3]);
|
|
833
871
|
if (VOID_TAGS.has(tag) || selfClosing) continue;
|
|
834
872
|
applyTag(tag, closing);
|
|
@@ -844,7 +882,14 @@ ${cont(scanText)}` };
|
|
|
844
882
|
if (m2) {
|
|
845
883
|
const closing = m2[1] === "/";
|
|
846
884
|
const tag = m2[2].toLowerCase();
|
|
847
|
-
if (
|
|
885
|
+
if (TABLE_PART_NAMES.has(tag)) cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + lastLt);
|
|
886
|
+
if (cp.htmlFlowReal) {
|
|
887
|
+
cp.tagAcrossLines = true;
|
|
888
|
+
cp.tagAcrossLinesIndent = ln.indent;
|
|
889
|
+
}
|
|
890
|
+
if (closing) {
|
|
891
|
+
if (!VOID_TAGS.has(tag) && cp.htmlFlowReal) cp.pendingTruncatedCloses.push(tag);
|
|
892
|
+
} else if (!VOID_TAGS.has(tag)) {
|
|
848
893
|
applyTag(tag, closing);
|
|
849
894
|
const rawLastLt = ln.text.lastIndexOf("<");
|
|
850
895
|
const rawTruncated = rawLastLt !== -1 && !ln.text.includes(">", rawLastLt);
|
|
@@ -1056,6 +1101,8 @@ function rebaseDualWalk(node, segments, maxEnd, offsetDelta, lineDelta) {
|
|
|
1056
1101
|
for (const child of children) rebaseDualWalk(child, segments, maxEnd, offsetDelta, lineDelta);
|
|
1057
1102
|
}
|
|
1058
1103
|
}
|
|
1104
|
+
var TABLE_PART_TAG_RE = /<(?:td|th|tr|tbody|thead|tfoot|caption|col|colgroup)\b/i;
|
|
1105
|
+
var STRAY_SYNTHESIZED_END_TAG_RE = /<\/(?:br|p)\b/i;
|
|
1059
1106
|
function spliceTrees(input) {
|
|
1060
1107
|
const { prevMdast, prevHast, tailMdast, tailHast, content, boundary, injectionPrefix, injectedSegments } = input;
|
|
1061
1108
|
const injectedLen = injectionPrefix.length;
|
|
@@ -1112,6 +1159,12 @@ function spliceTrees(input) {
|
|
|
1112
1159
|
return !(start !== void 0 && start < injectedLen);
|
|
1113
1160
|
});
|
|
1114
1161
|
const tailWrapVisible = tailMdastChildren.some((child) => !isWrapInvisible(child));
|
|
1162
|
+
if (prefixMdast.some((c) => c.type === "html" && TABLE_PART_TAG_RE.test(c.value))) return null;
|
|
1163
|
+
for (const child of tailMdastChildren) {
|
|
1164
|
+
if (isWrapInvisible(child)) continue;
|
|
1165
|
+
if (child.type !== "html") break;
|
|
1166
|
+
if (STRAY_SYNTHESIZED_END_TAG_RE.test(child.value) || TABLE_PART_TAG_RE.test(child.value)) return null;
|
|
1167
|
+
}
|
|
1115
1168
|
const aligned = alignPrefixCut(prefixMdast, cutRegion, tailWrapVisible);
|
|
1116
1169
|
if (aligned === null) return null;
|
|
1117
1170
|
const hastChildren = aligned.children;
|
|
@@ -1237,6 +1290,9 @@ function alignPrefixCut(prefixMdast, cutRegion, tailWrapVisible) {
|
|
|
1237
1290
|
return null;
|
|
1238
1291
|
}
|
|
1239
1292
|
const lastIsLiteral = last !== void 0 && last.type === "text" && last.value.trim() !== "";
|
|
1293
|
+
if (lastIsLiteral && pairIdx >= 0 && visibles[pairIdx].type !== "html") {
|
|
1294
|
+
return null;
|
|
1295
|
+
}
|
|
1240
1296
|
const litOwnerEnd = pairIdx >= 0 ? visibles[pairIdx].position?.end?.offset : void 0;
|
|
1241
1297
|
const litEnd = lastIsLiteral ? last.position?.end?.offset : void 0;
|
|
1242
1298
|
if (lastIsLiteral && last.position !== void 0 && (litEnd === void 0 || litOwnerEnd === void 0)) {
|
|
@@ -1325,8 +1381,9 @@ function stripInjectedHast(tailMdast, tailHast, injectedLen, tailWrapVisible) {
|
|
|
1325
1381
|
}
|
|
1326
1382
|
function tailLeadingTextIsHoist(tailMdastChildren, tailHastChildren) {
|
|
1327
1383
|
const firstText = tailHastChildren[0];
|
|
1328
|
-
if (!firstText) return false;
|
|
1329
1384
|
const firstVisible = tailMdastChildren.find((c) => !isWrapInvisible(c));
|
|
1385
|
+
if (firstVisible?.type === "html" && STRAY_SYNTHESIZED_END_TAG_RE.test(firstVisible.value)) return null;
|
|
1386
|
+
if (!firstText) return false;
|
|
1330
1387
|
if (!isSeparatorText(firstText)) {
|
|
1331
1388
|
if (firstText.type === "text" && firstText.position === void 0 && firstVisible?.type === "html") {
|
|
1332
1389
|
if (/^\s*<\/[A-Za-z][A-Za-z0-9-]*\s*>/.test(firstVisible.value)) return true;
|
|
@@ -1375,6 +1432,9 @@ function countTrailingNewlines(value) {
|
|
|
1375
1432
|
function countNewlines(text, end = text.length) {
|
|
1376
1433
|
let count = 0;
|
|
1377
1434
|
for (let i = text.indexOf("\n"); i !== -1 && i < end; i = text.indexOf("\n", i + 1)) count += 1;
|
|
1435
|
+
for (let i = text.indexOf("\r"); i !== -1 && i < end; i = text.indexOf("\r", i + 1)) {
|
|
1436
|
+
if (text.charCodeAt(i + 1) !== 10) count += 1;
|
|
1437
|
+
}
|
|
1378
1438
|
return count;
|
|
1379
1439
|
}
|
|
1380
1440
|
|
|
@@ -1494,7 +1554,7 @@ function normalizeId(s) {
|
|
|
1494
1554
|
return normalizeIdentifier3(s);
|
|
1495
1555
|
}
|
|
1496
1556
|
function normalizeForMatch(s) {
|
|
1497
|
-
return normalizeIdentifier3(s.replace(/\\(
|
|
1557
|
+
return normalizeIdentifier3(s.replace(/\\([!-/:-@[-`{-~])/g, "$1"));
|
|
1498
1558
|
}
|
|
1499
1559
|
|
|
1500
1560
|
// src/components/collectDefLabels.ts
|
|
@@ -1767,17 +1827,8 @@ function phantomSuffixCloser(content) {
|
|
|
1767
1827
|
}
|
|
1768
1828
|
|
|
1769
1829
|
// src/components/extractContributions.ts
|
|
1770
|
-
function fakeAnchorElement(url) {
|
|
1771
|
-
return { type: "element", tagName: "a", properties: { href: url }, children: [] };
|
|
1772
|
-
}
|
|
1773
|
-
function sanitizeDefUrl(url, urlTransform) {
|
|
1774
|
-
if (!urlTransform) return url;
|
|
1775
|
-
const result = urlTransform(url, "href", fakeAnchorElement(url));
|
|
1776
|
-
return result == null ? "" : String(result);
|
|
1777
|
-
}
|
|
1778
1830
|
function* extractContributions(mdast, options = {}) {
|
|
1779
1831
|
const phantomFn = options.phantomFootnoteLabels;
|
|
1780
|
-
const urlTransform = options.urlTransform;
|
|
1781
1832
|
const out = [];
|
|
1782
1833
|
visit3(mdast, (n) => {
|
|
1783
1834
|
if (n.type === "footnoteReference") {
|
|
@@ -1805,7 +1856,7 @@ function* extractContributions(mdast, options = {}) {
|
|
|
1805
1856
|
out.push({
|
|
1806
1857
|
kind: "linkDef",
|
|
1807
1858
|
label: normalizeId(d.identifier),
|
|
1808
|
-
url:
|
|
1859
|
+
url: d.url,
|
|
1809
1860
|
title: d.title
|
|
1810
1861
|
});
|
|
1811
1862
|
}
|
|
@@ -3519,8 +3570,7 @@ function isProtocolAllowed(url, allowed) {
|
|
|
3519
3570
|
}
|
|
3520
3571
|
function sanitizeCrossChunkUrl(rawUrl, key, tagName, urlTransform, schema) {
|
|
3521
3572
|
rawUrl = normalizeUri2(rawUrl);
|
|
3522
|
-
const
|
|
3523
|
-
const allowed = callerProtocols === void 0 || callerProtocols === null ? sanitizeSchema.protocols?.[key] : callerProtocols[key];
|
|
3573
|
+
const allowed = Object.hasOwn(schema, "protocols") ? schema.protocols?.[key] : sanitizeSchema.protocols?.[key];
|
|
3524
3574
|
if (allowed && allowed.length > 0 && !isProtocolAllowed(rawUrl, allowed)) return null;
|
|
3525
3575
|
const transformed = urlTransform(rawUrl, key, fakeElement(tagName, key, rawUrl));
|
|
3526
3576
|
if (transformed == null) return null;
|
|
@@ -3930,23 +3980,28 @@ function lineHasBacktick(content, pos) {
|
|
|
3930
3980
|
}
|
|
3931
3981
|
return false;
|
|
3932
3982
|
}
|
|
3933
|
-
function
|
|
3983
|
+
function lineIndentBefore(content, pos) {
|
|
3934
3984
|
let i = pos - 1;
|
|
3935
|
-
let
|
|
3936
|
-
while (i >= 0 && content[i] === " ") {
|
|
3937
|
-
|
|
3938
|
-
if (spaces > 3) return false;
|
|
3985
|
+
let indent = 0;
|
|
3986
|
+
while (i >= 0 && (content[i] === " " || content[i] === " ")) {
|
|
3987
|
+
indent += content[i] === " " ? 4 : 1;
|
|
3939
3988
|
i--;
|
|
3940
3989
|
}
|
|
3941
|
-
return i < 0 || content[i] === "\n" || content[i] === "\r";
|
|
3990
|
+
return i < 0 || content[i] === "\n" || content[i] === "\r" ? indent : -1;
|
|
3942
3991
|
}
|
|
3943
3992
|
function findClosingBacktickRun(content, start, n) {
|
|
3944
3993
|
let i = start;
|
|
3945
3994
|
while (i < content.length) {
|
|
3946
|
-
|
|
3995
|
+
const ch = content[i];
|
|
3996
|
+
if (ch === "`") {
|
|
3947
3997
|
const runLen = getRepeatedMarkerLength(content, i, "`");
|
|
3948
3998
|
if (runLen === n) return i;
|
|
3949
3999
|
i += runLen;
|
|
4000
|
+
} else if (ch === "\n") {
|
|
4001
|
+
let j = i + 1;
|
|
4002
|
+
while (j < content.length && (content[j] === " " || content[j] === " " || content[j] === "\r")) j += 1;
|
|
4003
|
+
if (j >= content.length || content[j] === "\n") return -1;
|
|
4004
|
+
i += 1;
|
|
3950
4005
|
} else {
|
|
3951
4006
|
i += 1;
|
|
3952
4007
|
}
|
|
@@ -3959,6 +4014,7 @@ function splitByProtectedRegions(content) {
|
|
|
3959
4014
|
let multilineStart = -1;
|
|
3960
4015
|
let multilineFenceMarker = null;
|
|
3961
4016
|
let multilineFenceLength = 0;
|
|
4017
|
+
let multilineFenceIndent = 0;
|
|
3962
4018
|
function pushProtected(start, end) {
|
|
3963
4019
|
if (start > lastIndex) {
|
|
3964
4020
|
segments.push({ text: content.substring(lastIndex, start), isCode: false });
|
|
@@ -3972,7 +4028,8 @@ function splitByProtectedRegions(content) {
|
|
|
3972
4028
|
if (multilineStart !== -1) {
|
|
3973
4029
|
if (char === multilineFenceMarker) {
|
|
3974
4030
|
const runLen = getRepeatedMarkerLength(content, i, multilineFenceMarker);
|
|
3975
|
-
|
|
4031
|
+
const closerIndent = lineIndentBefore(content, i);
|
|
4032
|
+
if (runLen >= multilineFenceLength && closerIndent !== -1 && closerIndent <= multilineFenceIndent + 3 && restOfLineIsBlank(content, i + runLen)) {
|
|
3976
4033
|
pushProtected(multilineStart, i + runLen);
|
|
3977
4034
|
multilineStart = -1;
|
|
3978
4035
|
multilineFenceMarker = null;
|
|
@@ -3988,10 +4045,12 @@ function splitByProtectedRegions(content) {
|
|
|
3988
4045
|
}
|
|
3989
4046
|
if (char === "`" || char === "~") {
|
|
3990
4047
|
const runLen = getRepeatedMarkerLength(content, i, char);
|
|
3991
|
-
|
|
4048
|
+
const openerIndent = lineIndentBefore(content, i);
|
|
4049
|
+
if (runLen >= 3 && openerIndent !== -1 && !(char === "`" && lineHasBacktick(content, i + runLen))) {
|
|
3992
4050
|
multilineStart = i;
|
|
3993
4051
|
multilineFenceMarker = char;
|
|
3994
4052
|
multilineFenceLength = runLen;
|
|
4053
|
+
multilineFenceIndent = openerIndent;
|
|
3995
4054
|
i += runLen;
|
|
3996
4055
|
continue;
|
|
3997
4056
|
}
|
|
@@ -4064,16 +4123,20 @@ function escapeCurrencyDollarSigns(text) {
|
|
|
4064
4123
|
currentLineProcessed += segment;
|
|
4065
4124
|
}
|
|
4066
4125
|
let needEscape = true;
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4126
|
+
const restStart = match.index + 1;
|
|
4127
|
+
const restEnd = i < currencyMatches.length - 1 ? currencyMatches[i + 1].index : text.length;
|
|
4128
|
+
let firstLineBeforeNextMatch = "";
|
|
4129
|
+
if (restEnd - restStart > 0) {
|
|
4130
|
+
let eol = restEnd;
|
|
4131
|
+
for (let k = restStart; k < restEnd; k++) {
|
|
4132
|
+
const c = text.charCodeAt(k);
|
|
4133
|
+
if (c === 10 || c === 13) {
|
|
4134
|
+
eol = k;
|
|
4135
|
+
break;
|
|
4136
|
+
}
|
|
4072
4137
|
}
|
|
4073
|
-
|
|
4074
|
-
restBeforeNextMatchOrEnd = text.substring(match.index + 1);
|
|
4138
|
+
firstLineBeforeNextMatch = text.substring(restStart, eol);
|
|
4075
4139
|
}
|
|
4076
|
-
const firstLineBeforeNextMatch = restBeforeNextMatchOrEnd.split(/\r\n|\r|\n/g)[0];
|
|
4077
4140
|
if (Array.from(firstLineBeforeNextMatch.matchAll(NO_ESCAPED_DOLLAR_REGEX)).length % 2 !== 0) {
|
|
4078
4141
|
const wholeLineBeforeNextMatchWithoutCurrentDollar = currentLineProcessed + firstLineBeforeNextMatch;
|
|
4079
4142
|
if (Array.from(wholeLineBeforeNextMatchWithoutCurrentDollar.matchAll(NO_ESCAPED_DOLLAR_REGEX)).length % 2 !== 0) {
|
|
@@ -4239,39 +4302,49 @@ function hasUnclosedTextCommand(text) {
|
|
|
4239
4302
|
return false;
|
|
4240
4303
|
}
|
|
4241
4304
|
var RESIDUAL_OPEN_BRACKET_RE = /(?<!!)\\\[/;
|
|
4242
|
-
|
|
4305
|
+
var LEADING_DOUBLE_DOLLAR_RE = /^\s*\$\$/;
|
|
4306
|
+
function processSliceInstrumented(slice, probe = true) {
|
|
4243
4307
|
const segments = splitByProtectedRegions(slice);
|
|
4244
|
-
|
|
4308
|
+
const parts = [];
|
|
4245
4309
|
let quiescent = true;
|
|
4246
4310
|
let truncatedAtSeamStart = false;
|
|
4247
4311
|
for (let index = 0; index < segments.length; index++) {
|
|
4248
4312
|
const segment = segments[index];
|
|
4249
4313
|
if (segment.isCode) {
|
|
4250
|
-
|
|
4314
|
+
parts.push(segment.text);
|
|
4251
4315
|
continue;
|
|
4252
4316
|
}
|
|
4253
4317
|
let text = segment.text;
|
|
4254
4318
|
text = escapeMhchemCommands(text);
|
|
4255
4319
|
text = escapeCurrencyDollarSigns(text);
|
|
4256
4320
|
text = convertLatexDelimiters(text);
|
|
4257
|
-
if (RESIDUAL_OPEN_BRACKET_RE.test(text)) quiescent = false;
|
|
4321
|
+
if (probe && RESIDUAL_OPEN_BRACKET_RE.test(text)) quiescent = false;
|
|
4258
4322
|
text = escapeLatexPipes(text);
|
|
4259
|
-
if (findUnclosedDelimiterStart(text, "both") !== -1) quiescent = false;
|
|
4323
|
+
if (probe && findUnclosedDelimiterStart(text, "both") !== -1) quiescent = false;
|
|
4260
4324
|
text = escapeLatexPipesInUnclosed(text);
|
|
4261
|
-
if (hasUnclosedTextCommand(text)) quiescent = false;
|
|
4325
|
+
if (probe && hasUnclosedTextCommand(text)) quiescent = false;
|
|
4262
4326
|
text = escapeTextUnderscores(text);
|
|
4263
4327
|
text = convertSingleToDoubleDollar(text);
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4328
|
+
if (probe || index === 0 && LEADING_DOUBLE_DOLLAR_RE.test(text)) {
|
|
4329
|
+
const unclosedDouble = findUnclosedDelimiterStart(text, "double-only");
|
|
4330
|
+
if (unclosedDouble !== -1) {
|
|
4331
|
+
quiescent = false;
|
|
4332
|
+
if (index === 0 && text.slice(0, unclosedDouble).trim() === "") {
|
|
4333
|
+
truncatedAtSeamStart = true;
|
|
4334
|
+
}
|
|
4269
4335
|
}
|
|
4270
4336
|
}
|
|
4271
4337
|
text = truncateUnclosedLatexBlock(text);
|
|
4272
|
-
|
|
4338
|
+
parts.push(text);
|
|
4273
4339
|
}
|
|
4274
|
-
return { out, quiescent, truncatedAtSeamStart };
|
|
4340
|
+
return { out: parts.join(""), quiescent, truncatedAtSeamStart };
|
|
4341
|
+
}
|
|
4342
|
+
function isBlankRawLine(text, from, to) {
|
|
4343
|
+
for (let i = from; i < to; i++) {
|
|
4344
|
+
const c = text.charCodeAt(i);
|
|
4345
|
+
if (c !== 32 && c !== 9 && c !== 13) return false;
|
|
4346
|
+
}
|
|
4347
|
+
return true;
|
|
4275
4348
|
}
|
|
4276
4349
|
function findRawSafeCut(active) {
|
|
4277
4350
|
const segments = splitByProtectedRegions(active);
|
|
@@ -4286,10 +4359,12 @@ function findRawSafeCut(active) {
|
|
|
4286
4359
|
continue;
|
|
4287
4360
|
}
|
|
4288
4361
|
const text = segment.text;
|
|
4362
|
+
let atLineStart = offset === 0 || active.charCodeAt(offset - 1) === 10;
|
|
4289
4363
|
let lineStart = 0;
|
|
4290
4364
|
while (lineStart <= text.length) {
|
|
4291
4365
|
const nl = text.indexOf("\n", lineStart);
|
|
4292
4366
|
const lineEnd = nl === -1 ? text.length : nl;
|
|
4367
|
+
if (atLineStart && nl !== -1 && isBlankRawLine(text, lineStart, lineEnd)) backtickHazard = false;
|
|
4293
4368
|
for (let i = lineStart; i < lineEnd; i++) {
|
|
4294
4369
|
const ch = text[i];
|
|
4295
4370
|
if (ch === "`") backtickHazard = true;
|
|
@@ -4302,6 +4377,7 @@ function findRawSafeCut(active) {
|
|
|
4302
4377
|
if (nl === -1) break;
|
|
4303
4378
|
if (!backtickHazard && !latentLt) lastCut = offset + nl + 1;
|
|
4304
4379
|
lineStart = nl + 1;
|
|
4380
|
+
atLineStart = true;
|
|
4305
4381
|
}
|
|
4306
4382
|
offset += text.length;
|
|
4307
4383
|
}
|
|
@@ -4310,11 +4386,14 @@ function findRawSafeCut(active) {
|
|
|
4310
4386
|
var DEFAULT_FREEZE_ATTEMPT_THRESHOLD = 512;
|
|
4311
4387
|
function createIncrementalLatexPreprocessor(options) {
|
|
4312
4388
|
const freezeThreshold = options?.freezeThreshold ?? DEFAULT_FREEZE_ATTEMPT_THRESHOLD;
|
|
4389
|
+
const onAttempt = options?.onAttempt;
|
|
4390
|
+
const backoff = options?.backoff ?? true;
|
|
4313
4391
|
let prevSource = "";
|
|
4314
4392
|
let prevOutput = "";
|
|
4315
4393
|
let frozenSrcEnd = 0;
|
|
4316
4394
|
let frozenOut = "";
|
|
4317
4395
|
let triggered = false;
|
|
4396
|
+
let nextAttemptLen = 0;
|
|
4318
4397
|
return function incrementalPreprocessLaTeX(source) {
|
|
4319
4398
|
if (source === prevSource) return prevOutput;
|
|
4320
4399
|
const isAppend = source.length > prevSource.length && source.startsWith(prevSource);
|
|
@@ -4322,6 +4401,7 @@ function createIncrementalLatexPreprocessor(options) {
|
|
|
4322
4401
|
frozenSrcEnd = 0;
|
|
4323
4402
|
frozenOut = "";
|
|
4324
4403
|
triggered = false;
|
|
4404
|
+
nextAttemptLen = 0;
|
|
4325
4405
|
}
|
|
4326
4406
|
if (!triggered) {
|
|
4327
4407
|
const checkFrom = isAppend ? Math.max(0, prevSource.length - 1) : 0;
|
|
@@ -4333,18 +4413,26 @@ function createIncrementalLatexPreprocessor(options) {
|
|
|
4333
4413
|
triggered = true;
|
|
4334
4414
|
}
|
|
4335
4415
|
let active = source.slice(frozenSrcEnd);
|
|
4336
|
-
if (active.length > freezeThreshold) {
|
|
4416
|
+
if (active.length > freezeThreshold && active.length >= nextAttemptLen) {
|
|
4417
|
+
const activeLength = active.length;
|
|
4418
|
+
let advanced = false;
|
|
4419
|
+
let frozenBytes = 0;
|
|
4420
|
+
const freeze = (cut2, slice) => {
|
|
4421
|
+
frozenOut += slice.out;
|
|
4422
|
+
frozenSrcEnd += cut2;
|
|
4423
|
+
active = source.slice(frozenSrcEnd);
|
|
4424
|
+
advanced = true;
|
|
4425
|
+
frozenBytes = cut2;
|
|
4426
|
+
};
|
|
4337
4427
|
const cut = findRawSafeCut(active);
|
|
4338
4428
|
if (cut > 0) {
|
|
4339
4429
|
const candidate = processSliceInstrumented(active.slice(0, cut));
|
|
4340
|
-
if (candidate.quiescent)
|
|
4341
|
-
frozenOut += candidate.out;
|
|
4342
|
-
frozenSrcEnd += cut;
|
|
4343
|
-
active = source.slice(frozenSrcEnd);
|
|
4344
|
-
}
|
|
4430
|
+
if (candidate.quiescent) freeze(cut, candidate);
|
|
4345
4431
|
}
|
|
4432
|
+
nextAttemptLen = advanced || !backoff ? 0 : active.length * 2;
|
|
4433
|
+
onAttempt?.({ activeLength, frozenBytes });
|
|
4346
4434
|
}
|
|
4347
|
-
const tail = processSliceInstrumented(active);
|
|
4435
|
+
const tail = processSliceInstrumented(active, false);
|
|
4348
4436
|
const head = tail.truncatedAtSeamStart ? frozenOut.replace(/\s+$/, "") : frozenOut;
|
|
4349
4437
|
const out = head + tail.out;
|
|
4350
4438
|
prevSource = source;
|