@ai-react-markdown/engine 2.5.1 → 2.5.3
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/dist/index.cjs +70 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +40 -1
- package/dist/index.d.ts +40 -1
- package/dist/index.dev.cjs +70 -34
- package/dist/index.dev.cjs.map +1 -1
- package/dist/index.dev.js +68 -34
- package/dist/index.dev.js.map +1 -1
- package/dist/index.js +68 -34
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -482,6 +482,23 @@ interface FreezeScanCheckpoint {
|
|
|
482
482
|
* htmlFlowSinceBlank swallowed them — a new under-block). Sticky to the
|
|
483
483
|
* blank; a type 6/1 start on a later line of a non-real run promotes it. */
|
|
484
484
|
htmlFlowReal: boolean;
|
|
485
|
+
/** The run since the last blank was OPENED by a CommonMark type-1 block
|
|
486
|
+
* (`<script` / `<pre` / `<style` / `<textarea`). Type 1 is the one block
|
|
487
|
+
* that ends at its CLOSER line rather than at a blank, so `htmlFlowReal`
|
|
488
|
+
* being "sticky to the blank" over-ran it: the line after `</script>` is
|
|
489
|
+
* a fresh PARAGRAPH to micromark, but the scanner still treated it as
|
|
490
|
+
* raw html flow — and in a real run end tags may carry attributes, so a
|
|
491
|
+
* `</div a="b">` there was counted as a REAL close. `p <div> x </div
|
|
492
|
+
* a="b"> y` after a `</script>` line therefore froze past an element the
|
|
493
|
+
* actual parse leaves OPEN, nesting the whole rest of the document
|
|
494
|
+
* inside it (2026-08-20 soak leg 2; identical for pre/style/textarea,
|
|
495
|
+
* and correct as-is for a type-6 run, which really does reach the blank).
|
|
496
|
+
* Only set when the type-1 opener is the line that STARTED the run — a
|
|
497
|
+
* `<script>` nested inside an open type-6 block must not end it. */
|
|
498
|
+
type1FlowOpen: boolean;
|
|
499
|
+
/** The currently open raw-text element (`rawTextOpen`) was opened INLINE —
|
|
500
|
+
* in paragraph context rather than in a real html-flow run. */
|
|
501
|
+
rawTextInline: boolean;
|
|
485
502
|
}
|
|
486
503
|
/** parse5 tokenizer position inside a tag's attribute area, tracked across
|
|
487
504
|
* line endings for `tagAcrossLines` (2026-08-19 review r2 P1-2 / P2-3):
|
|
@@ -1460,6 +1477,28 @@ declare const defaultEnginePlugins: readonly AIMarkdownEnginePlugin[];
|
|
|
1460
1477
|
* `tagName === 'section'` AND presence of the `dataFootnotes` property.
|
|
1461
1478
|
*/
|
|
1462
1479
|
declare function isFootnoteSection(node: Element): boolean;
|
|
1480
|
+
/**
|
|
1481
|
+
* Whitespace-only text node. `mdast-util-to-hast`'s `state.wrap(content,
|
|
1482
|
+
* true)` interleaves `\n` text nodes between (and around) the block-level
|
|
1483
|
+
* children of an `<li>`, so any code reasoning about a list item's real
|
|
1484
|
+
* children has to look past them.
|
|
1485
|
+
*/
|
|
1486
|
+
declare function isWhitespaceText(c: ElementContent): boolean;
|
|
1487
|
+
/**
|
|
1488
|
+
* Index of the last child that is not a whitespace-only text node, or -1 if
|
|
1489
|
+
* there is none.
|
|
1490
|
+
*
|
|
1491
|
+
* Both footnote-footer paths need exactly this and for the same reason.
|
|
1492
|
+
* Appending a backref follows mdast-util-to-hast's contract — "if the tail of
|
|
1493
|
+
* the `<li>`'s content is a `<p>`, push into it, else push onto the `<li>`" —
|
|
1494
|
+
* and stripping one has to find that tail again. Read the trailing
|
|
1495
|
+
* wrap-emitted `\n` as the tail and the `<p>` path is bypassed in one case
|
|
1496
|
+
* and the wrong node stripped in the other.
|
|
1497
|
+
*
|
|
1498
|
+
* Lived in two copies until 2.5.2 (core's aggregate footer and the engine's
|
|
1499
|
+
* body extractor), one on each side of the 2.3.0 package split.
|
|
1500
|
+
*/
|
|
1501
|
+
declare function lastMeaningfulIdx(children: ElementContent[]): number;
|
|
1463
1502
|
|
|
1464
1503
|
declare function normalizeId(s: string): string;
|
|
1465
1504
|
/**
|
|
@@ -2021,4 +2060,4 @@ type RemendPreprocessorOptions = Omit<RemendOptions, 'katex' | 'inlineKatex'>;
|
|
|
2021
2060
|
*/
|
|
2022
2061
|
declare function createRemendPreprocessor(options?: RemendPreprocessorOptions): AIMDContentPreprocessor;
|
|
2023
2062
|
|
|
2024
|
-
export { type AIMDContentPreprocessor, type AIMarkdownEnginePlugin, type AIMarkdownEnginePluginName, type AdvanceOptions, type AdvanceResult, type AllowElement, type ChunkData, type Contribution, type CrossChunkHandlerOptions, DEFAULT_PAYLOAD, type DefLabelScanner, type DefLabels, type Deprecation, type EnginePluginInternals, type EnginePluginStage, type ExtractContributionsOptions, type FootnoteDef, type FreezeBoundaryOptions, type IncrementalParseState, type IncrementalStage, type LinkDef, PIPELINE_STAGES, type ParsedMarkdown, type PhantomLabels, type PipelineOptions, type PipelineStage, type RefKind, type RefRecord, type Registry, type RegistryInternal, type RehypePlugins, type RehypeRebaseHashLinksOptions, type RemarkPlugins, type RemarkRehypeOptions, type RemendPreprocessorOptions, SENTINEL_FN_CONTENT, SENTINEL_LINK_URL, SMOOTH_STREAM_PACING_PRESETS, STAGE_MEASURE_PREFIX, type SanitizeSchema, type SmoothStreamController, type SmoothStreamOptions, type SmoothStreamPacing, type SmoothStreamPacingParams, type TransformContext, type UrlAttrKey, type UrlAttrTag, type UrlTransform, advanceIncrementalParse, attributeHastChildren, buildCoreRehypePlugins, buildCoreRemarkPlugins, buildCoreRemarkRehypeOptions, buildCrossChunkHandlers, buildPhantomSuffix, buildTransform, codePointSnapshots, collectDefLabels, computeFreezeBoundary, createDefLabelScanner, createFile, createIncrementalLatexPreprocessor, createProcessor, createRegistry, createRemendPreprocessor, createSmoothStreamController, defaultEnginePlugins, defaultUrlTransform, definitionList, extendSanitizeSchema, extractContributions, extractDefBodiesFromHast, footnoteSafeId, getEnginePluginInternals, hasLoneSurrogate, highlight, isFootnoteSection, measureStage, mergeClassNameAllowlist, normalizeForMatch, normalizeId, pangu, parseStage, phantomSuffixCloser, preprocessAIMDContent, preprocessLaTeX, rehypeFooterAdorn, rehypeRebaseHashLinks, removeComments, sanitizeCrossChunkUrl, sanitizeSchema, shortenDocumentId, smartypants, sourceIdFromFootnoteLiId, splitByProtectedRegions, subscribeStageTimings, transformStage, withDefs };
|
|
2063
|
+
export { type AIMDContentPreprocessor, type AIMarkdownEnginePlugin, type AIMarkdownEnginePluginName, type AdvanceOptions, type AdvanceResult, type AllowElement, type ChunkData, type Contribution, type CrossChunkHandlerOptions, DEFAULT_PAYLOAD, type DefLabelScanner, type DefLabels, type Deprecation, type EnginePluginInternals, type EnginePluginStage, type ExtractContributionsOptions, type FootnoteDef, type FreezeBoundaryOptions, type IncrementalParseState, type IncrementalStage, type LinkDef, PIPELINE_STAGES, type ParsedMarkdown, type PhantomLabels, type PipelineOptions, type PipelineStage, type RefKind, type RefRecord, type Registry, type RegistryInternal, type RehypePlugins, type RehypeRebaseHashLinksOptions, type RemarkPlugins, type RemarkRehypeOptions, type RemendPreprocessorOptions, SENTINEL_FN_CONTENT, SENTINEL_LINK_URL, SMOOTH_STREAM_PACING_PRESETS, STAGE_MEASURE_PREFIX, type SanitizeSchema, type SmoothStreamController, type SmoothStreamOptions, type SmoothStreamPacing, type SmoothStreamPacingParams, type TransformContext, type UrlAttrKey, type UrlAttrTag, type UrlTransform, advanceIncrementalParse, attributeHastChildren, buildCoreRehypePlugins, buildCoreRemarkPlugins, buildCoreRemarkRehypeOptions, buildCrossChunkHandlers, buildPhantomSuffix, buildTransform, codePointSnapshots, collectDefLabels, computeFreezeBoundary, createDefLabelScanner, createFile, createIncrementalLatexPreprocessor, createProcessor, createRegistry, createRemendPreprocessor, createSmoothStreamController, defaultEnginePlugins, defaultUrlTransform, definitionList, extendSanitizeSchema, extractContributions, extractDefBodiesFromHast, footnoteSafeId, getEnginePluginInternals, hasLoneSurrogate, highlight, isFootnoteSection, isWhitespaceText, lastMeaningfulIdx, measureStage, mergeClassNameAllowlist, normalizeForMatch, normalizeId, pangu, parseStage, phantomSuffixCloser, preprocessAIMDContent, preprocessLaTeX, rehypeFooterAdorn, rehypeRebaseHashLinks, removeComments, sanitizeCrossChunkUrl, sanitizeSchema, shortenDocumentId, smartypants, sourceIdFromFootnoteLiId, splitByProtectedRegions, subscribeStageTimings, transformStage, withDefs };
|
package/dist/index.d.ts
CHANGED
|
@@ -482,6 +482,23 @@ interface FreezeScanCheckpoint {
|
|
|
482
482
|
* htmlFlowSinceBlank swallowed them — a new under-block). Sticky to the
|
|
483
483
|
* blank; a type 6/1 start on a later line of a non-real run promotes it. */
|
|
484
484
|
htmlFlowReal: boolean;
|
|
485
|
+
/** The run since the last blank was OPENED by a CommonMark type-1 block
|
|
486
|
+
* (`<script` / `<pre` / `<style` / `<textarea`). Type 1 is the one block
|
|
487
|
+
* that ends at its CLOSER line rather than at a blank, so `htmlFlowReal`
|
|
488
|
+
* being "sticky to the blank" over-ran it: the line after `</script>` is
|
|
489
|
+
* a fresh PARAGRAPH to micromark, but the scanner still treated it as
|
|
490
|
+
* raw html flow — and in a real run end tags may carry attributes, so a
|
|
491
|
+
* `</div a="b">` there was counted as a REAL close. `p <div> x </div
|
|
492
|
+
* a="b"> y` after a `</script>` line therefore froze past an element the
|
|
493
|
+
* actual parse leaves OPEN, nesting the whole rest of the document
|
|
494
|
+
* inside it (2026-08-20 soak leg 2; identical for pre/style/textarea,
|
|
495
|
+
* and correct as-is for a type-6 run, which really does reach the blank).
|
|
496
|
+
* Only set when the type-1 opener is the line that STARTED the run — a
|
|
497
|
+
* `<script>` nested inside an open type-6 block must not end it. */
|
|
498
|
+
type1FlowOpen: boolean;
|
|
499
|
+
/** The currently open raw-text element (`rawTextOpen`) was opened INLINE —
|
|
500
|
+
* in paragraph context rather than in a real html-flow run. */
|
|
501
|
+
rawTextInline: boolean;
|
|
485
502
|
}
|
|
486
503
|
/** parse5 tokenizer position inside a tag's attribute area, tracked across
|
|
487
504
|
* line endings for `tagAcrossLines` (2026-08-19 review r2 P1-2 / P2-3):
|
|
@@ -1460,6 +1477,28 @@ declare const defaultEnginePlugins: readonly AIMarkdownEnginePlugin[];
|
|
|
1460
1477
|
* `tagName === 'section'` AND presence of the `dataFootnotes` property.
|
|
1461
1478
|
*/
|
|
1462
1479
|
declare function isFootnoteSection(node: Element): boolean;
|
|
1480
|
+
/**
|
|
1481
|
+
* Whitespace-only text node. `mdast-util-to-hast`'s `state.wrap(content,
|
|
1482
|
+
* true)` interleaves `\n` text nodes between (and around) the block-level
|
|
1483
|
+
* children of an `<li>`, so any code reasoning about a list item's real
|
|
1484
|
+
* children has to look past them.
|
|
1485
|
+
*/
|
|
1486
|
+
declare function isWhitespaceText(c: ElementContent): boolean;
|
|
1487
|
+
/**
|
|
1488
|
+
* Index of the last child that is not a whitespace-only text node, or -1 if
|
|
1489
|
+
* there is none.
|
|
1490
|
+
*
|
|
1491
|
+
* Both footnote-footer paths need exactly this and for the same reason.
|
|
1492
|
+
* Appending a backref follows mdast-util-to-hast's contract — "if the tail of
|
|
1493
|
+
* the `<li>`'s content is a `<p>`, push into it, else push onto the `<li>`" —
|
|
1494
|
+
* and stripping one has to find that tail again. Read the trailing
|
|
1495
|
+
* wrap-emitted `\n` as the tail and the `<p>` path is bypassed in one case
|
|
1496
|
+
* and the wrong node stripped in the other.
|
|
1497
|
+
*
|
|
1498
|
+
* Lived in two copies until 2.5.2 (core's aggregate footer and the engine's
|
|
1499
|
+
* body extractor), one on each side of the 2.3.0 package split.
|
|
1500
|
+
*/
|
|
1501
|
+
declare function lastMeaningfulIdx(children: ElementContent[]): number;
|
|
1463
1502
|
|
|
1464
1503
|
declare function normalizeId(s: string): string;
|
|
1465
1504
|
/**
|
|
@@ -2021,4 +2060,4 @@ type RemendPreprocessorOptions = Omit<RemendOptions, 'katex' | 'inlineKatex'>;
|
|
|
2021
2060
|
*/
|
|
2022
2061
|
declare function createRemendPreprocessor(options?: RemendPreprocessorOptions): AIMDContentPreprocessor;
|
|
2023
2062
|
|
|
2024
|
-
export { type AIMDContentPreprocessor, type AIMarkdownEnginePlugin, type AIMarkdownEnginePluginName, type AdvanceOptions, type AdvanceResult, type AllowElement, type ChunkData, type Contribution, type CrossChunkHandlerOptions, DEFAULT_PAYLOAD, type DefLabelScanner, type DefLabels, type Deprecation, type EnginePluginInternals, type EnginePluginStage, type ExtractContributionsOptions, type FootnoteDef, type FreezeBoundaryOptions, type IncrementalParseState, type IncrementalStage, type LinkDef, PIPELINE_STAGES, type ParsedMarkdown, type PhantomLabels, type PipelineOptions, type PipelineStage, type RefKind, type RefRecord, type Registry, type RegistryInternal, type RehypePlugins, type RehypeRebaseHashLinksOptions, type RemarkPlugins, type RemarkRehypeOptions, type RemendPreprocessorOptions, SENTINEL_FN_CONTENT, SENTINEL_LINK_URL, SMOOTH_STREAM_PACING_PRESETS, STAGE_MEASURE_PREFIX, type SanitizeSchema, type SmoothStreamController, type SmoothStreamOptions, type SmoothStreamPacing, type SmoothStreamPacingParams, type TransformContext, type UrlAttrKey, type UrlAttrTag, type UrlTransform, advanceIncrementalParse, attributeHastChildren, buildCoreRehypePlugins, buildCoreRemarkPlugins, buildCoreRemarkRehypeOptions, buildCrossChunkHandlers, buildPhantomSuffix, buildTransform, codePointSnapshots, collectDefLabels, computeFreezeBoundary, createDefLabelScanner, createFile, createIncrementalLatexPreprocessor, createProcessor, createRegistry, createRemendPreprocessor, createSmoothStreamController, defaultEnginePlugins, defaultUrlTransform, definitionList, extendSanitizeSchema, extractContributions, extractDefBodiesFromHast, footnoteSafeId, getEnginePluginInternals, hasLoneSurrogate, highlight, isFootnoteSection, measureStage, mergeClassNameAllowlist, normalizeForMatch, normalizeId, pangu, parseStage, phantomSuffixCloser, preprocessAIMDContent, preprocessLaTeX, rehypeFooterAdorn, rehypeRebaseHashLinks, removeComments, sanitizeCrossChunkUrl, sanitizeSchema, shortenDocumentId, smartypants, sourceIdFromFootnoteLiId, splitByProtectedRegions, subscribeStageTimings, transformStage, withDefs };
|
|
2063
|
+
export { type AIMDContentPreprocessor, type AIMarkdownEnginePlugin, type AIMarkdownEnginePluginName, type AdvanceOptions, type AdvanceResult, type AllowElement, type ChunkData, type Contribution, type CrossChunkHandlerOptions, DEFAULT_PAYLOAD, type DefLabelScanner, type DefLabels, type Deprecation, type EnginePluginInternals, type EnginePluginStage, type ExtractContributionsOptions, type FootnoteDef, type FreezeBoundaryOptions, type IncrementalParseState, type IncrementalStage, type LinkDef, PIPELINE_STAGES, type ParsedMarkdown, type PhantomLabels, type PipelineOptions, type PipelineStage, type RefKind, type RefRecord, type Registry, type RegistryInternal, type RehypePlugins, type RehypeRebaseHashLinksOptions, type RemarkPlugins, type RemarkRehypeOptions, type RemendPreprocessorOptions, SENTINEL_FN_CONTENT, SENTINEL_LINK_URL, SMOOTH_STREAM_PACING_PRESETS, STAGE_MEASURE_PREFIX, type SanitizeSchema, type SmoothStreamController, type SmoothStreamOptions, type SmoothStreamPacing, type SmoothStreamPacingParams, type TransformContext, type UrlAttrKey, type UrlAttrTag, type UrlTransform, advanceIncrementalParse, attributeHastChildren, buildCoreRehypePlugins, buildCoreRemarkPlugins, buildCoreRemarkRehypeOptions, buildCrossChunkHandlers, buildPhantomSuffix, buildTransform, codePointSnapshots, collectDefLabels, computeFreezeBoundary, createDefLabelScanner, createFile, createIncrementalLatexPreprocessor, createProcessor, createRegistry, createRemendPreprocessor, createSmoothStreamController, defaultEnginePlugins, defaultUrlTransform, definitionList, extendSanitizeSchema, extractContributions, extractDefBodiesFromHast, footnoteSafeId, getEnginePluginInternals, hasLoneSurrogate, highlight, isFootnoteSection, isWhitespaceText, lastMeaningfulIdx, measureStage, mergeClassNameAllowlist, normalizeForMatch, normalizeId, pangu, parseStage, phantomSuffixCloser, preprocessAIMDContent, preprocessLaTeX, rehypeFooterAdorn, rehypeRebaseHashLinks, removeComments, sanitizeCrossChunkUrl, sanitizeSchema, shortenDocumentId, smartypants, sourceIdFromFootnoteLiId, splitByProtectedRegions, subscribeStageTimings, transformStage, withDefs };
|
package/dist/index.dev.cjs
CHANGED
|
@@ -65,6 +65,8 @@ __export(src_exports, {
|
|
|
65
65
|
hasLoneSurrogate: () => hasLoneSurrogate,
|
|
66
66
|
highlight: () => highlight,
|
|
67
67
|
isFootnoteSection: () => isFootnoteSection,
|
|
68
|
+
isWhitespaceText: () => isWhitespaceText,
|
|
69
|
+
lastMeaningfulIdx: () => lastMeaningfulIdx,
|
|
68
70
|
measureStage: () => measureStage,
|
|
69
71
|
mergeClassNameAllowlist: () => mergeClassNameAllowlist,
|
|
70
72
|
normalizeForMatch: () => normalizeForMatch,
|
|
@@ -268,6 +270,26 @@ var import_micromark_util_html_tag_name = require("micromark-util-html-tag-name"
|
|
|
268
270
|
var import_micromark_util_normalize_identifier = require("micromark-util-normalize-identifier");
|
|
269
271
|
var TYPE6_NAMES = new Set(import_micromark_util_html_tag_name.htmlBlockNames);
|
|
270
272
|
var TABLE_PART_NAMES = /* @__PURE__ */ new Set(["td", "th", "tr", "tbody", "thead", "tfoot", "caption", "col", "colgroup"]);
|
|
273
|
+
var DOCUMENT_STRUCTURE_NAMES = /* @__PURE__ */ new Set(["html", "head", "body", "frameset"]);
|
|
274
|
+
var RETROACTIVE_OPENERS = [
|
|
275
|
+
"<!doctype",
|
|
276
|
+
"<html",
|
|
277
|
+
"<head",
|
|
278
|
+
"<body",
|
|
279
|
+
"<frameset",
|
|
280
|
+
"</html",
|
|
281
|
+
"</head",
|
|
282
|
+
"</body",
|
|
283
|
+
"</frameset"
|
|
284
|
+
];
|
|
285
|
+
function tailCarriesRetroactive(text) {
|
|
286
|
+
const lower = text.toLowerCase();
|
|
287
|
+
for (let i = lower.indexOf("<"); i !== -1; i = lower.indexOf("<", i + 1)) {
|
|
288
|
+
const rest = lower.slice(i);
|
|
289
|
+
for (const op of RETROACTIVE_OPENERS) if (rest.startsWith(op)) return true;
|
|
290
|
+
}
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
271
293
|
var HTML_BREAKOUT_TAGS = /* @__PURE__ */ new Set([
|
|
272
294
|
"b",
|
|
273
295
|
"big",
|
|
@@ -333,6 +355,7 @@ var RAW_TEXT_ELEMENTS = /* @__PURE__ */ new Set([
|
|
|
333
355
|
]);
|
|
334
356
|
var TYPE6_START_RE = /^<\/?([A-Za-z][A-Za-z0-9-]*)(?:[ \t\r]|\/?>|$)/;
|
|
335
357
|
var TYPE1_START_RE = /^<(script|pre|style|textarea)(?:[ \t\r]|>|$)/i;
|
|
358
|
+
var TYPE1_CLOSE_RE = /<\/(?:script|pre|style|textarea)>/i;
|
|
336
359
|
var TYPE7_LINE_RE = /^(?:<[A-Za-z][A-Za-z0-9-]*(?:[ \t\r][^>]*|\/)?>|<\/[A-Za-z][A-Za-z0-9-]*[ \t\r]*>)[ \t\r]*$/;
|
|
337
360
|
var t7Name = (line) => /^<\/?([A-Za-z][A-Za-z0-9-]*)/.exec(line)[1];
|
|
338
361
|
var VOID_TAGS = /* @__PURE__ */ new Set([
|
|
@@ -508,7 +531,9 @@ function freshCheckpoint(defListEnabled, mathFlow, referenceTaint) {
|
|
|
508
531
|
tagAcrossLines: false,
|
|
509
532
|
tagAcrossLinesIndent: 0,
|
|
510
533
|
tagAcrossLinesState: "outside",
|
|
511
|
-
htmlFlowReal: false
|
|
534
|
+
htmlFlowReal: false,
|
|
535
|
+
type1FlowOpen: false,
|
|
536
|
+
rawTextInline: false
|
|
512
537
|
};
|
|
513
538
|
}
|
|
514
539
|
function isPlausibleLinkDefRest(rest) {
|
|
@@ -653,8 +678,9 @@ function computeFreezeBoundary(text, options, resume) {
|
|
|
653
678
|
if (tailLine) return !canBecomeDdLine(tailLine.text, false);
|
|
654
679
|
return false;
|
|
655
680
|
};
|
|
681
|
+
const tailRetroactive = tailLine !== null && tailCarriesRetroactive(tailLine.text);
|
|
656
682
|
let boundary = 0;
|
|
657
|
-
for (let i = cp.candidates.length - 1; i >= 0; i--) {
|
|
683
|
+
for (let i = cp.candidates.length - 1; i >= 0 && !tailRetroactive; i--) {
|
|
658
684
|
const c = cp.candidates[i];
|
|
659
685
|
if (!c.htmlBalanced || c.hazard || c.seamRisk) continue;
|
|
660
686
|
if (c.offset > cp.phasePoisonedAt) continue;
|
|
@@ -738,8 +764,10 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
738
764
|
cp.rawTextOpen = null;
|
|
739
765
|
} else if (!closing && RAW_TEXT_ELEMENTS.has(tag) && htmlRulesApply()) {
|
|
740
766
|
cp.rawTextOpen = tag;
|
|
767
|
+
cp.rawTextInline = !cp.htmlFlowReal;
|
|
741
768
|
if (tag === "plaintext") cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
|
|
742
769
|
}
|
|
770
|
+
if (DOCUMENT_STRUCTURE_NAMES.has(tag)) cp.phasePoisonedAt = 0;
|
|
743
771
|
if (closing) {
|
|
744
772
|
const count = cp.tagBalance.get(tag) ?? 0;
|
|
745
773
|
if (count > 0) {
|
|
@@ -850,15 +878,22 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
850
878
|
cp.candidates.push({
|
|
851
879
|
offset: Math.min(ln.end + 1, text.length),
|
|
852
880
|
blankRun: cp.blankRun,
|
|
853
|
-
|
|
881
|
+
// `type1FlowOpen`: an unterminated type-1 block swallows this blank
|
|
882
|
+
// and everything after it as RAW content, so nothing here is a block
|
|
883
|
+
// boundary at all. Its tags are invisible to the balance scan
|
|
884
|
+
// (`rawTextOpen` suppresses them), which is exactly why `openTotal`
|
|
885
|
+
// reads 0 and the candidate looked safe.
|
|
886
|
+
htmlBalanced: cp.openTotal === 0 && !cp.commentOpen && !cp.piOpen && !cp.declOpen && !cp.cdataOpen && !cp.bogusOpen && !cp.type1FlowOpen,
|
|
854
887
|
hazard: cp.hazardVerdict,
|
|
855
888
|
seamRisk: cp.htmlSeamPending,
|
|
856
889
|
defListSettled: null
|
|
857
890
|
});
|
|
858
891
|
cp.paragraphHasUnpairedRun = false;
|
|
859
892
|
cp.openBracket = null;
|
|
860
|
-
cp.
|
|
861
|
-
|
|
893
|
+
if (!cp.type1FlowOpen) {
|
|
894
|
+
cp.htmlFlowSinceBlank = false;
|
|
895
|
+
cp.htmlFlowReal = false;
|
|
896
|
+
}
|
|
862
897
|
cp.prevLineBlank = true;
|
|
863
898
|
cp.prevLineWasText = false;
|
|
864
899
|
cp.prevLineWasValidDef = false;
|
|
@@ -872,7 +907,9 @@ function processConfirmedLine(cp, ln, text) {
|
|
|
872
907
|
}
|
|
873
908
|
const tagStart = ln.indent <= 3 ? /^<\/?([A-Za-z][A-Za-z0-9-]*)/.exec(mdTrimStart(ln.text)) : null;
|
|
874
909
|
if (tagStart) {
|
|
910
|
+
const noRealBlockOpen = !cp.htmlFlowReal;
|
|
875
911
|
cp.htmlFlowSinceBlank = true;
|
|
912
|
+
if (noRealBlockOpen && TYPE1_START_RE.test(mdTrimStart(ln.text))) cp.type1FlowOpen = true;
|
|
876
913
|
if (!TYPE6_NAMES.has(tagStart[1].toLowerCase())) cp.hazardVerdict = true;
|
|
877
914
|
if (!cp.htmlFlowReal) {
|
|
878
915
|
const t = mdTrimStart(ln.text);
|
|
@@ -1023,6 +1060,7 @@ ${cont(scanText)}` };
|
|
|
1023
1060
|
pos = pi + 2;
|
|
1024
1061
|
} else {
|
|
1025
1062
|
rawSpans.push([decl, decl + 2]);
|
|
1063
|
+
if (ln.indent <= 3 && /^doctype/i.test(scanText.slice(decl + 2))) cp.phasePoisonedAt = 0;
|
|
1026
1064
|
cp.declOpen = true;
|
|
1027
1065
|
pos = decl + 2;
|
|
1028
1066
|
}
|
|
@@ -1103,7 +1141,10 @@ ${cont(scanText)}` };
|
|
|
1103
1141
|
TAG_OR_COMMENT_RE.lastIndex = gt + 1;
|
|
1104
1142
|
}
|
|
1105
1143
|
}
|
|
1106
|
-
if (closing && !cp.htmlFlowReal && !/^\s*$/.test(attrs))
|
|
1144
|
+
if (closing && !cp.htmlFlowReal && !/^\s*$/.test(attrs)) {
|
|
1145
|
+
TAG_OR_COMMENT_RE.lastIndex = m.index + 2 + m[2].length;
|
|
1146
|
+
continue;
|
|
1147
|
+
}
|
|
1107
1148
|
const selfClosing = /\/\s*$/.test(attrs);
|
|
1108
1149
|
if (VOID_TAGS.has(tag) || selfClosing && honoursSelfClosing(tag)) continue;
|
|
1109
1150
|
applyTag(tag, closing);
|
|
@@ -1184,6 +1225,14 @@ ${cont(scanText)}` };
|
|
|
1184
1225
|
cp.htmlSeamPending = true;
|
|
1185
1226
|
}
|
|
1186
1227
|
}
|
|
1228
|
+
if (cp.rawTextOpen !== null && cp.rawTextInline) {
|
|
1229
|
+
cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
|
|
1230
|
+
}
|
|
1231
|
+
if (cp.type1FlowOpen && TYPE1_CLOSE_RE.test(ln.text)) {
|
|
1232
|
+
cp.type1FlowOpen = false;
|
|
1233
|
+
cp.htmlFlowSinceBlank = false;
|
|
1234
|
+
cp.htmlFlowReal = false;
|
|
1235
|
+
}
|
|
1187
1236
|
cp.blankRun = 0;
|
|
1188
1237
|
cp.prevLineBlank = false;
|
|
1189
1238
|
cp.prevLineWasText = true;
|
|
@@ -1199,6 +1248,15 @@ function isFootnoteSection(node) {
|
|
|
1199
1248
|
const props = node.properties;
|
|
1200
1249
|
return props?.dataFootnotes !== void 0;
|
|
1201
1250
|
}
|
|
1251
|
+
function isWhitespaceText(c) {
|
|
1252
|
+
return c.type === "text" && /^\s*$/.test(c.value);
|
|
1253
|
+
}
|
|
1254
|
+
function lastMeaningfulIdx(children) {
|
|
1255
|
+
for (let i = children.length - 1; i >= 0; i--) {
|
|
1256
|
+
if (!isWhitespaceText(children[i])) return i;
|
|
1257
|
+
}
|
|
1258
|
+
return -1;
|
|
1259
|
+
}
|
|
1202
1260
|
|
|
1203
1261
|
// src/components/incrementalParse/attributeHastChildren.ts
|
|
1204
1262
|
function attributeHastChildren(mdast, hast, stopAt = Infinity) {
|
|
@@ -1981,16 +2039,6 @@ function isBackrefAnchor(c) {
|
|
|
1981
2039
|
if (el.tagName !== "a") return false;
|
|
1982
2040
|
return Boolean(el.properties && "dataFootnoteBackref" in el.properties);
|
|
1983
2041
|
}
|
|
1984
|
-
function isWhitespaceText(c) {
|
|
1985
|
-
if (c.type !== "text") return false;
|
|
1986
|
-
return /^\s*$/.test(c.value);
|
|
1987
|
-
}
|
|
1988
|
-
function lastMeaningfulIdx(children) {
|
|
1989
|
-
for (let i = children.length - 1; i >= 0; i--) {
|
|
1990
|
-
if (!isWhitespaceText(children[i])) return i;
|
|
1991
|
-
}
|
|
1992
|
-
return -1;
|
|
1993
|
-
}
|
|
1994
2042
|
function dropTrailingBackrefs(children) {
|
|
1995
2043
|
let trailingWsStart = children.length;
|
|
1996
2044
|
while (trailingWsStart > 0 && isWhitespaceText(children[trailingWsStart - 1])) {
|
|
@@ -4669,21 +4717,7 @@ function convertSingleToDoubleDollar(text) {
|
|
|
4669
4717
|
}
|
|
4670
4718
|
function preprocessLaTeX(str) {
|
|
4671
4719
|
if (!hasLatexTrigger(str)) return str;
|
|
4672
|
-
|
|
4673
|
-
const result = segments.map((segment) => {
|
|
4674
|
-
if (segment.isCode) return segment.text;
|
|
4675
|
-
let text = segment.text;
|
|
4676
|
-
text = escapeMhchemCommands(text);
|
|
4677
|
-
text = escapeCurrencyDollarSigns(text);
|
|
4678
|
-
text = convertLatexDelimiters(text);
|
|
4679
|
-
text = escapeLatexPipes(text);
|
|
4680
|
-
text = escapeLatexPipesInUnclosed(text);
|
|
4681
|
-
text = escapeTextUnderscores(text);
|
|
4682
|
-
text = convertSingleToDoubleDollar(text);
|
|
4683
|
-
text = truncateUnclosedLatexBlock(text);
|
|
4684
|
-
return text;
|
|
4685
|
-
});
|
|
4686
|
-
return result.join("");
|
|
4720
|
+
return processSlice(str, false).out;
|
|
4687
4721
|
}
|
|
4688
4722
|
function hasLatexTrigger(str) {
|
|
4689
4723
|
return str.includes("$") || str.includes("\\[") || str.includes("\\(");
|
|
@@ -4712,7 +4746,7 @@ function hasUnclosedTextCommand(text) {
|
|
|
4712
4746
|
}
|
|
4713
4747
|
var RESIDUAL_OPEN_BRACKET_RE = /(?<!!)\\\[/;
|
|
4714
4748
|
var LEADING_DOUBLE_DOLLAR_RE = /^\s*\$\$/;
|
|
4715
|
-
function
|
|
4749
|
+
function processSlice(slice, probe = true) {
|
|
4716
4750
|
const segments = splitByProtectedRegions(slice);
|
|
4717
4751
|
const parts = [];
|
|
4718
4752
|
let quiescent = true;
|
|
@@ -4836,13 +4870,13 @@ function createIncrementalLatexPreprocessor(options) {
|
|
|
4836
4870
|
};
|
|
4837
4871
|
const cut = findRawSafeCut(active);
|
|
4838
4872
|
if (cut > 0) {
|
|
4839
|
-
const candidate =
|
|
4873
|
+
const candidate = processSlice(active.slice(0, cut));
|
|
4840
4874
|
if (candidate.quiescent) freeze(cut, candidate);
|
|
4841
4875
|
}
|
|
4842
4876
|
nextAttemptLen = advanced || !backoff ? 0 : active.length * 2;
|
|
4843
4877
|
onAttempt?.({ activeLength, frozenBytes });
|
|
4844
4878
|
}
|
|
4845
|
-
const tail =
|
|
4879
|
+
const tail = processSlice(active, false);
|
|
4846
4880
|
const head = tail.truncatedAtSeamStart ? frozenOut.replace(/\s+$/, "") : frozenOut;
|
|
4847
4881
|
const out = head + tail.out;
|
|
4848
4882
|
prevSource = source;
|
|
@@ -4907,6 +4941,8 @@ function createRemendPreprocessor(options) {
|
|
|
4907
4941
|
hasLoneSurrogate,
|
|
4908
4942
|
highlight,
|
|
4909
4943
|
isFootnoteSection,
|
|
4944
|
+
isWhitespaceText,
|
|
4945
|
+
lastMeaningfulIdx,
|
|
4910
4946
|
measureStage,
|
|
4911
4947
|
mergeClassNameAllowlist,
|
|
4912
4948
|
normalizeForMatch,
|