@ai-matrx/content-ir 0.18.3 → 0.18.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/dist/index.cjs +184 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +182 -31
- package/dist/index.js.map +1 -1
- package/dist/source.cjs +184 -30
- package/dist/source.cjs.map +1 -1
- package/dist/source.d.cts +37 -2
- package/dist/source.d.ts +37 -2
- package/dist/source.js +182 -31
- package/dist/source.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.18.5
|
|
4
|
+
|
|
5
|
+
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
6
|
+
`git diff npm/content-ir-core/v0.18.4..npm/content-ir-core/v0.18.5 -- apps/shared/content-ir-core`).
|
|
7
|
+
No source changes intended and no consumer action required.
|
|
8
|
+
|
|
9
|
+
## 0.18.4
|
|
10
|
+
|
|
11
|
+
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
12
|
+
`git diff npm/content-ir-core/v0.18.3..npm/content-ir-core/v0.18.4 -- apps/shared/content-ir-core`).
|
|
13
|
+
No source changes intended and no consumer action required.
|
|
14
|
+
|
|
15
|
+
## Unreleased
|
|
16
|
+
|
|
17
|
+
**`/source`: THE escaped-bracket rule** (verify-RC-B4 R3-2). `\[ … \]` is a
|
|
18
|
+
display-math island only when its content is real TeX — a command, `^ { } =
|
|
19
|
+
< > +`, or a subscript on a letter — and the `\[` is not an index on an
|
|
20
|
+
identifier. Everything else is CommonMark's escaped brackets and stays text:
|
|
21
|
+
citations `\[1\]`, dates `\[2026-09-25\]`, task boxes `- \[x\]`, `arr\[i\]`,
|
|
22
|
+
editorial `\[was\]`, placeholders `\[site name\]`. New export
|
|
23
|
+
`isEscapedBracketMath(content, before)`; the tokenizer asks it. Shared vectors:
|
|
24
|
+
`__tests__/fixtures/escaped-bracket-vectors.json` (7 of 11 red before).
|
|
25
|
+
No Python reader draws `\[ \]` math today (matrx-ai has no bracket-math
|
|
26
|
+
detector), so the vectors are the contract for any future twin.
|
|
27
|
+
- Consumer action: the renderer's math normalizer and the editor ask
|
|
28
|
+
`isEscapedBracketMath` instead of their own bracket rules (matrx-frontend
|
|
29
|
+
`components/markdown-core/math-normalizer.ts`).
|
|
30
|
+
|
|
3
31
|
## 0.18.3
|
|
4
32
|
|
|
5
33
|
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
package/dist/index.cjs
CHANGED
|
@@ -5296,6 +5296,7 @@ var FenceReader = class {
|
|
|
5296
5296
|
function closeFence(src, open, opener) {
|
|
5297
5297
|
const first = readFence(src, open, new FenceReader(opener));
|
|
5298
5298
|
if (first.closed || !first.reader.sawNested || first.reader.nestedDepth <= 0) return { line: first.line, closed: first.closed };
|
|
5299
|
+
if (src.streaming) return { line: first.line, closed: false };
|
|
5299
5300
|
const strict = readFence(src, open, new FenceReader(opener, { nesting: false }));
|
|
5300
5301
|
return { line: strict.line, closed: strict.closed };
|
|
5301
5302
|
}
|
|
@@ -5559,6 +5560,8 @@ function fenceLineKinds(text) {
|
|
|
5559
5560
|
function pendingCodeSpanStart(text) {
|
|
5560
5561
|
const n = text.length;
|
|
5561
5562
|
if (n === 0 || /\n[ \t]*\n[ \t]*$/.test(text)) return -1;
|
|
5563
|
+
const lastLine = text.slice(text.lastIndexOf("\n") + 1);
|
|
5564
|
+
if (lastLine && /^(?: {0,3}>[ \t]?)*[ \t]*$/.test(lastLine)) return pendingCodeSpanStart(`${text}x`);
|
|
5562
5565
|
const s = scan(text);
|
|
5563
5566
|
const para = s.pendingPara;
|
|
5564
5567
|
if (s.endsInFence || para === -1) return -1;
|
|
@@ -5705,13 +5708,26 @@ var MATH_SHAPE_CHARS = /^[A-Za-z0-9'\s(),.*\/-]+$/;
|
|
|
5705
5708
|
function isSingleDollarMath(content, after) {
|
|
5706
5709
|
if (!content || content.length > 400) return false;
|
|
5707
5710
|
if (/^\s/.test(content) || /\s$/.test(content)) return false;
|
|
5708
|
-
if (after !== void 0 &&
|
|
5711
|
+
if (after !== void 0 && /^[0-9]/.test(after)) return false;
|
|
5712
|
+
if (isVariableChain(content, after)) return false;
|
|
5709
5713
|
if (/(?:^|[^\\])%/.test(content)) return false;
|
|
5710
5714
|
if (/^[)\]}"/]/.test(content) || /[(\[{":;,/]$/.test(content)) return false;
|
|
5711
|
-
if (/^[0-9]/.test(content) && after !== void 0 &&
|
|
5715
|
+
if (/^[0-9]/.test(content) && after !== void 0 && /^[A-Za-z]/.test(after)) return false;
|
|
5712
5716
|
if (isMathPlaceholder(content)) return false;
|
|
5713
5717
|
return TEX_SIGNAL.test(content) || !readsAsProse(content);
|
|
5714
5718
|
}
|
|
5719
|
+
var IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
5720
|
+
var MATH_SUFFIX = /^(?:s|es|th|st|nd|rd)$/i;
|
|
5721
|
+
function isVariableChain(content, after) {
|
|
5722
|
+
if (/^\{[A-Za-z_][\w.]*\}$/.test(content)) return true;
|
|
5723
|
+
if (!after) return false;
|
|
5724
|
+
if (after[0] === "{") return IDENTIFIER.test(content);
|
|
5725
|
+
const run = /^[A-Za-z0-9_]+/.exec(after)?.[0];
|
|
5726
|
+
if (!run) return false;
|
|
5727
|
+
if (after.length === 1) return false;
|
|
5728
|
+
if (/^[A-Za-z_][A-Za-z0-9_]*[.@-]$/.test(content)) return true;
|
|
5729
|
+
return IDENTIFIER.test(content) && !MATH_SUFFIX.test(run);
|
|
5730
|
+
}
|
|
5715
5731
|
var FUNCTION_NAMES = /* @__PURE__ */ new Set([
|
|
5716
5732
|
"sin",
|
|
5717
5733
|
"cos",
|
|
@@ -5755,6 +5771,12 @@ function isMathShape(content) {
|
|
|
5755
5771
|
if (/[A-Za-z]'+[A-Za-z]/.test(content) || /(?:^|[\s(,])[A-Za-z]\.(?:[A-Za-z]\.|\s|$)/.test(content)) return false;
|
|
5756
5772
|
return /[A-Za-z]'*\(|[A-Za-z]'|\b[A-Za-z]\s+[A-Za-z]\b|\([^)]*[A-Za-z][^)]*\)/.test(content);
|
|
5757
5773
|
}
|
|
5774
|
+
var AFTER_WINDOW = 32;
|
|
5775
|
+
function singleDollarAfter(text, close) {
|
|
5776
|
+
const rest = text.slice(close + 1, close + 1 + AFTER_WINDOW);
|
|
5777
|
+
return rest.length < AFTER_WINDOW ? `${rest}
|
|
5778
|
+
` : rest;
|
|
5779
|
+
}
|
|
5758
5780
|
function singleDollarMathEnd(text, open, limit = text.length) {
|
|
5759
5781
|
const bound = Math.min(limit, open + 403);
|
|
5760
5782
|
let close = -1;
|
|
@@ -5772,7 +5794,13 @@ function singleDollarMathEnd(text, open, limit = text.length) {
|
|
|
5772
5794
|
}
|
|
5773
5795
|
if (close === -1 || text[close + 1] === "$") return -1;
|
|
5774
5796
|
const content = text.slice(open + 1, close);
|
|
5775
|
-
return isSingleDollarMath(content, text
|
|
5797
|
+
return isSingleDollarMath(content, singleDollarAfter(text, close)) ? close + 1 : -1;
|
|
5798
|
+
}
|
|
5799
|
+
var BRACKET_TEX_SIGNAL = /\\[A-Za-z]+|[\^{}=<>+]|_\{|(?:^|[^A-Za-z0-9])[A-Za-z]_[A-Za-z0-9](?![A-Za-z0-9])/;
|
|
5800
|
+
function isEscapedBracketMath(content, before) {
|
|
5801
|
+
if (!content.trim()) return false;
|
|
5802
|
+
if (before !== void 0 && /[A-Za-z0-9_)\]]/.test(before)) return false;
|
|
5803
|
+
return BRACKET_TEX_SIGNAL.test(content);
|
|
5776
5804
|
}
|
|
5777
5805
|
|
|
5778
5806
|
// source/xml-tag.ts
|
|
@@ -6137,18 +6165,14 @@ var Tokenizer = class {
|
|
|
6137
6165
|
/**
|
|
6138
6166
|
* Streaming: an open last line that begins with `{` is undecided — each new
|
|
6139
6167
|
* byte can balance or unbalance its braces and flip the whole line between
|
|
6140
|
-
* prose and a JSON island —
|
|
6141
|
-
* HTML tag
|
|
6168
|
+
* prose and a JSON island — so it is provisional until it ends (G5).
|
|
6169
|
+
* (A lone HTML tag on that line is held by {@link holdUndecidedTail}.)
|
|
6142
6170
|
*/
|
|
6143
6171
|
markOpenJsonTail() {
|
|
6144
6172
|
const last = this.lineStarts.length - 1;
|
|
6145
6173
|
if (!this.isOpenTail(last)) return;
|
|
6146
|
-
|
|
6147
|
-
|
|
6148
|
-
const oneTag = t.startsWith("<") ? readXmlTag(t, 0) : null;
|
|
6149
|
-
const loneTag = !!oneTag && oneTag.raw === t && ALLOWED_RAW_HTML_TAGS.has(oneTag.tagName.toLowerCase());
|
|
6150
|
-
if (t.startsWith("{") || loneTag) {
|
|
6151
|
-
this.provisionalFrom = Math.min(this.provisionalFrom, start);
|
|
6174
|
+
if (this.lineText(last).trim().startsWith("{")) {
|
|
6175
|
+
this.provisionalFrom = Math.min(this.provisionalFrom, this.lineStarts[last]);
|
|
6152
6176
|
}
|
|
6153
6177
|
}
|
|
6154
6178
|
/**
|
|
@@ -6181,11 +6205,22 @@ var Tokenizer = class {
|
|
|
6181
6205
|
/** Streaming only: a paragraph ending at `pe` may still be continued by a line not yet arrived. */
|
|
6182
6206
|
paragraphMayGrow(pe) {
|
|
6183
6207
|
if (!this.streaming) return false;
|
|
6208
|
+
if (this.undecidedBreaks.has(pe)) return true;
|
|
6184
6209
|
const rest = this.n - pe;
|
|
6185
6210
|
if (rest === 0) return true;
|
|
6186
6211
|
const tail = this.text.slice(pe);
|
|
6187
|
-
return
|
|
6212
|
+
return /^(?:\r\n|\r|\n)[ \t]*$/.test(tail);
|
|
6213
|
+
}
|
|
6214
|
+
/**
|
|
6215
|
+
* Streaming: an open block that may still turn back into prose — a `$$`
|
|
6216
|
+
* pair whose closer is on the open last line (prose after it makes it
|
|
6217
|
+
* inline), or a JSON head whose braces have not balanced (it may never parse).
|
|
6218
|
+
*/
|
|
6219
|
+
mayDissolve(block) {
|
|
6220
|
+
return this.streaming && !block.complete && (block.type === "math_block" || block.type === "json");
|
|
6188
6221
|
}
|
|
6222
|
+
/** Streaming: paragraph ends where an undecided, dissolvable block cut them short. */
|
|
6223
|
+
undecidedBreaks = /* @__PURE__ */ new Set();
|
|
6189
6224
|
/** Streaming only: the final line, still waiting for its terminator. */
|
|
6190
6225
|
isOpenTail(k) {
|
|
6191
6226
|
return this.streaming && k === this.lineStarts.length - 1 && (this.lineEnds[k] === this.contentEnds[k] || this.pendingCR);
|
|
@@ -6234,8 +6269,103 @@ var Tokenizer = class {
|
|
|
6234
6269
|
}
|
|
6235
6270
|
pos = this.paragraph(pos, li);
|
|
6236
6271
|
}
|
|
6272
|
+
if (this.streaming) this.holdUndecidedTail();
|
|
6237
6273
|
return this.blocks;
|
|
6238
6274
|
}
|
|
6275
|
+
/**
|
|
6276
|
+
* Streaming: settle nothing the next bytes can still change (verify-RC-B3 F3).
|
|
6277
|
+
*
|
|
6278
|
+
* 1. A block island that ends on the open last line is undecided — the next
|
|
6279
|
+
* bytes on that line can re-read it or dissolve it (`<!--@a:k1-->` +
|
|
6280
|
+
* ` more` is an inline anchor, `<br>` + `x` is prose). It runs open to
|
|
6281
|
+
* the end of the text.
|
|
6282
|
+
* 2. A box-drawing tree still forming at the end of the text claims, as its
|
|
6283
|
+
* root label, the lines directly above its first connector (the
|
|
6284
|
+
* renderer's `findTreeBlockStart`), and the open last line itself may
|
|
6285
|
+
* become one of its connector lines — so inlines on those lines are held
|
|
6286
|
+
* back as prose until a blank line, a heading or a tree line decides.
|
|
6287
|
+
* This also holds everything a closer still able to arrive on the open
|
|
6288
|
+
* last line could change (`$x$` + `5` is currency, G4; `{{v}}` + `}`).
|
|
6289
|
+
*/
|
|
6290
|
+
holdUndecidedTail() {
|
|
6291
|
+
const last = this.lineStarts.length - 1;
|
|
6292
|
+
if (last < 0) return;
|
|
6293
|
+
if (this.isOpenTail(last)) {
|
|
6294
|
+
const lineStart = this.lineStarts[last];
|
|
6295
|
+
for (const block2 of this.blocks) {
|
|
6296
|
+
if (block2.kind === "prose" && block2.end > lineStart) {
|
|
6297
|
+
block2.inlines = block2.inlines.filter((inline) => inline.end <= lineStart);
|
|
6298
|
+
}
|
|
6299
|
+
}
|
|
6300
|
+
let b = this.blocks.length - 1;
|
|
6301
|
+
while (b >= 0 && this.blocks[b].kind === "gap") b--;
|
|
6302
|
+
const block = this.blocks[b];
|
|
6303
|
+
if (block?.island?.complete && block.island.end > this.lineStarts[last]) {
|
|
6304
|
+
block.island.complete = false;
|
|
6305
|
+
block.island.end = this.n;
|
|
6306
|
+
block.end = this.n;
|
|
6307
|
+
this.blocks.length = b + 1;
|
|
6308
|
+
}
|
|
6309
|
+
}
|
|
6310
|
+
const from = this.treeRootHoldFrom();
|
|
6311
|
+
for (let b = this.blocks.length - 1; b >= 0; b--) {
|
|
6312
|
+
const block = this.blocks[b];
|
|
6313
|
+
if (block.end <= from) break;
|
|
6314
|
+
if (block.kind === "prose") block.inlines = block.inlines.filter((inline) => inline.end <= from);
|
|
6315
|
+
if (block.island) this.blocks[b] = { kind: "prose", start: block.start, end: block.end, island: null, inlines: [] };
|
|
6316
|
+
}
|
|
6317
|
+
}
|
|
6318
|
+
/**
|
|
6319
|
+
* Streaming: where a tree that may still form at the end of the text would
|
|
6320
|
+
* start claiming lines (`n` when none can). Only paragraph lines can be
|
|
6321
|
+
* claimed — a line that starts inside an island (a fence body, an XML
|
|
6322
|
+
* region…) is never a tree line nor a root label, so it stops the walk.
|
|
6323
|
+
*/
|
|
6324
|
+
treeRootHoldFrom() {
|
|
6325
|
+
const claimable = (k2) => {
|
|
6326
|
+
for (; ; ) {
|
|
6327
|
+
const block = this.blockAt(this.lineStarts[k2]);
|
|
6328
|
+
if (!block || block.kind !== "island" || block.island?.fromParagraph === true) return true;
|
|
6329
|
+
const opened = this.lineOf(block.start);
|
|
6330
|
+
if (this.lineStarts[opened] === block.start || opened === k2) return false;
|
|
6331
|
+
k2 = opened;
|
|
6332
|
+
}
|
|
6333
|
+
};
|
|
6334
|
+
let k = this.lineCount - 1;
|
|
6335
|
+
let start = this.lineCount;
|
|
6336
|
+
if (k >= 0 && this.isOpenTail(k)) {
|
|
6337
|
+
if (!claimable(k)) return this.n;
|
|
6338
|
+
start = k;
|
|
6339
|
+
k--;
|
|
6340
|
+
}
|
|
6341
|
+
for (; k >= 0 && claimable(k); k--) {
|
|
6342
|
+
this.tick(1);
|
|
6343
|
+
if (this.lineIsBlank(k)) continue;
|
|
6344
|
+
if (!TREE_GLYPHS.test(this.lineText(k))) break;
|
|
6345
|
+
start = k;
|
|
6346
|
+
}
|
|
6347
|
+
let root = start;
|
|
6348
|
+
for (let j = start - 1; j >= 0 && claimable(j); j--) {
|
|
6349
|
+
const trimmed = this.lineText(j).trim();
|
|
6350
|
+
this.tick(trimmed.length + 1);
|
|
6351
|
+
if (!trimmed || isSplitterTreeLine(trimmed) || /^#{1,6}\s/.test(trimmed)) break;
|
|
6352
|
+
root = j;
|
|
6353
|
+
}
|
|
6354
|
+
return root < this.lineCount ? this.lineStarts[root] : this.n;
|
|
6355
|
+
}
|
|
6356
|
+
/** The block (so far) containing offset `pos`, or null. */
|
|
6357
|
+
blockAt(pos) {
|
|
6358
|
+
let lo = 0;
|
|
6359
|
+
let hi = this.blocks.length - 1;
|
|
6360
|
+
while (lo <= hi) {
|
|
6361
|
+
const mid = lo + hi >>> 1;
|
|
6362
|
+
const block = this.blocks[mid];
|
|
6363
|
+
if (pos < block.start) hi = mid - 1;
|
|
6364
|
+
else if (pos >= block.end) lo = mid + 1;
|
|
6365
|
+
else return block;
|
|
6366
|
+
}
|
|
6367
|
+
return null;
|
|
6368
|
+
}
|
|
6239
6369
|
push(block) {
|
|
6240
6370
|
if (block.end <= block.start) return;
|
|
6241
6371
|
if (block.kind === "prose" && this.isBlank(block.start, block.end)) {
|
|
@@ -6439,7 +6569,10 @@ var Tokenizer = class {
|
|
|
6439
6569
|
continue;
|
|
6440
6570
|
}
|
|
6441
6571
|
if (this.isOpenTail(k)) return this.heldFootnote(p, open[1]);
|
|
6442
|
-
if (FOOTNOTE_DEF.test(line.trimStart())
|
|
6572
|
+
if (FOOTNOTE_DEF.test(line.trimStart())) break;
|
|
6573
|
+
const block = this.detectBlock(this.lineStarts[k], k, false);
|
|
6574
|
+
if (block && this.mayDissolve(block)) return this.heldFootnote(p, open[1]);
|
|
6575
|
+
if (block) break;
|
|
6443
6576
|
last = k;
|
|
6444
6577
|
}
|
|
6445
6578
|
const end = this.contentEnds[last];
|
|
@@ -6455,7 +6588,8 @@ var Tokenizer = class {
|
|
|
6455
6588
|
return {
|
|
6456
6589
|
count: this.lineCount,
|
|
6457
6590
|
line: (k) => this.lineText(k),
|
|
6458
|
-
openTail: (k) => this.isOpenTail(k)
|
|
6591
|
+
openTail: (k) => this.isOpenTail(k),
|
|
6592
|
+
streaming: this.streaming
|
|
6459
6593
|
};
|
|
6460
6594
|
}
|
|
6461
6595
|
/**
|
|
@@ -6515,6 +6649,10 @@ var Tokenizer = class {
|
|
|
6515
6649
|
if (fenceOpenerOf(this.lineText(j))?.char === "~") continue;
|
|
6516
6650
|
const inner = this.detectBlockUncached(start, j, false);
|
|
6517
6651
|
if (!inner) continue;
|
|
6652
|
+
if (this.streaming && inner.end >= tildeEnd && this.paragraphMayGrow(inner.end)) {
|
|
6653
|
+
this.overflowComplete = false;
|
|
6654
|
+
return this.n;
|
|
6655
|
+
}
|
|
6518
6656
|
if (inner.end > end) {
|
|
6519
6657
|
end = inner.end;
|
|
6520
6658
|
this.overflowComplete = inner.complete;
|
|
@@ -6643,12 +6781,7 @@ var Tokenizer = class {
|
|
|
6643
6781
|
return this.island("html_block", p, close.index + close[0].length, true, { tag: name });
|
|
6644
6782
|
}
|
|
6645
6783
|
const typeSix = HTML_BLOCK_LEVEL_TAGS.has(name);
|
|
6646
|
-
const
|
|
6647
|
-
if (loneTag && this.isOpenTail(li)) {
|
|
6648
|
-
this.provisionalFrom = Math.min(this.provisionalFrom, p);
|
|
6649
|
-
return null;
|
|
6650
|
-
}
|
|
6651
|
-
const typeSeven = loneTag;
|
|
6784
|
+
const typeSeven = atParaStart && t.trimEnd() === tag.raw;
|
|
6652
6785
|
if (!typeSix && !typeSeven) return null;
|
|
6653
6786
|
let end = this.contentEnds[li];
|
|
6654
6787
|
for (let k = li + 1; k < this.lineCount && !this.lineIsBlank(k); k++) {
|
|
@@ -6706,6 +6839,13 @@ var Tokenizer = class {
|
|
|
6706
6839
|
}
|
|
6707
6840
|
return null;
|
|
6708
6841
|
}
|
|
6842
|
+
if (this.isOpenTail(lastLine)) {
|
|
6843
|
+
if (isRecognizedJsonHead(this.text.slice(tp, tp + 512))) {
|
|
6844
|
+
return this.island("json", p, this.n, false, jsonMeta(this.text.slice(tp)));
|
|
6845
|
+
}
|
|
6846
|
+
this.provisionalFrom = Math.min(this.provisionalFrom, p);
|
|
6847
|
+
return null;
|
|
6848
|
+
}
|
|
6709
6849
|
if (net !== 0) return null;
|
|
6710
6850
|
const end = this.contentEnds[lastLine];
|
|
6711
6851
|
const content = this.text.slice(tp, end).trim();
|
|
@@ -6740,8 +6880,10 @@ var Tokenizer = class {
|
|
|
6740
6880
|
let breakLine = -1;
|
|
6741
6881
|
for (let k = li + 1; k < this.lineCount; k++) {
|
|
6742
6882
|
if (this.lineIsBlank(k)) break;
|
|
6743
|
-
|
|
6883
|
+
const block = this.detectBlock(this.lineStarts[k], k, false);
|
|
6884
|
+
if (block) {
|
|
6744
6885
|
breakLine = k;
|
|
6886
|
+
if (this.mayDissolve(block)) this.undecidedBreaks.add(end);
|
|
6745
6887
|
break;
|
|
6746
6888
|
}
|
|
6747
6889
|
end = this.contentEnds[k];
|
|
@@ -6779,7 +6921,7 @@ var Tokenizer = class {
|
|
|
6779
6921
|
this.push({ kind: "prose", start: pos, end, island: null, inlines: scan2.inlines });
|
|
6780
6922
|
return end;
|
|
6781
6923
|
}
|
|
6782
|
-
const br = scan2.breakIsland;
|
|
6924
|
+
const br = { ...scan2.breakIsland, fromParagraph: true };
|
|
6783
6925
|
if (scan2.orphan) {
|
|
6784
6926
|
let start = pos;
|
|
6785
6927
|
while (this.blocks.length) {
|
|
@@ -6802,6 +6944,15 @@ var Tokenizer = class {
|
|
|
6802
6944
|
this.push({ kind: "island", start: br.start, end: br.end, island: br, inlines: [] });
|
|
6803
6945
|
return br.end;
|
|
6804
6946
|
}
|
|
6947
|
+
/**
|
|
6948
|
+
* An island that opens inside a paragraph and closes past its end becomes a
|
|
6949
|
+
* block. Streaming: while the paragraph may still grow over its closer, the
|
|
6950
|
+
* island may yet be inline — undecided, so it runs open to the end (F3).
|
|
6951
|
+
*/
|
|
6952
|
+
spill(type, start, end, pe, meta) {
|
|
6953
|
+
if (this.paragraphMayGrow(pe)) return this.island(type, start, this.n, false, meta);
|
|
6954
|
+
return this.island(type, start, end, true, meta);
|
|
6955
|
+
}
|
|
6805
6956
|
scanInline(ps, pe) {
|
|
6806
6957
|
const text = this.text;
|
|
6807
6958
|
const inlines = [];
|
|
@@ -6830,11 +6981,15 @@ var Tokenizer = class {
|
|
|
6830
6981
|
const nextCh = text[i + 1];
|
|
6831
6982
|
if (nextCh === "(" || nextCh === "[") {
|
|
6832
6983
|
const close = within(nextCh === "(" ? "\\)" : "\\]", i + 2);
|
|
6833
|
-
|
|
6984
|
+
const isMath = close !== -1 && (nextCh === "(" || isEscapedBracketMath(text.slice(i + 2, close), i > 0 ? text[i - 1] : void 0));
|
|
6985
|
+
if (close !== -1 && isMath) {
|
|
6834
6986
|
inlines.push(this.island("math_inline", i, close + 2, true, { delimiter: nextCh === "(" ? "\\(" : "\\[" }));
|
|
6835
6987
|
i = close + 2;
|
|
6836
6988
|
continue;
|
|
6837
6989
|
}
|
|
6990
|
+
if (close === -1 && this.streaming && this.paragraphMayGrow(pe)) {
|
|
6991
|
+
return { inlines, breakIsland: null, orphan: false };
|
|
6992
|
+
}
|
|
6838
6993
|
}
|
|
6839
6994
|
i += 2;
|
|
6840
6995
|
continue;
|
|
@@ -6855,17 +7010,13 @@ var Tokenizer = class {
|
|
|
6855
7010
|
i += 2;
|
|
6856
7011
|
continue;
|
|
6857
7012
|
}
|
|
6858
|
-
if (close + 2 > pe) return stop(this.
|
|
7013
|
+
if (close + 2 > pe) return stop(this.spill("math_block", i, close + 2, pe, { delimiter: "$$" }));
|
|
6859
7014
|
inlines.push(this.island("math_inline", i, close + 2, true, { delimiter: "$$" }));
|
|
6860
7015
|
i = close + 2;
|
|
6861
7016
|
continue;
|
|
6862
7017
|
}
|
|
6863
7018
|
const end = singleDollarMathEnd(text, i, pe);
|
|
6864
7019
|
this.tick(end > 0 ? end - i : Math.min(403, pe - i));
|
|
6865
|
-
if (end > 0 && this.streaming && end === this.n) {
|
|
6866
|
-
this.provisionalFrom = Math.min(this.provisionalFrom, i);
|
|
6867
|
-
return { inlines, breakIsland: null, orphan: false };
|
|
6868
|
-
}
|
|
6869
7020
|
if (end > 0) {
|
|
6870
7021
|
inlines.push(this.island("math_inline", i, end, true, { delimiter: "$" }));
|
|
6871
7022
|
i = end;
|
|
@@ -6943,7 +7094,7 @@ var Tokenizer = class {
|
|
|
6943
7094
|
const anchor = end - i <= 64 ? PINNED_ANCHOR_RE.exec(text.slice(i, end)) : null;
|
|
6944
7095
|
const type = anchor ? "anchor" : "html_comment";
|
|
6945
7096
|
const meta = anchor ? { id: anchor[1] } : {};
|
|
6946
|
-
if (end > pe) return stop(this.
|
|
7097
|
+
if (end > pe) return stop(this.spill(type, i, end, pe, meta));
|
|
6947
7098
|
inlines.push(this.island(type, i, end, true, meta));
|
|
6948
7099
|
i = end;
|
|
6949
7100
|
continue;
|
|
@@ -6972,7 +7123,7 @@ var Tokenizer = class {
|
|
|
6972
7123
|
const blockType = isAttr ? "xml_attr" : "xml_region";
|
|
6973
7124
|
if (close === -1) return stop(this.island(blockType, i, this.n, false, { tag: name }));
|
|
6974
7125
|
const end = close + closer.length;
|
|
6975
|
-
if (end > pe) return stop(this.
|
|
7126
|
+
if (end > pe) return stop(this.spill(blockType, i, end, pe, { tag: name }));
|
|
6976
7127
|
inlines.push(this.island("xml_inline", i, end, true, { tag: name }));
|
|
6977
7128
|
i = end;
|
|
6978
7129
|
continue;
|
|
@@ -7358,6 +7509,7 @@ function mapRange(changes, start, end, unit = "utf16") {
|
|
|
7358
7509
|
}
|
|
7359
7510
|
|
|
7360
7511
|
exports.ACTION_BY_CLASS = ACTION_BY_CLASS;
|
|
7512
|
+
exports.AFTER_WINDOW = AFTER_WINDOW;
|
|
7361
7513
|
exports.BacktickRuns = BacktickRuns;
|
|
7362
7514
|
exports.CALLOUT_NAMES = CALLOUT_NAMES;
|
|
7363
7515
|
exports.CAPABILITY_BY_CLASS = CAPABILITY_BY_CLASS;
|
|
@@ -7440,6 +7592,7 @@ exports.isCanonicalBlockIR = isCanonicalBlockIR;
|
|
|
7440
7592
|
exports.isDirectiveClass = isDirectiveClass;
|
|
7441
7593
|
exports.isDuplicateBlockSlug = isDuplicateBlockSlug;
|
|
7442
7594
|
exports.isEmptyResidue = isEmptyResidue;
|
|
7595
|
+
exports.isEscapedBracketMath = isEscapedBracketMath;
|
|
7443
7596
|
exports.isIrEnvelopeCache = isIrEnvelopeCache;
|
|
7444
7597
|
exports.isJsonAnyField = isJsonAnyField;
|
|
7445
7598
|
exports.isKindDirective = isKindDirective;
|
|
@@ -7500,6 +7653,7 @@ exports.scalarArrayItemType = scalarArrayItemType;
|
|
|
7500
7653
|
exports.schemaLayoutMode = schemaLayoutMode;
|
|
7501
7654
|
exports.schemaStructureDepth = schemaStructureDepth;
|
|
7502
7655
|
exports.setJsonRootKeyLookup = setJsonRootKeyLookup;
|
|
7656
|
+
exports.singleDollarAfter = singleDollarAfter;
|
|
7503
7657
|
exports.singleDollarMathEnd = singleDollarMathEnd;
|
|
7504
7658
|
exports.spliceSave = spliceSave;
|
|
7505
7659
|
exports.splitsSurrogatePair = splitsSurrogatePair;
|