@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.
@@ -548,14 +548,22 @@ interface HtmlRenderContext {
548
548
  xhtml?: boolean;
549
549
  /** Where an in-document id lives (EPUB chapters split the document). */
550
550
  hrefFor?: (id: string) => string;
551
- /** Image URL override (EPUB packages images inside the book). */
552
- srcFor?: (url: string) => string;
551
+ /** Image URL override (EPUB packages images inside the book; the Markdown→HTML engine's asset port). `null` = unavailable. */
552
+ srcFor?: (url: string) => string | null;
553
553
  }
554
554
  declare function renderBlocksHtml(blocks: Block[], x: HtmlRenderContext): string;
555
555
  /** The print stylesheet for a document's settings. Light mode, always. */
556
556
  declare function documentCss(s: DocumentSettings): string;
557
557
  interface DocumentHtmlOptions {
558
558
  images?: ImageMap | undefined;
559
+ /** Image URL override (see `HtmlRenderContext.srcFor`). */
560
+ srcFor?: ((url: string) => string | null) | undefined;
561
+ /**
562
+ * Rewrites the rendered body (cover + sections) before it is placed in the
563
+ * page — the Markdown→HTML engine renders kind atoms and applies the
564
+ * allow-list here, so the trusted page shell and its CSS stay intact.
565
+ */
566
+ transformBody?: ((html: string) => string) | undefined;
559
567
  }
560
568
  /** A complete, standalone print-grade HTML document. */
561
569
  declare function documentToHtml(tree: DocTree, options?: DocumentHtmlOptions): string;
@@ -548,14 +548,22 @@ interface HtmlRenderContext {
548
548
  xhtml?: boolean;
549
549
  /** Where an in-document id lives (EPUB chapters split the document). */
550
550
  hrefFor?: (id: string) => string;
551
- /** Image URL override (EPUB packages images inside the book). */
552
- srcFor?: (url: string) => string;
551
+ /** Image URL override (EPUB packages images inside the book; the Markdown→HTML engine's asset port). `null` = unavailable. */
552
+ srcFor?: (url: string) => string | null;
553
553
  }
554
554
  declare function renderBlocksHtml(blocks: Block[], x: HtmlRenderContext): string;
555
555
  /** The print stylesheet for a document's settings. Light mode, always. */
556
556
  declare function documentCss(s: DocumentSettings): string;
557
557
  interface DocumentHtmlOptions {
558
558
  images?: ImageMap | undefined;
559
+ /** Image URL override (see `HtmlRenderContext.srcFor`). */
560
+ srcFor?: ((url: string) => string | null) | undefined;
561
+ /**
562
+ * Rewrites the rendered body (cover + sections) before it is placed in the
563
+ * page — the Markdown→HTML engine renders kind atoms and applies the
564
+ * allow-list here, so the trusted page shell and its CSS stay intact.
565
+ */
566
+ transformBody?: ((html: string) => string) | undefined;
559
567
  }
560
568
  /** A complete, standalone print-grade HTML document. */
561
569
  declare function documentToHtml(tree: DocTree, options?: DocumentHtmlOptions): string;
