@ai-matrx/print 0.8.4 → 0.8.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 CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.8.5
4
+
5
+ - **Word tables use content-aware column widths** (the same rule as the PDF,
6
+ now shared in `src/document/layout.ts`; fixed table layout). A 10-column
7
+ landscape table no longer splits its width equally.
8
+ - A `$$...$$` placeholder in prose prints as text (via content-ir's rule).
9
+ - Consumer action: none — refresh to latest.
10
+
3
11
  ## 0.8.4
4
12
 
5
13
  - **Right-to-left scripts in PDF (Arabic, Hebrew).** Lines are put in visual
package/dist/document.cjs CHANGED
@@ -146,65 +146,54 @@ function visualOrder(input, rtl) {
146
146
  return out;
147
147
  }
148
148
 
149
+ // src/document/layout.ts
150
+ 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("");
151
+ function contentColumnWidths(b, n, avail, measure, pad = 10) {
152
+ const min = new Array(n).fill(0);
153
+ const max = new Array(n).fill(0);
154
+ const rows = [[b.header, true], ...b.rows.map((r) => [r, false])];
155
+ for (const [r, head] of rows) {
156
+ for (let i = 0; i < n; i++) {
157
+ const t = plainInline(r[i] ?? []);
158
+ const longest = t.split(/\s+/).reduce((m, w) => Math.max(m, measure(w, head)), 0);
159
+ min[i] = Math.max(min[i], Math.min(longest, avail * 0.35) + pad);
160
+ max[i] = Math.max(max[i], measure(t, head) + pad);
161
+ }
162
+ }
163
+ const sumMax = max.reduce((a, x) => a + x, 0);
164
+ const sumMin = min.reduce((a, x) => a + x, 0);
165
+ if (sumMax <= avail) return max.map((m) => m + (avail - sumMax) / n);
166
+ if (sumMin >= avail) return min.map((m) => m / sumMin * avail);
167
+ const extra = avail - sumMin;
168
+ return min.map((m, i) => m + (max[i] - m) * (extra / (sumMax - sumMin)));
169
+ }
170
+
149
171
  // src/document/math.ts
150
172
  var import_source = require("@ai-matrx/content-ir/source");
151
173
  var MATH_OPEN = "\uE100";
152
174
  var MATH_CLOSE = "\uE101";
153
175
  var MATH_TOKEN_RE = /\uE100(\d+)\uE101/g;
154
- function codeRanges(text) {
155
- const ranges = [];
156
- for (const re of [/```[\s\S]*?(?:```|$)/g, /~~~[\s\S]*?(?:~~~|$)/g, /`[^`\n]*`/g]) {
157
- let m;
158
- while ((m = re.exec(text)) !== null) {
159
- ranges.push([m.index, m.index + m[0].length]);
160
- if (m[0].length === 0) re.lastIndex++;
161
- }
162
- }
163
- return ranges.sort((a, b) => a[0] - b[0]);
164
- }
176
+ var DELIMITERS = {
177
+ $$: { open: 2, close: 2, display: true },
178
+ "\\[": { open: 2, close: 2, display: true },
179
+ $: { open: 1, close: 1, display: false },
180
+ "\\(": { open: 2, close: 2, display: false }
181
+ };
165
182
  function extractMath(body) {
166
183
  const spans = [];
167
184
  if (!/[$\\]/.test(body)) return { text: body, spans };
168
- const code = codeRanges(body);
169
- const inCode = (i2) => code.some(([a, b]) => i2 >= a && i2 < b);
170
- const display = (0, import_source.pairDisplayMath)(body);
185
+ const islands = (0, import_source.listIslands)((0, import_source.tokenizeSource)(body)).filter((isl) => isl.complete && (isl.islandType === "math_block" || isl.islandType === "math_inline")).sort((a, b) => a.start - b.start);
171
186
  let out = "";
172
- let i = 0;
173
- const token = (tex, isDisplay) => {
174
- spans.push({ tex: tex.trim(), display: isDisplay });
175
- return `${MATH_OPEN}${spans.length - 1}${MATH_CLOSE}`;
176
- };
177
- while (i < body.length) {
178
- const ch = body[i];
179
- if (ch === "$" && !inCode(i)) {
180
- const close = display.get(i);
181
- if (close !== void 0) {
182
- out += token(body.slice(i + 2, close), true);
183
- i = close + 2;
184
- continue;
185
- }
186
- if (body[i + 1] !== "$" && body[i - 1] !== "$" && body[i - 1] !== "\\") {
187
- const end = (0, import_source.singleDollarMathEnd)(body, i);
188
- if (end > 0) {
189
- out += token(body.slice(i + 1, end - 1), false);
190
- i = end;
191
- continue;
192
- }
193
- }
194
- }
195
- if (ch === "\\" && !inCode(i) && (body[i + 1] === "[" || body[i + 1] === "(")) {
196
- const closer = body[i + 1] === "[" ? "\\]" : "\\)";
197
- const end = body.indexOf(closer, i + 2);
198
- if (end > i + 2 && end - i < 2e3 && (body[i + 1] === "[" || !body.slice(i, end).includes("\n\n"))) {
199
- out += token(body.slice(i + 2, end), body[i + 1] === "[");
200
- i = end + 2;
201
- continue;
202
- }
203
- }
204
- out += ch;
205
- i++;
187
+ let at = 0;
188
+ for (const isl of islands) {
189
+ const d = DELIMITERS[String(isl.meta.delimiter ?? "")];
190
+ if (!d || isl.start < at) continue;
191
+ out += body.slice(at, isl.start);
192
+ spans.push({ tex: body.slice(isl.start + d.open, isl.end - d.close).trim(), display: d.display });
193
+ out += `${MATH_OPEN}${spans.length - 1}${MATH_CLOSE}`;
194
+ at = isl.end;
206
195
  }
207
- return { text: out, spans };
196
+ return { text: out + body.slice(at), spans };
208
197
  }
209
198
  var mathKey = (tex, display) => `${display ? "D" : "I"}:${tex}`;
210
199
  var MATHJAX = /* @__PURE__ */ Symbol.for("ai-matrx.print.document.mathjax");
@@ -2964,6 +2953,8 @@ function block(b, c, o) {
2964
2953
  case "table": {
2965
2954
  const n = Math.max(b.header.length, ...b.rows.map((r) => r.length), 1);
2966
2955
  const keep = b.rows.length <= 20;
2956
+ const cellPt = c.s.fontSize;
2957
+ const colTw = contentColumnWidths(b, n, c.width, (t, bold) => t.length * cellPt * (bold ? 0.55 : 0.5), 10).map((w) => Math.round(w * TW));
2967
2958
  const alignOf = (i) => b.align[i] === "center" ? d.AlignmentType.CENTER : b.align[i] === "right" ? d.AlignmentType.RIGHT : d.AlignmentType.LEFT;
2968
2959
  const border = { style: d.BorderStyle.SINGLE, size: 4, color: "E5E7EB" };
2969
2960
  const none = { style: d.BorderStyle.NONE, size: 0, color: "FFFFFF" };
@@ -2973,6 +2964,7 @@ function block(b, c, o) {
2973
2964
  children: Array.from(
2974
2965
  { length: n },
2975
2966
  (_, i) => new d.TableCell({
2967
+ width: { size: colTw[i] ?? 0, type: d.WidthType.DXA },
2976
2968
  ...head ? { shading: { type: d.ShadingType.CLEAR, fill: "F3F4F6", color: "auto" } } : {},
2977
2969
  margins: { top: 60, bottom: 60, left: 100, right: 100 },
2978
2970
  borders: { top: none, left: none, right: none, bottom: head ? { ...border, size: 10, color: HEX.heading } : border },
@@ -2991,7 +2983,9 @@ function block(b, c, o) {
2991
2983
  if (b.caption) out.push(captionParagraph(b.caption, c, true));
2992
2984
  out.push(
2993
2985
  new d.Table({
2994
- width: { size: 100, type: d.WidthType.PERCENTAGE },
2986
+ width: { size: Math.round(c.width * TW), type: d.WidthType.DXA },
2987
+ columnWidths: colTw,
2988
+ layout: d.TableLayoutType.FIXED,
2995
2989
  rows: [row(b.header, true, b.rows.length === 0), ...b.rows.map((r, i) => row(r, false, i === b.rows.length - 1))]
2996
2990
  })
2997
2991
  );
@@ -4234,26 +4228,7 @@ function estimateLines(text, c, size = c.s.fontSize) {
4234
4228
  }
4235
4229
  function columnWidths(b, n, size, c) {
4236
4230
  const measure = (text, bold) => c.faces ? c.faces.measure(text, { bold, fontSize: size }) : text.length * size * 0.5;
4237
- const pad = 10;
4238
- const slack = 1;
4239
- const min = new Array(n).fill(0);
4240
- const max = new Array(n).fill(0);
4241
- const rows = [[b.header, true], ...b.rows.map((r) => [r, false])];
4242
- for (const [r, head] of rows) {
4243
- for (let i = 0; i < n; i++) {
4244
- const t = plain(r[i] ?? []);
4245
- const longest = t.split(/\s+/).reduce((m, w) => Math.max(m, measure(w, head)), 0);
4246
- min[i] = Math.max(min[i], Math.min(longest * slack, c.width * 0.35) + pad);
4247
- max[i] = Math.max(max[i], measure(t, head) * slack + pad);
4248
- }
4249
- }
4250
- const avail = c.width;
4251
- const sumMax = max.reduce((a, x) => a + x, 0);
4252
- const sumMin = min.reduce((a, x) => a + x, 0);
4253
- if (sumMax <= avail) return max.map((m) => m + (avail - sumMax) / n);
4254
- if (sumMin >= avail) return min.map((m) => m / sumMin * avail);
4255
- const extra = avail - sumMin;
4256
- return min.map((m, i) => m + (max[i] - m) * (extra / (sumMax - sumMin)));
4231
+ return contentColumnWidths(b, n, c.width, measure);
4257
4232
  }
4258
4233
  var plain = (nodes) => nodes.map((n) => "value" in n ? n.value : "label" in n ? n.label : "children" in n ? plain(n.children) : "").join("");
4259
4234
  function taskItem(checked, content, c) {