@ai-react-markdown/engine 2.10.0 → 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 +350 -50
- 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 +350 -50
- package/dist/index.dev.cjs.map +1 -1
- package/dist/index.dev.js +347 -50
- package/dist/index.dev.js.map +1 -1
- package/dist/index.js +347 -50
- 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,8 +4977,22 @@ function escapeLatexPipesInUnclosed(text) {
|
|
|
4918
4977
|
const tail = text.substring(unclosedStart + delimLen);
|
|
4919
4978
|
return before + delim + replaceUnescapedPipes(tail);
|
|
4920
4979
|
}
|
|
4921
|
-
function
|
|
4980
|
+
function opensMathFlow(text, pos, runStartsAtLineStart) {
|
|
4981
|
+
let i = pos;
|
|
4982
|
+
let spaces = 0;
|
|
4983
|
+
while (i > 0) {
|
|
4984
|
+
const prev = text[i - 1];
|
|
4985
|
+
if (prev === "\n" || prev === "\r") return true;
|
|
4986
|
+
i -= 1;
|
|
4987
|
+
if (text[i] !== " ") return false;
|
|
4988
|
+
spaces += 1;
|
|
4989
|
+
if (spaces > 3) return false;
|
|
4990
|
+
}
|
|
4991
|
+
return runStartsAtLineStart;
|
|
4992
|
+
}
|
|
4993
|
+
function truncateUnclosedLatexBlock(text, runStartsAtLineStart, unclosedStart = findUnclosedDelimiterStart(text, "double-only")) {
|
|
4922
4994
|
if (unclosedStart === -1) return text;
|
|
4995
|
+
if (!opensMathFlow(text, unclosedStart, runStartsAtLineStart)) return text;
|
|
4923
4996
|
return text.substring(0, unclosedStart).trimEnd();
|
|
4924
4997
|
}
|
|
4925
4998
|
function escapeTextUnderscores(text) {
|
|
@@ -4964,7 +5037,8 @@ function convertSingleToDoubleDollar(text) {
|
|
|
4964
5037
|
}
|
|
4965
5038
|
function preprocessLaTeX(str) {
|
|
4966
5039
|
if (!hasLatexTrigger(str)) return str;
|
|
4967
|
-
|
|
5040
|
+
const mask = selectMask(str);
|
|
5041
|
+
return (mask === null ? processSlice(str, { legacy: true, probe: false }) : processSlice(str, { probe: false, mask })).out;
|
|
4968
5042
|
}
|
|
4969
5043
|
function hasLatexTrigger(str) {
|
|
4970
5044
|
return str.includes("$") || str.includes("\\[") || str.includes("\\(");
|
|
@@ -4993,42 +5067,240 @@ function hasUnclosedTextCommand(text) {
|
|
|
4993
5067
|
}
|
|
4994
5068
|
var RESIDUAL_OPEN_BRACKET_RE = /(?<!!)\\\[/;
|
|
4995
5069
|
var LEADING_DOUBLE_DOLLAR_RE = /^\s*\$\$/;
|
|
4996
|
-
|
|
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) {
|
|
4997
5138
|
const segments = splitByProtectedRegions(slice);
|
|
4998
5139
|
const parts = [];
|
|
4999
5140
|
let quiescent = true;
|
|
5000
5141
|
let truncatedAtSeamStart = false;
|
|
5001
5142
|
for (let index = 0; index < segments.length; index++) {
|
|
5002
5143
|
const segment = segments[index];
|
|
5003
|
-
if (segment.
|
|
5144
|
+
if (segment.kind !== "text") {
|
|
5004
5145
|
parts.push(segment.text);
|
|
5005
5146
|
continue;
|
|
5006
5147
|
}
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
|
|
5023
|
-
|
|
5024
|
-
|
|
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 });
|
|
5025
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 });
|
|
5026
5195
|
}
|
|
5196
|
+
continue;
|
|
5027
5197
|
}
|
|
5028
|
-
|
|
5029
|
-
|
|
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
|
+
);
|
|
5030
5257
|
}
|
|
5031
|
-
|
|
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);
|
|
5032
5304
|
}
|
|
5033
5305
|
function isBlankRawLine(text, from, to) {
|
|
5034
5306
|
for (let i = from; i < to; i++) {
|
|
@@ -5044,7 +5316,7 @@ function findRawSafeCut(active) {
|
|
|
5044
5316
|
let backtickHazard = false;
|
|
5045
5317
|
let latentLt = false;
|
|
5046
5318
|
for (const segment of segments) {
|
|
5047
|
-
if (segment.
|
|
5319
|
+
if (segment.kind !== "text") {
|
|
5048
5320
|
if (segment.text.includes(">")) latentLt = false;
|
|
5049
5321
|
offset += segment.text.length;
|
|
5050
5322
|
continue;
|
|
@@ -5079,12 +5351,28 @@ function createIncrementalLatexPreprocessor(options) {
|
|
|
5079
5351
|
const freezeThreshold = options?.freezeThreshold ?? DEFAULT_FREEZE_ATTEMPT_THRESHOLD;
|
|
5080
5352
|
const onAttempt = options?.onAttempt;
|
|
5081
5353
|
const backoff = options?.backoff ?? true;
|
|
5354
|
+
const onDegrade = options?.onDegrade;
|
|
5082
5355
|
let prevSource = "";
|
|
5083
5356
|
let prevOutput = "";
|
|
5084
5357
|
let frozenSrcEnd = 0;
|
|
5085
5358
|
let frozenOut = "";
|
|
5086
5359
|
let triggered = false;
|
|
5087
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
|
+
};
|
|
5088
5376
|
return function incrementalPreprocessLaTeX(source) {
|
|
5089
5377
|
if (source === prevSource) return prevOutput;
|
|
5090
5378
|
const isAppend = source.length > prevSource.length && source.startsWith(prevSource);
|
|
@@ -5093,16 +5381,20 @@ function createIncrementalLatexPreprocessor(options) {
|
|
|
5093
5381
|
frozenOut = "";
|
|
5094
5382
|
triggered = false;
|
|
5095
5383
|
nextAttemptLen = 0;
|
|
5384
|
+
lineageDegraded = false;
|
|
5385
|
+
presence.reset();
|
|
5386
|
+
presence.add(source, 0);
|
|
5387
|
+
} else {
|
|
5388
|
+
presence.add(source, prevSource.length);
|
|
5096
5389
|
}
|
|
5097
5390
|
if (!triggered) {
|
|
5098
5391
|
const checkFrom = isAppend ? Math.max(0, prevSource.length - 1) : 0;
|
|
5099
|
-
if (!hasLatexTrigger(source.slice(checkFrom)))
|
|
5100
|
-
prevSource = source;
|
|
5101
|
-
prevOutput = source;
|
|
5102
|
-
return source;
|
|
5103
|
-
}
|
|
5392
|
+
if (!hasLatexTrigger(source.slice(checkFrom))) return commit(source, source);
|
|
5104
5393
|
triggered = true;
|
|
5105
5394
|
}
|
|
5395
|
+
if (lineageDegraded) return commit(source, legacyWhole(source));
|
|
5396
|
+
const mask = presence.select();
|
|
5397
|
+
if (mask === null) return degrade(source, "mask-exhausted");
|
|
5106
5398
|
let active = source.slice(frozenSrcEnd);
|
|
5107
5399
|
if (active.length > freezeThreshold && active.length >= nextAttemptLen) {
|
|
5108
5400
|
const activeLength = active.length;
|
|
@@ -5117,18 +5409,20 @@ function createIncrementalLatexPreprocessor(options) {
|
|
|
5117
5409
|
};
|
|
5118
5410
|
const cut = findRawSafeCut(active);
|
|
5119
5411
|
if (cut > 0) {
|
|
5120
|
-
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
|
+
}
|
|
5121
5417
|
if (candidate.quiescent) freeze(cut, candidate);
|
|
5122
5418
|
}
|
|
5123
5419
|
nextAttemptLen = advanced || !backoff ? 0 : active.length * 2;
|
|
5124
5420
|
onAttempt?.({ activeLength, frozenBytes });
|
|
5125
5421
|
}
|
|
5126
|
-
const tail = processSlice(active, false);
|
|
5422
|
+
const tail = processSlice(active, { probe: false, mask });
|
|
5423
|
+
if (tail.degradedReason !== null) return degrade(source, tail.degradedReason);
|
|
5127
5424
|
const head = tail.truncatedAtSeamStart ? frozenOut.replace(/\s+$/, "") : frozenOut;
|
|
5128
|
-
|
|
5129
|
-
prevSource = source;
|
|
5130
|
-
prevOutput = out;
|
|
5131
|
-
return out;
|
|
5425
|
+
return commit(source, head + tail.out);
|
|
5132
5426
|
};
|
|
5133
5427
|
}
|
|
5134
5428
|
|
|
@@ -5153,6 +5447,8 @@ function createRemendPreprocessor(options) {
|
|
|
5153
5447
|
}
|
|
5154
5448
|
export {
|
|
5155
5449
|
DEFAULT_PAYLOAD,
|
|
5450
|
+
ENGINE_PLACEHOLDER_TAGS,
|
|
5451
|
+
ENGINE_PROVENANCE_PROPERTY,
|
|
5156
5452
|
PIPELINE_STAGES,
|
|
5157
5453
|
SENTINEL_FN_CONTENT,
|
|
5158
5454
|
SENTINEL_LINK_URL,
|
|
@@ -5197,6 +5493,7 @@ export {
|
|
|
5197
5493
|
preprocessLaTeX,
|
|
5198
5494
|
rehypeFooterAdorn,
|
|
5199
5495
|
rehypeRebaseHashLinks_default as rehypeRebaseHashLinks,
|
|
5496
|
+
rehypeVerifyEngineTags,
|
|
5200
5497
|
removeComments,
|
|
5201
5498
|
sanitizeCrossChunkUrl,
|
|
5202
5499
|
sanitizeSchema,
|