@franken-suite/franken-markdown 0.3.2 → 0.4.4

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.
@@ -1,8 +1,17 @@
1
1
  import initWasm, {
2
+ accessibilityAudit as wasmAccessibilityAudit,
2
3
  capabilities as wasmCapabilities,
3
- renderHtmlConfigured,
4
- renderHtmlConfiguredWithFonts,
5
- renderPdfConfiguredMulti
4
+ documentStats as wasmDocumentStats,
5
+ renderBookPdf as wasmRenderBookPdf,
6
+ renderBookSite as wasmRenderBookSite,
7
+ renderEpubConfigured,
8
+ renderHtmlConfiguredAdvanced,
9
+ renderInteractiveHtmlConfigured,
10
+ renderPdfConfiguredMulti,
11
+ renderSemanticDiffHtml as wasmRenderSemanticDiffHtml,
12
+ renderSvgConfigured,
13
+ searchIndex as wasmSearchIndex,
14
+ semanticDiff as wasmSemanticDiff
6
15
  } from "./pkg/franken_markdown.js";
7
16
 
8
17
  let initPromise = null;
@@ -26,32 +35,39 @@ export async function capabilities() {
26
35
 
27
36
  export async function renderHtml(markdown, options = {}) {
28
37
  await init();
38
+ const pdfImages = pdfImagesOption(options.pdfImages);
29
39
  const fontAssets = fontAssetsOption(options.fontAssets);
30
- if (fontAssets.length > 0) {
31
- return normalizeResult(
32
- renderHtmlConfiguredWithFonts(
33
- String(markdown),
34
- stringOption(options.font),
35
- darkModeOption(options.darkMode),
36
- verbatimOption(options.title),
37
- verbatimOption(options.customCss),
38
- Boolean(options.allowRawHtml),
39
- fontBytesForSlot(fontAssets, "body-regular"),
40
- fontBytesForSlot(fontAssets, "body-bold"),
41
- fontBytesForSlot(fontAssets, "body-italic"),
42
- fontBytesForSlot(fontAssets, "body-bold-italic"),
43
- fontBytesForSlot(fontAssets, "mono-regular")
44
- )
45
- );
40
+ const fontScale = fontScaleOption(options.fontScale ?? options.typeSize);
41
+ const destinations = pdfImages.map((image) => image.destination);
42
+ const lengths = new Uint32Array(pdfImages.map((image) => image.bytes.length));
43
+ const totalBytes = pdfImages.reduce((sum, image) => sum + image.bytes.length, 0);
44
+ const flatBytes = new Uint8Array(totalBytes);
45
+ let offset = 0;
46
+ for (const image of pdfImages) {
47
+ flatBytes.set(image.bytes, offset);
48
+ offset += image.bytes.length;
46
49
  }
47
50
  return normalizeResult(
48
- renderHtmlConfigured(
51
+ renderHtmlConfiguredAdvanced(
49
52
  String(markdown),
50
53
  stringOption(options.font),
51
54
  darkModeOption(options.darkMode),
52
55
  verbatimOption(options.title),
53
56
  verbatimOption(options.customCss),
54
- Boolean(options.allowRawHtml)
57
+ Boolean(options.allowRawHtml),
58
+ fontScale,
59
+ fontBytesForSlot(fontAssets, "body-regular"),
60
+ fontBytesForSlot(fontAssets, "body-bold"),
61
+ fontBytesForSlot(fontAssets, "body-italic"),
62
+ fontBytesForSlot(fontAssets, "body-bold-italic"),
63
+ fontBytesForSlot(fontAssets, "mono-regular"),
64
+ fontWeightsForSlots(fontAssets),
65
+ destinations,
66
+ flatBytes,
67
+ lengths,
68
+ stringOption(options.lang),
69
+ Boolean(options.toc),
70
+ integerOption(options.tocDepth, "tocDepth")
55
71
  )
56
72
  );
57
73
  }
@@ -60,6 +76,8 @@ export async function renderPdf(markdown, options = {}) {
60
76
  await init();
61
77
  const pdfImages = pdfImagesOption(options.pdfImages);
62
78
  const fontAssets = fontAssetsOption(options.fontAssets);
79
+ const fontScale = fontScaleOption(options.fontScale ?? options.typeSize);
80
+ const baseFontSize = numberOption(options.baseFontSize) ?? (fontScale !== undefined ? 11 * fontScale : undefined);
63
81
 
64
82
  // Flatten any number of images into the three parallel arrays the core ABI
65
83
  // accepts (wasm-bindgen cannot pass a Vec<Vec<u8>>): a destination per image,
@@ -91,17 +109,136 @@ export async function renderPdf(markdown, options = {}) {
91
109
  fontBytesForSlot(fontAssets, "body-bold"),
92
110
  fontBytesForSlot(fontAssets, "body-italic"),
93
111
  fontBytesForSlot(fontAssets, "body-bold-italic"),
94
- fontBytesForSlot(fontAssets, "mono-regular")
112
+ fontBytesForSlot(fontAssets, "mono-regular"),
113
+ fontWeightsForSlots(fontAssets),
114
+ baseFontSize,
115
+ numberOption(options.headingScale),
116
+ numberOption(options.tableFontSize),
117
+ Boolean(options.pageNumbers),
118
+ fontScale,
119
+ stringOption(options.lang),
120
+ Boolean(options.toc),
121
+ integerOption(options.tocDepth, "tocDepth"),
122
+ integerOption(options.fitToPages, "fitToPages"),
123
+ options.microtype === "protrusion" || options.microtypeProtrusion === true
95
124
  )
96
125
  );
97
126
  }
98
127
 
128
+ export async function renderSvg(markdown, options = {}) {
129
+ await init();
130
+ return normalizeResult(renderSvgConfigured(
131
+ String(markdown),
132
+ stringOption(options.font),
133
+ darkModeOption(options.darkMode),
134
+ fontScaleOption(options.fontScale ?? options.typeSize),
135
+ numberOption(options.maxWidthPt)
136
+ ));
137
+ }
138
+
139
+ export async function renderEpub(markdown, options = {}) {
140
+ await init();
141
+ return normalizeResult(renderEpubConfigured(
142
+ String(markdown),
143
+ stringOption(options.font),
144
+ darkModeOption(options.darkMode),
145
+ verbatimOption(options.title),
146
+ stringOption(options.lang),
147
+ fontScaleOption(options.fontScale ?? options.typeSize)
148
+ ));
149
+ }
150
+
151
+ export async function renderInteractiveHtml(markdown, options = {}) {
152
+ await init();
153
+ return normalizeResult(renderInteractiveHtmlConfigured(
154
+ String(markdown),
155
+ stringOption(options.font),
156
+ darkModeOption(options.darkMode),
157
+ verbatimOption(options.title),
158
+ stringOption(options.lang),
159
+ fontScaleOption(options.fontScale ?? options.typeSize)
160
+ ));
161
+ }
162
+
163
+ export async function documentStats(markdown) {
164
+ await init();
165
+ return parseJson(wasmDocumentStats(String(markdown)), "document stats JSON");
166
+ }
167
+
168
+ export async function searchIndex(markdown) {
169
+ await init();
170
+ return parseJson(wasmSearchIndex(String(markdown)), "search index JSON");
171
+ }
172
+
173
+ export async function accessibilityAudit(markdown) {
174
+ await init();
175
+ return parseJson(wasmAccessibilityAudit(String(markdown)), "accessibility audit JSON");
176
+ }
177
+
178
+ export async function semanticDiff(oldMarkdown, newMarkdown, options = {}) {
179
+ await init();
180
+ return parseJson(wasmSemanticDiff(
181
+ String(oldMarkdown),
182
+ String(newMarkdown),
183
+ verbatimOption(options.oldName),
184
+ verbatimOption(options.newName)
185
+ ), "semantic diff JSON");
186
+ }
187
+
188
+ export async function renderSemanticDiff(oldMarkdown, newMarkdown, options = {}) {
189
+ await init();
190
+ return normalizeResult(wasmRenderSemanticDiffHtml(
191
+ String(oldMarkdown),
192
+ String(newMarkdown),
193
+ verbatimOption(options.oldName),
194
+ verbatimOption(options.newName)
195
+ ));
196
+ }
197
+
198
+ export async function renderBookSite(files, options = {}) {
199
+ await init();
200
+ const normalized = bookFilesOption(files);
201
+ return normalizeResult(wasmRenderBookSite(
202
+ normalized.map((file) => file.path),
203
+ normalized.map((file) => file.source),
204
+ verbatimOption(options.title),
205
+ stringOption(options.font),
206
+ darkModeOption(options.darkMode),
207
+ fontScaleOption(options.fontScale ?? options.typeSize)
208
+ ));
209
+ }
210
+
211
+ export async function renderBookPdf(files, options = {}) {
212
+ await init();
213
+ const normalized = bookFilesOption(files);
214
+ return normalizeResult(wasmRenderBookPdf(
215
+ normalized.map((file) => file.path),
216
+ normalized.map((file) => file.source),
217
+ verbatimOption(options.title),
218
+ verbatimOption(options.author),
219
+ stringOption(options.font),
220
+ darkModeOption(options.darkMode),
221
+ fontScaleOption(options.fontScale ?? options.typeSize),
222
+ options.pageNumbers !== false
223
+ ));
224
+ }
225
+
99
226
  export async function createRenderer(input) {
100
227
  await init(input);
101
228
  return Object.freeze({
102
229
  capabilities,
230
+ accessibilityAudit,
231
+ documentStats,
232
+ renderBookPdf,
233
+ renderBookSite,
234
+ renderEpub,
103
235
  renderHtml,
104
- renderPdf
236
+ renderInteractiveHtml,
237
+ renderPdf,
238
+ renderSemanticDiff,
239
+ renderSvg,
240
+ searchIndex,
241
+ semanticDiff
105
242
  });
106
243
  }
107
244
 
@@ -214,6 +351,133 @@ function epochOption(value) {
214
351
  return epoch;
215
352
  }
216
353
 
354
+
355
+ /**
356
+ * Coerce an optional typography override to a finite number for the core
357
+ * ABI. Non-finite values are rejected here so the Rust-side deterministic
358
+ * clamps only ever see well-formed input.
359
+ */
360
+ function numberOption(value) {
361
+ if (value === undefined || value === null) {
362
+ return undefined;
363
+ }
364
+ if (typeof value !== "number" || !Number.isFinite(value)) {
365
+ throw new TypeError("typography overrides must be finite numbers");
366
+ }
367
+ return value;
368
+ }
369
+
370
+ function integerOption(value, label) {
371
+ if (value === undefined || value === null) {
372
+ return undefined;
373
+ }
374
+ if (!Number.isSafeInteger(value) || value <= 0) {
375
+ throw new TypeError(`${label} must be a positive integer`);
376
+ }
377
+ return value;
378
+ }
379
+
380
+ function bookFilesOption(value) {
381
+ if (!Array.isArray(value) || value.length === 0) {
382
+ throw new TypeError("book files must be a non-empty array of { path, source } objects");
383
+ }
384
+ return value.map((file, index) => {
385
+ if (file === null || typeof file !== "object") {
386
+ throw new TypeError(`book files[${index}] must be an object`);
387
+ }
388
+ const path = stringOption(file.path);
389
+ if (path === undefined) {
390
+ throw new TypeError(`book files[${index}].path must be a non-empty string`);
391
+ }
392
+ return Object.freeze({ path, source: String(file.source ?? "") });
393
+ });
394
+ }
395
+
396
+ function fontScaleOption(value) {
397
+ if (value === undefined || value === null) {
398
+ return undefined;
399
+ }
400
+ if (typeof value === "number") {
401
+ if (!Number.isFinite(value) || value <= 0) {
402
+ throw new TypeError("fontScale must be a positive finite number");
403
+ }
404
+ return Math.min(3.0, Math.max(0.5, value));
405
+ }
406
+ if (typeof value === "string") {
407
+ const trimmed = value.trim().toLowerCase();
408
+ switch (trimmed) {
409
+ case "xs":
410
+ case "x-small":
411
+ case "extra-small":
412
+ case "extrasmall":
413
+ case "tiny":
414
+ return 0.75;
415
+ case "sm":
416
+ case "small":
417
+ case "compact":
418
+ return 0.875;
419
+ case "md":
420
+ case "medium":
421
+ case "normal":
422
+ case "default":
423
+ case "regular":
424
+ case "standard":
425
+ return 1.0;
426
+ case "lg":
427
+ case "large":
428
+ case "comfortable":
429
+ return 1.125;
430
+ case "xl":
431
+ case "x-large":
432
+ case "extra-large":
433
+ case "extralarge":
434
+ return 1.25;
435
+ case "2xl":
436
+ case "xxl":
437
+ case "huge":
438
+ case "display":
439
+ return 1.5;
440
+ default:
441
+ break;
442
+ }
443
+ if (trimmed.endsWith("%")) {
444
+ const parsed = parseFloat(trimmed.slice(0, -1));
445
+ if (Number.isFinite(parsed) && parsed > 0) {
446
+ return Math.min(3.0, Math.max(0.5, parsed / 100));
447
+ }
448
+ }
449
+ if (trimmed.endsWith("rem")) {
450
+ const parsed = parseFloat(trimmed.slice(0, -3));
451
+ if (Number.isFinite(parsed) && parsed > 0) {
452
+ return Math.min(3.0, Math.max(0.5, parsed));
453
+ }
454
+ }
455
+ if (trimmed.endsWith("em")) {
456
+ const parsed = parseFloat(trimmed.slice(0, -2));
457
+ if (Number.isFinite(parsed) && parsed > 0) {
458
+ return Math.min(3.0, Math.max(0.5, parsed));
459
+ }
460
+ }
461
+ if (trimmed.endsWith("px")) {
462
+ const parsed = parseFloat(trimmed.slice(0, -2));
463
+ if (Number.isFinite(parsed) && parsed > 0) {
464
+ return Math.min(3.0, Math.max(0.5, parsed / 16));
465
+ }
466
+ }
467
+ if (trimmed.endsWith("pt")) {
468
+ const parsed = parseFloat(trimmed.slice(0, -2));
469
+ if (Number.isFinite(parsed) && parsed > 0) {
470
+ return Math.min(3.0, Math.max(0.5, parsed / 11));
471
+ }
472
+ }
473
+ const parsed = parseFloat(trimmed);
474
+ if (Number.isFinite(parsed) && parsed > 0) {
475
+ return Math.min(3.0, Math.max(0.5, parsed));
476
+ }
477
+ throw new TypeError(`unknown fontScale '${value}'. Valid choices: xs, sm, md, lg, xl, 2xl, or a number/percentage.`);
478
+ }
479
+ throw new TypeError("fontScale must be a number or string");
480
+ }
217
481
  function pdfImagesOption(value) {
218
482
  if (value === undefined || value === null) {
219
483
  return [];
@@ -255,7 +519,8 @@ function fontAssetsOption(value) {
255
519
  if (bytes.byteLength === 0) {
256
520
  throw new TypeError(`fontAssets[${index}].bytes must not be empty`);
257
521
  }
258
- return Object.freeze({ slot, bytes });
522
+ const weight = fontWeightOption(asset.weight, `fontAssets[${index}].weight`);
523
+ return Object.freeze({ slot, bytes, weight });
259
524
  });
260
525
  }
261
526
 
@@ -281,6 +546,30 @@ function fontBytesForSlot(assets, slot) {
281
546
  return asset === undefined ? new Uint8Array() : asset.bytes;
282
547
  }
283
548
 
549
+ function fontWeightsForSlots(assets) {
550
+ const slots = [
551
+ "body-regular",
552
+ "body-bold",
553
+ "body-italic",
554
+ "body-bold-italic",
555
+ "mono-regular"
556
+ ];
557
+ return Uint32Array.from(slots, (slot) => {
558
+ const asset = assets.find((entry) => entry.slot === slot);
559
+ return asset === undefined || asset.weight === undefined ? 0 : asset.weight;
560
+ });
561
+ }
562
+
563
+ function fontWeightOption(value, label) {
564
+ if (value === undefined || value === null) {
565
+ return undefined;
566
+ }
567
+ if (typeof value !== "number" || !Number.isInteger(value) || value < 1 || value > 1000) {
568
+ throw new TypeError(`${label} must be an integer 1..=1000`);
569
+ }
570
+ return value;
571
+ }
572
+
284
573
  function bytesOption(value, label) {
285
574
  if (value instanceof Uint8Array) {
286
575
  return value;
package/package.json CHANGED
@@ -1,9 +1,11 @@
1
1
  {
2
2
  "name": "@franken-suite/franken-markdown",
3
- "version": "0.3.2",
3
+ "version": "0.4.4",
4
4
  "description": "Browser/WASM package for franken_markdown Markdown to HTML/PDF rendering.",
5
5
  "type": "module",
6
- "sideEffects": false,
6
+ "sideEffects": [
7
+ "./fmd-view.js"
8
+ ],
7
9
  "license": "LicenseRef-MIT-OpenAI-Anthropic-Rider",
8
10
  "author": "Jeffrey Emanuel",
9
11
  "homepage": "https://github.com/Dicklesworthstone/franken_markdown#readme",
@@ -35,6 +37,10 @@
35
37
  ".": {
36
38
  "types": "./franken_markdown.d.ts",
37
39
  "import": "./franken_markdown.js"
40
+ },
41
+ "./web-component": {
42
+ "types": "./fmd-view.d.ts",
43
+ "import": "./fmd-view.js"
38
44
  }
39
45
  },
40
46
  "files": [
@@ -45,6 +51,8 @@
45
51
  "pkg/franken_markdown.js",
46
52
  "pkg/franken_markdown_bg.wasm",
47
53
  "pkg/franken_markdown_bg.wasm.d.ts",
48
- "pkg/franken_markdown.d.ts"
54
+ "pkg/franken_markdown.d.ts",
55
+ "fmd-view.js",
56
+ "fmd-view.d.ts"
49
57
  ]
50
58
  }
@@ -21,7 +21,7 @@ export class FmdRenderResult {
21
21
  */
22
22
  readonly extension: string;
23
23
  /**
24
- * Stable output format: `html` or `pdf`.
24
+ * Stable output format (`html`, `pdf`, `svg`, `epub`, `zip`, or `diff-html`).
25
25
  */
26
26
  readonly format: string;
27
27
  /**
@@ -34,11 +34,40 @@ export class FmdRenderResult {
34
34
  readonly sourceLength: number;
35
35
  }
36
36
 
37
+ /**
38
+ * Run the exact PDF verification pipeline and keep only authoring-time
39
+ * accessibility findings.
40
+ */
41
+ export function accessibilityAudit(markdown: string): string;
42
+
37
43
  /**
38
44
  * Dependency-free capability contract as JSON.
39
45
  */
40
46
  export function capabilities(): string;
41
47
 
48
+ /**
49
+ * Compute the engine's document intelligence, readability, outline, and
50
+ * structural-lint report without rendering a second time in the host.
51
+ */
52
+ export function documentStats(markdown: string): string;
53
+
54
+ /**
55
+ * Compile in-memory Markdown files into one continuous, bookmarked PDF book.
56
+ */
57
+ export function renderBookPdf(paths: string[], sources: string[], title: string | null | undefined, author: string | null | undefined, font: string | null | undefined, dark_mode: string | null | undefined, font_scale: number | null | undefined, page_numbers: boolean): FmdRenderResult;
58
+
59
+ /**
60
+ * Compile in-memory Markdown files into a deterministic, zero-JavaScript HTML
61
+ * site ZIP. The host owns file selection; the core owns include expansion,
62
+ * link rewriting, navigation, parsing, rendering, and the search index.
63
+ */
64
+ export function renderBookSite(paths: string[], sources: string[], title?: string | null, font?: string | null, dark_mode?: string | null, font_scale?: number | null): FmdRenderResult;
65
+
66
+ /**
67
+ * Render an EPUB 3 e-book through the same parser and HTML theme model.
68
+ */
69
+ export function renderEpubConfigured(markdown: string, font?: string | null, dark_mode?: string | null, title?: string | null, lang?: string | null, font_scale?: number | null): FmdRenderResult;
70
+
42
71
  /**
43
72
  * Render Markdown to self-contained HTML using default browser-safe options.
44
73
  *
@@ -55,6 +84,33 @@ export function renderHtml(markdown: string): FmdRenderResult;
55
84
  */
56
85
  export function renderHtmlConfigured(markdown: string, font: string | null | undefined, dark_mode: string | null | undefined, title: string | null | undefined, custom_css: string | null | undefined, allow_raw_html: boolean): FmdRenderResult;
57
86
 
87
+ /**
88
+ * Render Markdown to self-contained HTML with the complete browser option
89
+ * set, including the core-owned uniform typographic scale.
90
+ *
91
+ * This additive entry point keeps the original narrow ABI stable while giving
92
+ * the ergonomic JavaScript wrapper one canonical path for fonts, images, and
93
+ * type scale. The scale is interpreted by [`WasmRenderOptions`] and therefore
94
+ * changes the Rust-generated theme rather than patching the returned HTML.
95
+ *
96
+ * # Errors
97
+ * Returns a JavaScript error when parallel image arrays are inconsistent, a
98
+ * font asset is invalid, the scale is not positive and finite, or rendering
99
+ * fails.
100
+ */
101
+ export function renderHtmlConfiguredAdvanced(markdown: string, font: string | null | undefined, dark_mode: string | null | undefined, title: string | null | undefined, custom_css: string | null | undefined, allow_raw_html: boolean, font_scale: number | null | undefined, body_regular: Uint8Array, body_bold: Uint8Array, body_italic: Uint8Array, body_bold_italic: Uint8Array, mono_regular: Uint8Array, font_weights: Uint32Array, image_destinations: string[], image_bytes_flat: Uint8Array, image_bytes_lengths: Uint32Array, lang: string | null | undefined, toc: boolean, toc_depth?: number | null): FmdRenderResult;
102
+
103
+ /**
104
+ * Render Markdown to self-contained HTML with fonts and any number of host
105
+ * image assets (data-URI inlined). Parallel image arrays match the PDF multi
106
+ * ABI so the JS wrapper can share flattening.
107
+ *
108
+ * # Errors
109
+ * Returns a JavaScript error when the image arrays are inconsistent, an option
110
+ * is invalid, or rendering fails.
111
+ */
112
+ export function renderHtmlConfiguredMulti(markdown: string, font: string | null | undefined, dark_mode: string | null | undefined, title: string | null | undefined, custom_css: string | null | undefined, allow_raw_html: boolean, body_regular: Uint8Array, body_bold: Uint8Array, body_italic: Uint8Array, body_bold_italic: Uint8Array, mono_regular: Uint8Array, font_weights: Uint32Array, image_destinations: string[], image_bytes_flat: Uint8Array, image_bytes_lengths: Uint32Array): FmdRenderResult;
113
+
58
114
  /**
59
115
  * Render Markdown to self-contained HTML with browser package options and
60
116
  * caller-supplied font bytes.
@@ -64,7 +120,13 @@ export function renderHtmlConfigured(markdown: string, font: string | null | und
64
120
  * # Errors
65
121
  * Returns a JavaScript error when options are invalid or rendering fails.
66
122
  */
67
- export function renderHtmlConfiguredWithFonts(markdown: string, font: string | null | undefined, dark_mode: string | null | undefined, title: string | null | undefined, custom_css: string | null | undefined, allow_raw_html: boolean, body_regular: Uint8Array, body_bold: Uint8Array, body_italic: Uint8Array, body_bold_italic: Uint8Array, mono_regular: Uint8Array): FmdRenderResult;
123
+ export function renderHtmlConfiguredWithFonts(markdown: string, font: string | null | undefined, dark_mode: string | null | undefined, title: string | null | undefined, custom_css: string | null | undefined, allow_raw_html: boolean, body_regular: Uint8Array, body_bold: Uint8Array, body_italic: Uint8Array, body_bold_italic: Uint8Array, mono_regular: Uint8Array, font_weights: Uint32Array): FmdRenderResult;
124
+
125
+ /**
126
+ * Render a self-hosting, single-file HTML workspace with its own editor,
127
+ * preview, intelligence panel, and print/PDF path.
128
+ */
129
+ export function renderInteractiveHtmlConfigured(markdown: string, font?: string | null, dark_mode?: string | null, title?: string | null, lang?: string | null, font_scale?: number | null): FmdRenderResult;
68
130
 
69
131
  /**
70
132
  * Render Markdown to PDF using default browser-safe options.
@@ -97,7 +159,7 @@ export function renderPdfConfigured(markdown: string, font: string | null | unde
97
159
  * Returns a JavaScript error when the image arrays are inconsistent, an option
98
160
  * is invalid, or rendering fails.
99
161
  */
100
- export function renderPdfConfiguredMulti(markdown: string, font: string | null | undefined, dark_mode: string | null | undefined, title: string | null | undefined, author: string | null | undefined, metadata_epoch_seconds: number | null | undefined, allow_raw_html: boolean, code_line_numbers: boolean, image_destinations: string[], image_bytes_flat: Uint8Array, image_bytes_lengths: Uint32Array, body_regular: Uint8Array, body_bold: Uint8Array, body_italic: Uint8Array, body_bold_italic: Uint8Array, mono_regular: Uint8Array): FmdRenderResult;
162
+ export function renderPdfConfiguredMulti(markdown: string, font: string | null | undefined, dark_mode: string | null | undefined, title: string | null | undefined, author: string | null | undefined, metadata_epoch_seconds: number | null | undefined, allow_raw_html: boolean, code_line_numbers: boolean, image_destinations: string[], image_bytes_flat: Uint8Array, image_bytes_lengths: Uint32Array, body_regular: Uint8Array, body_bold: Uint8Array, body_italic: Uint8Array, body_bold_italic: Uint8Array, mono_regular: Uint8Array, font_weights: Uint32Array, base_font_size: number | null | undefined, heading_scale: number | null | undefined, table_font_size: number | null | undefined, page_numbers: boolean, font_scale: number | null | undefined, lang: string | null | undefined, toc: boolean, toc_depth: number | null | undefined, fit_to_pages: number | null | undefined, microtype_protrusion: boolean): FmdRenderResult;
101
163
 
102
164
  /**
103
165
  * Render Markdown to PDF with browser package options, one optional image
@@ -123,26 +185,58 @@ export function renderPdfConfiguredWithAssets(markdown: string, font: string | n
123
185
  */
124
186
  export function renderPdfConfiguredWithImage(markdown: string, font: string | null | undefined, dark_mode: string | null | undefined, title: string | null | undefined, author: string | null | undefined, metadata_epoch_seconds: number | null | undefined, allow_raw_html: boolean, code_line_numbers: boolean, image_destination: string, image_bytes: Uint8Array): FmdRenderResult;
125
187
 
188
+ /**
189
+ * Render a semantic AST diff as a self-contained visual HTML document.
190
+ */
191
+ export function renderSemanticDiffHtml(old_markdown: string, new_markdown: string, old_name?: string | null, new_name?: string | null): FmdRenderResult;
192
+
193
+ /**
194
+ * Render a standalone vector poster with glyph outlines embedded as paths.
195
+ */
196
+ export function renderSvgConfigured(markdown: string, font?: string | null, dark_mode?: string | null, font_scale?: number | null, max_width_pt?: number | null): FmdRenderResult;
197
+
198
+ /**
199
+ * Build the deterministic search index used by static-document experiences.
200
+ */
201
+ export function searchIndex(markdown: string): string;
202
+
203
+ /**
204
+ * Compute a semantic AST diff and return its stable JSON contract.
205
+ */
206
+ export function semanticDiff(old_markdown: string, new_markdown: string, old_name?: string | null, new_name?: string | null): string;
207
+
126
208
  export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
127
209
 
128
210
  export interface InitOutput {
129
211
  readonly memory: WebAssembly.Memory;
130
212
  readonly __wbg_fmdrenderresult_free: (a: number, b: number) => void;
213
+ readonly accessibilityAudit: (a: number, b: number, c: number) => void;
131
214
  readonly capabilities: (a: number) => void;
215
+ readonly documentStats: (a: number, b: number, c: number) => void;
132
216
  readonly fmdrenderresult_bytes: (a: number, b: number) => void;
133
217
  readonly fmdrenderresult_diagnosticsJson: (a: number, b: number) => void;
134
218
  readonly fmdrenderresult_extension: (a: number, b: number) => void;
135
219
  readonly fmdrenderresult_format: (a: number, b: number) => void;
136
220
  readonly fmdrenderresult_mimeType: (a: number, b: number) => void;
137
221
  readonly fmdrenderresult_sourceLength: (a: number) => number;
222
+ readonly renderBookPdf: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number) => void;
223
+ readonly renderBookSite: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number) => void;
224
+ readonly renderEpubConfigured: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number) => void;
138
225
  readonly renderHtml: (a: number, b: number, c: number) => void;
139
226
  readonly renderHtmlConfigured: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number) => void;
140
- readonly renderHtmlConfiguredWithFonts: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number, v: number) => void;
227
+ readonly renderHtmlConfiguredAdvanced: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number, v: number, w: number, x: number, y: number, z: number, a1: number, b1: number, c1: number, d1: number, e1: number, f1: number, g1: number, h1: number, i1: number, j1: number) => void;
228
+ readonly renderHtmlConfiguredMulti: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number, v: number, w: number, x: number, y: number, z: number, a1: number, b1: number, c1: number, d1: number) => void;
229
+ readonly renderHtmlConfiguredWithFonts: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number, v: number, w: number, x: number) => void;
230
+ readonly renderInteractiveHtmlConfigured: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number) => void;
141
231
  readonly renderPdf: (a: number, b: number, c: number) => void;
