@quillmark/wasm 0.130.0 → 0.132.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,157 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.132.0 - 2026-10-27
4
+
5
+ Upgrade path: [0.131 → 0.132](docs/migrations/0.131-to-0.132.md). A row
6
+ holding a `qm-*` element or a definition list loads as what it held, and every
7
+ Typst PDF now carries a title.
8
+
9
+ ### Quill bundles
10
+
11
+ - feat(core): **a quill reads and writes as one `.quill` bundle**, its file
12
+ tree as one zip: `Quill.yaml` at the archive root, `/` paths with no `..`,
13
+ stored or deflated entries, and a budget of 2048 entries, 32 MiB a file and
14
+ 64 MiB in all, counted off the central directory before anything inflates.
15
+ [`prose/references/quill-bundle.md`](prose/references/quill-bundle.md)
16
+ specifies the format. `Quill::from_bundle` and `Quill::to_bundle` sit beside
17
+ `from_tree`, and a refused bundle fails as `quill::bundle_invalid`,
18
+ `quill::bundle_unsupported`, `quill::bundle_path` or
19
+ `quill::bundle_too_large`. An archive listing one path as both a file and a
20
+ directory is refused.
21
+ - feat(bindings): **every surface reads and writes a bundle**: WASM
22
+ `Quill.fromBundle(bytes)` and `quill.toBundle()` in both builds, Python
23
+ `Quill.from_bundle(bytes)` and `quill.to_bundle()`. `quill_from_path` reads a
24
+ file named `*.quill` as a bundle, so `Quill.from_path` and every CLI command
25
+ taking a quill path take one; `workspace` refuses a file. `quillmark pack
26
+ <QUILL_PATH> [-o FILE]` writes one, by default `<name>@<version>.quill`.
27
+
28
+ ### Content
29
+
30
+ - feat(content)!: **a `qm-<name>` element and a definition list are no longer
31
+ content.** A `qm-*` tag other than `qm-span` and `qm-anchor` drops, its open
32
+ tag warning `parse::dropped_construct` under its name, and what it wrapped
33
+ imports as written. A definition list reads as the paragraph CommonMark
34
+ reads. A stored `element` or `description` container or `term` line loads as
35
+ what it held and saves without it, under the tag it would take anyway; the
36
+ authored lanes refuse either container. The Typst helper's `elements`
37
+ registry, `_qm-element` and `typst::unregistered_element` are gone, so a
38
+ plate calling `qm.elements.update(..)` fails to compile until the call goes.
39
+
40
+ ### Rendering
41
+
42
+ - feat(typst)!: **every Typst PDF carries a title**, in `/Info /Title` and XMP
43
+ `dc:title`: the render's new `title` option, else the plate's
44
+ `set document(title: ..)`, else the quill's `description`, trimmed.
45
+ `RenderOptions` gains `title`, the WASM and Python render options carry it,
46
+ and `quillmark render` takes `--title`.
47
+ - fix(typst): **a table cell breaks inside an email address or dotted name**,
48
+ such as `Michael.Marshall@us.af.mil`, where one wider than its column ran
49
+ into the next cell. The address still copies out of the PDF whole.
50
+
51
+ ## v0.131.0 - 2026-10-26
52
+
53
+ Upgrade path: [0.130 → 0.131](docs/migrations/0.130-to-0.131.md). A row
54
+ holding a font mark, an element named `table`, a merged cell or a table `head`
55
+ 0.130 cannot draw saves under `quillmark/document@0.131.0`, which a 0.130
56
+ build refuses, so deploy every reader before a writer saves one.
57
+
58
+ ### Storage
59
+
60
+ - fix(core): **a row holding an element named `table`, a table cell spanning
61
+ more than one column or row, or a table `head` a 0.130 build cannot draw
62
+ saves under `quillmark/document@0.131.0`**, as a row holding a `font_family`
63
+ mark does: a 0.130 build refused the element as corrupt and drew the rest
64
+ wrong under `@0.129.0`. The check reads each body and each field and `$seed`
65
+ value that decodes as content, and no longer reads `$ext`, so host data
66
+ shaped like a font mark keeps `@0.129.0`.
67
+
68
+ ### Content
69
+
70
+ - feat(content)!: **a table writes as a GFM pipe table when pipes hold all of
71
+ it, and as an HTML table when it holds column widths, a placement, a cell's
72
+ alignment, a merged cell or other than one header row**, whichever spelling
73
+ the markdown used. An HTML block opening `<table>` imports as a table: the
74
+ subset is `table`, `thead`, `tbody`, `tfoot`, `tr`, `th` and `td`, with
75
+ `widths`, `aligns` and `align` on `<table>` and `colspan`, `rowspan`, `align`
76
+ and `valign` on a cell, whose content is inline markdown. A span stores as a
77
+ cell's `colspan` and `rowspan`, each cell it covers an empty placeholder, and
78
+ the header rows as the table's `head`, a count `headless: true` normalizes
79
+ to `head: 0`. What an HTML table cannot hold warns
80
+ `parse::dropped_construct` as `table`, `table:row`, `table:text` or
81
+ `<tag>[<attr>]`. Markdown after a `</table>` in its HTML block reads as
82
+ markdown of its own. An HTML table is as wide as its widest row, a `<th>`
83
+ row opening its `tbody` is a header row, and `border`, `class`, `scope` and
84
+ `style` drop silently. The Typst backend draws a span through
85
+ `table.cell(colspan:, rowspan:)` and every header row in `table.header`.
86
+ - feat(content)!: **`qm-table` and `qm-cell` no longer spell a table's
87
+ layout**: `qm-table` is an ordinary element name, and a `qm-cell` pair in a
88
+ cell drops, warning `qm-cell`, so markdown written with either loses its
89
+ table layout; rewrite such a table as HTML.
90
+ - fix(content): **a table's `head: 0` keeps `headless: true` beside it**, so a
91
+ 0.130 reader draws no header row on a table 0.131 saved, and a richtext
92
+ field holding a 0.130 `headless: true` table reads as content, exporting as
93
+ a table where it wrote its YAML tree. A cell a span covers keeps its `align`
94
+ and `valign`, drawn again once the span shrinks, and a cell holding a mark,
95
+ a comment anchor included, is no placeholder a span covers. A 0.130 row
96
+ holding `headless: true` or a cell span rewrites once when saved, under the
97
+ same tag unless a span still covers more than one slot, which saves under
98
+ `@0.131.0`.
99
+ - fix(content)!: **a body formatting mark spanning a line break loads as one
100
+ mark per line**, cut at each `\n`, the form markdown export writes, so a
101
+ mark over a hard break round-trips through markdown and a `MarkOp::Add`
102
+ across lines reads back split. A stored row holding such a
103
+ mark saves to new bytes on its first load. A table cell's or footnote's
104
+ marks still span its `<br>`.
105
+ - fix(content)!: **`link` is keyed like `font_family`**: overlapping links
106
+ settle to one url per character, the later-starting one winning, and a
107
+ `MarkOp::Add` of a link over a link replaces its url there, so
108
+ `MarkKind::is_keyed` holds for `Link`. Keyed marks settle before the cut at
109
+ line breaks, so a later-starting family keeps its whole range across one.
110
+ - fix(content)!: **a table's grid is capped at `MAX_TABLE_CELLS` (100 000)
111
+ slots, and a markdown import's tables share the cap**: import drops the rows
112
+ past it, warning `table:size`, and the stored lanes refuse such a table as
113
+ `Invariant::TableTooLarge` before padding it, where a few bytes could
114
+ allocate millions of cells.
115
+ - fix(content): **a code span in an HTML table's cell never reaches past a
116
+ subset tag**, so a stray backtick is the cell's text rather than merging
117
+ cells, rows or the prose after the table, and a code mark over a subset tag
118
+ exports the tag as escaped text.
119
+
120
+ ### Fonts
121
+
122
+ - feat!: **a run of richtext sets a font family, spelled in markdown as an
123
+ inline `<qm-span family="…">` pair** and stored as a `font_family` mark, one
124
+ family per character, so export writes nested pairs back side by side. A
125
+ row holding a `font_family` mark saves as `quillmark/document@0.131.0`,
126
+ which a 0.130 build refuses; `currentStorageVersion()` /
127
+ `current_storage_version()` return that tag. `MarkKind` gains
128
+ `FontFamily { name }`, `StoredDocument` gains `V0_131_0`, and the WASM
129
+ `ContentMark` gains `font_family`. A `qm-span` tag line, which 0.130 read as
130
+ an element named `span`, drops and warns `qm-span`.
131
+ - feat!: **an engine takes a host font library**: `Engine::with_fonts`, the
132
+ `fonts` option of `new Engine(..)`, `Engine(fonts=..)` and `--font` on
133
+ `quillmark render` and `quillmark workspace`. A file other than `.ttf`,
134
+ `.otf`, `.ttc` or `.otc` fails as `engine::font_unsupported`, one holding no
135
+ face Typst reads as `engine::font_unreadable`. A library face sets only text
136
+ a font mark sets, and a family the library lacks keeps the surrounding font
137
+ and warns `typst::unknown_font_family`. `TypstBackend` is a struct holding
138
+ the library, built with `TypstBackend::default()` or
139
+ `TypstBackend::new(Arc<FontLibrary>)`, `quillmark_typst::workspace::workspace`
140
+ takes a `&FontLibrary` third, and `Engine::font_faces`,
141
+ `engine.fontFaces(quill)` and `Engine.font_faces(quill)` list the faces,
142
+ sharing the library's bytes rather than copying them. The WASM engine copies
143
+ its `fonts` when built and parses them once, so a refused font rejects every
144
+ verb that loads the render build with the same error. A plate naming a
145
+ library family never reaches its face.
146
+
147
+ ### Fixes
148
+
149
+ - fix(acroform): a `richtext` array element holding no text binds as an empty
150
+ line, so a blank line between groups reaches the widget.
151
+ - fix(core): a list item with nothing after its marker ends at the blank line
152
+ below it, so a card fence inside a code block below such an item stays
153
+ code.
154
+
3
155
  ## v0.130.0 - 2026-10-22
