@ai-react-markdown/engine 2.10.1 → 2.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.cjs +342 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +95 -2
- package/dist/index.d.ts +95 -2
- package/dist/index.dev.cjs +342 -54
- package/dist/index.dev.cjs.map +1 -1
- package/dist/index.dev.js +339 -54
- package/dist/index.dev.js.map +1 -1
- package/dist/index.js +339 -54
- package/dist/index.js.map +1 -1
- package/package.json +5 -2
package/dist/index.dev.js
CHANGED
|
@@ -2708,6 +2708,44 @@ function rehypeUnwrapCrossChunkImages() {
|
|
|
2708
2708
|
|
|
2709
2709
|
// src/components/pluginChain.ts
|
|
2710
2710
|
import rehypeSanitize from "rehype-sanitize";
|
|
2711
|
+
|
|
2712
|
+
// src/components/rehypeVerifyEngineTags.ts
|
|
2713
|
+
var ENGINE_PLACEHOLDER_TAGS = /* @__PURE__ */ new Set([
|
|
2714
|
+
"footnote-sup",
|
|
2715
|
+
"cross-chunk-link",
|
|
2716
|
+
"cross-chunk-image"
|
|
2717
|
+
]);
|
|
2718
|
+
var ENGINE_PROVENANCE_PROPERTY = "engineProvenance";
|
|
2719
|
+
function walk(parent, provenance) {
|
|
2720
|
+
const children = parent.children;
|
|
2721
|
+
let i = 0;
|
|
2722
|
+
while (i < children.length) {
|
|
2723
|
+
const node = children[i];
|
|
2724
|
+
if (node.type === "element" && ENGINE_PLACEHOLDER_TAGS.has(node.tagName)) {
|
|
2725
|
+
const props = node.properties ?? {};
|
|
2726
|
+
const stamped = props[ENGINE_PROVENANCE_PROPERTY];
|
|
2727
|
+
const genuine = provenance !== "" && typeof stamped === "string" && stamped === provenance;
|
|
2728
|
+
if (genuine) {
|
|
2729
|
+
delete props[ENGINE_PROVENANCE_PROPERTY];
|
|
2730
|
+
walk(node, provenance);
|
|
2731
|
+
i += 1;
|
|
2732
|
+
} else {
|
|
2733
|
+
children.splice(i, 1, ...node.children);
|
|
2734
|
+
}
|
|
2735
|
+
continue;
|
|
2736
|
+
}
|
|
2737
|
+
if (node.type === "element") walk(node, provenance);
|
|
2738
|
+
i += 1;
|
|
2739
|
+
}
|
|
2740
|
+
}
|
|
2741
|
+
function rehypeVerifyEngineTags(options) {
|
|
2742
|
+
const provenance = options?.provenance ?? "";
|
|
2743
|
+
return function transformer(tree) {
|
|
2744
|
+
walk(tree, provenance);
|
|
2745
|
+
};
|
|
2746
|
+
}
|
|
2747
|
+
|
|
2748
|
+
// src/components/pluginChain.ts
|
|
2711
2749
|
import remarkBreaks from "remark-breaks";
|
|
2712
2750
|
import remarkCjkFriendly from "remark-cjk-friendly";
|
|
2713
2751
|
import remarkCjkFriendlyGfmStrikethrough from "remark-cjk-friendly-gfm-strikethrough";
|
|
@@ -2813,10 +2851,13 @@ function buildCoreRemarkPlugins(enginePlugins) {
|
|
|
2813
2851
|
...DISPLAY_OPTIMIZE_CHAIN.filter(([name]) => selected.has(name)).map(([, plugin]) => plugin)
|
|
2814
2852
|
];
|
|
2815
2853
|
}
|
|
2816
|
-
function buildCoreRehypePlugins(sanitizeSchema2, clobberPrefix) {
|
|
2854
|
+
function buildCoreRehypePlugins(sanitizeSchema2, clobberPrefix, options) {
|
|
2817
2855
|
return [
|
|
2818
2856
|
// Allow raw HTML through so rehype-sanitize can handle it.
|
|
2819
2857
|
[rehypeRaw, { passThrough: [] }],
|
|
2858
|
+
// Unwrap forged engine placeholders BEFORE sanitize admits their tag
|
|
2859
|
+
// names. Only when the caller holds a credential (see the option's doc).
|
|
2860
|
+
...options ? [[rehypeVerifyEngineTags, { provenance: options.provenance }]] : [],
|
|
2820
2861
|
// Sanitize HTML while allowing <mark> (highlight), KaTeX class names,
|
|
2821
2862
|
// and any extra protocols the caller permitted via the `sanitizeSchema`
|
|
2822
2863
|
// prop. Override `clobberPrefix` with the instance-scoped value — the
|
|
@@ -2856,6 +2897,10 @@ function buildCoreRemarkRehypeOptions(enableDefinitionList) {
|
|
|
2856
2897
|
}
|
|
2857
2898
|
|
|
2858
2899
|
// src/components/customMdastHandlers.ts
|
|
2900
|
+
function provenanceProps(s) {
|
|
2901
|
+
const provenance = s.options.provenance;
|
|
2902
|
+
return typeof provenance === "string" ? { engineProvenance: provenance } : {};
|
|
2903
|
+
}
|
|
2859
2904
|
function localDefProps(s, id) {
|
|
2860
2905
|
const def = s.definitionById.get(id);
|
|
2861
2906
|
if (!def || typeof def.url !== "string" || def.url === SENTINEL_LINK_URL) return {};
|
|
@@ -2894,7 +2939,8 @@ function buildCrossChunkHandlers() {
|
|
|
2894
2939
|
label: node.label ?? node.identifier,
|
|
2895
2940
|
referenceType: node.referenceType,
|
|
2896
2941
|
documentId: s.options.documentId,
|
|
2897
|
-
...localDefProps(s, id)
|
|
2942
|
+
...localDefProps(s, id),
|
|
2943
|
+
...provenanceProps(s)
|
|
2898
2944
|
},
|
|
2899
2945
|
children: s.all(node)
|
|
2900
2946
|
};
|
|
@@ -2912,7 +2958,8 @@ function buildCrossChunkHandlers() {
|
|
|
2912
2958
|
referenceType: node.referenceType,
|
|
2913
2959
|
alt: node.alt ?? "",
|
|
2914
2960
|
documentId: s.options.documentId,
|
|
2915
|
-
...localDefProps(s, id)
|
|
2961
|
+
...localDefProps(s, id),
|
|
2962
|
+
...provenanceProps(s)
|
|
2916
2963
|
},
|
|
2917
2964
|
children: []
|
|
2918
2965
|
};
|
|
@@ -2929,7 +2976,8 @@ function buildCrossChunkHandlers() {
|
|
|
2929
2976
|
properties: {
|
|
2930
2977
|
label: node.identifier,
|
|
2931
2978
|
localOccurrence,
|
|
2932
|
-
documentId: s.options.documentId
|
|
2979
|
+
documentId: s.options.documentId,
|
|
2980
|
+
...provenanceProps(s)
|
|
2933
2981
|
},
|
|
2934
2982
|
children: []
|
|
2935
2983
|
};
|
|
@@ -2947,7 +2995,8 @@ function buildCrossChunkHandlers() {
|
|
|
2947
2995
|
// first client frame), where the local synthetic footer is what
|
|
2948
2996
|
// renders, so marks and footer agree (core-render-02).
|
|
2949
2997
|
localNumber: s.footnoteOrder.indexOf(id) + 1,
|
|
2950
|
-
documentId: s.options.documentId
|
|
2998
|
+
documentId: s.options.documentId,
|
|
2999
|
+
...provenanceProps(s)
|
|
2951
3000
|
},
|
|
2952
3001
|
children: []
|
|
2953
3002
|
};
|
|
@@ -4619,6 +4668,12 @@ var createSmoothStreamController = (options = {}) => {
|
|
|
4619
4668
|
};
|
|
4620
4669
|
|
|
4621
4670
|
// src/preprocessors/latex.ts
|
|
4671
|
+
function isHardBoundary(kind) {
|
|
4672
|
+
return kind === "code" || kind === "literal" || kind === "multilineTag";
|
|
4673
|
+
}
|
|
4674
|
+
function hasLineEnding(text) {
|
|
4675
|
+
return text.includes("\n") || text.includes("\r");
|
|
4676
|
+
}
|
|
4622
4677
|
function getRepeatedMarkerLength(content, start, marker) {
|
|
4623
4678
|
let end = start;
|
|
4624
4679
|
while (end < content.length && content[end] === marker) {
|
|
@@ -4686,11 +4741,11 @@ function splitByProtectedRegions(content) {
|
|
|
4686
4741
|
let multilineFenceMarker = null;
|
|
4687
4742
|
let multilineFenceLength = 0;
|
|
4688
4743
|
let multilineFenceIndent = 0;
|
|
4689
|
-
function pushProtected(start, end) {
|
|
4744
|
+
function pushProtected(start, end, kind) {
|
|
4690
4745
|
if (start > lastIndex) {
|
|
4691
|
-
segments.push({ text: content.substring(lastIndex, start)
|
|
4746
|
+
segments.push({ kind: "text", text: content.substring(lastIndex, start) });
|
|
4692
4747
|
}
|
|
4693
|
-
segments.push({ text: content.substring(start, end)
|
|
4748
|
+
segments.push({ kind, text: content.substring(start, end) });
|
|
4694
4749
|
lastIndex = end;
|
|
4695
4750
|
}
|
|
4696
4751
|
let i = 0;
|
|
@@ -4701,7 +4756,7 @@ function splitByProtectedRegions(content) {
|
|
|
4701
4756
|
const runLen = getRepeatedMarkerLength(content, i, multilineFenceMarker);
|
|
4702
4757
|
const closerIndent = lineIndentBefore(content, i);
|
|
4703
4758
|
if (runLen >= multilineFenceLength && closerIndent !== -1 && closerIndent <= multilineFenceIndent + 3 && restOfLineIsBlank(content, i + runLen)) {
|
|
4704
|
-
pushProtected(multilineStart, i + runLen);
|
|
4759
|
+
pushProtected(multilineStart, i + runLen, "code");
|
|
4705
4760
|
multilineStart = -1;
|
|
4706
4761
|
multilineFenceMarker = null;
|
|
4707
4762
|
multilineFenceLength = 0;
|
|
@@ -4728,7 +4783,7 @@ function splitByProtectedRegions(content) {
|
|
|
4728
4783
|
if (char === "`") {
|
|
4729
4784
|
const closeIdx = findClosingBacktickRun(content, i + runLen, runLen);
|
|
4730
4785
|
if (closeIdx !== -1) {
|
|
4731
|
-
pushProtected(i, closeIdx + runLen);
|
|
4786
|
+
pushProtected(i, closeIdx + runLen, "code");
|
|
4732
4787
|
i = closeIdx + runLen;
|
|
4733
4788
|
continue;
|
|
4734
4789
|
}
|
|
@@ -4753,7 +4808,11 @@ function splitByProtectedRegions(content) {
|
|
|
4753
4808
|
endIndex = content.length;
|
|
4754
4809
|
}
|
|
4755
4810
|
}
|
|
4756
|
-
pushProtected(
|
|
4811
|
+
pushProtected(
|
|
4812
|
+
i,
|
|
4813
|
+
endIndex,
|
|
4814
|
+
isOpeningPairedTag ? "literal" : hasLineEnding(content.substring(i, endIndex)) ? "multilineTag" : "tag"
|
|
4815
|
+
);
|
|
4757
4816
|
i = endIndex;
|
|
4758
4817
|
continue;
|
|
4759
4818
|
}
|
|
@@ -4761,10 +4820,10 @@ function splitByProtectedRegions(content) {
|
|
|
4761
4820
|
i += 1;
|
|
4762
4821
|
}
|
|
4763
4822
|
if (multilineStart !== -1) {
|
|
4764
|
-
pushProtected(multilineStart, content.length);
|
|
4823
|
+
pushProtected(multilineStart, content.length, "code");
|
|
4765
4824
|
}
|
|
4766
4825
|
if (lastIndex < content.length) {
|
|
4767
|
-
segments.push({ text: content.substring(lastIndex)
|
|
4826
|
+
segments.push({ kind: "text", text: content.substring(lastIndex) });
|
|
4768
4827
|
}
|
|
4769
4828
|
return segments;
|
|
4770
4829
|
}
|
|
@@ -4918,20 +4977,22 @@ function escapeLatexPipesInUnclosed(text) {
|
|
|
4918
4977
|
const tail = text.substring(unclosedStart + delimLen);
|
|
4919
4978
|
return before + delim + replaceUnescapedPipes(tail);
|
|
4920
4979
|
}
|
|
4921
|
-
function opensMathFlow(text, pos) {
|
|
4980
|
+
function opensMathFlow(text, pos, runStartsAtLineStart) {
|
|
4922
4981
|
let i = pos;
|
|
4923
4982
|
let spaces = 0;
|
|
4924
|
-
while (i > 0
|
|
4983
|
+
while (i > 0) {
|
|
4984
|
+
const prev = text[i - 1];
|
|
4985
|
+
if (prev === "\n" || prev === "\r") return true;
|
|
4925
4986
|
i -= 1;
|
|
4926
4987
|
if (text[i] !== " ") return false;
|
|
4927
4988
|
spaces += 1;
|
|
4928
4989
|
if (spaces > 3) return false;
|
|
4929
4990
|
}
|
|
4930
|
-
return
|
|
4991
|
+
return runStartsAtLineStart;
|
|
4931
4992
|
}
|
|
4932
|
-
function truncateUnclosedLatexBlock(text, unclosedStart = findUnclosedDelimiterStart(text, "double-only")) {
|
|
4993
|
+
function truncateUnclosedLatexBlock(text, runStartsAtLineStart, unclosedStart = findUnclosedDelimiterStart(text, "double-only")) {
|
|
4933
4994
|
if (unclosedStart === -1) return text;
|
|
4934
|
-
if (!opensMathFlow(text, unclosedStart)) return text;
|
|
4995
|
+
if (!opensMathFlow(text, unclosedStart, runStartsAtLineStart)) return text;
|
|
4935
4996
|
return text.substring(0, unclosedStart).trimEnd();
|
|
4936
4997
|
}
|
|
4937
4998
|
function escapeTextUnderscores(text) {
|
|
@@ -4976,7 +5037,8 @@ function convertSingleToDoubleDollar(text) {
|
|
|
4976
5037
|
}
|
|
4977
5038
|
function preprocessLaTeX(str) {
|
|
4978
5039
|
if (!hasLatexTrigger(str)) return str;
|
|
4979
|
-
|
|
5040
|
+
const mask = selectMask(str);
|
|
5041
|
+
return (mask === null ? processSlice(str, { legacy: true, probe: false }) : processSlice(str, { probe: false, mask })).out;
|
|
4980
5042
|
}
|
|
4981
5043
|
function hasLatexTrigger(str) {
|
|
4982
5044
|
return str.includes("$") || str.includes("\\[") || str.includes("\\(");
|
|
@@ -5005,42 +5067,240 @@ function hasUnclosedTextCommand(text) {
|
|
|
5005
5067
|
}
|
|
5006
5068
|
var RESIDUAL_OPEN_BRACKET_RE = /(?<!!)\\\[/;
|
|
5007
5069
|
var LEADING_DOUBLE_DOLLAR_RE = /^\s*\$\$/;
|
|
5008
|
-
|
|
5070
|
+
var PUA_START = 57344;
|
|
5071
|
+
var PUA_END = 63743;
|
|
5072
|
+
var PUA_SIZE = PUA_END - PUA_START + 1;
|
|
5073
|
+
function selectMask(source) {
|
|
5074
|
+
const first = String.fromCharCode(PUA_START);
|
|
5075
|
+
if (source.indexOf(first) === -1) return first;
|
|
5076
|
+
const seen = new Uint8Array(PUA_SIZE);
|
|
5077
|
+
for (let i = 0; i < source.length; i++) {
|
|
5078
|
+
const c = source.charCodeAt(i);
|
|
5079
|
+
if (c >= PUA_START && c <= PUA_END) seen[c - PUA_START] = 1;
|
|
5080
|
+
}
|
|
5081
|
+
for (let k = 0; k < PUA_SIZE; k++) if (seen[k] === 0) return String.fromCharCode(PUA_START + k);
|
|
5082
|
+
return null;
|
|
5083
|
+
}
|
|
5084
|
+
var PuaPresence = class {
|
|
5085
|
+
bits = new Uint8Array(PUA_SIZE);
|
|
5086
|
+
distinct = 0;
|
|
5087
|
+
reset() {
|
|
5088
|
+
this.bits.fill(0);
|
|
5089
|
+
this.distinct = 0;
|
|
5090
|
+
}
|
|
5091
|
+
add(text, from) {
|
|
5092
|
+
for (let i = from; i < text.length; i++) {
|
|
5093
|
+
const c = text.charCodeAt(i);
|
|
5094
|
+
if (c >= PUA_START && c <= PUA_END) {
|
|
5095
|
+
const k = c - PUA_START;
|
|
5096
|
+
if (this.bits[k] === 0) {
|
|
5097
|
+
this.bits[k] = 1;
|
|
5098
|
+
this.distinct += 1;
|
|
5099
|
+
}
|
|
5100
|
+
}
|
|
5101
|
+
}
|
|
5102
|
+
}
|
|
5103
|
+
select() {
|
|
5104
|
+
if (this.distinct === 0) return String.fromCharCode(PUA_START);
|
|
5105
|
+
if (this.distinct >= PUA_SIZE) return null;
|
|
5106
|
+
for (let k = 0; k < PUA_SIZE; k++) if (this.bits[k] === 0) return String.fromCharCode(PUA_START + k);
|
|
5107
|
+
return null;
|
|
5108
|
+
}
|
|
5109
|
+
};
|
|
5110
|
+
function transformRun(input, probe, runStartsAtLineStart, seamEligible) {
|
|
5111
|
+
let text = input;
|
|
5112
|
+
let tailSensitive = false;
|
|
5113
|
+
let truncatedAtSeamStart = false;
|
|
5114
|
+
text = escapeMhchemCommands(text);
|
|
5115
|
+
text = escapeCurrencyDollarSigns(text);
|
|
5116
|
+
text = convertLatexDelimiters(text);
|
|
5117
|
+
if (probe && RESIDUAL_OPEN_BRACKET_RE.test(text)) tailSensitive = true;
|
|
5118
|
+
text = escapeLatexPipes(text);
|
|
5119
|
+
if (probe && findUnclosedDelimiterStart(text, "both") !== -1) tailSensitive = true;
|
|
5120
|
+
text = escapeLatexPipesInUnclosed(text);
|
|
5121
|
+
if (probe && hasUnclosedTextCommand(text)) tailSensitive = true;
|
|
5122
|
+
text = escapeTextUnderscores(text);
|
|
5123
|
+
text = convertSingleToDoubleDollar(text);
|
|
5124
|
+
let unclosedDouble;
|
|
5125
|
+
if (probe || seamEligible && LEADING_DOUBLE_DOLLAR_RE.test(text)) {
|
|
5126
|
+
unclosedDouble = findUnclosedDelimiterStart(text, "double-only");
|
|
5127
|
+
if (unclosedDouble !== -1) {
|
|
5128
|
+
tailSensitive = true;
|
|
5129
|
+
if (seamEligible && opensMathFlow(text, unclosedDouble, runStartsAtLineStart) && text.slice(0, unclosedDouble).trim() === "") {
|
|
5130
|
+
truncatedAtSeamStart = true;
|
|
5131
|
+
}
|
|
5132
|
+
}
|
|
5133
|
+
}
|
|
5134
|
+
text = truncateUnclosedLatexBlock(text, runStartsAtLineStart, unclosedDouble);
|
|
5135
|
+
return { out: text, tailSensitive, truncatedAtSeamStart };
|
|
5136
|
+
}
|
|
5137
|
+
function processSliceLegacy(slice, probe) {
|
|
5009
5138
|
const segments = splitByProtectedRegions(slice);
|
|
5010
5139
|
const parts = [];
|
|
5011
5140
|
let quiescent = true;
|
|
5012
5141
|
let truncatedAtSeamStart = false;
|
|
5013
5142
|
for (let index = 0; index < segments.length; index++) {
|
|
5014
5143
|
const segment = segments[index];
|
|
5015
|
-
if (segment.
|
|
5144
|
+
if (segment.kind !== "text") {
|
|
5016
5145
|
parts.push(segment.text);
|
|
5017
5146
|
continue;
|
|
5018
5147
|
}
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
|
|
5026
|
-
|
|
5027
|
-
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
|
|
5031
|
-
|
|
5032
|
-
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
5148
|
+
const r = transformRun(segment.text, probe, true, index === 0);
|
|
5149
|
+
if (r.tailSensitive) quiescent = false;
|
|
5150
|
+
if (r.truncatedAtSeamStart) truncatedAtSeamStart = true;
|
|
5151
|
+
parts.push(r.out);
|
|
5152
|
+
}
|
|
5153
|
+
return { out: parts.join(""), quiescent, truncatedAtSeamStart, degradedReason: null };
|
|
5154
|
+
}
|
|
5155
|
+
var SCOPE_DEPTH_CAP = 8;
|
|
5156
|
+
var VOID_TAGS2 = /* @__PURE__ */ new Set(["br", "hr", "img", "wbr", "input", "source"]);
|
|
5157
|
+
var TAG_NAME_RE = /^<(\/?)([A-Za-z][A-Za-z0-9]*)/;
|
|
5158
|
+
function tagInfo(tag) {
|
|
5159
|
+
const m = TAG_NAME_RE.exec(tag);
|
|
5160
|
+
const closing = m?.[1] === "/";
|
|
5161
|
+
const name = (m?.[2] ?? "").toLowerCase();
|
|
5162
|
+
const opensScope = !closing && !tag.endsWith("/>") && !VOID_TAGS2.has(name);
|
|
5163
|
+
return { name, closing, opensScope };
|
|
5164
|
+
}
|
|
5165
|
+
function buildRunTree(segments) {
|
|
5166
|
+
const root2 = [];
|
|
5167
|
+
const stack = [];
|
|
5168
|
+
const current = () => stack.length > 0 ? stack[stack.length - 1].children : root2;
|
|
5169
|
+
const unwind = () => {
|
|
5170
|
+
while (stack.length > 0) {
|
|
5171
|
+
const frame = stack.pop();
|
|
5172
|
+
current().push({ type: "atom", text: frame.open }, ...frame.children);
|
|
5173
|
+
}
|
|
5174
|
+
};
|
|
5175
|
+
for (const segment of segments) {
|
|
5176
|
+
if (segment.kind === "tag") {
|
|
5177
|
+
const info = tagInfo(segment.text);
|
|
5178
|
+
if (info.closing) {
|
|
5179
|
+
const top = stack[stack.length - 1];
|
|
5180
|
+
if (top !== void 0 && top.name === info.name) {
|
|
5181
|
+
stack.pop();
|
|
5182
|
+
const parent = current();
|
|
5183
|
+
if (top.suppressed) {
|
|
5184
|
+
parent.push({ type: "atom", text: top.open }, ...top.children, { type: "atom", text: segment.text });
|
|
5185
|
+
} else {
|
|
5186
|
+
parent.push({ type: "scope", open: top.open, close: segment.text, children: top.children });
|
|
5187
|
+
}
|
|
5188
|
+
} else {
|
|
5189
|
+
current().push({ type: "atom", text: segment.text });
|
|
5037
5190
|
}
|
|
5191
|
+
} else if (info.opensScope) {
|
|
5192
|
+
stack.push({ name: info.name, open: segment.text, suppressed: stack.length >= SCOPE_DEPTH_CAP, children: [] });
|
|
5193
|
+
} else {
|
|
5194
|
+
current().push({ type: "atom", text: segment.text });
|
|
5038
5195
|
}
|
|
5196
|
+
continue;
|
|
5039
5197
|
}
|
|
5040
|
-
|
|
5041
|
-
|
|
5198
|
+
const t = segment.text;
|
|
5199
|
+
let start = 0;
|
|
5200
|
+
for (let i = 0; i < t.length; i++) {
|
|
5201
|
+
const c = t.charCodeAt(i);
|
|
5202
|
+
if (c !== 10 && c !== 13) continue;
|
|
5203
|
+
if (i > start) current().push({ type: "text", text: t.slice(start, i) });
|
|
5204
|
+
const end = c === 13 && t.charCodeAt(i + 1) === 10 ? i + 2 : i + 1;
|
|
5205
|
+
unwind();
|
|
5206
|
+
root2.push({ type: "text", text: t.slice(i, end) });
|
|
5207
|
+
start = end;
|
|
5208
|
+
i = end - 1;
|
|
5209
|
+
}
|
|
5210
|
+
if (start < t.length) current().push({ type: "text", text: t.slice(start) });
|
|
5211
|
+
}
|
|
5212
|
+
unwind();
|
|
5213
|
+
return root2;
|
|
5214
|
+
}
|
|
5215
|
+
var restoreFailureInjector = null;
|
|
5216
|
+
function restore(out, atoms, mask) {
|
|
5217
|
+
if (restoreFailureInjector !== null && restoreFailureInjector(atoms)) return null;
|
|
5218
|
+
let result = "";
|
|
5219
|
+
let k = 0;
|
|
5220
|
+
let last = 0;
|
|
5221
|
+
for (; ; ) {
|
|
5222
|
+
const idx = out.indexOf(mask, last);
|
|
5223
|
+
if (idx === -1) break;
|
|
5224
|
+
if (k >= atoms.length) return null;
|
|
5225
|
+
result += out.slice(last, idx) + atoms[k];
|
|
5226
|
+
k += 1;
|
|
5227
|
+
last = idx + 1;
|
|
5228
|
+
}
|
|
5229
|
+
return result + out.slice(last);
|
|
5230
|
+
}
|
|
5231
|
+
function emitRun(nodes, mask) {
|
|
5232
|
+
let text = "";
|
|
5233
|
+
const atoms = [];
|
|
5234
|
+
for (const node of nodes) {
|
|
5235
|
+
if (node.type === "text") {
|
|
5236
|
+
text += node.text;
|
|
5237
|
+
} else if (node.type === "atom") {
|
|
5238
|
+
atoms.push(node.text);
|
|
5239
|
+
text += mask;
|
|
5240
|
+
} else {
|
|
5241
|
+
const inner = emitRun(node.children, mask);
|
|
5242
|
+
if (inner === null) return null;
|
|
5243
|
+
const transformed = transformRun(inner.text, false, false, false);
|
|
5244
|
+
const restored = restore(transformed.out, inner.atoms, mask);
|
|
5245
|
+
if (restored === null) return null;
|
|
5246
|
+
atoms.push(node.open + restored + node.close);
|
|
5247
|
+
text += mask;
|
|
5248
|
+
}
|
|
5249
|
+
}
|
|
5250
|
+
return { text, atoms };
|
|
5251
|
+
}
|
|
5252
|
+
function reportRestoreViolation() {
|
|
5253
|
+
if (true) {
|
|
5254
|
+
console.error(
|
|
5255
|
+
"[ai-react-markdown] LaTeX preprocessor: atom restoration violated its invariant (more masks in the output than atoms); the slice was re-processed on the legacy path. This is an engine defect \u2014 please report it."
|
|
5256
|
+
);
|
|
5042
5257
|
}
|
|
5043
|
-
|
|
5258
|
+
}
|
|
5259
|
+
function processSliceDefault(slice, probe, mask) {
|
|
5260
|
+
const segments = splitByProtectedRegions(slice);
|
|
5261
|
+
const parts = [];
|
|
5262
|
+
let quiescent = true;
|
|
5263
|
+
let truncatedAtSeamStart = false;
|
|
5264
|
+
let offset = 0;
|
|
5265
|
+
let i = 0;
|
|
5266
|
+
while (i < segments.length) {
|
|
5267
|
+
const segment = segments[i];
|
|
5268
|
+
if (isHardBoundary(segment.kind)) {
|
|
5269
|
+
parts.push(segment.text);
|
|
5270
|
+
offset += segment.text.length;
|
|
5271
|
+
i += 1;
|
|
5272
|
+
continue;
|
|
5273
|
+
}
|
|
5274
|
+
const runStart = offset;
|
|
5275
|
+
const runSegments = [];
|
|
5276
|
+
while (i < segments.length && !isHardBoundary(segments[i].kind)) {
|
|
5277
|
+
runSegments.push(segments[i]);
|
|
5278
|
+
offset += segments[i].text.length;
|
|
5279
|
+
i += 1;
|
|
5280
|
+
}
|
|
5281
|
+
const before = runStart === 0 ? -1 : slice.charCodeAt(runStart - 1);
|
|
5282
|
+
const runStartsAtLineStart = before === -1 || before === 10 || before === 13;
|
|
5283
|
+
const seamEligible = runStart === 0;
|
|
5284
|
+
const emitted = emitRun(buildRunTree(runSegments), mask);
|
|
5285
|
+
if (emitted === null) {
|
|
5286
|
+
reportRestoreViolation();
|
|
5287
|
+
return { ...processSliceLegacy(slice, probe), degradedReason: "restore-invariant" };
|
|
5288
|
+
}
|
|
5289
|
+
const r = transformRun(emitted.text, probe, runStartsAtLineStart, seamEligible);
|
|
5290
|
+
const restored = restore(r.out, emitted.atoms, mask);
|
|
5291
|
+
if (restored === null) {
|
|
5292
|
+
reportRestoreViolation();
|
|
5293
|
+
return { ...processSliceLegacy(slice, probe), degradedReason: "restore-invariant" };
|
|
5294
|
+
}
|
|
5295
|
+
if (r.tailSensitive) quiescent = false;
|
|
5296
|
+
if (r.truncatedAtSeamStart) truncatedAtSeamStart = true;
|
|
5297
|
+
parts.push(restored);
|
|
5298
|
+
}
|
|
5299
|
+
return { out: parts.join(""), quiescent, truncatedAtSeamStart, degradedReason: null };
|
|
5300
|
+
}
|
|
5301
|
+
function processSlice(slice, options) {
|
|
5302
|
+
if (options.legacy === true) return processSliceLegacy(slice, options.probe);
|
|
5303
|
+
return processSliceDefault(slice, options.probe, options.mask);
|
|
5044
5304
|
}
|
|
5045
5305
|
function isBlankRawLine(text, from, to) {
|
|
5046
5306
|
for (let i = from; i < to; i++) {
|
|
@@ -5056,7 +5316,7 @@ function findRawSafeCut(active) {
|
|
|
5056
5316
|
let backtickHazard = false;
|
|
5057
5317
|
let latentLt = false;
|
|
5058
5318
|
for (const segment of segments) {
|
|
5059
|
-
if (segment.
|
|
5319
|
+
if (segment.kind !== "text") {
|
|
5060
5320
|
if (segment.text.includes(">")) latentLt = false;
|
|
5061
5321
|
offset += segment.text.length;
|
|
5062
5322
|
continue;
|
|
@@ -5091,12 +5351,28 @@ function createIncrementalLatexPreprocessor(options) {
|
|
|
5091
5351
|
const freezeThreshold = options?.freezeThreshold ?? DEFAULT_FREEZE_ATTEMPT_THRESHOLD;
|
|
5092
5352
|
const onAttempt = options?.onAttempt;
|
|
5093
5353
|
const backoff = options?.backoff ?? true;
|
|
5354
|
+
const onDegrade = options?.onDegrade;
|
|
5094
5355
|
let prevSource = "";
|
|
5095
5356
|
let prevOutput = "";
|
|
5096
5357
|
let frozenSrcEnd = 0;
|
|
5097
5358
|
let frozenOut = "";
|
|
5098
5359
|
let triggered = false;
|
|
5099
5360
|
let nextAttemptLen = 0;
|
|
5361
|
+
let lineageDegraded = false;
|
|
5362
|
+
const presence = new PuaPresence();
|
|
5363
|
+
const commit = (source, out) => {
|
|
5364
|
+
prevSource = source;
|
|
5365
|
+
prevOutput = out;
|
|
5366
|
+
return out;
|
|
5367
|
+
};
|
|
5368
|
+
const legacyWhole = (source) => processSlice(source, { legacy: true, probe: false }).out;
|
|
5369
|
+
const degrade = (source, reason) => {
|
|
5370
|
+
lineageDegraded = true;
|
|
5371
|
+
frozenSrcEnd = 0;
|
|
5372
|
+
frozenOut = "";
|
|
5373
|
+
onDegrade?.(reason);
|
|
5374
|
+
return commit(source, legacyWhole(source));
|
|
5375
|
+
};
|
|
5100
5376
|
return function incrementalPreprocessLaTeX(source) {
|
|
5101
5377
|
if (source === prevSource) return prevOutput;
|
|
5102
5378
|
const isAppend = source.length > prevSource.length && source.startsWith(prevSource);
|
|
@@ -5105,16 +5381,20 @@ function createIncrementalLatexPreprocessor(options) {
|
|
|
5105
5381
|
frozenOut = "";
|
|
5106
5382
|
triggered = false;
|
|
5107
5383
|
nextAttemptLen = 0;
|
|
5384
|
+
lineageDegraded = false;
|
|
5385
|
+
presence.reset();
|
|
5386
|
+
presence.add(source, 0);
|
|
5387
|
+
} else {
|
|
5388
|
+
presence.add(source, prevSource.length);
|
|
5108
5389
|
}
|
|
5109
5390
|
if (!triggered) {
|
|
5110
5391
|
const checkFrom = isAppend ? Math.max(0, prevSource.length - 1) : 0;
|
|
5111
|
-
if (!hasLatexTrigger(source.slice(checkFrom)))
|
|
5112
|
-
prevSource = source;
|
|
5113
|
-
prevOutput = source;
|
|
5114
|
-
return source;
|
|
5115
|
-
}
|
|
5392
|
+
if (!hasLatexTrigger(source.slice(checkFrom))) return commit(source, source);
|
|
5116
5393
|
triggered = true;
|
|
5117
5394
|
}
|
|
5395
|
+
if (lineageDegraded) return commit(source, legacyWhole(source));
|
|
5396
|
+
const mask = presence.select();
|
|
5397
|
+
if (mask === null) return degrade(source, "mask-exhausted");
|
|
5118
5398
|
let active = source.slice(frozenSrcEnd);
|
|
5119
5399
|
if (active.length > freezeThreshold && active.length >= nextAttemptLen) {
|
|
5120
5400
|
const activeLength = active.length;
|
|
@@ -5129,18 +5409,20 @@ function createIncrementalLatexPreprocessor(options) {
|
|
|
5129
5409
|
};
|
|
5130
5410
|
const cut = findRawSafeCut(active);
|
|
5131
5411
|
if (cut > 0) {
|
|
5132
|
-
const candidate = processSlice(active.slice(0, cut));
|
|
5412
|
+
const candidate = processSlice(active.slice(0, cut), { probe: true, mask });
|
|
5413
|
+
if (candidate.degradedReason !== null) {
|
|
5414
|
+
onAttempt?.({ activeLength, frozenBytes: 0 });
|
|
5415
|
+
return degrade(source, candidate.degradedReason);
|
|
5416
|
+
}
|
|
5133
5417
|
if (candidate.quiescent) freeze(cut, candidate);
|
|
5134
5418
|
}
|
|
5135
5419
|
nextAttemptLen = advanced || !backoff ? 0 : active.length * 2;
|
|
5136
5420
|
onAttempt?.({ activeLength, frozenBytes });
|
|
5137
5421
|
}
|
|
5138
|
-
const tail = processSlice(active, false);
|
|
5422
|
+
const tail = processSlice(active, { probe: false, mask });
|
|
5423
|
+
if (tail.degradedReason !== null) return degrade(source, tail.degradedReason);
|
|
5139
5424
|
const head = tail.truncatedAtSeamStart ? frozenOut.replace(/\s+$/, "") : frozenOut;
|
|
5140
|
-
|
|
5141
|
-
prevSource = source;
|
|
5142
|
-
prevOutput = out;
|
|
5143
|
-
return out;
|
|
5425
|
+
return commit(source, head + tail.out);
|
|
5144
5426
|
};
|
|
5145
5427
|
}
|
|
5146
5428
|
|
|
@@ -5165,6 +5447,8 @@ function createRemendPreprocessor(options) {
|
|
|
5165
5447
|
}
|
|
5166
5448
|
export {
|
|
5167
5449
|
DEFAULT_PAYLOAD,
|
|
5450
|
+
ENGINE_PLACEHOLDER_TAGS,
|
|
5451
|
+
ENGINE_PROVENANCE_PROPERTY,
|
|
5168
5452
|
PIPELINE_STAGES,
|
|
5169
5453
|
SENTINEL_FN_CONTENT,
|
|
5170
5454
|
SENTINEL_LINK_URL,
|
|
@@ -5209,6 +5493,7 @@ export {
|
|
|
5209
5493
|
preprocessLaTeX,
|
|
5210
5494
|
rehypeFooterAdorn,
|
|
5211
5495
|
rehypeRebaseHashLinks_default as rehypeRebaseHashLinks,
|
|
5496
|
+
rehypeVerifyEngineTags,
|
|
5212
5497
|
removeComments,
|
|
5213
5498
|
sanitizeCrossChunkUrl,
|
|
5214
5499
|
sanitizeSchema,
|