@ai-matrx/content-ir 0.16.0 → 0.16.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/dist/source.cjs CHANGED
@@ -321,6 +321,9 @@ var STRUCTURAL_MARKDOWN = /\]\(|https?:\/\/|\*\*|(?:^|\n)[ \t]{0,3}#{1,6}[ \t]|(
321
321
  var LATEX_COMMAND = /\\[a-zA-Z]/;
322
322
  var PROSE_WORD = /[A-Za-z]{3,}/g;
323
323
  var PROSE_WORD_LIMIT = 6;
324
+ function isMathPlaceholder(inner) {
325
+ return /^[\s.…·⋯_-]*$/.test(inner) && /[.…·⋯]/.test(inner);
326
+ }
324
327
  function opensFlowBlock(text, open) {
325
328
  for (let k = open - 1; k >= 0 && text[k] !== "\n"; k--) if (text[k] !== " " && text[k] !== " ") return false;
326
329
  for (let k = open + 2; k < text.length && text[k] !== "\n"; k++) if (text[k] !== " " && text[k] !== " " && text[k] !== "\r") return false;
@@ -339,13 +342,84 @@ function looksLikeDisplayMath(inner, flow = false) {
339
342
  }
340
343
  function codeRanges(text) {
341
344
  const ranges = [];
342
- for (const re of [/```[\s\S]*?(?:```|$)/g, /~~~[\s\S]*?(?:~~~|$)/g, /`[^`\n]*`/g]) {
343
- let m;
344
- while ((m = re.exec(text)) !== null) {
345
- ranges.push([m.index, m.index + m[0].length]);
346
- if (m[0].length === 0) re.lastIndex++;
345
+ const n = text.length;
346
+ let fence = null;
347
+ let para = -1;
348
+ const spans = (from, to) => {
349
+ const runs = [];
350
+ for (let k = from; k < to; ) {
351
+ if (text.charCodeAt(k) !== 96) {
352
+ k++;
353
+ continue;
354
+ }
355
+ let len = 1;
356
+ while (k + len < to && text.charCodeAt(k + len) === 96) len++;
357
+ runs.push([k, len]);
358
+ k += len;
359
+ }
360
+ const nextSame = new Array(runs.length).fill(-1);
361
+ const last = /* @__PURE__ */ new Map();
362
+ for (let r = runs.length - 1; r >= 0; r--) {
363
+ const len = runs[r][1];
364
+ nextSame[r] = last.get(len) ?? -1;
365
+ last.set(len, r);
366
+ }
367
+ for (let r = 0; r < runs.length; ) {
368
+ const j = nextSame[r];
369
+ if (j === -1) {
370
+ r++;
371
+ continue;
372
+ }
373
+ const [s0] = runs[r];
374
+ const [s1, l1] = runs[j];
375
+ ranges.push([s0, s1 + l1]);
376
+ r = j + 1;
347
377
  }
348
- }
378
+ };
379
+ let pos = 0;
380
+ while (pos <= n) {
381
+ const nl = text.indexOf("\n", pos);
382
+ const lineEnd = nl === -1 ? n : nl;
383
+ const line = text.slice(pos, lineEnd);
384
+ let indent = 0;
385
+ while (indent < line.length && line[indent] === " ") indent++;
386
+ const body = line.slice(indent);
387
+ if (fence) {
388
+ const trimmed = trimFenceLine(line);
389
+ let closes = false;
390
+ if (fence.char === "`") {
391
+ const kind = classifyInnerFenceLine(trimmed, fence.len, fence.nests, fence.depth);
392
+ if (kind === "open-nested") fence.depth++;
393
+ else if (kind === "close-nested") fence.depth--;
394
+ else if (kind === "close-outer") closes = indent <= 3;
395
+ } else {
396
+ let t = 0;
397
+ while (t < trimmed.length && trimmed[t] === "~") t++;
398
+ closes = indent <= 3 && t >= fence.len && trimFenceLine(trimmed.slice(t)) === "";
399
+ }
400
+ if (closes) {
401
+ ranges.push([fence.start, lineEnd]);
402
+ fence = null;
403
+ }
404
+ } else {
405
+ const opener = indent <= 3 ? /^(`{3,}|~{3,})(.*)$/.exec(body) : null;
406
+ const info = opener ? opener[2] : "";
407
+ if (opener && !(opener[1][0] === "`" && info.includes("`"))) {
408
+ if (para !== -1) spans(para, pos);
409
+ para = -1;
410
+ const char = opener[1][0];
411
+ const parsed = char === "`" ? parseFenceOpener(line) : null;
412
+ fence = { char, len: opener[1].length, start: pos, nests: fenceNestsInnerFences(parsed?.lang), depth: 0 };
413
+ } else if (body.trim() === "") {
414
+ if (para !== -1) spans(para, pos);
415
+ para = -1;
416
+ } else if (para === -1) para = pos;
417
+ }
418
+ if (nl === -1) break;
419
+ pos = nl + 1;
420
+ }
421
+ if (fence) ranges.push([fence.start, n]);
422
+ else if (para !== -1) spans(para, n);
349
423
  return ranges.sort((a, b) => a[0] - b[0]);