4
156
 
5
157
  Upgrade path: [0.129 → 0.130](docs/migrations/0.129-to-0.130.md). A stored row
package/README.md CHANGED
@@ -182,10 +182,11 @@ const doc = Document.storageVersionOf(content)
182
182
  : Document.fromMarkdown(content);
183
183
  ```
184
184
 
185
- The `schema` value (`quillmark/document@0.129.0`) is the **model version**,
186
- not the running crate version. It is a hand-set constant, bumped only when
187
- the `Document` model itself changes, so every `0.129.x` patch release reads
188
- and writes that same value.
185
+ The `schema` value (`quillmark/document@0.131.0` for a document holding a font
186
+ mark, `@0.129.0` for any other) is the **model version**, not the running crate
187
+ version. It is a hand-set constant, bumped only when the `Document` model
188
+ itself changes, so every `0.131.x` patch release reads and writes those same
189
+ values.
189
190
 
190
191
  - **Upgrading is safe.** A newer build reads documents an older build's
191
192
  *writer* produced. Each schema version's wire format is frozen and never
@@ -206,19 +207,26 @@ and writes that same value.
206
207
  read, newer than the build or retired, rather than guessing at its format.
207
208
  Don't feed documents written by a newer build back into an older one.
208
209
 
209
- To detect a version mismatch before parsing, use the static accessors:
210
+ `Document.currentStorageVersion()` is the newest tag this build writes. A
211
+ save writes the oldest tag that holds the row, so a fresh row can carry an
212
+ older tag still read: a row holding no font mark, `table` element, merged
213
+ table cell or table `head` 0.130 cannot draw saves as
214
+ `quillmark/document@0.129.0`. A tag other than `currentStorageVersion()` is
215
+ therefore not a mismatch. Use `storageVersionOf` after `fromStored` throws,
216
+ to tell "a version this build does not read" from "corrupt":
210
217
 
211
218
  ```ts
