@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.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;
|
|
@@ -3918,23 +3968,28 @@ function lineHasBacktick(content, pos) {
|
|
|
3918
3968
|
}
|
|
3919
3969
|
return false;
|
|
3920
3970
|
}
|
|
3921
|
-
function
|
|
3971
|
+
function lineIndentBefore(content, pos) {
|
|
3922
3972
|
let i = pos - 1;
|
|
3923
|
-
let
|
|
3924
|
-
while (i >= 0 && content[i] === " ") {
|
|
3925
|
-
|
|
3926
|
-
if (spaces > 3) return false;
|
|
3973
|
+
let indent = 0;
|
|
3974
|
+
while (i >= 0 && (content[i] === " " || content[i] === " ")) {
|
|
3975
|
+
indent += content[i] === " " ? 4 : 1;
|
|
3927
3976
|
i--;
|
|
3928
3977
|
}
|
|
3929
|
-
return i < 0 || content[i] === "\n" || content[i] === "\r";
|
|
3978
|
+
return i < 0 || content[i] === "\n" || content[i] === "\r" ? indent : -1;
|
|
3930
3979
|
}
|
|
3931
3980
|
function findClosingBacktickRun(content, start, n) {
|
|
3932
3981
|
let i = start;
|
|
3933
3982
|
while (i < content.length) {
|
|
3934
|
-
|
|
3983
|
+
const ch = content[i];
|
|
3984
|
+
if (ch === "`") {
|
|
3935
3985
|
const runLen = getRepeatedMarkerLength(content, i, "`");
|
|
3936
3986
|
if (runLen === n) return i;
|
|
3937
3987
|
i += runLen;
|
|
3988
|
+
} else if (ch === "\n") {
|
|
3989
|
+
let j = i + 1;
|
|
3990
|
+
while (j < content.length && (content[j] === " " || content[j] === " " || content[j] === "\r")) j += 1;
|
|
3991
|
+
if (j >= content.length || content[j] === "\n") return -1;
|
|
3992
|
+
i += 1;
|
|
3938
3993
|
} else {
|
|
3939
3994
|
i += 1;
|
|
3940
3995
|
}
|
|
@@ -3947,6 +4002,7 @@ function splitByProtectedRegions(content) {
|
|
|
3947
4002
|
let multilineStart = -1;
|
|
3948
4003
|
let multilineFenceMarker = null;
|
|
3949
4004
|
let multilineFenceLength = 0;
|
|
4005
|
+
let multilineFenceIndent = 0;
|
|
3950
4006
|
function pushProtected(start, end) {
|
|
3951
4007
|
if (start > lastIndex) {
|
|
3952
4008
|
segments.push({ text: content.substring(lastIndex, start), isCode: false });
|
|
@@ -3960,7 +4016,8 @@ function splitByProtectedRegions(content) {
|
|
|
3960
4016
|
if (multilineStart !== -1) {
|
|
3961
4017
|
if (char === multilineFenceMarker) {
|
|
3962
4018
|
const runLen = getRepeatedMarkerLength(content, i, multilineFenceMarker);
|
|
3963
|
-
|
|
4019
|
+
const closerIndent = lineIndentBefore(content, i);
|
|
4020
|
+
if (runLen >= multilineFenceLength && closerIndent !== -1 && closerIndent <= multilineFenceIndent + 3 && restOfLineIsBlank(content, i + runLen)) {
|
|
3964
4021
|
pushProtected(multilineStart, i + runLen);
|
|
3965
4022
|
multilineStart = -1;
|
|
3966
4023
|
multilineFenceMarker = null;
|
|
@@ -3976,10 +4033,12 @@ function splitByProtectedRegions(content) {
|
|
|
3976
4033
|
}
|
|
3977
4034
|
if (char === "`" || char === "~") {
|
|
3978
4035
|
const runLen = getRepeatedMarkerLength(content, i, char);
|
|
3979
|
-
|
|
4036
|
+
const openerIndent = lineIndentBefore(content, i);
|
|
4037
|
+
if (runLen >= 3 && openerIndent !== -1 && !(char === "`" && lineHasBacktick(content, i + runLen))) {
|
|
3980
4038
|
multilineStart = i;
|
|
3981
4039
|
multilineFenceMarker = char;
|
|
3982
4040
|
multilineFenceLength = runLen;
|
|
4041
|
+
multilineFenceIndent = openerIndent;
|
|
3983
4042
|
i += runLen;
|
|
3984
4043
|
continue;
|
|
3985
4044
|
}
|
|
@@ -4052,16 +4111,20 @@ function escapeCurrencyDollarSigns(text) {
|
|
|
4052
4111
|
currentLineProcessed += segment;
|
|
4053
4112
|
}
|
|
4054
4113
|
let needEscape = true;
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4114
|
+
const restStart = match.index + 1;
|
|
4115
|
+
const restEnd = i < currencyMatches.length - 1 ? currencyMatches[i + 1].index : text.length;
|
|
4116
|
+
let firstLineBeforeNextMatch = "";
|
|
4117
|
+
if (restEnd - restStart > 0) {
|
|
4118
|
+
let eol = restEnd;
|
|
4119
|
+
for (let k = restStart; k < restEnd; k++) {
|
|
4120
|
+
const c = text.charCodeAt(k);
|
|
4121
|
+
if (c === 10 || c === 13) {
|
|
4122
|
+
eol = k;
|
|
4123
|
+
break;
|
|
4124
|
+
}
|
|
4060
4125
|
}
|
|
4061
|
-
|
|
4062
|
-
restBeforeNextMatchOrEnd = text.substring(match.index + 1);
|
|
4126
|
+
firstLineBeforeNextMatch = text.substring(restStart, eol);
|
|
4063
4127
|
}
|
|
4064
|
-
const firstLineBeforeNextMatch = restBeforeNextMatchOrEnd.split(/\r\n|\r|\n/g)[0];
|
|
4065
4128
|
if (Array.from(firstLineBeforeNextMatch.matchAll(NO_ESCAPED_DOLLAR_REGEX)).length % 2 !== 0) {
|
|
4066
4129
|
const wholeLineBeforeNextMatchWithoutCurrentDollar = currentLineProcessed + firstLineBeforeNextMatch;
|
|
4067
4130
|
if (Array.from(wholeLineBeforeNextMatchWithoutCurrentDollar.matchAll(NO_ESCAPED_DOLLAR_REGEX)).length % 2 !== 0) {
|
|
@@ -4227,39 +4290,49 @@ function hasUnclosedTextCommand(text) {
|
|
|
4227
4290
|
return false;
|
|
4228
4291
|
}
|
|
4229
4292
|
var RESIDUAL_OPEN_BRACKET_RE = /(?<!!)\\\[/;
|
|
4230
|
-
|
|
4293
|
+
var LEADING_DOUBLE_DOLLAR_RE = /^\s*\$\$/;
|
|
4294
|
+
function processSliceInstrumented(slice, probe = true) {
|
|
4231
4295
|
const segments = splitByProtectedRegions(slice);
|
|
4232
|
-
|
|
4296
|
+
const parts = [];
|
|
4233
4297
|
let quiescent = true;
|
|
4234
4298
|
let truncatedAtSeamStart = false;
|
|
4235
4299
|
for (let index = 0; index < segments.length; index++) {
|
|
4236
4300
|
const segment = segments[index];
|
|
4237
4301
|
if (segment.isCode) {
|
|
4238
|
-
|
|
4302
|
+
parts.push(segment.text);
|
|
4239
4303
|
continue;
|
|
4240
4304
|
}
|
|
4241
4305
|
let text = segment.text;
|
|
4242
4306
|
text = escapeMhchemCommands(text);
|
|
4243
4307
|
text = escapeCurrencyDollarSigns(text);
|
|
4244
4308
|
text = convertLatexDelimiters(text);
|
|
4245
|
-
if (RESIDUAL_OPEN_BRACKET_RE.test(text)) quiescent = false;
|
|
4309
|
+
if (probe && RESIDUAL_OPEN_BRACKET_RE.test(text)) quiescent = false;
|
|
4246
4310
|
text = escapeLatexPipes(text);
|
|
4247
|
-
if (findUnclosedDelimiterStart(text, "both") !== -1) quiescent = false;
|
|
4311
|
+
if (probe && findUnclosedDelimiterStart(text, "both") !== -1) quiescent = false;
|
|
4248
4312
|
text = escapeLatexPipesInUnclosed(text);
|
|
4249
|
-
if (hasUnclosedTextCommand(text)) quiescent = false;
|
|
4313
|
+
if (probe && hasUnclosedTextCommand(text)) quiescent = false;
|
|
4250
4314
|
text = escapeTextUnderscores(text);
|
|
4251
4315
|
text = convertSingleToDoubleDollar(text);
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4316
|
+
if (probe || index === 0 && LEADING_DOUBLE_DOLLAR_RE.test(text)) {
|
|
4317
|
+
const unclosedDouble = findUnclosedDelimiterStart(text, "double-only");
|
|
4318
|
+
if (unclosedDouble !== -1) {
|
|
4319
|
+
quiescent = false;
|
|
4320
|
+
if (index === 0 && text.slice(0, unclosedDouble).trim() === "") {
|
|
4321
|
+
truncatedAtSeamStart = true;
|
|
4322
|
+
}
|
|
4257
4323
|
}
|
|
4258
4324
|
}
|
|
4259
4325
|
text = truncateUnclosedLatexBlock(text);
|
|
4260
|
-
|
|
4326
|
+
parts.push(text);
|
|
4261
4327
|
}
|
|
4262
|
-
return { out, quiescent, truncatedAtSeamStart };
|
|
4328
|
+
return { out: parts.join(""), quiescent, truncatedAtSeamStart };
|
|
4329
|
+
}
|
|
4330
|
+
function isBlankRawLine(text, from, to) {
|
|
4331
|
+
for (let i = from; i < to; i++) {
|
|
4332
|
+
const c = text.charCodeAt(i);
|
|
4333
|
+
if (c !== 32 && c !== 9 && c !== 13) return false;
|
|
4334
|
+
}
|
|
4335
|
+
return true;
|
|
4263
4336
|
}
|
|
4264
4337
|
function findRawSafeCut(active) {
|
|
4265
4338
|
const segments = splitByProtectedRegions(active);
|
|
@@ -4274,10 +4347,12 @@ function findRawSafeCut(active) {
|
|
|
4274
4347
|
continue;
|
|
4275
4348
|
}
|
|
4276
4349
|
const text = segment.text;
|
|
4350
|
+
let atLineStart = offset === 0 || active.charCodeAt(offset - 1) === 10;
|
|
4277
4351
|
let lineStart = 0;
|
|
4278
4352
|
while (lineStart <= text.length) {
|
|
4279
4353
|
const nl = text.indexOf("\n", lineStart);
|
|
4280
4354
|
const lineEnd = nl === -1 ? text.length : nl;
|
|
4355
|
+
if (atLineStart && nl !== -1 && isBlankRawLine(text, lineStart, lineEnd)) backtickHazard = false;
|
|
4281
4356
|
for (let i = lineStart; i < lineEnd; i++) {
|
|
4282
4357
|
const ch = text[i];
|
|
4283
4358
|
if (ch === "`") backtickHazard = true;
|
|
@@ -4290,6 +4365,7 @@ function findRawSafeCut(active) {
|
|
|
4290
4365
|
if (nl === -1) break;
|
|
4291
4366
|
if (!backtickHazard && !latentLt) lastCut = offset + nl + 1;
|
|
4292
4367
|
lineStart = nl + 1;
|
|
4368
|
+
atLineStart = true;
|
|
4293
4369
|
}
|
|
4294
4370
|
offset += text.length;
|
|
4295
4371
|
}
|
|
@@ -4298,11 +4374,14 @@ function findRawSafeCut(active) {
|
|
|
4298
4374
|
var DEFAULT_FREEZE_ATTEMPT_THRESHOLD = 512;
|
|
4299
4375
|
function createIncrementalLatexPreprocessor(options) {
|
|
4300
4376
|
const freezeThreshold = options?.freezeThreshold ?? DEFAULT_FREEZE_ATTEMPT_THRESHOLD;
|
|
4377
|
+
const onAttempt = options?.onAttempt;
|
|
4378
|
+
const backoff = options?.backoff ?? true;
|
|
4301
4379
|
let prevSource = "";
|
|
4302
4380
|
let prevOutput = "";
|
|
4303
4381
|
let frozenSrcEnd = 0;
|
|
4304
4382
|
let frozenOut = "";
|
|
4305
4383
|
let triggered = false;
|
|
4384
|
+
let nextAttemptLen = 0;
|
|
4306
4385
|
return function incrementalPreprocessLaTeX(source) {
|
|
4307
4386
|
if (source === prevSource) return prevOutput;
|
|
4308
4387
|
const isAppend = source.length > prevSource.length && source.startsWith(prevSource);
|
|
@@ -4310,6 +4389,7 @@ function createIncrementalLatexPreprocessor(options) {
|
|
|
4310
4389
|
frozenSrcEnd = 0;
|
|
4311
4390
|
frozenOut = "";
|
|
4312
4391
|
triggered = false;
|
|
4392
|
+
nextAttemptLen = 0;
|
|
4313
4393
|
}
|
|
4314
4394
|
if (!triggered) {
|
|
4315
4395
|
const checkFrom = isAppend ? Math.max(0, prevSource.length - 1) : 0;
|
|
@@ -4321,18 +4401,26 @@ function createIncrementalLatexPreprocessor(options) {
|
|
|
4321
4401
|
triggered = true;
|
|
4322
4402
|
}
|
|
4323
4403
|
let active = source.slice(frozenSrcEnd);
|
|
4324
|
-
if (active.length > freezeThreshold) {
|
|
4404
|
+
if (active.length > freezeThreshold && active.length >= nextAttemptLen) {
|
|
4405
|
+
const activeLength = active.length;
|
|
4406
|
+
let advanced = false;
|
|
4407
|
+
let frozenBytes = 0;
|
|
4408
|
+
const freeze = (cut2, slice) => {
|
|
4409
|
+
frozenOut += slice.out;
|
|
4410
|
+
frozenSrcEnd += cut2;
|
|
4411
|
+
active = source.slice(frozenSrcEnd);
|
|
4412
|
+
advanced = true;
|
|
4413
|
+
frozenBytes = cut2;
|
|
4414
|
+
};
|
|
4325
4415
|
const cut = findRawSafeCut(active);
|
|
4326
4416
|
if (cut > 0) {
|
|
4327
4417
|
const candidate = processSliceInstrumented(active.slice(0, cut));
|
|
4328
|
-
if (candidate.quiescent)
|
|
4329
|
-
frozenOut += candidate.out;
|
|
4330
|
-
frozenSrcEnd += cut;
|
|
4331
|
-
active = source.slice(frozenSrcEnd);
|
|
4332
|
-
}
|
|
4418
|
+
if (candidate.quiescent) freeze(cut, candidate);
|
|
4333
4419
|
}
|
|
4420
|
+
nextAttemptLen = advanced || !backoff ? 0 : active.length * 2;
|
|
4421
|
+
onAttempt?.({ activeLength, frozenBytes });
|
|
4334
4422
|
}
|
|
4335
|
-
const tail = processSliceInstrumented(active);
|
|
4423
|
+
const tail = processSliceInstrumented(active, false);
|
|
4336
4424
|
const head = tail.truncatedAtSeamStart ? frozenOut.replace(/\s+$/, "") : frozenOut;
|
|
4337
4425
|
const out = head + tail.out;
|
|
4338
4426
|
prevSource = source;
|