350
424
  }
351
425
  function pendingDisplayMathOpener(text) {
@@ -368,6 +442,10 @@ function pendingDisplayMathOpener(text) {
368
442
  const open = tokens[j];
369
443
  const close = tokens[j + 1];
370
444
  if (close === void 0) break;
445
+ if (isMathPlaceholder(text.slice(open + 2, close))) {
446
+ j += 2;
447
+ continue;
448
+ }
371
449
  if (looksLikeDisplayMath(text.slice(open + 2, close), opensFlowBlock(text, open))) {
372
450
  paired.add(open);
373
451
  paired.add(close);
@@ -412,6 +490,10 @@ function pairDisplayMath(text) {
412
490
  const open = tokens[j];
413
491
  const close = tokens[j + 1];
414
492
  if (close === void 0) break;
493
+ if (isMathPlaceholder(text.slice(open + 2, close))) {
494
+ j += 2;
495
+ continue;
496
+ }
415
497
  if (looksLikeDisplayMath(text.slice(open + 2, close), opensFlowBlock(text, open))) {
416
498
  pairs.set(open, close);
417
499
  j += 2;
@@ -749,6 +831,19 @@ var Tokenizer = class {
749
831
  this.mathPairs = pairDisplayMath(text);
750
832
  this.provisionalFrom = streaming ? pendingDisplayMathOpener(text) : -1;
751
833
  if (this.provisionalFrom === -1) this.provisionalFrom = Number.POSITIVE_INFINITY;
834
+ if (streaming && text.includes("$$")) {
835
+ for (const pad of ["`", "``", "```", "~~~"]) {
836
+ const alt = pairDisplayMath(text + pad);
837
+ for (const [open, close] of this.mathPairs) {
838
+ if (alt.get(open) !== close) this.provisionalFrom = Math.min(this.provisionalFrom, open);
839
+ }
840
+ for (const [open, close] of alt) {
841
+ if (close < text.length && this.mathPairs.get(open) !== close) {
842
+ this.provisionalFrom = Math.min(this.provisionalFrom, open);
843
+ }
844
+ }
845
+ }
846
+ }
752
847
  let start = 0;
753
848
  for (let i = 0; i < text.length; i++) {
754
849
  if (text.charCodeAt(i) === 10) {
@@ -789,13 +884,17 @@ var Tokenizer = class {
789
884
  /**
790
885
  * Streaming: an open last line that begins with `{` is undecided — each new
791
886
  * byte can balance or unbalance its braces and flip the whole line between
792
- * prose and a JSON island — so it is provisional until it ends (G5).
887
+ * prose and a JSON island — and so is a line that is exactly one allowed
888
+ * HTML tag so far; both are provisional until they end (G5).
793
889
  */
794
890
  markOpenJsonTail() {
795
891
  const last = this.lineStarts.length - 1;
796
892
  if (!this.isOpenTail(last)) return;
797
893
  const start = this.lineStarts[last];
798
- if (this.lineText(last).trimStart().startsWith("{")) {
894
+ const t = this.lineText(last).trim();
895
+ const oneTag = t.startsWith("<") ? readXmlTag(t, 0) : null;
896
+ const loneTag = !!oneTag && oneTag.raw === t && ALLOWED_RAW_HTML_TAGS.has(oneTag.tagName.toLowerCase());
897
+ if (t.startsWith("{") || loneTag) {
799
898
  this.provisionalFrom = Math.min(this.provisionalFrom, start);
800
899
  }
801
900
  }
@@ -924,7 +1023,8 @@ var Tokenizer = class {
924
1023
  const fm = this.frontMatter(li, t);
925
1024
  if (fm) return fm;
926
1025
  }
927
- if (indent <= 3 && t.startsWith("::")) {
1026
+ const listNested = indent > 0 && this.inListContinuation(li);
1027
+ if (indent <= 3 && !listNested && t.startsWith("::")) {
928
1028
  const directive = this.directive(p, li, t);
929
1029
  if (directive) return directive;
930
1030
  }
@@ -932,7 +1032,7 @@ var Tokenizer = class {
932
1032
  const admonition = this.mkdocsAdmonition(p, li, t);
933
1033
  if (admonition) return admonition;
934
1034
  }
935
- if (indent <= 3 && t.startsWith(">")) {
1035
+ if (indent <= 3 && !listNested && t.startsWith(">")) {
936
1036
  const callout = this.callout(p, li, t);
937
1037
  if (callout) return callout;
938
1038
  }
@@ -973,6 +1073,17 @@ var Tokenizer = class {
973
1073
  }
974
1074
  return null;
975
1075
  }
1076
+ /** True when line `li` continues a list item (the nearest non-blank line above is a list item or indented text under one). */
1077
+ inListContinuation(li) {
1078
+ for (let k = li - 1; k >= 0; k--) {
1079
+ const line = this.lineText(k);
1080
+ if (!NOT_WHITESPACE.test(line)) continue;
1081
+ if (/^[ \t]*(?:[-*+]|\d{1,9}[.)])[ \t]/.test(line)) return true;
1082
+ if (/^[ \t]/.test(line)) continue;
1083
+ return false;
1084
+ }
1085
+ return false;
1086
+ }
976
1087
  island(type, start, end, complete, meta = {}) {
977
1088
  return { type, start, end, complete, meta };
978
1089
  }
@@ -1077,10 +1188,16 @@ var Tokenizer = class {
1077
1188
  continue;
1078
1189
  }
1079
1190
  if (FOOTNOTE_DEF.test(line.trimStart()) || this.detectBlock(this.lineStarts[k], k, false)) break;
1080
- if (this.isOpenTail(k)) break;
1191
+ if (this.isOpenTail(k)) return this.heldFootnote(p, open[1]);
1081
1192
  last = k;
1082
1193
  }
1083
- return this.island("footnote_def", p, this.contentEnds[last], true, { id: open[1] });
1194
+ const end = this.contentEnds[last];
1195
+ if (this.paragraphMayGrow(end)) return this.heldFootnote(p, open[1]);
1196
+ return this.island("footnote_def", p, end, true, { id: open[1] });
1197
+ }
1198
+ /** A footnote whose continuation is still arriving: open to the end of the text. */
1199
+ heldFootnote(p, id) {
1200
+ return this.island("footnote_def", p, this.n, false, { id });
1084
1201
  }
1085
1202
  /**
1086
1203
  * Backtick fence — the renderer splitter's close rules: JSON-string aware for
@@ -1324,7 +1441,12 @@ var Tokenizer = class {
1324
1441
  return this.island("html_block", p, close.index + close[0].length, true, { tag: name });
1325
1442
  }
1326
1443
  const typeSix = HTML_BLOCK_LEVEL_TAGS.has(name);
1327
- const typeSeven = atParaStart && t.trimEnd() === tag.raw && !this.isOpenTail(li);
1444
+ const loneTag = atParaStart && t.trimEnd() === tag.raw;
1445
+ if (loneTag && this.isOpenTail(li)) {
1446
+ this.provisionalFrom = Math.min(this.provisionalFrom, p);
1447
+ return null;
1448
+ }
1449
+ const typeSeven = loneTag;
1328
1450
  if (!typeSix && !typeSeven) return null;
1329
1451
  let end = this.contentEnds[li];
1330
1452
  for (let k = li + 1; k < this.lineCount && !this.lineIsBlank(k); k++) {
@@ -1416,10 +1538,6 @@ var Tokenizer = class {
1416
1538
  let breakLine = -1;
1417
1539
  for (let k = li + 1; k < this.lineCount; k++) {
1418
1540
  if (this.lineIsBlank(k)) break;
1419
- if (this.lineStarts[k] >= this.provisionalFrom) {
1420
- end = this.n;
1421
- break;
1422
- }
1423
1541
  if (this.detectBlock(this.lineStarts[k], k, false)) {
1424
1542
  breakLine = k;
1425
1543
  break;
@@ -1562,7 +1680,11 @@ var Tokenizer = class {
1562
1680
  }
1563
1681
  const end = singleDollarMathEnd(text, i, pe);
1564
1682
  this.tick(end > 0 ? end - i : Math.min(403, pe - i));
1565
- if (end > 0 && !(this.streaming && end === this.n)) {
1683
+ if (end > 0 && this.streaming && end === this.n) {
1684
+ this.provisionalFrom = Math.min(this.provisionalFrom, i);
1685
+ return { inlines, breakIsland: null, orphan: false };
1686
+ }
1687
+ if (end > 0) {
1566
1688
  inlines.push(this.island("math_inline", i, end, true, { delimiter: "$" }));
1567
1689
  i = end;
1568
1690
  continue;
@@ -2065,6 +2187,7 @@ exports.blockRangeEdit = blockRangeEdit;
2065
2187
  exports.buildCodePointIndex = buildCodePointIndex;
2066
2188
  exports.classifyInnerFenceLine = classifyInnerFenceLine;
2067
2189
  exports.fenceNestsInnerFences = fenceNestsInnerFences;
2190
+ exports.isMathPlaceholder = isMathPlaceholder;
2068
2191
  exports.isSingleDollarMath = isSingleDollarMath;
2069
2192
  exports.islandEdit = islandEdit;
2070
2193
  exports.joinSource = joinSource;