@ai-matrx/print 0.8.4 → 0.8.6

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.
@@ -21,7 +21,16 @@ interface MathSpan {
21
21
  tex: string;
22
22
  display: boolean;
23
23
  }
24
- /** Replace every math span with a private-use token; returns the spans. */
24
+ /**
25
+ * Replace every math span with a private-use token; returns the spans.
26
+ *
27
+ * Print keeps NO fence, code-span or math detection of its own: the spans are
28
+ * the shared tokenizer's complete `math_block` / `math_inline` islands
29
+ * (`tokenizeSource` + `listIslands` from `@ai-matrx/content-ir/source` — the
30
+ * one fence-nesting rule and the one math pairing), so print, the renderer and
31
+ * the editor can never disagree about what is math. The delimiter decides the
32
+ * form: `$$`/`\[` display, `$`/`\(` inline.
33
+ */
25
34
  declare function extractMath(body: string): {
26
35
  text: string;
27
36
  spans: MathSpan[];
@@ -21,7 +21,16 @@ interface MathSpan {
21
21
  tex: string;
22
22
  display: boolean;
23
23
  }
24
- /** Replace every math span with a private-use token; returns the spans. */
24
+ /**
25
+ * Replace every math span with a private-use token; returns the spans.
26
+ *
27
+ * Print keeps NO fence, code-span or math detection of its own: the spans are
28
+ * the shared tokenizer's complete `math_block` / `math_inline` islands
29
+ * (`tokenizeSource` + `listIslands` from `@ai-matrx/content-ir/source` — the
30
+ * one fence-nesting rule and the one math pairing), so print, the renderer and
31
+ * the editor can never disagree about what is math. The delimiter decides the
32
+ * form: `$$`/`\[` display, `$`/`\(` inline.
33
+ */
25
34
  declare function extractMath(body: string): {
26
35
  text: string;
27
36
  spans: MathSpan[];
package/dist/document.js CHANGED
@@ -63,65 +63,54 @@ function visualOrder(input, rtl) {
63
63
  return out;
64
64
  }
65
65
 
66
+ // src/document/layout.ts
67
+ var plainInline = (nodes) => nodes.map((n) => "value" in n ? n.value : "label" in n ? n.label : "tex" in n ? n.tex : "children" in n ? plainInline(n.children) : "").join("");
68
+ function contentColumnWidths(b, n, avail, measure, pad = 10) {
69
+ const min = new Array(n).fill(0);
70
+ const max = new Array(n).fill(0);
71
+ const rows = [[b.header, true], ...b.rows.map((r) => [r, false])];
72
+ for (const [r, head] of rows) {
73
+ for (let i = 0; i < n; i++) {
74
+ const t = plainInline(r[i] ?? []);
75
+ const longest = t.split(/\s+/).reduce((m, w) => Math.max(m, measure(w, head)), 0);
76
+ min[i] = Math.max(min[i], Math.min(longest, avail * 0.35) + pad);
77
+ max[i] = Math.max(max[i], measure(t, head) + pad);
78
+ }
79
+ }
80
+ const sumMax = max.reduce((a, x) => a + x, 0);
81
+ const sumMin = min.reduce((a, x) => a + x, 0);
82
+ if (sumMax <= avail) return max.map((m) => m + (avail - sumMax) / n);
83
+ if (sumMin >= avail) return min.map((m) => m / sumMin * avail);
84
+ const extra = avail - sumMin;
85
+ return min.map((m, i) => m + (max[i] - m) * (extra / (sumMax - sumMin)));
86
+ }
87
+
66
88
  // src/document/math.ts
67
- import { pairDisplayMath, singleDollarMathEnd } from "@ai-matrx/content-ir/source";
89
+ import { listIslands, tokenizeSource } from "@ai-matrx/content-ir/source";
68
90
  var MATH_OPEN = "\uE100";
69
91
  var MATH_CLOSE = "\uE101";
70
92
  var MATH_TOKEN_RE = /\uE100(\d+)\uE101/g;
71
- function codeRanges(text) {
72
- const ranges = [];
73
- for (const re of [/```[\s\S]*?(?:```|$)/g, /~~~[\s\S]*?(?:~~~|$)/g, /`[^`\n]*`/g]) {
74
- let m;
75
- while ((m = re.exec(text)) !== null) {
76
- ranges.push([m.index, m.index + m[0].length]);
77
- if (m[0].length === 0) re.lastIndex++;
78
- }
79
- }
80
- return ranges.sort((a, b) => a[0] - b[0]);
81
- }
93
+ var DELIMITERS = {
94
+ $$: { open: 2, close: 2, display: true },
95
+ "\\[": { open: 2, close: 2, display: true },
96
+ $: { open: 1, close: 1, display: false },
97
+ "\\(": { open: 2, close: 2, display: false }
98
+ };
82
99
  function extractMath(body) {
83
100
  const spans = [];
84
101
  if (!/[$\\]/.test(body)) return { text: body, spans };
85
- const code = codeRanges(body);
86
- const inCode = (i2) => code.some(([a, b]) => i2 >= a && i2 < b);
87
- const display = pairDisplayMath(body);
102
+ const islands = listIslands(tokenizeSource(body)).filter((isl) => isl.complete && (isl.islandType === "math_block" || isl.islandType === "math_inline")).sort((a, b) => a.start - b.start);
88
103
  let out = "";
89
- let i = 0;
90
- const token = (tex, isDisplay) => {
91
- spans.push({ tex: tex.trim(), display: isDisplay });
92
- return `${MATH_OPEN}${spans.length - 1}${MATH_CLOSE}`;
93
- };
94
- while (i < body.length) {
95
- const ch = body[i];
96
- if (ch === "$" && !inCode(i)) {
97
- const close = display.get(i);
98
- if (close !== void 0) {
99
- out += token(body.slice(i + 2, close), true);
100
- i = close + 2;
101
- continue;
102
- }
103
- if (body[i + 1] !== "$" && body[i - 1] !== "$" && body[i - 1] !== "\\") {
104
- const end = singleDollarMathEnd(body, i);
105
- if (end > 0) {
106
- out += token(body.slice(i + 1, end - 1), false);
107
- i = end;
108
- continue;
109
- }
110
- }
111
- }
112
- if (ch === "\\" && !inCode(i) && (body[i + 1] === "[" || body[i + 1] === "(")) {
113
- const closer = body[i + 1] === "[" ? "\\]" : "\\)";
114
- const end = body.indexOf(closer, i + 2);
115
- if (end > i + 2 && end - i < 2e3 && (body[i + 1] === "[" || !body.slice(i, end).includes("\n\n"))) {
116
- out += token(body.slice(i + 2, end), body[i + 1] === "[");
117
- i = end + 2;
118
- continue;
119
- }
120
- }
121
- out += ch;
122
- i++;
104
+ let at = 0;
105
+ for (const isl of islands) {
106
+ const d = DELIMITERS[String(isl.meta.delimiter ?? "")];
107
+ if (!d || isl.start < at) continue;
108
+ out += body.slice(at, isl.start);
109
+ spans.push({ tex: body.slice(isl.start + d.open, isl.end - d.close).trim(), display: d.display });
110
+ out += `${MATH_OPEN}${spans.length - 1}${MATH_CLOSE}`;
111
+ at = isl.end;
123
112
  }
124
- return { text: out, spans };
113
+ return { text: out + body.slice(at), spans };
125
114
  }
126
115
  var mathKey = (tex, display) => `${display ? "D" : "I"}:${tex}`;
127
116
  var MATHJAX = /* @__PURE__ */ Symbol.for("ai-matrx.print.document.mathjax");
@@ -2881,6 +2870,8 @@ function block(b, c, o) {
2881
2870
  case "table": {
2882
2871
  const n = Math.max(b.header.length, ...b.rows.map((r) => r.length), 1);
2883
2872
  const keep = b.rows.length <= 20;
2873
+ const cellPt = c.s.fontSize;
2874
+ const colTw = contentColumnWidths(b, n, c.width, (t, bold) => t.length * cellPt * (bold ? 0.55 : 0.5), 10).map((w) => Math.round(w * TW));
2884
2875
  const alignOf = (i) => b.align[i] === "center" ? d.AlignmentType.CENTER : b.align[i] === "right" ? d.AlignmentType.RIGHT : d.AlignmentType.LEFT;
2885
2876
  const border = { style: d.BorderStyle.SINGLE, size: 4, color: "E5E7EB" };
2886
2877
  const none = { style: d.BorderStyle.NONE, size: 0, color: "FFFFFF" };
@@ -2890,6 +2881,7 @@ function block(b, c, o) {
2890
2881
  children: Array.from(
2891
2882
  { length: n },
2892
2883
  (_, i) => new d.TableCell({
2884
+ width: { size: colTw[i] ?? 0, type: d.WidthType.DXA },
2893
2885
  ...head ? { shading: { type: d.ShadingType.CLEAR, fill: "F3F4F6", color: "auto" } } : {},
2894
2886
  margins: { top: 60, bottom: 60, left: 100, right: 100 },
2895
2887
  borders: { top: none, left: none, right: none, bottom: head ? { ...border, size: 10, color: HEX.heading } : border },
@@ -2908,7 +2900,9 @@ function block(b, c, o) {
2908
2900
  if (b.caption) out.push(captionParagraph(b.caption, c, true));
2909
2901
  out.push(
2910
2902
  new d.Table({
2911
- width: { size: 100, type: d.WidthType.PERCENTAGE },
2903
+ width: { size: Math.round(c.width * TW), type: d.WidthType.DXA },
2904
+ columnWidths: colTw,
2905
+ layout: d.TableLayoutType.FIXED,
2912
2906
  rows: [row(b.header, true, b.rows.length === 0), ...b.rows.map((r, i) => row(r, false, i === b.rows.length - 1))]
2913
2907
  })
2914
2908
  );
@@ -4151,26 +4145,7 @@ function estimateLines(text, c, size = c.s.fontSize) {
4151
4145
  }
4152
4146
  function columnWidths(b, n, size, c) {
4153
4147
  const measure = (text, bold) => c.faces ? c.faces.measure(text, { bold, fontSize: size }) : text.length * size * 0.5;
4154
- const pad = 10;
4155
- const slack = 1;
4156
- const min = new Array(n).fill(0);
4157
- const max = new Array(n).fill(0);
4158
- const rows = [[b.header, true], ...b.rows.map((r) => [r, false])];
4159
- for (const [r, head] of rows) {
4160
- for (let i = 0; i < n; i++) {
4161
- const t = plain(r[i] ?? []);
4162
- const longest = t.split(/\s+/).reduce((m, w) => Math.max(m, measure(w, head)), 0);
4163
- min[i] = Math.max(min[i], Math.min(longest * slack, c.width * 0.35) + pad);
4164
- max[i] = Math.max(max[i], measure(t, head) * slack + pad);
4165
- }
4166
- }
4167
- const avail = c.width;
4168
- const sumMax = max.reduce((a, x) => a + x, 0);
4169
- const sumMin = min.reduce((a, x) => a + x, 0);
4170
- if (sumMax <= avail) return max.map((m) => m + (avail - sumMax) / n);
4171
- if (sumMin >= avail) return min.map((m) => m / sumMin * avail);
4172
- const extra = avail - sumMin;
4173
- return min.map((m, i) => m + (max[i] - m) * (extra / (sumMax - sumMin)));
4148
+ return contentColumnWidths(b, n, c.width, measure);
4174
4149
  }
4175
4150
  var plain = (nodes) => nodes.map((n) => "value" in n ? n.value : "label" in n ? n.label : "children" in n ? plain(n.children) : "").join("");
4176
4151
  function taskItem(checked, content, c) {