package/dist/document.js CHANGED
@@ -285,6 +285,49 @@ var MATHML_SCHEMA = {
285
285
  function sanitizeMathml(mathml) {
286
286
  return sanitizeHtmlFragment(mathml, MATHML_SCHEMA);
287
287
  }
288
+ var MATH_SVG_TAGS = ["svg", "g", "path", "rect", "line", "polyline", "polygon", "circle", "ellipse", "text", "title", "desc"];
289
+ var MATH_SVG_ATTRIBUTES = [
290
+ "xmlns",
291
+ "width",
292
+ "height",
293
+ "viewBox",
294
+ "role",
295
+ "focusable",
296
+ "ariaHidden",
297
+ "ariaLabel",
298
+ "stroke",
299
+ "fill",
300
+ "strokeWidth",
301
+ "strokeLinecap",
302
+ "strokeLinejoin",
303
+ "transform",
304
+ "d",
305
+ "x",
306
+ "y",
307
+ "x1",
308
+ "y1",
309
+ "x2",
310
+ "y2",
311
+ "points",
312
+ "cx",
313
+ "cy",
314
+ "r",
315
+ "rx",
316
+ "ry",
317
+ "dataMmlNode",
318
+ "dataC"
319
+ ];
320
+ var MATH_SVG_SCHEMA = {
321
+ tagNames: MATH_SVG_TAGS,
322
+ attributes: { "*": MATH_SVG_ATTRIBUTES },
323
+ strip: ["script", "style", "foreignObject"],
324
+ clobberPrefix: "",
325
+ clobber: [],
326
+ protocols: {}
327
+ };
328
+ function sanitizeMathSvg(svg) {
329
+ return sanitizeHtmlFragment(svg, MATH_SVG_SCHEMA);
330
+ }
288
331
 
289
332
  // src/document/math.ts
290
333
  var MATH_OPEN = "\uE100";
@@ -358,7 +401,7 @@ async function typesetMathSpans(spans) {
358
401
  }
359
402
  const entry = { mathml: sanitizeMathml(mathml.replace(/\n\s*/g, "")) };
360
403
  if (s.display) {
361
- const svg = mj.svg(s.tex, true);
404
+ const svg = sanitizeMathSvg(mj.svg(s.tex, true));
362
405
  entry.svg = svg;
363
406
  entry.widthEx = Number(/width="([\d.]+)ex"/.exec(svg)?.[1] ?? 0);
364
407
  entry.heightEx = Number(/height="([\d.]+)ex"/.exec(svg)?.[1] ?? 0);
@@ -3468,7 +3511,10 @@ function mathHtml(tex, display, x, inText = false) {
3468
3511
  }
3469
3512
  var href = (id, x) => x.hrefFor ? x.hrefFor(id) : `#${id}`;
3470
3513
  function imageSrc(url, x) {
3471
- if (x.srcFor) return x.srcFor(url);
3514
+ if (x.srcFor) {
3515
+ const src = x.srcFor(url);
3516
+ return src === null ? null : safeUrl(src);
3517
+ }
3472
3518
  const resolved = x.images?.get(url);
3473
3519
  if (resolved) return resolved.dataUrl;
3474
3520
  return safeUrl(url);
@@ -3649,7 +3695,7 @@ ${[2, 3, 4, 5, 6].map((l) => `.doc-toc .toc-l${l}{padding-left:${(l - 1) * 1.2}e
3649
3695
  }
3650
3696
  function documentToHtml(tree, options = {}) {
3651
3697
  const s = tree.settings;
3652
- const x = { tree, images: options.images };
3698
+ const x = { tree, images: options.images, ...options.srcFor ? { srcFor: options.srcFor } : {} };
3653
3699
  const sections = tree.sections.map((sec) => {
3654
3700
  const cls = [
3655
3701
  "doc-section",
@@ -3672,8 +3718,8 @@ ${s.author ? `<meta name="author" content="${escapeHtml(s.author)}">` : ""}
3672
3718
  </head>
3673
3719
  <body>
3674
3720
  <main class="doc">
3675
- ${s.cover ? coverHtml(s, x) : ""}
3676
- ${sections}
3721
+ ${(options.transformBody ?? ((h) => h))(`${s.cover ? coverHtml(s, x) : ""}
3722
+ ${sections}`)}
3677
3723
  </main>
3678
3724
  </body>
3679
3725
  </html>`;
@@ -5012,6 +5058,7 @@ import { gfm } from "micromark-extension-gfm";
5012
5058
 
5013
5059
  // src/markdown.ts
5014
5060
  import { escapeHtml as escapeHtml3 } from "@ai-matrx/kit/html-escape";
5061
+ import { codeSpanText, findTableEnd, mapCodeRanges, rowCells, tableStartsAt, unescapeCellPipes } from "@ai-matrx/content-ir/source";
5015
5062
  function removeThinkingContent(content) {
5016
5063
  if (!content) return "";
5017
5064
  const hide = (_match, before, after) => before.length >= 2 || after.length >= 2 ? "\n\n" : "\n";