@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.js
CHANGED
|
@@ -2701,6 +2701,44 @@ function rehypeUnwrapCrossChunkImages() {
|
|
|
2701
2701
|
|
|
2702
2702
|
// src/components/pluginChain.ts
|
|
2703
2703
|
import rehypeSanitize from "rehype-sanitize";
|
|
2704
|
+
|
|
2705
|
+
// src/components/rehypeVerifyEngineTags.ts
|
|
2706
|
+
var ENGINE_PLACEHOLDER_TAGS = /* @__PURE__ */ new Set([
|
|
2707
|
+
"footnote-sup",
|
|
2708
|
+
"cross-chunk-link",
|
|
2709
|
+
"cross-chunk-image"
|
|
2710
|
+
]);
|
|
2711
|
+
var ENGINE_PROVENANCE_PROPERTY = "engineProvenance";
|
|
2712
|
+
function walk(parent, provenance) {
|
|
2713
|
+
const children = parent.children;
|
|
2714
|
+
let i = 0;
|
|
2715
|
+
while (i < children.length) {
|
|
2716
|
+
const node = children[i];
|
|
2717
|
+
if (node.type === "element" && ENGINE_PLACEHOLDER_TAGS.has(node.tagName)) {
|
|
2718
|
+
const props = node.properties ?? {};
|
|
2719
|
+
const stamped = props[ENGINE_PROVENANCE_PROPERTY];
|
|
2720
|
+
const genuine = provenance !== "" && typeof stamped === "string" && stamped === provenance;
|
|
2721
|
+
if (genuine) {
|
|
2722
|
+
delete props[ENGINE_PROVENANCE_PROPERTY];
|
|
2723
|
+
walk(node, provenance);
|
|
2724
|
+
i += 1;
|
|
2725
|
+
} else {
|
|
2726
|
+
children.splice(i, 1, ...node.children);
|
|
2727
|
+
}
|
|
2728
|
+
continue;
|
|
2729
|
+
}
|
|
2730
|
+
if (node.type === "element") walk(node, provenance);
|
|
2731
|
+
i += 1;
|
|
2732
|
+
}
|
|
2733
|
+
}
|
|
2734
|
+
function rehypeVerifyEngineTags(options) {
|
|
2735
|
+
const provenance = options?.provenance ?? "";
|
|
2736
|
+
return function transformer(tree) {
|
|
2737
|
+
walk(tree, provenance);
|
|
2738
|
+
};
|
|
2739
|
+
}
|
|
2740
|
+
|
|
2741
|
+
// src/components/pluginChain.ts
|
|
2704
2742
|
import remarkBreaks from "remark-breaks";
|
|
2705
2743
|
import remarkCjkFriendly from "remark-cjk-friendly";
|
|
2706
2744
|
import remarkCjkFriendlyGfmStrikethrough from "remark-cjk-friendly-gfm-strikethrough";
|
|
@@ -2806,10 +2844,13 @@ function buildCoreRemarkPlugins(enginePlugins) {
|
|
|
2806
2844
|
...DISPLAY_OPTIMIZE_CHAIN.filter(([name]) => selected.has(name)).map(([, plugin]) => plugin)
|
|
2807
2845
|
];
|
|
2808
2846
|
}
|
|
2809
|
-
function buildCoreRehypePlugins(sanitizeSchema2, clobberPrefix) {
|
|
2847
|
+
function buildCoreRehypePlugins(sanitizeSchema2, clobberPrefix, options) {
|
|
2810
2848
|
return [
|
|
2811
2849
|
// Allow raw HTML through so rehype-sanitize can handle it.
|
|
2812
2850
|
[rehypeRaw, { passThrough: [] }],
|
|
2851
|
+
// Unwrap forged engine placeholders BEFORE sanitize admits their tag
|
|
2852
|
+
// names. Only when the caller holds a credential (see the option's doc).
|
|
2853
|
+
...options ? [[rehypeVerifyEngineTags, { provenance: options.provenance }]] : [],
|
|
2813
2854
|
// Sanitize HTML while allowing <mark> (highlight), KaTeX class names,
|
|
2814
2855
|
// and any extra protocols the caller permitted via the `sanitizeSchema`
|
|
2815
2856
|
// prop. Override `clobberPrefix` with the instance-scoped value — the
|
|
@@ -2849,6 +2890,10 @@ function buildCoreRemarkRehypeOptions(enableDefinitionList) {
|
|
|
2849
2890
|
}
|
|
2850
2891
|
|
|
2851
2892
|
// src/components/customMdastHandlers.ts
|
|
2893
|
+
function provenanceProps(s) {
|
|
2894
|
+
const provenance = s.options.provenance;
|
|
2895
|
+
return typeof provenance === "string" ? { engineProvenance: provenance } : {};
|
|
2896
|
+
}
|
|
2852
2897
|
function localDefProps(s, id) {
|
|
2853
2898
|
const def = s.definitionById.get(id);
|
|
2854
2899
|
if (!def || typeof def.url !== "string" || def.url === SENTINEL_LINK_URL) return {};
|
|
@@ -2887,7 +2932,8 @@ function buildCrossChunkHandlers() {
|
|
|
2887
2932
|
label: node.label ?? node.identifier,
|
|
2888
2933
|
referenceType: node.referenceType,
|
|
2889
2934
|
documentId: s.options.documentId,
|
|
2890
|
-
...localDefProps(s, id)
|
|
2935
|
+
...localDefProps(s, id),
|
|
2936
|
+
...provenanceProps(s)
|
|
2891
2937
|
},
|
|
2892
2938
|
children: s.all(node)
|
|
2893
2939
|
};
|
|
@@ -2905,7 +2951,8 @@ function buildCrossChunkHandlers() {
|
|
|
2905
2951
|
referenceType: node.referenceType,
|
|
2906
2952
|
alt: node.alt ?? "",
|
|
2907
2953
|
documentId: s.options.documentId,
|
|
2908
|
-
...localDefProps(s, id)
|
|
2954
|
+
...localDefProps(s, id),
|
|
2955
|
+
...provenanceProps(s)
|
|
2909
2956
|
},
|
|
2910
2957
|
children: []
|
|
2911
2958
|
};
|
|
@@ -2922,7 +2969,8 @@ function buildCrossChunkHandlers() {
|
|
|
2922
2969
|
properties: {
|
|
2923
2970
|
label: node.identifier,
|
|
2924
2971
|
localOccurrence,
|
|
2925
|
-
documentId: s.options.documentId
|
|
2972
|
+
documentId: s.options.documentId,
|
|
2973
|
+
...provenanceProps(s)
|
|
2926
2974
|
},
|
|
2927
2975
|
children: []
|
|
2928
2976
|
};
|
|
@@ -2940,7 +2988,8 @@ function buildCrossChunkHandlers() {
|
|
|
2940
2988
|
// first client frame), where the local synthetic footer is what
|
|
2941
2989
|
// renders, so marks and footer agree (core-render-02).
|
|
2942
2990
|
localNumber: s.footnoteOrder.indexOf(id) + 1,
|
|
2943
|
-
documentId: s.options.documentId
|
|
2991
|
+
documentId: s.options.documentId,
|
|
2992
|
+
...provenanceProps(s)
|
|
2944
2993
|
},
|
|
2945
2994
|
children: []
|
|
2946
2995
|
};
|
|
@@ -4600,6 +4649,12 @@ var createSmoothStreamController = (options = {}) => {
|
|
|
4600
4649
|
};
|
|
4601
4650
|
|
|
4602
4651
|
// src/preprocessors/latex.ts
|
|
4652
|
+
function isHardBoundary(kind) {
|
|
4653
|
+
return kind === "code" || kind === "literal" || kind === "multilineTag";
|
|
4654
|
+
}
|
|
4655
|
+
function hasLineEnding(text) {
|
|
4656
|
+
return text.includes("\n") || text.includes("\r");
|
|
4657
|
+
}
|
|
4603
4658
|
function getRepeatedMarkerLength(content, start, marker) {
|
|
4604
4659
|
let end = start;
|
|
4605
4660
|
while (end < content.length && content[end] === marker) {
|
|
@@ -4667,11 +4722,11 @@ function splitByProtectedRegions(content) {
|
|
|
4667
4722
|
let multilineFenceMarker = null;
|
|
4668
4723
|
let multilineFenceLength = 0;
|
|
4669
4724
|
let multilineFenceIndent = 0;
|
|
4670
|
-
function pushProtected(start, end) {
|
|
4725
|
+
function pushProtected(start, end, kind) {
|
|
4671
4726
|
if (start > lastIndex) {
|
|
4672
|
-
segments.push({ text: content.substring(lastIndex, start)
|
|
4727
|
+
segments.push({ kind: "text", text: content.substring(lastIndex, start) });
|
|
4673
4728
|
}
|
|
4674
|
-
segments.push({ text: content.substring(start, end)
|
|
4729
|
+
segments.push({ kind, text: content.substring(start, end) });
|
|
4675
4730
|
lastIndex = end;
|
|
4676
4731
|
}
|
|
4677
4732
|
let i = 0;
|
|
@@ -4682,7 +4737,7 @@ function splitByProtectedRegions(content) {
|
|
|
4682
4737
|
const runLen = getRepeatedMarkerLength(content, i, multilineFenceMarker);
|
|
4683
4738
|
const closerIndent = lineIndentBefore(content, i);
|
|
4684
4739
|
if (runLen >= multilineFenceLength && closerIndent !== -1 && closerIndent <= multilineFenceIndent + 3 && restOfLineIsBlank(content, i + runLen)) {
|
|
4685
|
-
pushProtected(multilineStart, i + runLen);
|
|
4740
|
+
pushProtected(multilineStart, i + runLen, "code");
|
|
4686
4741
|
multilineStart = -1;
|
|
4687
4742
|
multilineFenceMarker = null;
|
|
4688
4743
|
multilineFenceLength = 0;
|
|
@@ -4709,7 +4764,7 @@ function splitByProtectedRegions(content) {
|
|
|
4709
4764
|
if (char === "`") {
|
|
4710
4765
|
const closeIdx = findClosingBacktickRun(content, i + runLen, runLen);
|
|
4711
4766
|
if (closeIdx !== -1) {
|
|
4712
|
-
pushProtected(i, closeIdx + runLen);
|
|
4767
|
+
pushProtected(i, closeIdx + runLen, "code");
|
|
4713
4768
|
i = closeIdx + runLen;
|
|
4714
4769
|
continue;
|
|
4715
4770
|
}
|
|
@@ -4734,7 +4789,11 @@ function splitByProtectedRegions(content) {
|
|
|
4734
4789
|
endIndex = content.length;
|
|
4735
4790
|
}
|
|
4736
4791
|
}
|
|
4737
|
-
pushProtected(
|
|
4792
|
+
pushProtected(
|
|
4793
|
+
i,
|
|
4794
|
+
endIndex,
|
|
4795
|
+
isOpeningPairedTag ? "literal" : hasLineEnding(content.substring(i, endIndex)) ? "multilineTag" : "tag"
|
|
4796
|
+
);
|
|
4738
4797
|
i = endIndex;
|
|
4739
4798
|
continue;
|
|
4740
4799
|
}
|
|
@@ -4742,10 +4801,10 @@ function splitByProtectedRegions(content) {
|
|
|
4742
4801
|
i += 1;
|
|
4743
4802
|
}
|
|
4744
4803
|
if (multilineStart !== -1) {
|
|
4745
|
-
pushProtected(multilineStart, content.length);
|
|
4804
|
+
pushProtected(multilineStart, content.length, "code");
|
|
4746
4805
|
}
|
|
4747
4806
|
if (lastIndex < content.length) {
|
|
4748
|
-
segments.push({ text: content.substring(lastIndex)
|
|
4807
|
+
segments.push({ kind: "text", text: content.substring(lastIndex) });
|
|
4749
4808
|
}
|
|
4750
4809
|
return segments;
|
|
4751
4810
|
}
|
|
@@ -4899,20 +4958,22 @@ function escapeLatexPipesInUnclosed(text) {
|
|
|
4899
4958
|
const tail = text.substring(unclosedStart + delimLen);
|
|
4900
4959
|
return before + delim + replaceUnescapedPipes(tail);
|
|
4901
4960
|
}
|
|
4902
|
-
function opensMathFlow(text, pos) {
|
|
4961
|
+
function opensMathFlow(text, pos, runStartsAtLineStart) {
|
|
4903
4962
|
let i = pos;
|
|
4904
4963
|
let spaces = 0;
|
|
4905
|
-
while (i > 0
|
|
4964
|
+
while (i > 0) {
|
|
4965
|
+
const prev = text[i - 1];
|
|
4966
|
+
if (prev === "\n" || prev === "\r") return true;
|
|
4906
4967
|
i -= 1;
|
|
4907
4968
|
if (text[i] !== " ") return false;
|
|
4908
4969
|
spaces += 1;
|
|
4909
4970
|
if (spaces > 3) return false;
|
|
4910
4971
|
}
|
|
4911
|
-
return
|
|
4972
|
+
return runStartsAtLineStart;
|
|
4912
4973
|
}
|
|
4913
|
-
function truncateUnclosedLatexBlock(text, unclosedStart = findUnclosedDelimiterStart(text, "double-only")) {
|
|
4974
|
+
function truncateUnclosedLatexBlock(text, runStartsAtLineStart, unclosedStart = findUnclosedDelimiterStart(text, "double-only")) {
|
|
4914
4975
|
if (unclosedStart === -1) return text;
|
|
4915
|
-
if (!opensMathFlow(text, unclosedStart)) return text;
|
|
4976
|
+
if (!opensMathFlow(text, unclosedStart, runStartsAtLineStart)) return text;
|
|
4916
4977
|
return text.substring(0, unclosedStart).trimEnd();
|
|
4917
4978
|
}
|
|
4918
4979
|
function escapeTextUnderscores(text) {
|
|
@@ -4957,7 +5018,8 @@ function convertSingleToDoubleDollar(text) {
|
|
|
4957
5018
|
}
|
|
4958
5019
|
function preprocessLaTeX(str) {
|
|
4959
5020
|
if (!hasLatexTrigger(str)) return str;
|
|
4960
|
-
|
|
5021
|
+
const mask = selectMask(str);
|
|
5022
|
+
return (mask === null ? processSlice(str, { legacy: true, probe: false }) : processSlice(str, { probe: false, mask })).out;
|
|
4961
5023
|
}
|
|
4962
5024
|
function hasLatexTrigger(str) {
|
|
4963
5025
|
return str.includes("$") || str.includes("\\[") || str.includes("\\(");
|
|
@@ -4986,42 +5048,240 @@ function hasUnclosedTextCommand(text) {
|
|
|
4986
5048
|
}
|
|
4987
5049
|
var RESIDUAL_OPEN_BRACKET_RE = /(?<!!)\\\[/;
|
|
4988
5050
|
var LEADING_DOUBLE_DOLLAR_RE = /^\s*\$\$/;
|
|
4989
|
-
|
|
5051
|
+
var PUA_START = 57344;
|
|
5052
|
+
var PUA_END = 63743;
|
|
5053
|
+
var PUA_SIZE = PUA_END - PUA_START + 1;
|
|
5054
|
+
function selectMask(source) {
|
|
5055
|
+
const first = String.fromCharCode(PUA_START);
|
|
5056
|
+
if (source.indexOf(first) === -1) return first;
|
|
5057
|
+
const seen = new Uint8Array(PUA_SIZE);
|
|
5058
|
+
for (let i = 0; i < source.length; i++) {
|
|
5059
|
+
const c = source.charCodeAt(i);
|
|
5060
|
+
if (c >= PUA_START && c <= PUA_END) seen[c - PUA_START] = 1;
|
|
5061
|
+
}
|
|
5062
|
+
for (let k = 0; k < PUA_SIZE; k++) if (seen[k] === 0) return String.fromCharCode(PUA_START + k);
|
|
5063
|
+
return null;
|
|
5064
|
+
}
|
|
5065
|
+
var PuaPresence = class {
|
|
5066
|
+
bits = new Uint8Array(PUA_SIZE);
|
|
5067
|
+
distinct = 0;
|
|
5068
|
+
reset() {
|
|
5069
|
+
this.bits.fill(0);
|
|
5070
|
+
this.distinct = 0;
|
|
5071
|
+
}
|
|
5072
|
+
add(text, from) {
|
|
5073
|
+
for (let i = from; i < text.length; i++) {
|
|
5074
|
+
const c = text.charCodeAt(i);
|
|
5075
|
+
if (c >= PUA_START && c <= PUA_END) {
|
|
5076
|
+
const k = c - PUA_START;
|
|
5077
|
+
if (this.bits[k] === 0) {
|
|
5078
|
+
this.bits[k] = 1;
|
|
5079
|
+
this.distinct += 1;
|
|
5080
|
+
}
|
|
5081
|
+
}
|
|
5082
|
+
}
|
|
5083
|
+
}
|
|
5084
|
+
select() {
|
|
5085
|
+
if (this.distinct === 0) return String.fromCharCode(PUA_START);
|
|
5086
|
+
if (this.distinct >= PUA_SIZE) return null;
|
|
5087
|
+
for (let k = 0; k < PUA_SIZE; k++) if (this.bits[k] === 0) return String.fromCharCode(PUA_START + k);
|
|
5088
|
+
return null;
|
|
5089
|
+
}
|
|
5090
|
+
};
|
|
5091
|
+
function transformRun(input, probe, runStartsAtLineStart, seamEligible) {
|
|
5092
|
+
let text = input;
|
|
5093
|
+
let tailSensitive = false;
|
|
5094
|
+
let truncatedAtSeamStart = false;
|
|
5095
|
+
text = escapeMhchemCommands(text);
|
|
5096
|
+
text = escapeCurrencyDollarSigns(text);
|
|
5097
|
+
text = convertLatexDelimiters(text);
|
|
5098
|
+
if (probe && RESIDUAL_OPEN_BRACKET_RE.test(text)) tailSensitive = true;
|
|
5099
|
+
text = escapeLatexPipes(text);
|
|
5100
|
+
if (probe && findUnclosedDelimiterStart(text, "both") !== -1) tailSensitive = true;
|
|
5101
|
+
text = escapeLatexPipesInUnclosed(text);
|
|
5102
|
+
if (probe && hasUnclosedTextCommand(text)) tailSensitive = true;
|
|
5103
|
+
text = escapeTextUnderscores(text);
|
|
5104
|
+
text = convertSingleToDoubleDollar(text);
|
|
5105
|
+
let unclosedDouble;
|
|
5106
|
+
if (probe || seamEligible && LEADING_DOUBLE_DOLLAR_RE.test(text)) {
|
|
5107
|
+
unclosedDouble = findUnclosedDelimiterStart(text, "double-only");
|
|
5108
|
+
if (unclosedDouble !== -1) {
|
|
5109
|
+
tailSensitive = true;
|
|
5110
|
+
if (seamEligible && opensMathFlow(text, unclosedDouble, runStartsAtLineStart) && text.slice(0, unclosedDouble).trim() === "") {
|
|
5111
|
+
truncatedAtSeamStart = true;
|
|
5112
|
+
}
|
|
5113
|
+
}
|
|
5114
|
+
}
|
|
5115
|
+
text = truncateUnclosedLatexBlock(text, runStartsAtLineStart, unclosedDouble);
|
|
5116
|
+
return { out: text, tailSensitive, truncatedAtSeamStart };
|
|
5117
|
+
}
|
|
5118
|
+
function processSliceLegacy(slice, probe) {
|
|
4990
5119
|
const segments = splitByProtectedRegions(slice);
|
|
4991
5120
|
const parts = [];
|
|
4992
5121
|
let quiescent = true;
|
|
4993
5122
|
let truncatedAtSeamStart = false;
|
|
4994
5123
|
for (let index = 0; index < segments.length; index++) {
|
|
4995
5124
|
const segment = segments[index];
|
|
4996
|
-
if (segment.
|
|
5125
|
+
if (segment.kind !== "text") {
|
|
4997
5126
|
parts.push(segment.text);
|
|
4998
5127
|
continue;
|
|
4999
5128
|
}
|
|
5000
|
-
|
|
5001
|
-
|
|
5002
|
-
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
|
|
5129
|
+
const r = transformRun(segment.text, probe, true, index === 0);
|
|
5130
|
+
if (r.tailSensitive) quiescent = false;
|
|
5131
|
+
if (r.truncatedAtSeamStart) truncatedAtSeamStart = true;
|
|
5132
|
+
parts.push(r.out);
|
|
5133
|
+
}
|
|
5134
|
+
return { out: parts.join(""), quiescent, truncatedAtSeamStart, degradedReason: null };
|
|
5135
|
+
}
|
|
5136
|
+
var SCOPE_DEPTH_CAP = 8;
|
|
5137
|
+
var VOID_TAGS2 = /* @__PURE__ */ new Set(["br", "hr", "img", "wbr", "input", "source"]);
|
|
5138
|
+
var TAG_NAME_RE = /^<(\/?)([A-Za-z][A-Za-z0-9]*)/;
|
|
5139
|
+
function tagInfo(tag) {
|
|
5140
|
+
const m = TAG_NAME_RE.exec(tag);
|
|
5141
|
+
const closing = m?.[1] === "/";
|
|
5142
|
+
const name = (m?.[2] ?? "").toLowerCase();
|
|
5143
|
+
const opensScope = !closing && !tag.endsWith("/>") && !VOID_TAGS2.has(name);
|
|
5144
|
+
return { name, closing, opensScope };
|
|
5145
|
+
}
|
|
5146
|
+
function buildRunTree(segments) {
|
|
5147
|
+
const root2 = [];
|
|
5148
|
+
const stack = [];
|
|
5149
|
+
const current = () => stack.length > 0 ? stack[stack.length - 1].children : root2;
|
|
5150
|
+
const unwind = () => {
|
|
5151
|
+
while (stack.length > 0) {
|
|
5152
|
+
const frame = stack.pop();
|
|
5153
|
+
current().push({ type: "atom", text: frame.open }, ...frame.children);
|
|
5154
|
+
}
|
|
5155
|
+
};
|
|
5156
|
+
for (const segment of segments) {
|
|
5157
|
+
if (segment.kind === "tag") {
|
|
5158
|
+
const info = tagInfo(segment.text);
|
|
5159
|
+
if (info.closing) {
|
|
5160
|
+
const top = stack[stack.length - 1];
|
|
5161
|
+
if (top !== void 0 && top.name === info.name) {
|
|
5162
|
+
stack.pop();
|
|
5163
|
+
const parent = current();
|
|
5164
|
+
if (top.suppressed) {
|
|
5165
|
+
parent.push({ type: "atom", text: top.open }, ...top.children, { type: "atom", text: segment.text });
|
|
5166
|
+
} else {
|
|
5167
|
+
parent.push({ type: "scope", open: top.open, close: segment.text, children: top.children });
|
|
5168
|
+
}
|
|
5169
|
+
} else {
|
|
5170
|
+
current().push({ type: "atom", text: segment.text });
|
|
5018
5171
|
}
|
|
5172
|
+
} else if (info.opensScope) {
|
|
5173
|
+
stack.push({ name: info.name, open: segment.text, suppressed: stack.length >= SCOPE_DEPTH_CAP, children: [] });
|
|
5174
|
+
} else {
|
|
5175
|
+
current().push({ type: "atom", text: segment.text });
|
|
5019
5176
|
}
|
|
5177
|
+
continue;
|
|
5020
5178
|
}
|
|
5021
|
-
|
|
5022
|
-
|
|
5179
|
+
const t = segment.text;
|
|
5180
|
+
let start = 0;
|
|
5181
|
+
for (let i = 0; i < t.length; i++) {
|
|
5182
|
+
const c = t.charCodeAt(i);
|
|
5183
|
+
if (c !== 10 && c !== 13) continue;
|
|
5184
|
+
if (i > start) current().push({ type: "text", text: t.slice(start, i) });
|
|
5185
|
+
const end = c === 13 && t.charCodeAt(i + 1) === 10 ? i + 2 : i + 1;
|
|
5186
|
+
unwind();
|
|
5187
|
+
root2.push({ type: "text", text: t.slice(i, end) });
|
|
5188
|
+
start = end;
|
|
5189
|
+
i = end - 1;
|
|
5190
|
+
}
|
|
5191
|
+
if (start < t.length) current().push({ type: "text", text: t.slice(start) });
|
|
5192
|
+
}
|
|
5193
|
+
unwind();
|
|
5194
|
+
return root2;
|
|
5195
|
+
}
|
|
5196
|
+
var restoreFailureInjector = null;
|
|
5197
|
+
function restore(out, atoms, mask) {
|
|
5198
|
+
if (restoreFailureInjector !== null && restoreFailureInjector(atoms)) return null;
|
|
5199
|
+
let result = "";
|
|
5200
|
+
let k = 0;
|
|
5201
|
+
let last = 0;
|
|
5202
|
+
for (; ; ) {
|
|
5203
|
+
const idx = out.indexOf(mask, last);
|
|
5204
|
+
if (idx === -1) break;
|
|
5205
|
+
if (k >= atoms.length) return null;
|
|
5206
|
+
result += out.slice(last, idx) + atoms[k];
|
|
5207
|
+
k += 1;
|
|
5208
|
+
last = idx + 1;
|
|
5209
|
+
}
|
|
5210
|
+
return result + out.slice(last);
|
|
5211
|
+
}
|
|
5212
|
+
function emitRun(nodes, mask) {
|
|
5213
|
+
let text = "";
|
|
5214
|
+
const atoms = [];
|
|
5215
|
+
for (const node of nodes) {
|
|
5216
|
+
if (node.type === "text") {
|
|
5217
|
+
text += node.text;
|
|
5218
|
+
} else if (node.type === "atom") {
|
|
5219
|
+
atoms.push(node.text);
|
|
5220
|
+
text += mask;
|
|
5221
|
+
} else {
|
|
5222
|
+
const inner = emitRun(node.children, mask);
|
|
5223
|
+
if (inner === null) return null;
|
|
5224
|
+
const transformed = transformRun(inner.text, false, false, false);
|
|
5225
|
+
const restored = restore(transformed.out, inner.atoms, mask);
|
|
5226
|
+
if (restored === null) return null;
|
|
5227
|
+
atoms.push(node.open + restored + node.close);
|
|
5228
|
+
text += mask;
|
|
5229
|
+
}
|
|
5230
|
+
}
|
|
5231
|
+
return { text, atoms };
|
|
5232
|
+
}
|
|
5233
|
+
function reportRestoreViolation() {
|
|
5234
|
+
if (false) {
|
|
5235
|
+
console.error(
|
|
5236
|
+
"[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."
|
|
5237
|
+
);
|
|
5023
5238
|
}
|
|
5024
|
-
|
|
5239
|
+
}
|
|
5240
|
+
function processSliceDefault(slice, probe, mask) {
|
|
5241
|
+
const segments = splitByProtectedRegions(slice);
|
|
5242
|
+
const parts = [];
|
|
5243
|
+
let quiescent = true;
|
|
5244
|
+
let truncatedAtSeamStart = false;
|
|
5245
|
+
let offset = 0;
|
|
5246
|
+
let i = 0;
|
|
5247
|
+
while (i < segments.length) {
|
|
5248
|
+
const segment = segments[i];
|
|
5249
|
+
if (isHardBoundary(segment.kind)) {
|
|
5250
|
+
parts.push(segment.text);
|
|
5251
|
+
offset += segment.text.length;
|
|
5252
|
+
i += 1;
|
|
5253
|
+
continue;
|
|
5254
|
+
}
|
|
5255
|
+
const runStart = offset;
|
|
5256
|
+
const runSegments = [];
|
|
5257
|
+
while (i < segments.length && !isHardBoundary(segments[i].kind)) {
|
|
5258
|
+
runSegments.push(segments[i]);
|
|
5259
|
+
offset += segments[i].text.length;
|
|
5260
|
+
i += 1;
|
|
5261
|
+
}
|
|
5262
|
+
const before = runStart === 0 ? -1 : slice.charCodeAt(runStart - 1);
|
|
5263
|
+
const runStartsAtLineStart = before === -1 || before === 10 || before === 13;
|
|
5264
|
+
const seamEligible = runStart === 0;
|
|
5265
|
+
const emitted = emitRun(buildRunTree(runSegments), mask);
|
|
5266
|
+
if (emitted === null) {
|
|
5267
|
+
reportRestoreViolation();
|
|
5268
|
+
return { ...processSliceLegacy(slice, probe), degradedReason: "restore-invariant" };
|
|
5269
|
+
}
|
|
5270
|
+
const r = transformRun(emitted.text, probe, runStartsAtLineStart, seamEligible);
|
|
5271
|
+
const restored = restore(r.out, emitted.atoms, mask);
|
|
5272
|
+
if (restored === null) {
|
|
5273
|
+
reportRestoreViolation();
|
|
5274
|
+
return { ...processSliceLegacy(slice, probe), degradedReason: "restore-invariant" };
|
|
5275
|
+
}
|
|
5276
|
+
if (r.tailSensitive) quiescent = false;
|
|
5277
|
+
if (r.truncatedAtSeamStart) truncatedAtSeamStart = true;
|
|
5278
|
+
parts.push(restored);
|
|
5279
|
+
}
|
|
5280
|
+
return { out: parts.join(""), quiescent, truncatedAtSeamStart, degradedReason: null };
|
|
5281
|
+
}
|
|
5282
|
+
function processSlice(slice, options) {
|
|
5283
|
+
if (options.legacy === true) return processSliceLegacy(slice, options.probe);
|
|
5284
|
+
return processSliceDefault(slice, options.probe, options.mask);
|
|
5025
5285
|
}
|
|
5026
5286
|
function isBlankRawLine(text, from, to) {
|
|
5027
5287
|
for (let i = from; i < to; i++) {
|
|
@@ -5037,7 +5297,7 @@ function findRawSafeCut(active) {
|
|
|
5037
5297
|
let backtickHazard = false;
|
|
5038
5298
|
let latentLt = false;
|
|
5039
5299
|
for (const segment of segments) {
|
|
5040
|
-
if (segment.
|
|
5300
|
+
if (segment.kind !== "text") {
|
|
5041
5301
|
if (segment.text.includes(">")) latentLt = false;
|
|
5042
5302
|
offset += segment.text.length;
|
|
5043
5303
|
continue;
|
|
@@ -5072,12 +5332,28 @@ function createIncrementalLatexPreprocessor(options) {
|
|
|
5072
5332
|
const freezeThreshold = options?.freezeThreshold ?? DEFAULT_FREEZE_ATTEMPT_THRESHOLD;
|
|
5073
5333
|
const onAttempt = options?.onAttempt;
|
|
5074
5334
|
const backoff = options?.backoff ?? true;
|
|
5335
|
+
const onDegrade = options?.onDegrade;
|
|
5075
5336
|
let prevSource = "";
|
|
5076
5337
|
let prevOutput = "";
|
|
5077
5338
|
let frozenSrcEnd = 0;
|
|
5078
5339
|
let frozenOut = "";
|
|
5079
5340
|
let triggered = false;
|
|
5080
5341
|
let nextAttemptLen = 0;
|
|
5342
|
+
let lineageDegraded = false;
|
|
5343
|
+
const presence = new PuaPresence();
|
|
5344
|
+
const commit = (source, out) => {
|
|
5345
|
+
prevSource = source;
|
|
5346
|
+
prevOutput = out;
|
|
5347
|
+
return out;
|
|
5348
|
+
};
|
|
5349
|
+
const legacyWhole = (source) => processSlice(source, { legacy: true, probe: false }).out;
|
|
5350
|
+
const degrade = (source, reason) => {
|
|
5351
|
+
lineageDegraded = true;
|
|
5352
|
+
frozenSrcEnd = 0;
|
|
5353
|
+
frozenOut = "";
|
|
5354
|
+
onDegrade?.(reason);
|
|
5355
|
+
return commit(source, legacyWhole(source));
|
|
5356
|
+
};
|
|
5081
5357
|
return function incrementalPreprocessLaTeX(source) {
|
|
5082
5358
|
if (source === prevSource) return prevOutput;
|
|
5083
5359
|
const isAppend = source.length > prevSource.length && source.startsWith(prevSource);
|
|
@@ -5086,16 +5362,20 @@ function createIncrementalLatexPreprocessor(options) {
|
|
|
5086
5362
|
frozenOut = "";
|
|
5087
5363
|
triggered = false;
|
|
5088
5364
|
nextAttemptLen = 0;
|
|
5365
|
+
lineageDegraded = false;
|
|
5366
|
+
presence.reset();
|
|
5367
|
+
presence.add(source, 0);
|
|
5368
|
+
} else {
|
|
5369
|
+
presence.add(source, prevSource.length);
|
|
5089
5370
|
}
|
|
5090
5371
|
if (!triggered) {
|
|
5091
5372
|
const checkFrom = isAppend ? Math.max(0, prevSource.length - 1) : 0;
|
|
5092
|
-
if (!hasLatexTrigger(source.slice(checkFrom)))
|
|
5093
|
-
prevSource = source;
|
|
5094
|
-
prevOutput = source;
|
|
5095
|
-
return source;
|
|
5096
|
-
}
|
|
5373
|
+
if (!hasLatexTrigger(source.slice(checkFrom))) return commit(source, source);
|
|
5097
5374
|
triggered = true;
|
|
5098
5375
|
}
|
|
5376
|
+
if (lineageDegraded) return commit(source, legacyWhole(source));
|
|
5377
|
+
const mask = presence.select();
|
|
5378
|
+
if (mask === null) return degrade(source, "mask-exhausted");
|
|
5099
5379
|
let active = source.slice(frozenSrcEnd);
|
|
5100
5380
|
if (active.length > freezeThreshold && active.length >= nextAttemptLen) {
|
|
5101
5381
|
const activeLength = active.length;
|
|
@@ -5110,18 +5390,20 @@ function createIncrementalLatexPreprocessor(options) {
|
|
|
5110
5390
|
};
|
|
5111
5391
|
const cut = findRawSafeCut(active);
|
|
5112
5392
|
if (cut > 0) {
|
|
5113
|
-
const candidate = processSlice(active.slice(0, cut));
|
|
5393
|
+
const candidate = processSlice(active.slice(0, cut), { probe: true, mask });
|
|
5394
|
+
if (candidate.degradedReason !== null) {
|
|
5395
|
+
onAttempt?.({ activeLength, frozenBytes: 0 });
|
|
5396
|
+
return degrade(source, candidate.degradedReason);
|
|
5397
|
+
}
|
|
5114
5398
|
if (candidate.quiescent) freeze(cut, candidate);
|
|
5115
5399
|
}
|
|
5116
5400
|
nextAttemptLen = advanced || !backoff ? 0 : active.length * 2;
|
|
5117
5401
|
onAttempt?.({ activeLength, frozenBytes });
|
|
5118
5402
|
}
|
|
5119
|
-
const tail = processSlice(active, false);
|
|
5403
|
+
const tail = processSlice(active, { probe: false, mask });
|
|
5404
|
+
if (tail.degradedReason !== null) return degrade(source, tail.degradedReason);
|
|
5120
5405
|
const head = tail.truncatedAtSeamStart ? frozenOut.replace(/\s+$/, "") : frozenOut;
|
|
5121
|
-
|
|
5122
|
-
prevSource = source;
|
|
5123
|
-
prevOutput = out;
|
|
5124
|
-
return out;
|
|
5406
|
+
return commit(source, head + tail.out);
|
|
5125
5407
|
};
|
|
5126
5408
|
}
|
|
5127
5409
|
|
|
@@ -5146,6 +5428,8 @@ function createRemendPreprocessor(options) {
|
|
|
5146
5428
|
}
|
|
5147
5429
|
export {
|
|
5148
5430
|
DEFAULT_PAYLOAD,
|
|
5431
|
+
ENGINE_PLACEHOLDER_TAGS,
|
|
5432
|
+
ENGINE_PROVENANCE_PROPERTY,
|
|
5149
5433
|
PIPELINE_STAGES,
|
|
5150
5434
|
SENTINEL_FN_CONTENT,
|
|
5151
5435
|
SENTINEL_LINK_URL,
|
|
@@ -5190,6 +5474,7 @@ export {
|
|
|
5190
5474
|
preprocessLaTeX,
|
|
5191
5475
|
rehypeFooterAdorn,
|
|
5192
5476
|
rehypeRebaseHashLinks_default as rehypeRebaseHashLinks,
|
|
5477
|
+
rehypeVerifyEngineTags,
|
|
5193
5478
|
removeComments,
|
|
5194
5479
|
sanitizeCrossChunkUrl,
|
|
5195
5480
|
sanitizeSchema,
|