212
- const v = Document.storageVersionOf(blob); // undefined | string
213
- if (v && v !== Document.currentStorageVersion()) {
214
- // payload is from a build with a different model version
219
+ try {
220
+ return Document.fromStored(blob);
221
+ } catch (err) {
222
+ const v = Document.storageVersionOf(blob); // undefined | string
223
+ // v: a tag this build does not read; undefined: not a stored document
215
224
  }
216
225
  ```
217
226
 
218
227
  `storageVersionOf` does not validate the payload: it only reads the
219
228
  `schema` field, returning `undefined` for non-JSON, non-objects, or
220
- payloads that don't carry one. Use it to distinguish "wrong version" from
221
- "corrupt" when `fromStored` throws.
229
+ payloads that don't carry one.
222
230
 
223
231
  In short: persist the `toStored` string, resave rows under a retired tag
224
232
  before upgrading past it, never downgrade. The full design (including how
@@ -375,7 +383,7 @@ the local date): what a `today` date field and a plate's `datetime.today()`
375
383
  render as. A session keeps the date it opened with, so a preview left open past
376
384
  midnight renders yesterday's until it is reopened.
377
385
 
378
- `opts` takes `format`, `ppi`, `pages` and `regions`, on `engine.render` and
386
+ `opts` takes `format`, `ppi`, `pages`, `regions` and `title`, on `engine.render` and
379
387
  `session.render` alike. Any other key throws rather than reading as absent,
380
388
  `today` included, so `engine.render(quill, doc, { today })` rejects instead of
381
389
  rendering the local date. The date goes last:
@@ -2153,14 +2153,14 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH RE
2153
2153
 
2154
2154
  ## Apache License 2.0
2155
2155
 
2156
- - quillmark-acroform 0.130.0 (https://github.com/borb-sh/quillmark)
2157
- - quillmark-typst 0.130.0 (https://github.com/borb-sh/quillmark)
2158
- - quillmark-cli 0.130.0 (https://github.com/borb-sh/quillmark)
2159
- - quillmark-python 0.130.0
2160
- - quillmark-content 0.130.0 (https://github.com/borb-sh/quillmark)
2161
- - quillmark-core 0.130.0 (https://github.com/borb-sh/quillmark)
2162
- - quillmark 0.130.0 (https://github.com/borb-sh/quillmark)
2163
- - quillmark-pdf 0.130.0 (https://github.com/borb-sh/quillmark)
2156
+ - quillmark-acroform 0.132.0 (https://github.com/borb-sh/quillmark)
2157
+ - quillmark-typst 0.132.0 (https://github.com/borb-sh/quillmark)
2158
+ - quillmark-cli 0.132.0 (https://github.com/borb-sh/quillmark)
2159
+ - quillmark-python 0.132.0
2160
+ - quillmark-content 0.132.0 (https://github.com/borb-sh/quillmark)
2161
+ - quillmark-core 0.132.0 (https://github.com/borb-sh/quillmark)
2162
+ - quillmark 0.132.0 (https://github.com/borb-sh/quillmark)
2163
+ - quillmark-pdf 0.132.0 (https://github.com/borb-sh/quillmark)
2164
2164
  - ciborium-io 0.2.2 (https://github.com/enarx/ciborium)
2165
2165
  - ciborium-ll 0.2.2 (https://github.com/enarx/ciborium)
2166
2166
  - ciborium 0.2.2 (https://github.com/enarx/ciborium)
@@ -2377,6 +2377,11 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH RE
2377
2377
  - clap 4.6.7 (https://github.com/clap-rs/clap)
2378
2378
  - clap_builder 4.6.7 (https://github.com/clap-rs/clap)
2379
2379
  - clap_derive 4.6.7 (https://github.com/clap-rs/clap)
2380
+ - serde_spanned 1.1.2 (https://github.com/toml-rs/toml)
2381
+ - toml 1.1.8+spec-1.1.0 (https://github.com/toml-rs/toml)
2382
+ - toml_datetime 1.1.2+spec-1.1.0 (https://github.com/toml-rs/toml)
2383
+ - toml_parser 1.1.5+spec-1.1.0 (https://github.com/toml-rs/toml)
2384
+ - toml_writer 1.1.3+spec-1.1.0 (https://github.com/toml-rs/toml)
2380
2385
 
2381
2386
  ~~~~text
2382
2387
  Apache License
@@ -2600,15 +2605,10 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH RE
2600
2605
  - once_cell_polyfill 1.70.2 (https://github.com/polyfill-rs/once_cell_polyfill)
2601
2606
  - quick-error 2.0.1 (http://github.com/tailhook/quick-error)
2602
2607
  - serde_spanned 0.6.9 (https://github.com/toml-rs/toml)
2603
- - serde_spanned 1.1.1 (https://github.com/toml-rs/toml)
2604
2608
  - toml 0.8.23 (https://github.com/toml-rs/toml)
2605
- - toml 1.1.6+spec-1.1.0 (https://github.com/toml-rs/toml)
2606
2609
  - toml_datetime 0.6.11 (https://github.com/toml-rs/toml)
2607
- - toml_datetime 1.1.1+spec-1.1.0 (https://github.com/toml-rs/toml)
2608
2610
  - toml_edit 0.22.27 (https://github.com/toml-rs/toml)
2609
- - toml_parser 1.1.3+spec-1.1.0 (https://github.com/toml-rs/toml)
2610
2611
  - toml_write 0.1.2 (https://github.com/toml-rs/toml)
2611
- - toml_writer 1.1.2+spec-1.1.0 (https://github.com/toml-rs/toml)
2612
2612
 
2613
2613
  ~~~~text
2614
2614
  Apache License
@@ -4555,7 +4555,7 @@ limitations under the License.
4555
4555
  - unic-langid-macros-impl 0.9.6 (https://github.com/zbraniecki/unic-locale)
4556
4556
  - unic-langid-macros 0.9.6 (https://github.com/zbraniecki/unic-locale)
4557
4557
  - unic-langid 0.9.6 (https://github.com/zbraniecki/unic-locale)
4558
- - unicase 2.9.0 (https://github.com/seanmonstar/unicase)
4558
+ - unicase 2.10.0 (https://github.com/seanmonstar/unicase)
4559
4559
  - unicode-bidi-mirroring 0.4.0 (https://github.com/RazrFalcon/unicode-bidi-mirroring)
4560
4560
  - unicode-bidi 0.3.18 (https://github.com/servo/unicode-bidi)
4561
4561
  - unicode-ccc 0.4.0 (https://github.com/RazrFalcon/unicode-ccc)
@@ -5395,6 +5395,7 @@ APPENDIX: How to apply the Apache License to your work.
5395
5395
 
5396
5396
  ## Apache License 2.0
5397
5397
 
5398
+ - getrandom 0.4.3 (https://github.com/rust-random/getrandom)
5398
5399
  - rand_chacha 0.3.1 (https://github.com/rust-random/rand)
5399
5400
 
5400
5401
  ~~~~text
@@ -6247,8 +6248,8 @@ limitations under the License.
6247
6248
 
6248
6249
  ## Apache License 2.0
6249
6250
 
6250
- - quillmark-wasm 0.130.0 (https://github.com/borb-sh/quillmark)
6251
- - quillmark-fixtures 0.130.0
6251
+ - quillmark-wasm 0.132.0 (https://github.com/borb-sh/quillmark)
6252
+ - quillmark-fixtures 0.132.0
6252
6253
  - arraydeque 0.5.1 (https://github.com/andylokandy/arraydeque)
6253
6254
  - codex 0.3.0 (https://github.com/typst/codex)
6254
6255
  - color 0.3.3 (https://github.com/linebender/color)
@@ -6311,7 +6312,7 @@ limitations under the License.
6311
6312
  - serde_core 1.0.229 (https://github.com/serde-rs/serde)
6312
6313
  - serde_derive 1.0.229 (https://github.com/serde-rs/serde)
6313
6314
  - serde_derive_internals 0.29.1 (https://github.com/serde-rs/serde)
6314
- - serde_json 1.0.151 (https://github.com/serde-rs/json)
6315
+ - serde_json 1.0.154 (https://github.com/serde-rs/json)
6315
6316
  - serde_path_to_error 0.1.20 (https://github.com/dtolnay/path-to-error)
6316
6317
  - serde_yaml 0.9.34+deprecated (https://github.com/dtolnay/serde-yaml)
6317
6318
  - siphasher 1.0.2 (https://github.com/jedisct1/rust-siphash)
package/core/wasm.d.ts CHANGED
@@ -80,8 +80,7 @@ export type ContentLineKind =
80
80
  | { kind: "para" }
81
81
  | { kind: "heading"; attrs: { level: number } }
82
82
  | { kind: "code"; attrs?: { lang?: string } }
83
- | { kind: "rule" }
84
- | { kind: "term" };
83
+ | { kind: "rule" };
85
84
 
86
85
  /** An ancestor block a line nests inside, outermost first. Closed like
87
86
  * `ContentLine.kind`.
@@ -110,14 +109,7 @@ export type ContentContainer =
110
109
  attrs: { ordered: boolean; start: number; ordinal: number; checked?: boolean };
111
110
  instance?: number;
112
111
  }
113
- | { container: "quote"; instance?: number }
114
- | { container: "description"; instance?: number }
115
- | { container: "element"; attrs: ElementAttrs; instance?: number };
116
-
117
- /** A carrier element's name and attributes, one bag: `$name` is the part of
118
- * its `qm-<name>` tag after the prefix, and every other key an attribute as
119
- * written. */
120
- export type ElementAttrs = { $name: string; [attr: string]: string };
112
+ | { container: "quote"; instance?: number };
121
113
 
122
114
  /** A mark over char range `[start, end)` into `Content.text`. `type` is a
123
115
  * closed set, so `type === "link"` narrows `attrs` to `{ url: string }` with no
@@ -132,7 +124,8 @@ export type ContentMark = { start: number; end: number } & ContentMarkKind;
132
124
  export type ContentMarkKind =
133
125
  | { type: "strong" | "emph" | "underline" | "strike" | "code" }
134
126
  | { type: "link"; attrs: { url: string } }
135
- | { type: "anchor"; attrs: { id: string } };
127
+ | { type: "anchor"; attrs: { id: string } }
128
+ | { type: "font_family"; attrs: { name: string } };
136
129
 
137
130
  /** A cell in a `TableProps`. `marks` rides the prose `ContentMark` shape, but
138
131
  * each mark's `start`/`end` are USV offsets into this cell's `text`, not into
@@ -144,12 +137,17 @@ export interface TableCell {
144
137
  align?: "left" | "center" | "right";
145
138
  /** The cell's vertical alignment; absent is the quill's. */
146
139
  valign?: "top" | "middle" | "bottom";
140
+ /** The columns the cell spans, from 2; absent is one. Each cell it covers
141
+ * holds its slot as an empty placeholder. */
142
+ colspan?: number;
143
+ /** The rows the cell spans, from 2; absent is one. */
144
+ rowspan?: number;
147
145
  }
148
146
 
149
- /** `props` of a `type: "table"` island: a pipe table normalized to one column
150
- * count that `header`, every row of `rows`, `aligns` and `widths` all share.
151
- * A layout key at its default is absent; one holding a value outside its type
152
- * stays as written and reads as absent. */
147
+ /** `props` of a `type: "table"` island: a rectangular grid normalized to one
148
+ * column count that `header`, every row of `rows`, `aligns` and `widths` all
149
+ * share. A layout key at its default is absent; one holding a value outside
150
+ * its type stays as written and reads as absent. */
153
151
  export interface TableProps {
154
152
  header: TableCell[];
155
153
  rows: TableCell[][];
@@ -161,8 +159,9 @@ export interface TableProps {
161
159
  widths?: (number | null)[];
162
160
  /** The table's placement; absent is the quill's. */
163
161
  align?: "left" | "center" | "right";
164
- /** `true` draws `header` as the first body row; absent is a header row. */
165
- headless?: true;
162
+ /** How many rows from the top of `header` then `rows` are header rows;
163
+ * `0` draws `header` as the first body row, and absent is one. */
164
+ head?: number;
166
165
  }
167
166
 
168
167
  /** `props` of a `type: "image"` island. Stores and round-trips; no backend
@@ -300,7 +299,9 @@ export type Assoc = "before" | "after";
300
299
  /**
301
300
  * A mark edit in final-text coordinates (post-delta, post-line-op). `add` /
302
301
  * `remove` are a `ContentMark` under an op, so a held mark spreads in whole;
303
- * `removeAnchor` drops one identity anchor by id. An `add` of an `anchor`
302
+ * `removeAnchor` drops one identity anchor by id. An `add` of a `link` or a
303
+ * `font_family` replaces the one under its range, and a mark added across a
304
+ * line break reads back as one mark per line. An `add` of an `anchor`
304
305
  * requires a non-empty `id` not already live in the field; a collision or the
305
306
  * empty id throws.
306
307
  */
@@ -675,8 +676,12 @@ export class Document {
675
676
  card(index: number): Card;
676
677
  clone(): Document;
677
678
  /**
678
- * Storage version this build writes via [`toStored`](Document::to_stored). The
679
- * tag advances only when the wire format changes, not on every release.
679
+ * The newest storage version this build writes via
680
+ * [`toStored`](Document::to_stored): a document spelling a font mark, a
681
+ * `table` element, a merged table cell or a table head 0.130 cannot draw
682
+ * carries it, every other the tag before it, which a 0.130 build reads.
683
+ * The tag advances only when the wire format changes, not on every
684
+ * release.
680
685
  */
681
686
  static currentStorageVersion(): string;
682
687
  /**
@@ -944,6 +949,12 @@ export class Quill {
944
949
  * parse or its `$quill` is not this quill's bare name.
945
950
  */
946
951
  exampleDocument(): Document | undefined;
952
+ /**
953
+ * Read a `.quill` bundle, the zip archive holding one quill's file tree.
954
+ * Pure, as [`fromTree`](Self::from_tree) is. A bundle outside the format
955
+ * throws one `quill::bundle_*` diagnostic.
956
+ */
957
+ static fromBundle(bytes: Uint8Array): Quill;
947
958
  /**
948
959
  * Build a quill from a file tree. Pure: the declared backend is resolved
949
960
  * later, at render time. Accepts a `Map<string, Uint8Array>` or a plain
@@ -986,6 +997,11 @@ export class Quill {
986
997
  * `$kind: main` card of [`seedDocument`](Self::seed_document) alone.
987
998
  */
988
999
  seedMain(): Card;
1000
+ /**
1001
+ * This quill's file tree as a `.quill` bundle, the bytes
1002
+ * [`fromBundle`](Self::from_bundle) reads.
1003
+ */
1004
+ toBundle(): Uint8Array;
989
1005
  /**
990
1006
  * Flatten this quill back into its canonical file tree, the inverse of
991
1007
  * [`fromTree`](Self::from_tree). Keys are `"/"`-joined relative paths.
@@ -1200,6 +1216,7 @@ export interface InitOutput {
1200
1216
  readonly quill_conform: (a: number, b: number, c: number) => void;
1201
1217
  readonly quill_emptyDocument: (a: number) => number;
1202
1218
  readonly quill_exampleDocument: (a: number, b: number) => void;
1219
+ readonly quill_fromBundle: (a: number, b: number, c: number) => void;
1203
1220
  readonly quill_fromTree: (a: number, b: number) => void;
1204
1221
  readonly quill_metadata: (a: number, b: number) => void;
1205
1222
  readonly quill_parse: (a: number, b: number, c: number, d: number) => void;
@@ -1207,6 +1224,7 @@ export interface InitOutput {
1207
1224
  readonly quill_seedCard: (a: number, b: number, c: number, d: number, e: number) => void;
1208
1225
  readonly quill_seedDocument: (a: number) => number;
1209
1226
  readonly quill_seedMain: (a: number, b: number) => void;
1227
+ readonly quill_toBundle: (a: number, b: number) => void;
1210
1228
  readonly quill_toTree: (a: number) => number;
1211
1229
  readonly quill_validate: (a: number, b: number, c: number) => void;
1212
1230
  readonly quill_warnings: (a: number, b: number) => void;
package/core/wasm.js CHANGED
@@ -441,8 +441,12 @@ export class Document {
441
441
  return Document.__wrap(ret);
442
442
  }
443
443
  /**
444
- * Storage version this build writes via [`toStored`](Document::to_stored). The
445
- * tag advances only when the wire format changes, not on every release.
444
+ * The newest storage version this build writes via
445
+ * [`toStored`](Document::to_stored): a document spelling a font mark, a
446
+ * `table` element, a merged table cell or a table head 0.130 cannot draw
447
+ * carries it, every other the tag before it, which a 0.130 build reads.
448
+ * The tag advances only when the wire format changes, not on every
449
+ * release.
446
450
  * @returns {string}
447
451
  */
448
452
  static currentStorageVersion() {
@@ -1339,6 +1343,30 @@ export class Quill {
1339
1343
  wasm.__wbindgen_add_to_stack_pointer(16);
1340
1344
  }
1341
1345
  }
1346
+ /**
1347
+ * Read a `.quill` bundle, the zip archive holding one quill's file tree.
1348
+ * Pure, as [`fromTree`](Self::from_tree) is. A bundle outside the format
1349
+ * throws one `quill::bundle_*` diagnostic.
1350
+ * @param {Uint8Array} bytes
1351
+ * @returns {Quill}
1352
+ */
1353
+ static fromBundle(bytes) {
1354
+ try {
1355
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1356
+ const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_export);
1357
+ const len0 = WASM_VECTOR_LEN;
1358
+ wasm.quill_fromBundle(retptr, ptr0, len0);
1359
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1360
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1361
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
1362
+ if (r2) {
1363
+ throw takeObject(r1);
1364
+ }
1365
+ return Quill.__wrap(r0);
1366
+ } finally {
1367
+ wasm.__wbindgen_add_to_stack_pointer(16);
1368
+ }
1369
+ }
1342
1370
  /**
1343
1371
  * Build a quill from a file tree. Pure: the declared backend is resolved
1344
1372
  * later, at render time. Accepts a `Map<string, Uint8Array>` or a plain
@@ -1495,6 +1523,29 @@ export class Quill {
1495
1523
  wasm.__wbindgen_add_to_stack_pointer(16);
1496
1524
  }
1497
1525
  }
1526
+ /**
1527
+ * This quill's file tree as a `.quill` bundle, the bytes
1528
+ * [`fromBundle`](Self::from_bundle) reads.
1529
+ * @returns {Uint8Array}
1530
+ */
1531
+ toBundle() {
1532
+ try {
1533
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1534
+ wasm.quill_toBundle(retptr, this.__wbg_ptr);
1535
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1536
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1537
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
1538
+ var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
1539
+ if (r3) {
1540
+ throw takeObject(r2);
1541
+ }
1542
+ var v1 = getArrayU8FromWasm0(r0, r1).slice();
1543
+ wasm.__wbindgen_export4(r0, r1 * 1, 1);
1544
+ return v1;
1545
+ } finally {
1546
+ wasm.__wbindgen_add_to_stack_pointer(16);
1547
+ }
1548
+ }
1498
1549
  /**
1499
1550
  * Flatten this quill back into its canonical file tree, the inverse of
1500
1551
  * [`fromTree`](Self::from_tree). Keys are `"/"`-joined relative paths.
@@ -2326,6 +2377,13 @@ function isLikeNone(x) {
2326
2377
  return x === undefined || x === null;
2327
2378
  }
2328
2379
 
2380
+ function passArray8ToWasm0(arg, malloc) {
2381
+ const ptr = malloc(arg.length * 1, 1) >>> 0;
2382
+ getUint8ArrayMemory0().set(arg, ptr / 1);
2383
+ WASM_VECTOR_LEN = arg.length;
2384
+ return ptr;
2385
+ }
2386
+
2329
2387
  function passStringToWasm0(arg, malloc, realloc) {
2330
2388
  if (realloc === undefined) {
2331
2389
  const buf = cachedTextEncoder.encode(arg);
package/core/wasm_bg.wasm CHANGED
Binary file
@@ -65,6 +65,7 @@ export const quill_blueprint: (a: number, b: number) => void;
65
65
  export const quill_conform: (a: number, b: number, c: number) => void;
66
66
  export const quill_emptyDocument: (a: number) => number;
67
67
  export const quill_exampleDocument: (a: number, b: number) => void;
68
+ export const quill_fromBundle: (a: number, b: number, c: number) => void;
68
69
  export const quill_fromTree: (a: number, b: number) => void;
69
70
  export const quill_metadata: (a: number, b: number) => void;
70
71
  export const quill_parse: (a: number, b: number, c: number, d: number) => void;
@@ -72,6 +73,7 @@ export const quill_schema: (a: number, b: number) => void;
72
73
  export const quill_seedCard: (a: number, b: number, c: number, d: number, e: number) => void;
73
74
  export const quill_seedDocument: (a: number) => number;
74
75
  export const quill_seedMain: (a: number, b: number) => void;
76
+ export const quill_toBundle: (a: number, b: number) => void;
75
77
  export const quill_toTree: (a: number) => number;
76
78
  export const quill_validate: (a: number, b: number, c: number) => void;
77
79
  export const quill_warnings: (a: number, b: number) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quillmark/wasm",
3
- "version": "0.130.0",
3
+ "version": "0.132.0",
4
4
  "description": "WebAssembly bindings for Quillmark, a schema-driven document framework",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",