142
232
  readonly renderPdfConfigured: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number) => void;
143
- readonly renderPdfConfiguredMulti: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number, v: number, w: number, x: number, y: number, z: number, a1: number, b1: number, c1: number, d1: number, e1: number) => void;
233
+ readonly renderPdfConfiguredMulti: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number, v: number, w: number, x: number, y: number, z: number, a1: number, b1: number, c1: number, d1: number, e1: number, f1: number, g1: number, h1: number, i1: number, j1: number, k1: number, l1: number, m1: number, n1: number, o1: number, p1: number, q1: number, r1: number, s1: number, t1: number, u1: number, v1: number) => void;
144
234
  readonly renderPdfConfiguredWithAssets: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number, v: number, w: number, x: number, y: number, z: number, a1: number, b1: number, c1: number) => void;
145
235
  readonly renderPdfConfiguredWithImage: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number) => void;
236
+ readonly renderSemanticDiffHtml: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => number;
237
+ readonly renderSvgConfigured: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number) => void;
238
+ readonly searchIndex: (a: number, b: number, c: number) => void;
239
+ readonly semanticDiff: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => void;
146
240
  readonly __wbindgen_export: (a: number, b: number) => number;
147
241
  readonly __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
148
242
  readonly __wbindgen_add_to_stack_pointer: (a: number) => number;