@ai-matrx/print 0.8.8 → 0.8.10

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,43 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.8.10
4
+ ### Unreleased
5
+
6
+ - **Printed table cells read exactly as GFM reads them** (verify-RC-B4 R7-2):
7
+ tables are found and split BEFORE any inline pass, then each cell is read as
8
+ inline content — `\|` prints `|` inside code spans too, backslash escapes
9
+ resolve (`\\\\nas03\\fridge\\` prints `\\nas03\fridge\`, `C:\\temp` prints
10
+ `C:\temp`), code spans by the one code-range rule; a `> 8C | …` line after a
11
+ pipe-less table is a blockquote. Prose backslash escapes (`\*x\*`) print the
12
+ literal character in both skins. Judged against micromark + GFM over the
13
+ shared vectors (`src/markdown-tables-oracle.test.ts`); the verifier's
14
+ round-7 scripts live in `scripts/verifier-rcb4-round7/`.
15
+
16
+ ## 0.8.9
17
+ ### Unreleased
18
+
19
+ - **New subpath `/markdown-html` — THE ONE Markdown→HTML engine** (Matrx
20
+ Alchemy CONTRACT §1.9, ALC-16). `createMarkdownHtmlEngine({ projectors })`
21
+ → `parse` (content-ir marks every kind island, each becomes an atom
22
+ placeholder, the `/document` parse runs once), `fragment` (skins
23
+ `document` / `article` / `inline`; profiles `generic` / `google-docs` /
24
+ `word`), `document`, `plainText` (tables as TSV, TeX kept as `$…$`). Every
25
+ string ends in the allow-list. Optional asset resolver for private images
26
+ (an unresolved image becomes its description with a notice).
27
+ - **Security (LIST T26):** the display-math SVG the PDF writer draws is
28
+ allow-list sanitized (`MATH_SVG_SCHEMA`, `sanitizeMathSvg`) — TeX `\href`,
29
+ `\style`, `\class`, `\cssId`, `\bbox[…]`, `\mmlToken[…]` no longer reach it.
30
+ - `/safe-html`: `engineHtmlSchema`, `sanitizeEngineHtml`.
31
+ - `/document`: `documentToHtml` accepts `srcFor` and `transformBody`; an
32
+ image `srcFor` result now also passes the URL check (EPUB included).
33
+
34
+ - **Tables print by THE GFM rule** (`@ai-matrx/content-ir/source`, verify-RC-B4):
35
+ tables written without edge pipes print as tables; an escaped `\|` stays in
36
+ its cell by backslash parity and prints as `|`; a line that starts another
37
+ block (`- x`, `> y`) ends a pipe-less table; rows print at the header's width.
38
+ The private `splitTableRow` and the pipe-led-only table regex are gone.
39
+ Requires `@ai-matrx/content-ir` with `/source` table exports.
40
+
3
41
  ## 0.8.8
4
42
 
5
43
  - **Security: every markdown→HTML path is allow-list sanitized.** The regex
@@ -608,3 +646,5 @@ originals die at the adoption swap):
608
646
  defaults; the template registry is now immutable; the dev-time geometry
609
647
  check no longer reads `process.env` bare (which would throw in browser
610
648
  consumers).
649
+
650
+
package/dist/document.cjs CHANGED
@@ -368,6 +368,49 @@ var MATHML_SCHEMA = {
368
368
  function sanitizeMathml(mathml) {
369
369
  return sanitizeHtmlFragment(mathml, MATHML_SCHEMA);
370
370
  }
371
+ var MATH_SVG_TAGS = ["svg", "g", "path", "rect", "line", "polyline", "polygon", "circle", "ellipse", "text", "title", "desc"];
372
+ var MATH_SVG_ATTRIBUTES = [
373
+ "xmlns",
374
+ "width",
375
+ "height",
376
+ "viewBox",
377
+ "role",
378
+ "focusable",
379
+ "ariaHidden",
380
+ "ariaLabel",
381
+ "stroke",
382
+ "fill",
383
+ "strokeWidth",
384
+ "strokeLinecap",
385
+ "strokeLinejoin",
386
+ "transform",
387
+ "d",
388
+ "x",
389
+ "y",
390
+ "x1",
391
+ "y1",
392
+ "x2",
393
+ "y2",
394
+ "points",
395
+ "cx",
396
+ "cy",
397
+ "r",
398
+ "rx",
399
+ "ry",
400
+ "dataMmlNode",
401
+ "dataC"
402
+ ];
403
+ var MATH_SVG_SCHEMA = {
404
+ tagNames: MATH_SVG_TAGS,
405
+ attributes: { "*": MATH_SVG_ATTRIBUTES },
406
+ strip: ["script", "style", "foreignObject"],
407
+ clobberPrefix: "",
408
+ clobber: [],
409
+ protocols: {}
410
+ };
411
+ function sanitizeMathSvg(svg) {
412
+ return sanitizeHtmlFragment(svg, MATH_SVG_SCHEMA);
413
+ }
371
414
 
372
415
  // src/document/math.ts
373
416
  var MATH_OPEN = "\uE100";
@@ -441,7 +484,7 @@ async function typesetMathSpans(spans) {
441
484
  }
442
485
  const entry = { mathml: sanitizeMathml(mathml.replace(/\n\s*/g, "")) };
443
486
  if (s.display) {
444
- const svg = mj.svg(s.tex, true);
487
+ const svg = sanitizeMathSvg(mj.svg(s.tex, true));
445
488
  entry.svg = svg;
446
489
  entry.widthEx = Number(/width="([\d.]+)ex"/.exec(svg)?.[1] ?? 0);
447
490
  entry.heightEx = Number(/height="([\d.]+)ex"/.exec(svg)?.[1] ?? 0);
@@ -3551,7 +3594,10 @@ function mathHtml(tex, display, x, inText = false) {
3551
3594
  }
3552
3595
  var href = (id, x) => x.hrefFor ? x.hrefFor(id) : `#${id}`;
3553
3596
  function imageSrc(url, x) {
3554
- if (x.srcFor) return x.srcFor(url);
3597
+ if (x.srcFor) {
3598
+ const src = x.srcFor(url);
3599
+ return src === null ? null : safeUrl(src);
3600
+ }
3555
3601
  const resolved = x.images?.get(url);
3556
3602
  if (resolved) return resolved.dataUrl;
3557
3603
  return safeUrl(url);
@@ -3732,7 +3778,7 @@ ${[2, 3, 4, 5, 6].map((l) => `.doc-toc .toc-l${l}{padding-left:${(l - 1) * 1.2}e
3732
3778
  }
3733
3779
  function documentToHtml(tree, options = {}) {
3734
3780
  const s = tree.settings;
3735
- const x = { tree, images: options.images };
3781
+ const x = { tree, images: options.images, ...options.srcFor ? { srcFor: options.srcFor } : {} };
3736
3782
  const sections = tree.sections.map((sec) => {
3737
3783
  const cls = [
3738
3784
  "doc-section",
@@ -3755,8 +3801,8 @@ ${s.author ? `<meta name="author" content="${(0, import_html_escape.escapeHtml)(
3755
3801
  </head>
3756
3802
  <body>
3757
3803
  <main class="doc">
3758
- ${s.cover ? coverHtml(s, x) : ""}
3759
- ${sections}
3804
+ ${(options.transformBody ?? ((h) => h))(`${s.cover ? coverHtml(s, x) : ""}
3805
+ ${sections}`)}
3760
3806
  </main>
3761
3807
  </body>
3762
3808
  </html>`;
@@ -5095,6 +5141,7 @@ var import_micromark_extension_gfm = require("micromark-extension-gfm");
5095
5141
 
5096
5142
  // src/markdown.ts
5097
5143
  var import_html_escape3 = require("@ai-matrx/kit/html-escape");
5144
+ var import_source2 = require("@ai-matrx/content-ir/source");
5098
5145
  function removeThinkingContent(content) {
5099
5146
  if (!content) return "";
5100
5147
  const hide = (_match, before, after) => before.length >= 2 || after.length >= 2 ? "\n\n" : "\n";