@ai-matrx/content-ir 0.21.0 → 0.21.1

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 CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.21.1
4
+
5
+ ### `/source`: the tokenizer locks what the renderer draws (fuzz `source-covers-renderer`)
6
+
7
+ - A `~~~` island now ends at its closer. The 0.14.2 "renderer overflow" assumed the renderer did not know `~~~`
8
+ (it has since matrx-frontend A4, 2026-09-30), and swallowed the next fence's opener into the tilde island,
9
+ leaving a following ````` ````md ````` block editable.
10
+ - A JSON-family fence (unlabelled / json / jsonc / json5) opened on a quoted line (`> ```) is an island up to its
11
+ own closer, which may carry no `>`: the renderer lifts such a region out of its quote (V1 quoted-kind-lift). A
12
+ quoted fence of another language stays prose (source).
13
+
14
+ ### Consumer action
15
+
16
+ - None required.
17
+
3
18
  ## 0.21.0
4
19
 
5
20
  ### `/source`: the markdown text helpers move in from matrx-frontend (chat-package-move P14)
package/dist/index.cjs CHANGED
@@ -6418,6 +6418,8 @@ function findTableEnd(lines, start) {
6418
6418
  }
6419
6419
 
6420
6420
  // source/tokenize.ts
6421
+ var QUOTE_PREFIX = /^ {0,3}>(?: ?>)* ?/;
6422
+ var QUOTED_JSON_FENCE_LANGS = /* @__PURE__ */ new Set(["", "json", "jsonc", "json5"]);
6421
6423
  var NOT_WHITESPACE = /\S/;
6422
6424
  var DIRECTIVE_OPEN = /^(:{2,})([A-Za-z][\w-]*)/;
6423
6425
  var MKDOCS_OPEN = /^(!!!|\?\?\?\+?)[ \t]+([A-Za-z][\w-]*)/;
@@ -6907,6 +6909,8 @@ var Tokenizer = class {
6907
6909
  if (indent <= 3 && !listNested && t.startsWith(">")) {
6908
6910
  const callout = this.callout(p, li, t);
6909
6911
  if (callout) return callout;
6912
+ const lifted = this.quotedJsonFence(p, li, seg);
6913
+ if (lifted) return lifted;
6910
6914
  }
6911
6915
  if (atParaStart && indent <= 3 && t.startsWith("[^")) {
6912
6916
  const footnote = this.footnoteDefinition(p, li, t);
@@ -7102,6 +7106,42 @@ var Tokenizer = class {
7102
7106
  streaming: this.streaming
7103
7107
  };
7104
7108
  }
7109
+ /**
7110
+ * A JSON-family fence (unlabelled, json, jsonc, json5) opening on a quoted line. The renderer LIFTS it out
7111
+ * of the quote (matrx-frontend V1, never-raw law): the quote prefix is removed from every line of the
7112
+ * region, so the region is an ordinary top-level fence — drawn as code up to its own closer, which may sit on
7113
+ * a line that carries no `>` at all. The editor must lock at least what the renderer draws, so the island
7114
+ * runs from the quoted opener line to that closer (found on the lines with their quote prefix removed).
7115
+ */
7116
+ quotedJsonFence(p, li, seg) {
7117
+ const m = QUOTE_PREFIX.exec(seg);
7118
+ if (!m) return null;
7119
+ const opener = fenceOpenerOf(seg.slice(m[0].length));
7120
+ if (!opener || opener.char !== "`" || !QUOTED_JSON_FENCE_LANGS.has(opener.lang.toLowerCase())) return null;
7121
+ const base2 = this.fenceLines;
7122
+ const lines = {
7123
+ ...base2,
7124
+ line: (k) => {
7125
+ const text = base2.line(k);
7126
+ if (text === null) return null;
7127
+ const q = QUOTE_PREFIX.exec(text);
7128
+ return q ? text.slice(q[0].length) : text;
7129
+ }
7130
+ };
7131
+ let first = li;
7132
+ while (first > 0 && li - first < 400 && QUOTE_PREFIX.test(this.lineText(first - 1))) first--;
7133
+ for (let k = first; k < li; k++) {
7134
+ const o = fenceOpenerOf(lines.line(k) ?? "");
7135
+ if (!o || o.char !== "`" || QUOTED_JSON_FENCE_LANGS.has(o.lang.toLowerCase())) continue;
7136
+ const c = closeFence(lines, k, o);
7137
+ if (!c.closed || c.line >= li) return null;
7138
+ k = c.line;
7139
+ }
7140
+ const end = closeFence(lines, li, opener);
7141
+ const meta = { fence: "`", ticks: opener.ticks, lang: opener.lang };
7142
+ if (end.closed) return this.island("fence", p, this.contentEnds[end.line], true, meta);
7143
+ return this.island("fence", p, this.n, false, meta);
7144
+ }
7105
7145
  /**
7106
7146
  * Backtick fence — THE one closer (`closeFence`, source/code-ranges.ts): the
7107
7147
  * nested-fence rule for markdown fences with the strict-CommonMark retry, the
@@ -7134,44 +7174,14 @@ var Tokenizer = class {
7134
7174
  if (normalized && SPECIAL_CODE_LANGUAGES.has(normalized)) meta.special = normalized;
7135
7175
  const close = closeFence(this.fenceLines, li, opener);
7136
7176
  if (close.closed) {
7137
- const tildeEnd = this.contentEnds[close.line];
7138
- const end = this.rendererOverflow(li + 1, close.line, tildeEnd);
7139
- return this.island("fence", p, end, end === this.n ? this.overflowComplete : true, meta);
7177
+ return this.island("fence", p, this.contentEnds[close.line], true, meta);
7140
7178
  }
7141
7179
  return this.island("fence", p, this.n, false, meta);
7142
7180
  }
7143
- /** Completion of the last `rendererOverflow` that ran to the end of the text. */
7144
- overflowComplete = true;
7145
- /**
7146
- * The renderer's splitter does not know ~~~ fences: it reads the lines inside
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
- }
7181
+ // A tilde island ends at its closer. The renderer's splitter treats `~~~` as a real fence since
7182
+ // matrx-frontend A4 (2026-09-30): the lines inside are code, so nothing that starts inside one runs
7183
+ // past the closer (the 0.14.2 "overflow" assumed the renderer did not know ~~~ and, kept, swallowed the
7184
+ // next fence's opener into the tilde island: a ````md block after a ~~~ block was left unlocked).
7175
7185
  /**
7176
7186
  * A line-leading `$$` that OPENS a math pair (source/math-pairs.ts — the
7177
7187
  * core's rule). A closer, an unpaired `$$`, or a prose pair is never a block: