@ai-matrx/content-ir 0.21.0 → 0.21.2
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 +30 -0
- package/dist/index.cjs +48 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +48 -48
- package/dist/index.js.map +1 -1
- package/dist/source.cjs +48 -48
- package/dist/source.cjs.map +1 -1
- package/dist/source.d.cts +0 -12
- package/dist/source.d.ts +0 -12
- package/dist/source.js +48 -48
- package/dist/source.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.21.2
|
|
4
|
+
|
|
5
|
+
### `/source`: a ```json fence's string state never crosses a line end (never-raw R11 H2)
|
|
6
|
+
|
|
7
|
+
- `FenceReader` (behind `closeFence`, `fenceLineKinds`, `findCodeRanges`, the XML / directive balance walkers) read
|
|
8
|
+
JSON-string state across lines inside a ```json fence. A JSON string never holds a raw newline, so a body line
|
|
9
|
+
that ends inside one (`{\"__kind\":\"note\"}` — escaped quotes, a cut value) swallowed the closing ``` and every
|
|
10
|
+
following list item / quoted line. The state is now read per line; a backtick run inside a string on the same line
|
|
11
|
+
is still text.
|
|
12
|
+
|
|
13
|
+
### Consumer action
|
|
14
|
+
|
|
15
|
+
- None required. matrx-frontend may drop its splitter workaround (`jsonLineForFenceReader` in
|
|
16
|
+
content-splitter-core.ts) once on 0.21.2.
|
|
17
|
+
|
|
18
|
+
## 0.21.1
|
|
19
|
+
|
|
20
|
+
### `/source`: the tokenizer locks what the renderer draws (fuzz `source-covers-renderer`)
|
|
21
|
+
|
|
22
|
+
- A `~~~` island now ends at its closer. The 0.14.2 "renderer overflow" assumed the renderer did not know `~~~`
|
|
23
|
+
(it has since matrx-frontend A4, 2026-09-30), and swallowed the next fence's opener into the tilde island,
|
|
24
|
+
leaving a following ````` ````md ````` block editable.
|
|
25
|
+
- A JSON-family fence (unlabelled / json / jsonc / json5) opened on a quoted line (`> ```) is an island up to its
|
|
26
|
+
own closer, which may carry no `>`: the renderer lifts such a region out of its quote (V1 quoted-kind-lift). A
|
|
27
|
+
quoted fence of another language stays prose (source).
|
|
28
|
+
|
|
29
|
+
### Consumer action
|
|
30
|
+
|
|
31
|
+
- None required.
|
|
32
|
+
|
|
3
33
|
## 0.21.0
|
|
4
34
|
|
|
5
35
|
### `/source`: the markdown text helpers move in from matrx-frontend (chat-package-move P14)
|
package/dist/index.cjs
CHANGED
|
@@ -5487,9 +5487,9 @@ function fenceOpenerOf(content) {
|
|
|
5487
5487
|
function opensStrictFence(line) {
|
|
5488
5488
|
return fenceOpenerOf(line) !== null;
|
|
5489
5489
|
}
|
|
5490
|
+
var LINE_START = { inString: false, escaped: false };
|
|
5490
5491
|
var FenceReader = class {
|
|
5491
5492
|
opener;
|
|
5492
|
-
state = { inString: false, escaped: false };
|
|
5493
5493
|
depth = 0;
|
|
5494
5494
|
/** A nested fence was opened at some point. */
|
|
5495
5495
|
sawNested = false;
|
|
@@ -5510,17 +5510,8 @@ var FenceReader = class {
|
|
|
5510
5510
|
if (this.tildeCloser) return this.tildeCloser.test(line);
|
|
5511
5511
|
const trimmedLine = trimFenceLine(line);
|
|
5512
5512
|
const at = line.indexOf("```");
|
|
5513
|
-
if (at === -1)
|
|
5514
|
-
|
|
5515
|
-
return false;
|
|
5516
|
-
}
|
|
5517
|
-
if (this.isJson) {
|
|
5518
|
-
const probe = jsonStringState(line, 0, at, this.state);
|
|
5519
|
-
if (probe.inString) {
|
|
5520
|
-
this.state = jsonStringState(line, at, line.length, probe);
|
|
5521
|
-
return false;
|
|
5522
|
-
}
|
|
5523
|
-
}
|
|
5513
|
+
if (at === -1) return false;
|
|
5514
|
+
if (this.isJson && jsonStringState(line, 0, at, LINE_START).inString) return false;
|
|
5524
5515
|
if (trimmedLine.startsWith("```")) {
|
|
5525
5516
|
const kind = classifyInnerFenceLine(trimmedLine, this.opener.ticks, this.nesting, this.depth);
|
|
5526
5517
|
if (kind === "close-outer") return true;
|
|
@@ -5534,7 +5525,6 @@ var FenceReader = class {
|
|
|
5534
5525
|
const after = trimFenceLine(line.slice(at + closeTicks));
|
|
5535
5526
|
if (closeTicks >= this.opener.ticks && after === "" && this.depth === 0) return true;
|
|
5536
5527
|
}
|
|
5537
|
-
if (this.isJson) this.state = jsonStringState(line, 0, line.length, this.state);
|
|
5538
5528
|
return false;
|
|
5539
5529
|
}
|
|
5540
5530
|
};
|
|
@@ -6418,6 +6408,8 @@ function findTableEnd(lines, start) {
|
|
|
6418
6408
|
}
|
|
6419
6409
|
|
|
6420
6410
|
// source/tokenize.ts
|
|
6411
|
+
var QUOTE_PREFIX = /^ {0,3}>(?: ?>)* ?/;
|
|
6412
|
+
var QUOTED_JSON_FENCE_LANGS = /* @__PURE__ */ new Set(["", "json", "jsonc", "json5"]);
|
|
6421
6413
|
var NOT_WHITESPACE = /\S/;
|
|
6422
6414
|
var DIRECTIVE_OPEN = /^(:{2,})([A-Za-z][\w-]*)/;
|
|
6423
6415
|
var MKDOCS_OPEN = /^(!!!|\?\?\?\+?)[ \t]+([A-Za-z][\w-]*)/;
|
|
@@ -6907,6 +6899,8 @@ var Tokenizer = class {
|
|
|
6907
6899
|
if (indent <= 3 && !listNested && t.startsWith(">")) {
|
|
6908
6900
|
const callout = this.callout(p, li, t);
|
|
6909
6901
|
if (callout) return callout;
|
|
6902
|
+
const lifted = this.quotedJsonFence(p, li, seg);
|
|
6903
|
+
if (lifted) return lifted;
|
|
6910
6904
|
}
|
|
6911
6905
|
if (atParaStart && indent <= 3 && t.startsWith("[^")) {
|
|
6912
6906
|
const footnote = this.footnoteDefinition(p, li, t);
|
|
@@ -7102,6 +7096,42 @@ var Tokenizer = class {
|
|
|
7102
7096
|
streaming: this.streaming
|
|
7103
7097
|
};
|
|
7104
7098
|
}
|
|
7099
|
+
/**
|
|
7100
|
+
* A JSON-family fence (unlabelled, json, jsonc, json5) opening on a quoted line. The renderer LIFTS it out
|
|
7101
|
+
* of the quote (matrx-frontend V1, never-raw law): the quote prefix is removed from every line of the
|
|
7102
|
+
* region, so the region is an ordinary top-level fence — drawn as code up to its own closer, which may sit on
|
|
7103
|
+
* a line that carries no `>` at all. The editor must lock at least what the renderer draws, so the island
|
|
7104
|
+
* runs from the quoted opener line to that closer (found on the lines with their quote prefix removed).
|
|
7105
|
+
*/
|
|
7106
|
+
quotedJsonFence(p, li, seg) {
|
|
7107
|
+
const m = QUOTE_PREFIX.exec(seg);
|
|
7108
|
+
if (!m) return null;
|
|
7109
|
+
const opener = fenceOpenerOf(seg.slice(m[0].length));
|
|
7110
|
+
if (!opener || opener.char !== "`" || !QUOTED_JSON_FENCE_LANGS.has(opener.lang.toLowerCase())) return null;
|
|
7111
|
+
const base2 = this.fenceLines;
|
|
7112
|
+
const lines = {
|
|
7113
|
+
...base2,
|
|
7114
|
+
line: (k) => {
|
|
7115
|
+
const text = base2.line(k);
|
|
7116
|
+
if (text === null) return null;
|
|
7117
|
+
const q = QUOTE_PREFIX.exec(text);
|
|
7118
|
+
return q ? text.slice(q[0].length) : text;
|
|
7119
|
+
}
|
|
7120
|
+
};
|
|
7121
|
+
let first = li;
|
|
7122
|
+
while (first > 0 && li - first < 400 && QUOTE_PREFIX.test(this.lineText(first - 1))) first--;
|
|
7123
|
+
for (let k = first; k < li; k++) {
|
|
7124
|
+
const o = fenceOpenerOf(lines.line(k) ?? "");
|
|
7125
|
+
if (!o || o.char !== "`" || QUOTED_JSON_FENCE_LANGS.has(o.lang.toLowerCase())) continue;
|
|
7126
|
+
const c = closeFence(lines, k, o);
|
|
7127
|
+
if (!c.closed || c.line >= li) return null;
|
|
7128
|
+
k = c.line;
|
|
7129
|
+
}
|
|
7130
|
+
const end = closeFence(lines, li, opener);
|
|
7131
|
+
const meta = { fence: "`", ticks: opener.ticks, lang: opener.lang };
|
|
7132
|
+
if (end.closed) return this.island("fence", p, this.contentEnds[end.line], true, meta);
|
|
7133
|
+
return this.island("fence", p, this.n, false, meta);
|
|
7134
|
+
}
|
|
7105
7135
|
/**
|
|
7106
7136
|
* Backtick fence — THE one closer (`closeFence`, source/code-ranges.ts): the
|
|
7107
7137
|
* nested-fence rule for markdown fences with the strict-CommonMark retry, the
|
|
@@ -7134,44 +7164,14 @@ var Tokenizer = class {
|
|
|
7134
7164
|
if (normalized && SPECIAL_CODE_LANGUAGES.has(normalized)) meta.special = normalized;
|
|
7135
7165
|
const close = closeFence(this.fenceLines, li, opener);
|
|
7136
7166
|
if (close.closed) {
|
|
7137
|
-
|
|
7138
|
-
const end = this.rendererOverflow(li + 1, close.line, tildeEnd);
|
|
7139
|
-
return this.island("fence", p, end, end === this.n ? this.overflowComplete : true, meta);
|
|
7167
|
+
return this.island("fence", p, this.contentEnds[close.line], true, meta);
|
|
7140
7168
|
}
|
|
7141
7169
|
return this.island("fence", p, this.n, false, meta);
|
|
7142
7170
|
}
|
|
7143
|
-
|
|
7144
|
-
|
|
7145
|
-
|
|
7146
|
-
|
|
7147
|
-
* one as ordinary lines, so a ```` ``` ```` fence (or an XML section, a JSON
|
|
7148
|
-
* block…) that STARTS inside the tilde fence can run past its closer. The
|
|
7149
|
-
* editor must lock at least what the renderer draws (verify-RC-B3 residual
|
|
7150
|
-
* R5), so a tilde island extends over every block the renderer would detect
|
|
7151
|
-
* starting inside it. Returns the island's end.
|
|
7152
|
-
*/
|
|
7153
|
-
rendererOverflow(firstLine, closeLine, tildeEnd) {
|
|
7154
|
-
let end = tildeEnd;
|
|
7155
|
-
this.overflowComplete = true;
|
|
7156
|
-
for (let j = firstLine; j <= closeLine && j < this.lineCount; j++) {
|
|
7157
|
-
const start = this.lineStarts[j];
|
|
7158
|
-
if (this.lineIsBlank(j)) continue;
|
|
7159
|
-
if (fenceOpenerOf(this.lineText(j))?.char === "~") continue;
|
|
7160
|
-
const inner = this.detectBlockUncached(start, j, false);
|
|
7161
|
-
if (!inner) continue;
|
|
7162
|
-
if (this.streaming && inner.end >= tildeEnd && this.paragraphMayGrow(inner.end)) {
|
|
7163
|
-
this.overflowComplete = false;
|
|
7164
|
-
return this.n;
|
|
7165
|
-
}
|
|
7166
|
-
if (inner.end > end) {
|
|
7167
|
-
end = inner.end;
|
|
7168
|
-
this.overflowComplete = inner.complete;
|
|
7169
|
-
}
|
|
7170
|
-
const lastLine = this.lineOf(Math.max(start, inner.end - 1));
|
|
7171
|
-
if (lastLine > j) j = lastLine;
|
|
7172
|
-
}
|
|
7173
|
-
return end;
|
|
7174
|
-
}
|
|
7171
|
+
// A tilde island ends at its closer. The renderer's splitter treats `~~~` as a real fence since
|
|
7172
|
+
// matrx-frontend A4 (2026-09-30): the lines inside are code, so nothing that starts inside one runs
|
|
7173
|
+
// past the closer (the 0.14.2 "overflow" assumed the renderer did not know ~~~ and, kept, swallowed the
|
|
7174
|
+
// next fence's opener into the tilde island: a ````md block after a ~~~ block was left unlocked).
|
|
7175
7175
|
/**
|
|
7176
7176
|
* A line-leading `$$` that OPENS a math pair (source/math-pairs.ts — the
|
|
7177
7177
|
* core's rule). A closer, an unpaired `$$`, or a prose pair is never a block:
|