@markup-carve/carve-wasm 0.1.3 → 0.1.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.
package/carve_wasm_bg.js CHANGED
@@ -1,3 +1,101 @@
1
+ /**
2
+ * Replay patch JSON onto a PART 12 tree, returning the result as AST JSON.
3
+ * @param {string} ast
4
+ * @param {string} patch
5
+ * @returns {string}
6
+ */
7
+ export function applyAstPatch(ast, patch) {
8
+ let deferred4_0;
9
+ let deferred4_1;
10
+ try {
11
+ const ptr0 = passStringToWasm0(ast, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
12
+ const len0 = WASM_VECTOR_LEN;
13
+ const ptr1 = passStringToWasm0(patch, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
14
+ const len1 = WASM_VECTOR_LEN;
15
+ const ret = wasm.applyAstPatch(ptr0, len0, ptr1, len1);
16
+ var ptr3 = ret[0];
17
+ var len3 = ret[1];
18
+ if (ret[3]) {
19
+ ptr3 = 0; len3 = 0;
20
+ throw takeFromExternrefTable0(ret[2]);
21
+ }
22
+ deferred4_0 = ptr3;
23
+ deferred4_1 = len3;
24
+ return getStringFromWasm0(ptr3, len3);
25
+ } finally {
26
+ wasm.__wbindgen_free(deferred4_0, deferred4_1, 1);
27
+ }
28
+ }
29
+
30
+ /**
31
+ * Apply a security profile to an AST-JSON document (PART 12), keeping the
32
+ * filtered tree.
33
+ *
34
+ * The `profile` render option filters on the way to HTML and throws the result
35
+ * of the filtering away. This is the same pass with the tree kept, so a host
36
+ * that stores, diffs or re-renders an untrusted document does not have to
37
+ * render HTML and parse it back to get one.
38
+ *
39
+ * `violations` reports what the filter degraded or stripped, which the HTML
40
+ * path cannot: a profile whose action is `error` throws instead, so a
41
+ * resolved call under `to-text` or `strip` is the only place this is visible.
42
+ *
43
+ * Only `profileBaseHost` and `smartTypography` are read from `options`. The
44
+ * rest of the render options describe a renderer, and this is not one.
45
+ *
46
+ * The profile's `max_length` is NOT enforced here: the engine applies it to the
47
+ * source bytes before a parse, and this entry point is handed a tree.
48
+ * @param {string} json
49
+ * @param {string} profile
50
+ * @param {object | null} [options]
51
+ * @returns {ProfileFilterResult}
52
+ */
53
+ export function applyProfile(json, profile, options) {
54
+ const ptr0 = passStringToWasm0(json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
55
+ const len0 = WASM_VECTOR_LEN;
56
+ const ptr1 = passStringToWasm0(profile, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
57
+ const len1 = WASM_VECTOR_LEN;
58
+ const ret = wasm.applyProfile(ptr0, len0, ptr1, len1, isLikeNone(options) ? 0 : addToExternrefTable0(options));
59
+ if (ret[2]) {
60
+ throw takeFromExternrefTable0(ret[1]);
61
+ }
62
+ return takeFromExternrefTable0(ret[0]);
63
+ }
64
+
65
+ /**
66
+ * Replay a reversible patch, forward or inverted.
67
+ *
68
+ * The fingerprint is checked first: a tree that is not the one this patch was
69
+ * made against is refused rather than half-patched. That is a broken caller
70
+ * contract, so it throws.
71
+ * @param {string} ast
72
+ * @param {string} patch
73
+ * @param {boolean | null} [inverse]
74
+ * @returns {string}
75
+ */
76
+ export function applyReversibleAstPatch(ast, patch, inverse) {
77
+ let deferred4_0;
78
+ let deferred4_1;
79
+ try {
80
+ const ptr0 = passStringToWasm0(ast, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
81
+ const len0 = WASM_VECTOR_LEN;
82
+ const ptr1 = passStringToWasm0(patch, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
83
+ const len1 = WASM_VECTOR_LEN;
84
+ const ret = wasm.applyReversibleAstPatch(ptr0, len0, ptr1, len1, isLikeNone(inverse) ? 0xFFFFFF : inverse ? 1 : 0);
85
+ var ptr3 = ret[0];
86
+ var len3 = ret[1];
87
+ if (ret[3]) {
88
+ ptr3 = 0; len3 = 0;
89
+ throw takeFromExternrefTable0(ret[2]);
90
+ }
91
+ deferred4_0 = ptr3;
92
+ deferred4_1 = len3;
93
+ return getStringFromWasm0(ptr3, len3);
94
+ } finally {
95
+ wasm.__wbindgen_free(deferred4_0, deferred4_1, 1);
96
+ }
97
+ }
98
+
1
99
  /**
2
100
  * Apply a trusted patch after its source length and fingerprint still match.
3
101
  * @param {string} source
@@ -25,6 +123,34 @@ export function applySourcePatch(source, patch) {
25
123
  }
26
124
  }
27
125
 
126
+ /**
127
+ * Render an AST-JSON document (PART 12) to ANSI-styled text. See
128
+ * [`ast_json_to_markdown`], including what a tree without positions costs.
129
+ * @param {string} json
130
+ * @param {object | null} [options]
131
+ * @returns {string}
132
+ */
133
+ export function astJsonToAnsi(json, options) {
134
+ let deferred3_0;
135
+ let deferred3_1;
136
+ try {
137
+ const ptr0 = passStringToWasm0(json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
138
+ const len0 = WASM_VECTOR_LEN;
139
+ const ret = wasm.astJsonToAnsi(ptr0, len0, isLikeNone(options) ? 0 : addToExternrefTable0(options));
140
+ var ptr2 = ret[0];
141
+ var len2 = ret[1];
142
+ if (ret[3]) {
143
+ ptr2 = 0; len2 = 0;
144
+ throw takeFromExternrefTable0(ret[2]);
145
+ }
146
+ deferred3_0 = ptr2;
147
+ deferred3_1 = len2;
148
+ return getStringFromWasm0(ptr2, len2);
149
+ } finally {
150
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
151
+ }
152
+ }
153
+
28
154
  /**
29
155
  * Render an AST-JSON document (PART 12) back to canonical Carve source.
30
156
  *
@@ -89,6 +215,164 @@ export function astJsonToHtml(json, options) {
89
215
  }
90
216
  }
91
217
 
218
+ /**
219
+ * Render an AST-JSON document (PART 12) to Markdown.
220
+ *
221
+ * The direct call for a host that already holds a tree. Without it Markdown was
222
+ * reached through `astJsonToCarve` and then `toMarkdown`: a canonical write, a
223
+ * re-parse and a second render for one answer, and lossier than this, because a
224
+ * tree holding something no Carve source can spell is refused by the write
225
+ * rather than rendered.
226
+ *
227
+ * Takes the same options object as [`to_markdown_with_options`], and reads the
228
+ * same narrow part of it. The profile filter and the `before_render` hooks run,
229
+ * as they do in [`ast_json_to_html`].
230
+ *
231
+ * ORDERING FOLLOWS THE TREE. `toMarkdown` parses with positions on, because
232
+ * section 7 orders collected definitions by source position. A tree arriving as
233
+ * JSON carries whatever positions its producer put there, and one carrying none
234
+ * prints its footnote and link definitions in label order. That is the only
235
+ * order available to a tree without spans, so it is reported here rather than
236
+ * repaired.
237
+ * @param {string} json
238
+ * @param {object | null} [options]
239
+ * @returns {string}
240
+ */
241
+ export function astJsonToMarkdown(json, options) {
242
+ let deferred3_0;
243
+ let deferred3_1;
244
+ try {
245
+ const ptr0 = passStringToWasm0(json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
246
+ const len0 = WASM_VECTOR_LEN;
247
+ const ret = wasm.astJsonToMarkdown(ptr0, len0, isLikeNone(options) ? 0 : addToExternrefTable0(options));
248
+ var ptr2 = ret[0];
249
+ var len2 = ret[1];
250
+ if (ret[3]) {
251
+ ptr2 = 0; len2 = 0;
252
+ throw takeFromExternrefTable0(ret[2]);
253
+ }
254
+ deferred3_0 = ptr2;
255
+ deferred3_1 = len2;
256
+ return getStringFromWasm0(ptr2, len2);
257
+ } finally {
258
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
259
+ }
260
+ }
261
+
262
+ /**
263
+ * Render an AST-JSON document (PART 12) to plain text. See
264
+ * [`ast_json_to_markdown`], including what a tree without positions costs.
265
+ * @param {string} json
266
+ * @param {object | null} [options]
267
+ * @returns {string}
268
+ */
269
+ export function astJsonToPlainText(json, options) {
270
+ let deferred3_0;
271
+ let deferred3_1;
272
+ try {
273
+ const ptr0 = passStringToWasm0(json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
274
+ const len0 = WASM_VECTOR_LEN;
275
+ const ret = wasm.astJsonToPlainText(ptr0, len0, isLikeNone(options) ? 0 : addToExternrefTable0(options));
276
+ var ptr2 = ret[0];
277
+ var len2 = ret[1];
278
+ if (ret[3]) {
279
+ ptr2 = 0; len2 = 0;
280
+ throw takeFromExternrefTable0(ret[2]);
281
+ }
282
+ deferred3_0 = ptr2;
283
+ deferred3_1 = len2;
284
+ return getStringFromWasm0(ptr2, len2);
285
+ } finally {
286
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
287
+ }
288
+ }
289
+
290
+ /**
291
+ * The difference between two PART 12 trees, as patch JSON.
292
+ *
293
+ * ```js
294
+ * const patch = createAstPatch(parseJson('# One\n'), parseJson('# Two\n'))
295
+ * applyAstPatch(parseJson('# One\n'), patch) // the '# Two' tree
296
+ * ```
297
+ *
298
+ * Trees and patches both cross as JSON strings, matching `parseJson` and
299
+ * `astJsonToHtml`. A patch carries node payloads, so it carries arbitrary
300
+ * document text - the reason `parseJson` chose a string in the first place.
301
+ *
302
+ * The engine's `ast_patch_to_json` and `ast_patch_from_json` are not bound
303
+ * separately. With the patch crossing as JSON they ARE the encoding of this
304
+ * pair, and a host calling them would be converting JSON it already holds.
305
+ *
306
+ * The operations are position-independent `{ op, path, value }`, so a patch
307
+ * stays meaningful against a tree that moved underneath it - unlike a source
308
+ * patch, which `createSourcePatch` fingerprints against staleness.
309
+ * @param {string} before
310
+ * @param {string} after
311
+ * @returns {string}
312
+ */
313
+ export function createAstPatch(before, after) {
314
+ let deferred4_0;
315
+ let deferred4_1;
316
+ try {
317
+ const ptr0 = passStringToWasm0(before, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
318
+ const len0 = WASM_VECTOR_LEN;
319
+ const ptr1 = passStringToWasm0(after, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
320
+ const len1 = WASM_VECTOR_LEN;
321
+ const ret = wasm.createAstPatch(ptr0, len0, ptr1, len1);
322
+ var ptr3 = ret[0];
323
+ var len3 = ret[1];
324
+ if (ret[3]) {
325
+ ptr3 = 0; len3 = 0;
326
+ throw takeFromExternrefTable0(ret[2]);
327
+ }
328
+ deferred4_0 = ptr3;
329
+ deferred4_1 = len3;
330
+ return getStringFromWasm0(ptr3, len3);
331
+ } finally {
332
+ wasm.__wbindgen_free(deferred4_0, deferred4_1, 1);
333
+ }
334
+ }
335
+
336
+ /**
337
+ * The same difference with its inverse and both fingerprints, as one JSON
338
+ * object: `{ forward, inverse, beforeFingerprint, afterFingerprint }`.
339
+ *
340
+ * This is the shape an undo step wants. THE STACK IS THE HOST'S: every entry
341
+ * point in this package is a pure function that owns nothing, so there is no
342
+ * history kept here to undo against, and a browser host already has one - a
343
+ * key handler, a toolbar, an editor's own history plugin.
344
+ *
345
+ * What the pair adds over two `createAstPatch` calls is the precondition.
346
+ * [`apply_reversible_ast_patch`] refuses a tree whose fingerprint is not the
347
+ * one the patch was made against, so an undo cannot be replayed onto a
348
+ * document that has moved on.
349
+ * @param {string} before
350
+ * @param {string} after
351
+ * @returns {string}
352
+ */
353
+ export function createReversibleAstPatch(before, after) {
354
+ let deferred4_0;
355
+ let deferred4_1;
356
+ try {
357
+ const ptr0 = passStringToWasm0(before, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
358
+ const len0 = WASM_VECTOR_LEN;
359
+ const ptr1 = passStringToWasm0(after, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
360
+ const len1 = WASM_VECTOR_LEN;
361
+ const ret = wasm.createReversibleAstPatch(ptr0, len0, ptr1, len1);
362
+ var ptr3 = ret[0];
363
+ var len3 = ret[1];
364
+ if (ret[3]) {
365
+ ptr3 = 0; len3 = 0;
366
+ throw takeFromExternrefTable0(ret[2]);
367
+ }
368
+ deferred4_0 = ptr3;
369
+ deferred4_1 = len3;
370
+ return getStringFromWasm0(ptr3, len3);
371
+ } finally {
372
+ wasm.__wbindgen_free(deferred4_0, deferred4_1, 1);
373
+ }
374
+ }
375
+
92
376
  /**
93
377
  * Build the smallest single UTF-8 byte-range replacement between two sources.
94
378
  * @param {string} source
@@ -113,6 +397,60 @@ export function createSourcePatch(source, replacement, kind, code) {
113
397
  return takeFromExternrefTable0(ret[0]);
114
398
  }
115
399
 
400
+ /**
401
+ * Expand `{{ path }}` include directives (spec PART 9 §19) through a JS
402
+ * resolver, and hand back the expanded tree as AST JSON.
403
+ *
404
+ * The resolver MUST BE SYNCHRONOUS, which decides who can use this. A browser
405
+ * host that would resolve a path by `fetch` cannot: `fetch` is a Promise and
406
+ * wasm-bindgen cannot await across the call. A host whose files are already in
407
+ * memory - an editor with its open buffers, a bundler, a VFS, a test harness -
408
+ * resolves from that map and is exactly who this is for.
409
+ *
410
+ * ```js
411
+ * const files = new Map([['child.crv', 'Included body.\n']])
412
+ * expandIncludes('Before.\n\n{{ child.crv }}\n', {
413
+ * resolve: (path) => files.get(path) ?? null,
414
+ * })
415
+ * // { json, warnings: [], suppressedWarnings: 0, dependencies: […],
416
+ * // chargedBytes: 15, resolverErrors: [] }
417
+ * ```
418
+ *
419
+ * The resolver returns the child's source as a string, or
420
+ * `{ source, id }` when it can name the file canonically - the id is what the
421
+ * cycle guard compares, so two spellings of one file defeat it without one.
422
+ * `null` refuses the directive as `not-found`; `{ denial }` refuses it in one
423
+ * of the classes §19 names.
424
+ *
425
+ * An `async` resolver returns a Promise, which is not a string and cannot be
426
+ * awaited. That is a per-document failure reported in `resolverErrors`,
427
+ * matching what an `async` `renderers.math` gets from
428
+ * [`to_html_with_renderers`]: the directive stays literal and the caller is
429
+ * told why, rather than the value being swallowed or stringified.
430
+ *
431
+ * The BUDGETS are part of the contract, not a detail: `maxBytes` defaults to
432
+ * `max(1 MB, 8 x source bytes)`, `maxDepth` to 16, `maxResolverCalls` to 1000
433
+ * and `maxWarnings` to 100. They bound what a document of directives can make
434
+ * a host do, and lowering them is how a host serving untrusted documents keeps
435
+ * that bounded.
436
+ *
437
+ * The tree carries no positions. Expansion merges nodes from several files,
438
+ * and a span on a node that came from a child would point into a source the
439
+ * caller did not pass.
440
+ * @param {string} source
441
+ * @param {object} options
442
+ * @returns {IncludeExpansion}
443
+ */
444
+ export function expandIncludes(source, options) {
445
+ const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
446
+ const len0 = WASM_VECTOR_LEN;
447
+ const ret = wasm.expandIncludes(ptr0, len0, options);
448
+ if (ret[2]) {
449
+ throw takeFromExternrefTable0(ret[1]);
450
+ }
451
+ return takeFromExternrefTable0(ret[0]);
452
+ }
453
+
116
454
  /**
117
455
  * Every extension name this build accepts, in registry order.
118
456
  *
@@ -184,7 +522,7 @@ export function fromDjot(source) {
184
522
  /**
185
523
  * @param {string} source
186
524
  * @param {string | null} [mode]
187
- * @returns {any}
525
+ * @returns {MigrationResult}
188
526
  */
189
527
  export function fromHtml(source, mode) {
190
528
  const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
@@ -200,7 +538,7 @@ export function fromHtml(source, mode) {
200
538
 
201
539
  /**
202
540
  * @param {string} source
203
- * @returns {any}
541
+ * @returns {MigrationResult}
204
542
  */
205
543
  export function fromMarkdown(source) {
206
544
  const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
@@ -212,6 +550,77 @@ export function fromMarkdown(source) {
212
550
  return takeFromExternrefTable0(ret[0]);
213
551
  }
214
552
 
553
+ /**
554
+ * Convert a ProseMirror document back to canonical Carve source.
555
+ *
556
+ * The save half of the editor loop. A payload the schema map does not describe
557
+ * is refused rather than written approximately, so an editor extended with a
558
+ * node the bridge has never seen fails where it can be reported.
559
+ * @param {string} doc
560
+ * @returns {string}
561
+ */
562
+ export function fromProseMirror(doc) {
563
+ let deferred3_0;
564
+ let deferred3_1;
565
+ try {
566
+ const ptr0 = passStringToWasm0(doc, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
567
+ const len0 = WASM_VECTOR_LEN;
568
+ const ret = wasm.fromProseMirror(ptr0, len0);
569
+ var ptr2 = ret[0];
570
+ var len2 = ret[1];
571
+ if (ret[3]) {
572
+ ptr2 = 0; len2 = 0;
573
+ throw takeFromExternrefTable0(ret[2]);
574
+ }
575
+ deferred3_0 = ptr2;
576
+ deferred3_1 = len2;
577
+ return getStringFromWasm0(ptr2, len2);
578
+ } finally {
579
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
580
+ }
581
+ }
582
+
583
+ /**
584
+ * Import HTML straight to the tree, as AST JSON.
585
+ *
586
+ * `htmlToCarve` writes Carve SOURCE, so a host that wanted the tree had to
587
+ * re-parse what it had just written - two parses of one document to get one
588
+ * answer. This is the same importer without that round trip.
589
+ *
590
+ * ```js
591
+ * const { value, report } = htmlToAst('<p>Hello <b>world</b></p>', 'safe')
592
+ * astJsonToHtml(value)
593
+ * ```
594
+ *
595
+ * Returns the SAME `{ value, report }` shape `htmlToCarve` does, with `value`
596
+ * holding the tree instead of the source, in the same fidelity vocabulary. A
597
+ * third result shape for one importer is what that avoids.
598
+ *
599
+ * The REPORT IS NOT ALWAYS IDENTICAL, and the difference is the point. A loss
600
+ * only a WRITER takes is not reported here, because no writer ran (PART 12
601
+ * §16): a `<figure>` wrapping a table, or a table with an explicit
602
+ * head/body/foot grouping, has no Carve spelling, so `htmlToCarve` reports
603
+ * `structure-unspellable` and this does not - the tree keeps the thing that
604
+ * would have been lost.
605
+ *
606
+ * `mode` is spelled as it is there: `safe` (the default), `semantic`, and
607
+ * trusted-only `roundtrip`.
608
+ * @param {string} source
609
+ * @param {string | null} [mode]
610
+ * @returns {MigrationResult}
611
+ */
612
+ export function htmlToAst(source, mode) {
613
+ const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
614
+ const len0 = WASM_VECTOR_LEN;
615
+ var ptr1 = isLikeNone(mode) ? 0 : passStringToWasm0(mode, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
616
+ var len1 = WASM_VECTOR_LEN;
617
+ const ret = wasm.htmlToAst(ptr0, len0, ptr1, len1);
618
+ if (ret[2]) {
619
+ throw takeFromExternrefTable0(ret[1]);
620
+ }
621
+ return takeFromExternrefTable0(ret[0]);
622
+ }
623
+
215
624
  /**
216
625
  * Import HTML through the Rust HTML5 DOM and canonical Carve writer.
217
626
  *
@@ -219,7 +628,7 @@ export function fromMarkdown(source) {
219
628
  * decision observable. `roundtrip` is only safe for Carve-produced HTML.
220
629
  * @param {string} source
221
630
  * @param {string | null} [mode]
222
- * @returns {any}
631
+ * @returns {MigrationResult}
223
632
  */
224
633
  export function htmlToCarve(source, mode) {
225
634
  const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
@@ -233,6 +642,25 @@ export function htmlToCarve(source, mode) {
233
642
  return takeFromExternrefTable0(ret[0]);
234
643
  }
235
644
 
645
+ /**
646
+ * The accessibility diagnostics, a second family beside `lintCarve`.
647
+ *
648
+ * Its own rule ids (`a11y/image-alt`, `a11y/heading-jump`) and its own
649
+ * severity, which `lintCarve` has no field for. Offsets are `null` when the
650
+ * node that triggered the rule carried no position.
651
+ * @param {string} source
652
+ * @returns {AccessibilityDiagnostic[]}
653
+ */
654
+ export function lintAccessibility(source) {
655
+ const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
656
+ const len0 = WASM_VECTOR_LEN;
657
+ const ret = wasm.lintAccessibility(ptr0, len0);
658
+ if (ret[2]) {
659
+ throw takeFromExternrefTable0(ret[1]);
660
+ }
661
+ return takeFromExternrefTable0(ret[0]);
662
+ }
663
+
236
664
  /**
237
665
  * Lint a document for the degradations PART 15 describes.
238
666
  *
@@ -249,7 +677,237 @@ export function htmlToCarve(source, mode) {
249
677
  export function lintCarve(source) {
250
678
  const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
251
679
  const len0 = WASM_VECTOR_LEN;
252
- const ret = wasm.lintCarve(ptr0, len0);
680
+ const ret = wasm.lintCarve(ptr0, len0);
681
+ if (ret[2]) {
682
+ throw takeFromExternrefTable0(ret[1]);
683
+ }
684
+ return takeFromExternrefTable0(ret[0]);
685
+ }
686
+
687
+ /**
688
+ * Lint a document with the same options object the render entry points take.
689
+ *
690
+ * `lintCarve` is the option-less form. Which degradations exist depends on the
691
+ * extensions in play, so a host that renders with a set has to lint with it.
692
+ * @param {string} source
693
+ * @param {object | null} [options]
694
+ * @returns {LintWarning[]}
695
+ */
696
+ export function lintCarveWithOptions(source, options) {
697
+ const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
698
+ const len0 = WASM_VECTOR_LEN;
699
+ const ret = wasm.lintCarveWithOptions(ptr0, len0, isLikeNone(options) ? 0 : addToExternrefTable0(options));
700
+ if (ret[2]) {
701
+ throw takeFromExternrefTable0(ret[1]);
702
+ }
703
+ return takeFromExternrefTable0(ret[0]);
704
+ }
705
+
706
+ /**
707
+ * Import Markdown straight to the tree, as AST JSON.
708
+ *
709
+ * `fromMarkdown` writes Carve SOURCE, so a host that wanted the tree had to
710
+ * re-parse what it had just written. This is the same importer without that
711
+ * round trip. The losses `fromMarkdown` reports are not repeated here; a host
712
+ * that needs them calls that one.
713
+ * @param {string} source
714
+ * @returns {string}
715
+ */
716
+ export function markdownToAstJson(source) {
717
+ let deferred2_0;
718
+ let deferred2_1;
719
+ try {
720
+ const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
721
+ const len0 = WASM_VECTOR_LEN;
722
+ const ret = wasm.markdownToAstJson(ptr0, len0);
723
+ deferred2_0 = ret[0];
724
+ deferred2_1 = ret[1];
725
+ return getStringFromWasm0(ret[0], ret[1]);
726
+ } finally {
727
+ wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
728
+ }
729
+ }
730
+
731
+ /**
732
+ * Three-way merge over PART 12 trees, with conflicts as a VALUE.
733
+ *
734
+ * ```js
735
+ * const { ok, ast, conflicts } = JSON.parse(mergeAst(base, ours, theirs))
736
+ * ```
737
+ *
738
+ * Returns `{ ok, ast, conflicts, resolverErrors }` as one JSON string. A
739
+ * conflict does NOT throw: it is a result the caller asked for, and two people
740
+ * editing one document is the ordinary case rather than a broken contract.
741
+ * `ok` is false, `ast` is null, and `conflicts` says where and why.
742
+ *
743
+ * The `{ ok, ast, conflicts }` shape and the three `reason` names -
744
+ * `both-changed`, `delete-edit`, `concurrent-sequence-edit` - are carve-js's,
745
+ * so a host merging with either engine reads one contract. The Rust engine
746
+ * carries no `deleted` flags on a conflict, so that optional carve-js field is
747
+ * absent here rather than guessed at.
748
+ *
749
+ * `options.resolve` is an optional `(conflict) => 'base' | 'ours' | 'theirs' |
750
+ * { value } | null`, answering conflicts while the merge runs; an answer of
751
+ * `null` leaves one unresolved. IT MUST BE SYNCHRONOUS. A resolver that asks a
752
+ * server, or asks the user, returns a Promise the merge cannot await - that is
753
+ * reported in `resolverErrors` and the conflict is left unresolved, the same
754
+ * treatment an `async` `renderers.math` gets.
755
+ * @param {string} base
756
+ * @param {string} ours
757
+ * @param {string} theirs
758
+ * @param {object | null} [options]
759
+ * @returns {string}
760
+ */
761
+ export function mergeAst(base, ours, theirs, options) {
762
+ let deferred5_0;
763
+ let deferred5_1;
764
+ try {
765
+ const ptr0 = passStringToWasm0(base, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
766
+ const len0 = WASM_VECTOR_LEN;
767
+ const ptr1 = passStringToWasm0(ours, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
768
+ const len1 = WASM_VECTOR_LEN;
769
+ const ptr2 = passStringToWasm0(theirs, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
770
+ const len2 = WASM_VECTOR_LEN;
771
+ const ret = wasm.mergeAst(ptr0, len0, ptr1, len1, ptr2, len2, isLikeNone(options) ? 0 : addToExternrefTable0(options));
772
+ var ptr4 = ret[0];
773
+ var len4 = ret[1];
774
+ if (ret[3]) {
775
+ ptr4 = 0; len4 = 0;
776
+ throw takeFromExternrefTable0(ret[2]);
777
+ }
778
+ deferred5_0 = ptr4;
779
+ deferred5_1 = len4;
780
+ return getStringFromWasm0(ptr4, len4);
781
+ } finally {
782
+ wasm.__wbindgen_free(deferred5_0, deferred5_1, 1);
783
+ }
784
+ }
785
+
786
+ /**
787
+ * Convert BBCode and retain a conservative v2 fidelity report.
788
+ * @param {string} source
789
+ * @returns {MigrationResult}
790
+ */
791
+ export function migrateBbcode(source) {
792
+ const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
793
+ const len0 = WASM_VECTOR_LEN;
794
+ const ret = wasm.migrateBbcode(ptr0, len0);
795
+ if (ret[2]) {
796
+ throw takeFromExternrefTable0(ret[1]);
797
+ }
798
+ return takeFromExternrefTable0(ret[0]);
799
+ }
800
+
801
+ /**
802
+ * Convert Djot and retain a conservative v2 fidelity report.
803
+ * @param {string} source
804
+ * @returns {MigrationResult}
805
+ */
806
+ export function migrateDjot(source) {
807
+ const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
808
+ const len0 = WASM_VECTOR_LEN;
809
+ const ret = wasm.migrateDjot(ptr0, len0);
810
+ if (ret[2]) {
811
+ throw takeFromExternrefTable0(ret[1]);
812
+ }
813
+ return takeFromExternrefTable0(ret[0]);
814
+ }
815
+
816
+ /**
817
+ * Whether a document was last processed under an older spec version than
818
+ * `currentVersion`. An unstamped document counts as needing review.
819
+ * @param {string} source
820
+ * @param {string} current_version
821
+ * @returns {boolean}
822
+ */
823
+ export function needsReview(source, current_version) {
824
+ const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
825
+ const len0 = WASM_VECTOR_LEN;
826
+ const ptr1 = passStringToWasm0(current_version, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
827
+ const len1 = WASM_VECTOR_LEN;
828
+ const ret = wasm.needsReview(ptr0, len0, ptr1, len1);
829
+ return ret !== 0;
830
+ }
831
+
832
+ /**
833
+ * Parse Carve source and return its AST as a JSON string.
834
+ *
835
+ * The PART 12 exchange shape (https://markup-carve.github.io/carve/ast-json):
836
+ * the same tree every Carve engine publishes, so a consumer written against
837
+ * one implementation reads another's output. The root carries exactly `type`,
838
+ * `children` and `srcByteLength`; frontmatter and footnote definitions are
839
+ * block nodes inside `children`, not root fields.
840
+ *
841
+ * Returns a STRING rather than a JS object: the caller runs `JSON.parse`, which
842
+ * is what a browser does natively and faster than building the object graph
843
+ * across the wasm boundary one property at a time. It also keeps the bytes
844
+ * available for a caller that stores or forwards them.
845
+ *
846
+ * Position tracking is on for this entry point and nowhere else. PART 12 §4
847
+ * lets an engine gate tracking behind a parse option but requires the
848
+ * serialized form to carry it, and rendering would pay for spans nobody reads.
849
+ * @param {string} source
850
+ * @returns {string}
851
+ */
852
+ export function parseJson(source) {
853
+ let deferred2_0;
854
+ let deferred2_1;
855
+ try {
856
+ const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
857
+ const len0 = WASM_VECTOR_LEN;
858
+ const ret = wasm.parseJson(ptr0, len0);
859
+ deferred2_0 = ret[0];
860
+ deferred2_1 = ret[1];
861
+ return getStringFromWasm0(ret[0], ret[1]);
862
+ } finally {
863
+ wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
864
+ }
865
+ }
866
+
867
+ /**
868
+ * Serialize the tree with the same options object as
869
+ * [`to_html_with_options`], so a host can export the tree of an untrusted
870
+ * document under the `profile` it renders that document with.
871
+ *
872
+ * `positions` is not read: every serialized tree this binding produces carries
873
+ * them, as in [`parse_json`].
874
+ * @param {string} source
875
+ * @param {object | null} [options]
876
+ * @returns {string}
877
+ */
878
+ export function parseJsonWithOptions(source, options) {
879
+ let deferred3_0;
880
+ let deferred3_1;
881
+ try {
882
+ const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
883
+ const len0 = WASM_VECTOR_LEN;
884
+ const ret = wasm.parseJsonWithOptions(ptr0, len0, isLikeNone(options) ? 0 : addToExternrefTable0(options));
885
+ var ptr2 = ret[0];
886
+ var len2 = ret[1];
887
+ if (ret[3]) {
888
+ ptr2 = 0; len2 = 0;
889
+ throw takeFromExternrefTable0(ret[2]);
890
+ }
891
+ deferred3_0 = ptr2;
892
+ deferred3_1 = len2;
893
+ return getStringFromWasm0(ptr2, len2);
894
+ } finally {
895
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
896
+ }
897
+ }
898
+
899
+ /**
900
+ * Parse the locator portion of a citation into `{ label, value, suffixText }`.
901
+ *
902
+ * A field the source did not carry is `null`. Same shape as carve-js
903
+ * `parseLocator`; pure, and never throws on bad input.
904
+ * @param {string} loc
905
+ * @returns {ParsedLocator}
906
+ */
907
+ export function parseLocator(loc) {
908
+ const ptr0 = passStringToWasm0(loc, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
909
+ const len0 = WASM_VECTOR_LEN;
910
+ const ret = wasm.parseLocator(ptr0, len0);
253
911
  if (ret[2]) {
254
912
  throw takeFromExternrefTable0(ret[1]);
255
913
  }
@@ -257,48 +915,53 @@ export function lintCarve(source) {
257
915
  }
258
916
 
259
917
  /**
260
- * Whether a document was last processed under an older spec version than
261
- * `currentVersion`. An unstamped document counts as needing review.
918
+ * Parse a document and keep what a later [`reparse`] needs.
919
+ *
920
+ * Returns one JSON object: `{ source, document, sourceLayout, changedSource,
921
+ * reusedPreviousTree }`. `document` is the PART 12 tree, `sourceLayout` the
922
+ * byte-exact record [`parse_source_layout_json`] produces, and
923
+ * `changedSource` the byte ranges this parse covered - the whole document, on
924
+ * a first parse.
925
+ *
926
+ * The snapshot crosses as JSON rather than as a handle a host has to `free()`.
927
+ * Every other entry point here is a pure function that owns nothing, and the
928
+ * engine's own snapshot holds only the source, so there is no tree being kept
929
+ * alive in wasm memory for a handle to point at.
262
930
  * @param {string} source
263
- * @param {string} current_version
264
- * @returns {boolean}
931
+ * @returns {string}
265
932
  */
266
- export function needsReview(source, current_version) {
267
- const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
268
- const len0 = WASM_VECTOR_LEN;
269
- const ptr1 = passStringToWasm0(current_version, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
270
- const len1 = WASM_VECTOR_LEN;
271
- const ret = wasm.needsReview(ptr0, len0, ptr1, len1);
272
- return ret !== 0;
933
+ export function parseSnapshot(source) {
934
+ let deferred2_0;
935
+ let deferred2_1;
936
+ try {
937
+ const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
938
+ const len0 = WASM_VECTOR_LEN;
939
+ const ret = wasm.parseSnapshot(ptr0, len0);
940
+ deferred2_0 = ret[0];
941
+ deferred2_1 = ret[1];
942
+ return getStringFromWasm0(ret[0], ret[1]);
943
+ } finally {
944
+ wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
945
+ }
273
946
  }
274
947
 
275
948
  /**
276
- * Parse Carve source and return its AST as a JSON string.
277
- *
278
- * The PART 12 exchange shape (https://markup-carve.github.io/carve/ast-json):
279
- * the same tree every Carve engine publishes, so a consumer written against
280
- * one implementation reads another's output. The root carries exactly `type`,
281
- * `children` and `srcByteLength`; frontmatter and footnote definitions are
282
- * block nodes inside `children`, not root fields.
283
- *
284
- * Returns a STRING rather than a JS object: the caller runs `JSON.parse`, which
285
- * is what a browser does natively and faster than building the object graph
286
- * across the wasm boundary one property at a time. It also keeps the bytes
287
- * available for a caller that stores or forwards them.
949
+ * The PART 12 §13 source-layout sidecar for a document.
288
950
  *
289
- * Position tracking is on for this entry point and nowhere else. PART 12 §4
290
- * lets an engine gate tracking behind a parse option but requires the
291
- * serialized form to carry it, and rendering would pay for spans nobody reads.
951
+ * Separate from `parseJson`, which carries semantic positions on the nodes.
952
+ * This is the byte-exact record of the SOURCE: its line endings, whether it
953
+ * had a BOM, and a path-addressed byte span per node - what a host needs to
954
+ * write an edit back into the file it came from.
292
955
  * @param {string} source
293
956
  * @returns {string}
294
957
  */
295
- export function parseJson(source) {
958
+ export function parseSourceLayoutJson(source) {
296
959
  let deferred2_0;
297
960
  let deferred2_1;
298
961
  try {
299
962
  const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
300
963
  const len0 = WASM_VECTOR_LEN;
301
- const ret = wasm.parseJson(ptr0, len0);
964
+ const ret = wasm.parseSourceLayoutJson(ptr0, len0);
302
965
  deferred2_0 = ret[0];
303
966
  deferred2_1 = ret[1];
304
967
  return getStringFromWasm0(ret[0], ret[1]);
@@ -322,6 +985,120 @@ export function readStamp(source) {
322
985
  return takeFromExternrefTable0(ret[0]);
323
986
  }
324
987
 
988
+ /**
989
+ * Re-parse `source` with `changes` applied.
990
+ *
991
+ * ```js
992
+ * const first = JSON.parse(parseSnapshot('# One\n'))
993
+ * const next = JSON.parse(reparse(first.source, '[{"range":[2,5],"replacement":"Two"}]'))
994
+ * ```
995
+ *
996
+ * `changes` is a JSON array of `{ range: [start, end], replacement }`.
997
+ *
998
+ * THE OFFSETS ARE UTF-8 BYTE OFFSETS, which is what `parseJson` positions and
999
+ * `createSourcePatch` ranges already mean. A browser editor counts UTF-16 code
1000
+ * units, so a host holding a `selectionStart` converts before calling - an
1001
+ * offset that lands inside a multi-byte character is refused rather than
1002
+ * guessed at.
1003
+ *
1004
+ * A malformed change THROWS: overlapping ranges, an end past the source, and a
1005
+ * range that splits a code point are all a broken caller contract, not a
1006
+ * result the caller asked for.
1007
+ *
1008
+ * `reusedPreviousTree` says whether the parse reused any of the previous one.
1009
+ * The pinned engine always reports `false` - it validates and applies the
1010
+ * edits and then parses the whole source - so a host should read this as the
1011
+ * engine's own answer rather than assume work was saved.
1012
+ * @param {string} source
1013
+ * @param {string} changes
1014
+ * @returns {string}
1015
+ */
1016
+ export function reparse(source, changes) {
1017
+ let deferred4_0;
1018
+ let deferred4_1;
1019
+ try {
1020
+ const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1021
+ const len0 = WASM_VECTOR_LEN;
1022
+ const ptr1 = passStringToWasm0(changes, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1023
+ const len1 = WASM_VECTOR_LEN;
1024
+ const ret = wasm.reparse(ptr0, len0, ptr1, len1);
1025
+ var ptr3 = ret[0];
1026
+ var len3 = ret[1];
1027
+ if (ret[3]) {
1028
+ ptr3 = 0; len3 = 0;
1029
+ throw takeFromExternrefTable0(ret[2]);
1030
+ }
1031
+ deferred4_0 = ptr3;
1032
+ deferred4_1 = len3;
1033
+ return getStringFromWasm0(ptr3, len3);
1034
+ } finally {
1035
+ wasm.__wbindgen_free(deferred4_0, deferred4_1, 1);
1036
+ }
1037
+ }
1038
+
1039
+ /**
1040
+ * Sanitize an SVG document, the helper a host embedding SVG would otherwise
1041
+ * reimplement.
1042
+ *
1043
+ * `{ svg, ok }`. `ok` false means the input was not a single well-formed
1044
+ * `<svg>` root, and a caller must then show the SOURCE rather than the input:
1045
+ * `svg` carries nothing to display. Every option defaults to `false`, which is
1046
+ * the strict setting.
1047
+ * @param {string} source
1048
+ * @param {object | null} [options]
1049
+ * @returns {SanitizeResult}
1050
+ */
1051
+ export function sanitizeSvg(source, options) {
1052
+ const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1053
+ const len0 = WASM_VECTOR_LEN;
1054
+ const ret = wasm.sanitizeSvg(ptr0, len0, isLikeNone(options) ? 0 : addToExternrefTable0(options));
1055
+ if (ret[2]) {
1056
+ throw takeFromExternrefTable0(ret[1]);
1057
+ }
1058
+ return takeFromExternrefTable0(ret[0]);
1059
+ }
1060
+
1061
+ /**
1062
+ * Write a provenance marker onto already-formatted Carve.
1063
+ *
1064
+ * The other half of `readStamp` and `needsReview`, which could read a marker
1065
+ * this package had no way to write. `generatedBy` is the engine identity a
1066
+ * host wants recorded, e.g. `"my-app 1.2"`; `form` is `"line"` (default) or
1067
+ * `"block"`. Same signature as carve-js `stampCarve`.
1068
+ *
1069
+ * The input is expected to be formatted already: this appends the marker and
1070
+ * replaces one the document carries, it does not canonicalize. `toCarve` is
1071
+ * the formatter.
1072
+ * @param {string} formatted
1073
+ * @param {string} generated_by
1074
+ * @param {string | null} [form]
1075
+ * @returns {string}
1076
+ */
1077
+ export function stampCarve(formatted, generated_by, form) {
1078
+ let deferred5_0;
1079
+ let deferred5_1;
1080
+ try {
1081
+ const ptr0 = passStringToWasm0(formatted, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1082
+ const len0 = WASM_VECTOR_LEN;
1083
+ const ptr1 = passStringToWasm0(generated_by, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1084
+ const len1 = WASM_VECTOR_LEN;
1085
+ var ptr2 = isLikeNone(form) ? 0 : passStringToWasm0(form, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1086
+ var len2 = WASM_VECTOR_LEN;
1087
+ const ret = wasm.stampCarve(ptr0, len0, ptr1, len1, ptr2, len2);
1088
+ var ptr4 = ret[0];
1089
+ var len4 = ret[1];
1090
+ if (ret[3]) {
1091
+ ptr4 = 0; len4 = 0;
1092
+ throw takeFromExternrefTable0(ret[2]);
1093
+ }
1094
+ deferred5_0 = ptr4;
1095
+ deferred5_1 = len4;
1096
+ return getStringFromWasm0(ptr4, len4);
1097
+ } finally {
1098
+ wasm.__wbindgen_free(deferred5_0, deferred5_1, 1);
1099
+ }
1100
+ }
1101
+
325
1102
  /**
326
1103
  * @param {string} source
327
1104
  * @returns {string}
@@ -341,6 +1118,34 @@ export function toAnsi(source) {
341
1118
  }
342
1119
  }
343
1120
 
1121
+ /**
1122
+ * Render to ANSI text with an options object. See
1123
+ * [`to_markdown_with_options`].
1124
+ * @param {string} source
1125
+ * @param {object | null} [options]
1126
+ * @returns {string}
1127
+ */
1128
+ export function toAnsiWithOptions(source, options) {
1129
+ let deferred3_0;
1130
+ let deferred3_1;
1131
+ try {
1132
+ const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1133
+ const len0 = WASM_VECTOR_LEN;
1134
+ const ret = wasm.toAnsiWithOptions(ptr0, len0, isLikeNone(options) ? 0 : addToExternrefTable0(options));
1135
+ var ptr2 = ret[0];
1136
+ var len2 = ret[1];
1137
+ if (ret[3]) {
1138
+ ptr2 = 0; len2 = 0;
1139
+ throw takeFromExternrefTable0(ret[2]);
1140
+ }
1141
+ deferred3_0 = ptr2;
1142
+ deferred3_1 = len2;
1143
+ return getStringFromWasm0(ptr2, len2);
1144
+ } finally {
1145
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
1146
+ }
1147
+ }
1148
+
344
1149
  /**
345
1150
  * @param {string} source
346
1151
  * @param {boolean | null} [strict]
@@ -391,6 +1196,36 @@ export function toCarvePatch(source) {
391
1196
  return takeFromExternrefTable0(ret[0]);
392
1197
  }
393
1198
 
1199
+ /**
1200
+ * Write canonical Carve with an options object.
1201
+ *
1202
+ * `profile` is the only option this target reads; see
1203
+ * [`to_markdown_with_options`] for why.
1204
+ * @param {string} source
1205
+ * @param {object | null} [options]
1206
+ * @returns {string}
1207
+ */
1208
+ export function toCarveWithOptions(source, options) {
1209
+ let deferred3_0;
1210
+ let deferred3_1;
1211
+ try {
1212
+ const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1213
+ const len0 = WASM_VECTOR_LEN;
1214
+ const ret = wasm.toCarveWithOptions(ptr0, len0, isLikeNone(options) ? 0 : addToExternrefTable0(options));
1215
+ var ptr2 = ret[0];
1216
+ var len2 = ret[1];
1217
+ if (ret[3]) {
1218
+ ptr2 = 0; len2 = 0;
1219
+ throw takeFromExternrefTable0(ret[2]);
1220
+ }
1221
+ deferred3_0 = ptr2;
1222
+ deferred3_1 = len2;
1223
+ return getStringFromWasm0(ptr2, len2);
1224
+ } finally {
1225
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
1226
+ }
1227
+ }
1228
+
394
1229
  /**
395
1230
  * @param {string} source
396
1231
  * @param {boolean | null} [strict]
@@ -522,11 +1357,22 @@ export function toHtmlFull(source, symbols) {
522
1357
  * * `lowercaseHeadingIds` (default `false`) and `asciiHeadingIds`
523
1358
  * (`"off"` (default), `"fold"`, `"strict"`) - the slug policy, for a host
524
1359
  * whose anchors have to match another generator's.
1360
+ * * `mentionUrl` and `tagUrl` - URL templates for `@mention` and `#tag`.
1361
+ * Without them both render as inert spans, which is why a host that wants
1362
+ * them linked has to say where to. The token name is percent-encoded into
1363
+ * `{name}` - `{user}` works too for a mention - and the result goes through
1364
+ * the same URL sanitizer as an authored link. These are the HOST's
1365
+ * configuration, not the document's: the template is trusted, the name
1366
+ * substituted into it is not.
525
1367
  *
526
1368
  * An unrecognized key is ignored: the object is configuration, and a caller
527
1369
  * who mistypes one deserves the render to still work. A wrong TYPE on a key
528
1370
  * that is recognized does throw, because that changes behavior silently.
529
1371
  *
1372
+ * `renderers` is the one recognized key this entry point refuses, because a
1373
+ * render callback can fail and a bare string has nowhere to report that. Use
1374
+ * [`to_html_with_renderers`].
1375
+ *
530
1376
  * Turning sections off changes nothing else. Ids, collision dedup, `</#id>`
531
1377
  * crossrefs, implicit `[Heading][]` references and heading numbering all
532
1378
  * resolve against the slug rather than the element carrying it, and the
@@ -557,6 +1403,77 @@ export function toHtmlWithOptions(source, options) {
557
1403
  }
558
1404
  }
559
1405
 
1406
+ /**
1407
+ * Render with a build-time math renderer, the option `mode: "static"` needs.
1408
+ *
1409
+ * Static output carries no client scripts, so a formula it contains has to be
1410
+ * rendered while the HTML is being written. `renderers.math` is the callback
1411
+ * the engine calls for each ``` ```math ``` fence, with the TeX source and a
1412
+ * display flag; KaTeX's `renderToString` has that exact shape.
1413
+ *
1414
+ * ```js
1415
+ * toHtmlWithRenderers(src, {
1416
+ * mode: 'static',
1417
+ * extensions: ['math-block'],
1418
+ * renderers: { math: (tex, display) => katex.renderToString(tex, { displayMode: display }) },
1419
+ * })
1420
+ * // { html: '…', rendererErrors: [] }
1421
+ * ```
1422
+ *
1423
+ * SECURITY: what the callback returns is inserted as **TRUSTED RAW HTML**, the
1424
+ * same trust class as a `symbols` value. The difference worth stating: a symbol
1425
+ * value is host configuration keyed by a NAME, while a renderer is host
1426
+ * configuration that is HANDED DOCUMENT CONTENT and typically echoes some of it
1427
+ * back. A host rendering documents it did not author is accepting whatever its
1428
+ * renderer makes of that input, so the escaping is the renderer's job.
1429
+ *
1430
+ * The engine consults the renderer only under `mode: "static"`; interactive
1431
+ * output keeps the `\[…\]` source for the client to typeset, and so does a
1432
+ * static render with no renderer supplied.
1433
+ *
1434
+ * The callback must be SYNCHRONOUS. wasm-bindgen cannot await across it, so an
1435
+ * `async` renderer returns a Promise the engine has no way to resolve; that is
1436
+ * recorded as a failure rather than stringified into the document.
1437
+ *
1438
+ * `renderers.diagrams` is the same callback one level down, keyed by the
1439
+ * fence's css class: `{ mermaid: (source) => html }`. A host that renders its
1440
+ * diagrams beforehand passes the lookup in that one line -
1441
+ * `(source) => prerendered.get(source)`. Mermaid itself cannot be passed,
1442
+ * because its `render` returns a Promise from v10 on.
1443
+ *
1444
+ * ```js
1445
+ * toHtmlWithRenderers(src, {
1446
+ * mode: 'static',
1447
+ * extensions: ['fenced-render'],
1448
+ * renderers: { diagrams: { mermaid: (source) => prerendered.get(source) } },
1449
+ * })
1450
+ * ```
1451
+ *
1452
+ * A diagram key the document never uses renders nothing and reports nothing.
1453
+ * So does a fence whose class the caller did not configure: the engine
1454
+ * degrades it to an escaped source block, and this binding never sees the
1455
+ * node.
1456
+ *
1457
+ * A callback that throws, or returns anything other than a string, does not
1458
+ * abort the render: the node it was called for emits nothing and the failure
1459
+ * is reported in `rendererErrors`, with `renderer` naming the css class.
1460
+ * This entry point exists because [`to_html_with_options`] returns a bare
1461
+ * string with nowhere to put that, and so it rejects `renderers` rather than
1462
+ * dropping the failures.
1463
+ * @param {string} source
1464
+ * @param {object | null} [options]
1465
+ * @returns {StaticRenderResult}
1466
+ */
1467
+ export function toHtmlWithRenderers(source, options) {
1468
+ const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1469
+ const len0 = WASM_VECTOR_LEN;
1470
+ const ret = wasm.toHtmlWithRenderers(ptr0, len0, isLikeNone(options) ? 0 : addToExternrefTable0(options));
1471
+ if (ret[2]) {
1472
+ throw takeFromExternrefTable0(ret[1]);
1473
+ }
1474
+ return takeFromExternrefTable0(ret[0]);
1475
+ }
1476
+
560
1477
  /**
561
1478
  * @param {string} source
562
1479
  * @param {boolean | null} [strict]
@@ -632,6 +1549,52 @@ export function toMarkdown(source) {
632
1549
  }
633
1550
  }
634
1551
 
1552
+ /**
1553
+ * Render to Markdown with the same options object as
1554
+ * [`to_html_with_options`].
1555
+ *
1556
+ * `profile` is why this exists. Without it a host can hold an untrusted
1557
+ * document to a profile on the way to HTML and not on the way to Markdown,
1558
+ * out of one package: the max-length bound, the denied constructs and the
1559
+ * link policy were all unreachable here. A document the profile rejects
1560
+ * throws a `ProfileViolationError` rather than resolving to an empty string.
1561
+ *
1562
+ * What these targets read is narrower than HTML's list: `profile` and
1563
+ * `smartTypography` change the output and extensions run, while `symbols`
1564
+ * (markup-carve/carve-rs#1668), `labels`, `sections`, `sourceLine`, `mode` and
1565
+ * the heading-id switches are HTML-side concerns the engine's other renderers
1566
+ * do not consult. `renderers` is refused for the reason
1567
+ * [`to_html_with_options`] refuses it.
1568
+ *
1569
+ * [`to_carve_with_options`] is narrower again and reads `profile` alone: the
1570
+ * engine's canonical writer is parse-only by contract, so extensions and
1571
+ * `smartTypography` are inert there. They are accepted rather than refused
1572
+ * because one options object is meant to serve every target.
1573
+ * @param {string} source
1574
+ * @param {object | null} [options]
1575
+ * @returns {string}
1576
+ */
1577
+ export function toMarkdownWithOptions(source, options) {
1578
+ let deferred3_0;
1579
+ let deferred3_1;
1580
+ try {
1581
+ const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1582
+ const len0 = WASM_VECTOR_LEN;
1583
+ const ret = wasm.toMarkdownWithOptions(ptr0, len0, isLikeNone(options) ? 0 : addToExternrefTable0(options));
1584
+ var ptr2 = ret[0];
1585
+ var len2 = ret[1];
1586
+ if (ret[3]) {
1587
+ ptr2 = 0; len2 = 0;
1588
+ throw takeFromExternrefTable0(ret[2]);
1589
+ }
1590
+ deferred3_0 = ptr2;
1591
+ deferred3_1 = len2;
1592
+ return getStringFromWasm0(ptr2, len2);
1593
+ } finally {
1594
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
1595
+ }
1596
+ }
1597
+
635
1598
  /**
636
1599
  * @param {string} source
637
1600
  * @param {boolean | null} [strict]
@@ -667,6 +1630,34 @@ export function toPlainText(source) {
667
1630
  }
668
1631
  }
669
1632
 
1633
+ /**
1634
+ * Render to plain text with an options object. See
1635
+ * [`to_markdown_with_options`].
1636
+ * @param {string} source
1637
+ * @param {object | null} [options]
1638
+ * @returns {string}
1639
+ */
1640
+ export function toPlainTextWithOptions(source, options) {
1641
+ let deferred3_0;
1642
+ let deferred3_1;
1643
+ try {
1644
+ const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1645
+ const len0 = WASM_VECTOR_LEN;
1646
+ const ret = wasm.toPlainTextWithOptions(ptr0, len0, isLikeNone(options) ? 0 : addToExternrefTable0(options));
1647
+ var ptr2 = ret[0];
1648
+ var len2 = ret[1];
1649
+ if (ret[3]) {
1650
+ ptr2 = 0; len2 = 0;
1651
+ throw takeFromExternrefTable0(ret[2]);
1652
+ }
1653
+ deferred3_0 = ptr2;
1654
+ deferred3_1 = len2;
1655
+ return getStringFromWasm0(ptr2, len2);
1656
+ } finally {
1657
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
1658
+ }
1659
+ }
1660
+
670
1661
  /**
671
1662
  * @param {string} source
672
1663
  * @param {boolean | null} [strict]
@@ -683,6 +1674,33 @@ export function toPlainTextWithReport(source, strict, maximum) {
683
1674
  return takeFromExternrefTable0(ret[0]);
684
1675
  }
685
1676
 
1677
+ /**
1678
+ * Convert Carve source to the ProseMirror document shape.
1679
+ *
1680
+ * ProseMirror runs in a browser and nowhere else, so this is the one engine
1681
+ * capability whose whole audience sits behind a WASM binding. Without it a host
1682
+ * wiring a Carve editor either round-trips to a server or reimplements the node
1683
+ * mapping in JS, where it drifts from the engine's.
1684
+ *
1685
+ * Returns `{ json, dropped, degraded }`. `json` is the ProseMirror document as
1686
+ * a JSON string, the same choice `parseJson` makes and for the same reason.
1687
+ * The two maps say what the ProseMirror model could not hold: `dropped` where
1688
+ * the content is gone, `degraded` where the text survives without its node
1689
+ * type. A silent conversion is the degradation shape `lintCarve` exists to
1690
+ * avoid.
1691
+ * @param {string} source
1692
+ * @returns {ProseMirrorResult}
1693
+ */
1694
+ export function toProseMirror(source) {
1695
+ const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1696
+ const len0 = WASM_VECTOR_LEN;
1697
+ const ret = wasm.toProseMirror(ptr0, len0);
1698
+ if (ret[2]) {
1699
+ throw takeFromExternrefTable0(ret[1]);
1700
+ }
1701
+ return takeFromExternrefTable0(ret[0]);
1702
+ }
1703
+
686
1704
  /**
687
1705
  * @returns {string}
688
1706
  */
@@ -785,10 +1803,22 @@ export function __wbg___wbindgen_string_get_914df97fcfa788f2(arg0, arg1) {
785
1803
  export function __wbg___wbindgen_throw_81fc77679af83bc6(arg0, arg1) {
786
1804
  throw new Error(getStringFromWasm0(arg0, arg1));
787
1805
  }
1806
+ export function __wbg___wbindgen_typeof_ec2e006152efc95c(arg0) {
1807
+ const ret = typeof arg0;
1808
+ return ret;
1809
+ }
1810
+ export function __wbg_call_368fa9c372d473ba() { return handleError(function (arg0, arg1, arg2, arg3) {
1811
+ const ret = arg0.call(arg1, arg2, arg3);
1812
+ return ret;
1813
+ }, arguments); }
788
1814
  export function __wbg_call_7f2987183bb62793() { return handleError(function (arg0, arg1) {
789
1815
  const ret = arg0.call(arg1);
790
1816
  return ret;
791
1817
  }, arguments); }
1818
+ export function __wbg_call_d578befcc3145dee() { return handleError(function (arg0, arg1, arg2) {
1819
+ const ret = arg0.call(arg1, arg2);
1820
+ return ret;
1821
+ }, arguments); }
792
1822
  export function __wbg_done_547d467e97529006(arg0) {
793
1823
  const ret = arg0.done;
794
1824
  return ret;
@@ -835,6 +1865,16 @@ export function __wbg_instanceof_ArrayBuffer_ff7c1337a5e3b33a(arg0) {
835
1865
  const ret = result;
836
1866
  return ret;
837
1867
  }
1868
+ export function __wbg_instanceof_Error_e3390d6805733dad(arg0) {
1869
+ let result;
1870
+ try {
1871
+ result = arg0 instanceof Error;
1872
+ } catch (_) {
1873
+ result = false;
1874
+ }
1875
+ const ret = result;
1876
+ return ret;
1877
+ }
838
1878
  export function __wbg_instanceof_Map_a10a2795ef4bfe97(arg0) {
839
1879
  let result;
840
1880
  try {
@@ -855,6 +1895,16 @@ export function __wbg_instanceof_Object_72ee0c53dd8f0726(arg0) {
855
1895
  const ret = result;
856
1896
  return ret;
857
1897
  }
1898
+ export function __wbg_instanceof_Promise_95d523058012a13d(arg0) {
1899
+ let result;
1900
+ try {
1901
+ result = arg0 instanceof Promise;
1902
+ } catch (_) {
1903
+ result = false;
1904
+ }
1905
+ const ret = result;
1906
+ return ret;
1907
+ }
858
1908
  export function __wbg_instanceof_Uint8Array_4b8da683deb25d72(arg0) {
859
1909
  let result;
860
1910
  try {
@@ -885,6 +1935,10 @@ export function __wbg_length_6e821edde497a532(arg0) {
885
1935
  const ret = arg0.length;
886
1936
  return ret;
887
1937
  }
1938
+ export function __wbg_message_7367f8c7d0fa1589(arg0) {
1939
+ const ret = arg0.message;
1940
+ return ret;
1941
+ }
888
1942
  export function __wbg_new_47dfee3855dec446(arg0, arg1) {
889
1943
  const ret = new TypeError(getStringFromWasm0(arg0, arg1));
890
1944
  return ret;
@@ -937,6 +1991,10 @@ export function __wbg_set_8ee2d34facb8466e() { return handleError(function (arg0
937
1991
  export function __wbg_set_name_ab9c98596fd7310a(arg0, arg1, arg2) {
938
1992
  arg0.name = getStringFromWasm0(arg1, arg2);
939
1993
  }
1994
+ export function __wbg_stringify_a2c39d991e1bf91d() { return handleError(function (arg0) {
1995
+ const ret = JSON.stringify(arg0);
1996
+ return ret;
1997
+ }, arguments); }
940
1998
  export function __wbg_value_7f6052747ccf940f(arg0) {
941
1999
  const ret = arg0.value;
942
2000
  return ret;