@quillmark/wasm 0.128.0 → 0.130.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,92 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.130.0 - 2026-10-22
4
+
5
+ Upgrade path: [0.129 → 0.130](docs/migrations/0.129-to-0.130.md). A stored row
6
+ tagged older than `quillmark/document@0.124.0` fails to load, so resave every
7
+ such row with a 0.124 to 0.129 build before upgrading, client-side copies and
8
+ backups included.
9
+
10
+ ### Storage
11
+
12
+ - refactor(core)!: **a row tagged `quillmark/document@0.81.0`, `@0.82.0`,
13
+ `@0.92.0`, `@0.93.0`, `@0.112.0`, `@0.115.0` or `@0.116.0` fails to load as
14
+ an unknown schema version**: 0.130 reads `@0.124.0` and `@0.129.0` only, and
15
+ the forward migrations from the seven older tags are gone. `fromStored` /
16
+ `from_stored` refuses such a row as it refuses a tag newer than the build,
17
+ and `storageVersionOf` / `storage_version_of` still returns its tag. In
18
+ Rust, `StoredDocument` loses the `V0_116_0` through `V0_81_0` variants,
19
+ `STORAGE_V0_116_0`, `STORAGE_V0_115_0`, `STORAGE_V0_112_0` and
20
+ `STORAGE_V0_93_0` are gone, and the payload types `@0.124.0` and `@0.129.0`
21
+ share are `PayloadV0_124_0`, `PayloadItemV0_124_0`, `NestedCommentV0_124_0`
22
+ and `CommentPathSegmentV0_124_0`. The legacy content spellings a `richtext`
23
+ field can hold still decode. (#2266)
24
+
25
+ ## v0.129.0 - 2026-10-21
26
+
27
+ Upgrade path: [0.128 → 0.129](docs/migrations/0.128-to-0.129.md). Footnotes,
28
+ `$…$` math and definition lists render, where 0.128 imported each as text, so
29
+ markdown that spelled one changes what it renders and nothing reports it. A
30
+ save writes `quillmark/document@0.129.0`, which a 0.128 build refuses. A
31
+ one-line text value printed in a Typst plate carries no space at its edges,
32
+ and `ui.layout: flat` is deprecated.
33
+
34
+ ### Content
35
+
36
+ - feat(content)!: **`text[^1]` with a `[^1]: note` definition renders a
37
+ footnote**, stored as a `footnote` island holding the note as one table
38
+ cell and drawn through Typst's `footnote`. A definition nothing references,
39
+ a second definition of one label, a reference in a table cell, an alt text
40
+ or a note, and a block inside a note warn `parse::dropped_construct`
41
+ (`footnote`, `footnote[<block>]`). Export numbers the references in reading
42
+ order and writes each note after the body. (#2258)
43
+ - feat(content)!: **`$tex$` and `$$tex$$` render equations**, stored as a
44
+ `math` island holding the TeX under `tex`, `display: true` on the second.
45
+ The Typst backend translates the TeX to Typst math, warns
46
+ `typst::unsupported_tex` for a command outside its vocabulary, and embeds
47
+ Noto Sans Math, which answers to `New Computer Modern Math` for a quill
48
+ shipping no font of that family. An equation in a table cell, an alt text
49
+ or a note, or one whose TeX is blank, keeps its source and warns `math`.
50
+ Export escapes a text `$` wherever another could pair with it. (#2258)
51
+ - feat(content)!: **a paragraph with a `: description` line under it is a
52
+ definition list**, stored as a `term` line and a `description` container
53
+ and drawn through Typst's `terms.item`. Export writes `\:` before a
54
+ paragraph line opening `:`. (#2258)
55
+ - feat(content)!: **a save writes `quillmark/document@0.129.0`**, the first
56
+ tag that holds a footnote, an equation or a definition; a row under an older
57
+ tag loads as before, and a 0.128 build refuses one under the new tag. An
58
+ acroform quill declines all three constructs under
59
+ `backend::declined_construct`. (#2258)
60
+
61
+ ### Plates
62
+
63
+ - fix(typst)!: **a one-line text value printed in a Typst plate carries no
64
+ space at either edge**, so `Dear #qm.ink(qm.data, "name"),` renders "Dear
65
+ Mr. Babbage," where it rendered "Dear Mr. Babbage ,". A plate that trimmed
66
+ the spaces can drop the trim; one that leaned on them writes the space
67
+ itself. (#2262)
68
+
69
+ ### Schemas
70
+
71
+ - feat(core)!: **`ui.layout: flat` is deprecated** and warns
72
+ `quill::deprecated_flat` per field, naming its path; it still loads, and
73
+ `schema()` still echoes it. `schema()` no longer writes it on an object
74
+ alone in its legacy `ui.group`. A card-level field outside every group,
75
+ declared after a top-level object or a grouped field, warns
76
+ `quill::field_after_object`. (#2261)
77
+
78
+ ### Parsing
79
+
80
+ - fix(core): **a code fence inside a list item or block quote closes where
81
+ its container ends**, so it no longer shields a column-zero card below it,
82
+ and markers nested past the parser's depth limit read as text. (#2255)
83
+
84
+ ### Docs
85
+
86
+ - docs: **Creating Quills opens with `quillkit init`** and walks the starter
87
+ letter in studio, a quillkit & studio page names the verbs, and a glossary
88
+ defines the author's terms. (#2259)
89
+
3
90
  ## v0.128.0 - 2026-10-21
4
91
 
5
92
  Upgrade path: [0.127 → 0.128](docs/migrations/0.127-to-0.128.md). A quill
package/README.md CHANGED
@@ -182,27 +182,29 @@ const doc = Document.storageVersionOf(content)
182
182
  : Document.fromMarkdown(content);
183
183
  ```
184
184
 
185
- The `schema` value (`quillmark/document@0.124.0`) is the **model version**,
185
+ The `schema` value (`quillmark/document@0.129.0`) is the **model version**,
186
186
  not the running crate version. It is a hand-set constant, bumped only when
187
- the `Document` model itself changes, so every `0.124.x` patch release reads
187
+ the `Document` model itself changes, so every `0.129.x` patch release reads
188
188
  and writes that same value.
189
189
 
190
190
  - **Upgrading is safe.** A newer build reads documents an older build's
191
191
  *writer* produced. Each schema version's wire format is frozen and never
192
192
  changes; when the model does change, the new build ships a migration that
193
193
  converts old payloads on `fromStored`. A document you commit as your
194
- canonical on-disk format keeps loading across crate upgrades: there is no
195
- need to pin old wasm to read old data. The exception is a row a host
196
- authored a content construct of its own into — a line `kind`, container,
197
- mark `type` or island `type` outside the vocabulary. Those are refused from
198
- 0.113 on; see that release's migration guide. An island `loss` is not one of
199
- them: 0.115 drops the key, so a row spelling one opens whatever the class and
194
+ canonical on-disk format keeps loading across crate upgrades until its tag
195
+ is retired: 0.130 reads `@0.124.0` and `@0.129.0` only, so resave an older
196
+ row with a 0.124 to 0.129 build before taking 0.130, as that release's
197
+ migration guide shows. The other exception is a row a host authored a
198
+ content construct of its own into — a line `kind`, container, mark `type`
199
+ or island `type` outside the vocabulary. Those are refused from 0.113 on;
200
+ see that release's migration guide. An island `loss` is not one of them:
201
+ 0.115 drops the key, so a row spelling one opens whatever the class and
200
202
  comes back without it. From 0.126 on, a row whose `$quill` is a lone major,
201
203
  `memo@1`, or whose body nests past 12 levels is refused too; rewrite it
202
204
  before upgrading, as that release's migration guide shows.
203
- - **Downgrading is not.** `fromStored` rejects an *unknown* (i.e. newer)
204
- `schema` version rather than guessing at a format it predates. Don't feed
205
- documents written by a newer build back into an older one.
205
+ - **Downgrading is not.** `fromStored` rejects a `schema` version it does not
206
+ read, newer than the build or retired, rather than guessing at its format.
207
+ Don't feed documents written by a newer build back into an older one.
206
208
 
207
209
  To detect a version mismatch before parsing, use the static accessors:
208
210
 
@@ -218,9 +220,9 @@ if (v && v !== Document.currentStorageVersion()) {
218
220
  payloads that don't carry one. Use it to distinguish "wrong version" from
219
221
  "corrupt" when `fromStored` throws.
220
222
 
221
- In short: persist the `toStored` string, upgrade freely, never downgrade. The
222
- full design (including how migrations are added) is in
223
- `prose/canon/DOCUMENT_STORAGE.md`.
223
+ In short: persist the `toStored` string, resave rows under a retired tag
224
+ before upgrading past it, never downgrade. The full design (including how
225
+ migrations are added) is in `prose/canon/DOCUMENT_STORAGE.md`.
224
226
 
225
227
  ### Cards, seeds, and addresses
226
228
 
@@ -1,8 +1,9 @@
1
1
  # Third-party licenses
2
2
 
3
3
  The crates the workspace links, Quillmark's own included, grouped by license;
4
- then the notices those crates carry and the license of the embedded Roboto
5
- faces. Generated by `scripts/third-party-licenses.sh`; do not edit.
4
+ then the notices those crates carry and the licenses of the embedded Roboto
5
+ and Noto Sans Math faces. Generated by `scripts/third-party-licenses.sh`; do
6
+ not edit.
6
7
 
7
8
  ## BSD Zero Clause License
8
9
 
@@ -2152,14 +2153,14 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH RE
2152
2153
 
2153
2154
  ## Apache License 2.0
2154
2155
 
2155
- - quillmark-acroform 0.128.0 (https://github.com/borb-sh/quillmark)
2156
- - quillmark-typst 0.128.0 (https://github.com/borb-sh/quillmark)
2157
- - quillmark-cli 0.128.0 (https://github.com/borb-sh/quillmark)
2158
- - quillmark-python 0.128.0
2159
- - quillmark-content 0.128.0 (https://github.com/borb-sh/quillmark)
2160
- - quillmark-core 0.128.0 (https://github.com/borb-sh/quillmark)
2161
- - quillmark 0.128.0 (https://github.com/borb-sh/quillmark)
2162
- - quillmark-pdf 0.128.0 (https://github.com/borb-sh/quillmark)
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)
2163
2164
  - ciborium-io 0.2.2 (https://github.com/enarx/ciborium)
2164
2165
  - ciborium-ll 0.2.2 (https://github.com/enarx/ciborium)
2165
2166
  - ciborium 0.2.2 (https://github.com/enarx/ciborium)
@@ -6246,8 +6247,8 @@ limitations under the License.
6246
6247
 
6247
6248
  ## Apache License 2.0
6248
6249
 
6249
- - quillmark-wasm 0.128.0 (https://github.com/borb-sh/quillmark)
6250
- - quillmark-fixtures 0.128.0
6250
+ - quillmark-wasm 0.130.0 (https://github.com/borb-sh/quillmark)
6251
+ - quillmark-fixtures 0.130.0
6251
6252
  - arraydeque 0.5.1 (https://github.com/andylokandy/arraydeque)
6252
6253
  - codex 0.3.0 (https://github.com/typst/codex)
6253
6254
  - color 0.3.3 (https://github.com/linebender/color)
@@ -10540,6 +10541,104 @@ This license is copied below, and is also available with a FAQ at:
10540
10541
  https://openfontlicense.org
10541
10542
 
10542
10543
 
10544
+ -----------------------------------------------------------
10545
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10546
+ -----------------------------------------------------------
10547
+
10548
+ PREAMBLE
10549
+ The goals of the Open Font License (OFL) are to stimulate worldwide
10550
+ development of collaborative font projects, to support the font creation
10551
+ efforts of academic and linguistic communities, and to provide a free and
10552
+ open framework in which fonts may be shared and improved in partnership
10553
+ with others.
10554
+
10555
+ The OFL allows the licensed fonts to be used, studied, modified and
10556
+ redistributed freely as long as they are not sold by themselves. The
10557
+ fonts, including any derivative works, can be bundled, embedded,
10558
+ redistributed and/or sold with any software provided that any reserved
10559
+ names are not used by derivative works. The fonts and derivatives,
10560
+ however, cannot be released under any other type of license. The
10561
+ requirement for fonts to remain under this license does not apply
10562
+ to any document created using the fonts or their derivatives.
10563
+
10564
+ DEFINITIONS
10565
+ "Font Software" refers to the set of files released by the Copyright
10566
+ Holder(s) under this license and clearly marked as such. This may
10567
+ include source files, build scripts and documentation.
10568
+
10569
+ "Reserved Font Name" refers to any names specified as such after the
10570
+ copyright statement(s).
10571
+
10572
+ "Original Version" refers to the collection of Font Software components as
10573
+ distributed by the Copyright Holder(s).
10574
+
10575
+ "Modified Version" refers to any derivative made by adding to, deleting,
10576
+ or substituting -- in part or in whole -- any of the components of the
10577
+ Original Version, by changing formats or by porting the Font Software to a
10578
+ new environment.
10579
+
10580
+ "Author" refers to any designer, engineer, programmer, technical
10581
+ writer or other person who contributed to the Font Software.
10582
+
10583
+ PERMISSION & CONDITIONS
10584
+ Permission is hereby granted, free of charge, to any person obtaining
10585
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
10586
+ redistribute, and sell modified and unmodified copies of the Font
10587
+ Software, subject to the following conditions:
10588
+
10589
+ 1) Neither the Font Software nor any of its individual components,
10590
+ in Original or Modified Versions, may be sold by itself.
10591
+
10592
+ 2) Original or Modified Versions of the Font Software may be bundled,
10593
+ redistributed and/or sold with any software, provided that each copy
10594
+ contains the above copyright notice and this license. These can be
10595
+ included either as stand-alone text files, human-readable headers or
10596
+ in the appropriate machine-readable metadata fields within text or
10597
+ binary files as long as those fields can be easily viewed by the user.
10598
+
10599
+ 3) No Modified Version of the Font Software may use the Reserved Font
10600
+ Name(s) unless explicit written permission is granted by the corresponding
10601
+ Copyright Holder. This restriction only applies to the primary font name as
10602
+ presented to the users.
10603
+
10604
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
10605
+ Software shall not be used to promote, endorse or advertise any
10606
+ Modified Version, except to acknowledge the contribution(s) of the
10607
+ Copyright Holder(s) and the Author(s) or with their explicit written
10608
+ permission.
10609
+
10610
+ 5) The Font Software, modified or unmodified, in part or in whole,
10611
+ must be distributed entirely under this license, and must not be
10612
+ distributed under any other license. The requirement for fonts to
10613
+ remain under this license does not apply to any document created
10614
+ using the Font Software.
10615
+
10616
+ TERMINATION
10617
+ This license becomes null and void if any of the above conditions are
10618
+ not met.
10619
+
10620
+ DISCLAIMER
10621
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10622
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
10623
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
10624
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
10625
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
10626
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
10627
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
10628
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
10629
+ OTHER DEALINGS IN THE FONT SOFTWARE.
10630
+ ~~~~
10631
+
10632
+ ## Noto Sans Math (embedded by quillmark-typst)
10633
+
10634
+ ~~~~text
10635
+ Copyright 2022 The Noto Project Authors (https://github.com/notofonts/math)
10636
+
10637
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
10638
+ This license is copied below, and is also available with a FAQ at:
10639
+ https://openfontlicense.org
10640
+
10641
+
10543
10642
  -----------------------------------------------------------
10544
10643
  SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10545
10644
  -----------------------------------------------------------
package/core/wasm.d.ts CHANGED
@@ -80,7 +80,8 @@ export type ContentLineKind =
80
80
  | { kind: "para" }
81
81
  | { kind: "heading"; attrs: { level: number } }
82
82
  | { kind: "code"; attrs?: { lang?: string } }
83
- | { kind: "rule" };
83
+ | { kind: "rule" }
84
+ | { kind: "term" };
84
85
 
85
86
  /** An ancestor block a line nests inside, outermost first. Closed like
86
87
  * `ContentLine.kind`.
@@ -110,6 +111,7 @@ export type ContentContainer =
110
111
  instance?: number;
111
112
  }
112
113
  | { container: "quote"; instance?: number }
114
+ | { container: "description"; instance?: number }
113
115
  | { container: "element"; attrs: ElementAttrs; instance?: number };
114
116
 
115
117
  /** A carrier element's name and attributes, one bag: `$name` is the part of
@@ -171,6 +173,19 @@ export interface ImageProps {
171
173
  alt: string;
172
174
  }
173
175
 
176
+ /** `props` of a `type: "footnote"` island: the note, shaped as one `TableCell`
177
+ * with no `\n` at either edge. The island's slot is the reference, inline in
178
+ * its paragraph. */
179
+ export type FootnoteProps = TableCell;
180
+
181
+ /** `props` of a `type: "math"` island: the equation's TeX, as written between
182
+ * its dollars, on one line with no edge whitespace. `display` is present and
183
+ * `true` on a `$$…$$` equation. */
184
+ export interface MathProps {
185
+ tex: string;
186
+ display?: true;
187
+ }
188
+
174
189
  /** A structured object occupying one island slot in `Content.text`. `type` is a
175
190
  * closed set, so `type === "table"` narrows `props` to `TableProps`. */
176
191
  export type ContentIsland = {
@@ -178,6 +193,8 @@ export type ContentIsland = {
178
193
  } & (
179
194
  | { type: "table"; props: TableProps }
180
195
  | { type: "image"; props: ImageProps }
196
+ | { type: "footnote"; props: FootnoteProps }
197
+ | { type: "math"; props: MathProps }
181
198
  );
182
199
 
183
200
  /**
@@ -814,9 +831,9 @@ export class Document {
814
831
  setQuillRef(ref_str: string): void;
815
832
  /**
816
833
  * Read the storage version tag from a raw storage DTO string without a full
817
- * parse, or `undefined`. Unknown future versions come back as-is, which
818
- * distinguishes "build too old" from "payload corrupt" when `fromStored`
819
- * throws. This is the storage version, not a field schema, though the JSON
834
+ * parse, or `undefined`. A tag this build does not read, newer or retired,
835
+ * comes back as-is, which tells a version mismatch from a corrupt payload
836
+ * when `fromStored` throws. This is the storage version, not a field schema, though the JSON
820
837
  * key is spelled `"schema"`: that is the DTO's serde tag.
821
838
  */
822
839
  static storageVersionOf(json: string): string | undefined;
package/core/wasm.js CHANGED
@@ -978,9 +978,9 @@ export class Document {
978
978
  }
979
979
  /**
980
980
  * Read the storage version tag from a raw storage DTO string without a full
981
- * parse, or `undefined`. Unknown future versions come back as-is, which
982
- * distinguishes "build too old" from "payload corrupt" when `fromStored`
983
- * throws. This is the storage version, not a field schema, though the JSON
981
+ * parse, or `undefined`. A tag this build does not read, newer or retired,
982
+ * comes back as-is, which tells a version mismatch from a corrupt payload
983
+ * when `fromStored` throws. This is the storage version, not a field schema, though the JSON
984
984
  * key is spelled `"schema"`: that is the DTO's serde tag.
985
985
  * @param {string} json
986
986
  * @returns {string | undefined}
package/core/wasm_bg.wasm CHANGED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quillmark/wasm",
3
- "version": "0.128.0",
3
+ "version": "0.130.0",
4
4
  "description": "WebAssembly bindings for Quillmark, a schema-driven document framework",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
package/render/wasm.d.ts CHANGED
@@ -80,7 +80,8 @@ export type ContentLineKind =
80
80
  | { kind: "para" }
81
81
  | { kind: "heading"; attrs: { level: number } }
82
82
  | { kind: "code"; attrs?: { lang?: string } }
83
- | { kind: "rule" };
83
+ | { kind: "rule" }
84
+ | { kind: "term" };
84
85
 
85
86
  /** An ancestor block a line nests inside, outermost first. Closed like
86
87
  * `ContentLine.kind`.
@@ -110,6 +111,7 @@ export type ContentContainer =
110
111
  instance?: number;
111
112
  }
112
113
  | { container: "quote"; instance?: number }
114
+ | { container: "description"; instance?: number }
113
115
  | { container: "element"; attrs: ElementAttrs; instance?: number };
114
116
 
115
117
  /** A carrier element's name and attributes, one bag: `$name` is the part of
@@ -171,6 +173,19 @@ export interface ImageProps {
171
173
  alt: string;
172
174
  }
173
175
 
176
+ /** `props` of a `type: "footnote"` island: the note, shaped as one `TableCell`
177
+ * with no `\n` at either edge. The island's slot is the reference, inline in
178
+ * its paragraph. */
179
+ export type FootnoteProps = TableCell;
180
+
181
+ /** `props` of a `type: "math"` island: the equation's TeX, as written between
182
+ * its dollars, on one line with no edge whitespace. `display` is present and
183
+ * `true` on a `$$…$$` equation. */
184
+ export interface MathProps {
185
+ tex: string;
186
+ display?: true;
187
+ }
188
+
174
189
  /** A structured object occupying one island slot in `Content.text`. `type` is a
175
190
  * closed set, so `type === "table"` narrows `props` to `TableProps`. */
176
191
  export type ContentIsland = {
@@ -178,6 +193,8 @@ export type ContentIsland = {
178
193
  } & (
179
194
  | { type: "table"; props: TableProps }
180
195
  | { type: "image"; props: ImageProps }
196
+ | { type: "footnote"; props: FootnoteProps }
197
+ | { type: "math"; props: MathProps }
181
198
  );
182
199
 
183
200
  /**
@@ -952,9 +969,9 @@ export class Document {
952
969
  setQuillRef(ref_str: string): void;
953
970
  /**
954
971
  * Read the storage version tag from a raw storage DTO string without a full
955
- * parse, or `undefined`. Unknown future versions come back as-is, which
956
- * distinguishes "build too old" from "payload corrupt" when `fromStored`
957
- * throws. This is the storage version, not a field schema, though the JSON
972
+ * parse, or `undefined`. A tag this build does not read, newer or retired,
973
+ * comes back as-is, which tells a version mismatch from a corrupt payload
974
+ * when `fromStored` throws. This is the storage version, not a field schema, though the JSON
958
975
  * key is spelled `"schema"`: that is the DTO's serde tag.
959
976
  */
960
977
  static storageVersionOf(json: string): string | undefined;
package/render/wasm.js CHANGED
@@ -978,9 +978,9 @@ export class Document {
978
978
  }
979
979
  /**
980
980
  * Read the storage version tag from a raw storage DTO string without a full
981
- * parse, or `undefined`. Unknown future versions come back as-is, which
982
- * distinguishes "build too old" from "payload corrupt" when `fromStored`
983
- * throws. This is the storage version, not a field schema, though the JSON
981
+ * parse, or `undefined`. A tag this build does not read, newer or retired,
982
+ * comes back as-is, which tells a version mismatch from a corrupt payload
983
+ * when `fromStored` throws. This is the storage version, not a field schema, though the JSON
984
984
  * key is spelled `"schema"`: that is the DTO's serde tag.
985
985
  * @param {string} json
986
986
  * @returns {string | undefined}
Binary file
@@ -133,6 +133,8 @@ export type {
133
133
  ContentIsland,
134
134
  TableProps,
135
135
  ImageProps,
136
+ FootnoteProps,
137
+ MathProps,
136
138
  TableCell,
137
139
  CardInput,
138
140
  PathStep,
@@ -334,7 +334,7 @@ function requireLocalQuill(quill, method) {
334
334
  // every container has an entry. An entry of `'*'` welds on the whole bag: an
335
335
  // element's attributes are open, its name among them.
336
336
 
337
- const WELD_KEYS = { list_item: ['ordered'], quote: [], element: '*' };
337
+ const WELD_KEYS = { list_item: ['ordered'], quote: [], description: [], element: '*' };
338
338
 
339
339
  /**
340
340
  * @param {import('../core/wasm.js').ContentContainer} a
package/sbom.cdx.json CHANGED
@@ -2,9 +2,9 @@
2
2
  "bomFormat": "CycloneDX",
3
3
  "specVersion": "1.5",
4
4
  "version": 1,
5
- "serialNumber": "urn:uuid:1043ed1d-f769-49b6-ad4a-cf23d2702ebf",
5
+ "serialNumber": "urn:uuid:a491c604-802a-4c9d-82a3-22c16147aa8f",
6
6
  "metadata": {
7
- "timestamp": "2026-10-21T17:35:53.828174476Z",
7
+ "timestamp": "2026-10-22T13:12:19.770287903Z",
8
8
  "tools": [
9
9
  {
10
10
  "vendor": "CycloneDX",
@@ -14,9 +14,9 @@
14
14
  ],
15
15
  "component": {
16
16
  "type": "library",
17
- "bom-ref": "path+file:///home/runner/work/quillmark/quillmark/crates/bindings/wasm#quillmark-wasm@0.128.0",
17
+ "bom-ref": "path+file:///home/runner/work/quillmark/quillmark/crates/bindings/wasm#quillmark-wasm@0.130.0",
18
18
  "name": "quillmark-wasm",
19
- "version": "0.128.0",
19
+ "version": "0.130.0",
20
20
  "description": "WebAssembly bindings for Quillmark, a schema-driven document framework",
21
21
  "scope": "required",
22
22
  "licenses": [
@@ -24,7 +24,7 @@
24
24
  "expression": "Apache-2.0"
25
25
  }
26
26
  ],
27
- "purl": "pkg:cargo/quillmark-wasm@0.128.0?download_url=file://.",
27
+ "purl": "pkg:cargo/quillmark-wasm@0.130.0?download_url=file://.",
28
28
  "externalReferences": [
29
29
  {
30
30
  "type": "vcs",
@@ -34,10 +34,10 @@
34
34
  "components": [
35
35
  {
36
36
  "type": "library",
37
- "bom-ref": "path+file:///home/runner/work/quillmark/quillmark/crates/bindings/wasm#quillmark-wasm@0.128.0 bin-target-0",
37
+ "bom-ref": "path+file:///home/runner/work/quillmark/quillmark/crates/bindings/wasm#quillmark-wasm@0.130.0 bin-target-0",
38
38
  "name": "quillmark_wasm",
39
- "version": "0.128.0",
40
- "purl": "pkg:cargo/quillmark-wasm@0.128.0?download_url=file://.#src/lib.rs"
39
+ "version": "0.130.0",
40
+ "purl": "pkg:cargo/quillmark-wasm@0.130.0?download_url=file://.#src/lib.rs"
41
41
  }
42
42
  ]
43
43
  },
@@ -51,9 +51,9 @@
51
51
  "components": [
52
52
  {
53
53
  "type": "library",
54
- "bom-ref": "path+file:///home/runner/work/quillmark/quillmark/crates/backends/acroform#quillmark-acroform@0.128.0",
54
+ "bom-ref": "path+file:///home/runner/work/quillmark/quillmark/crates/backends/acroform#quillmark-acroform@0.130.0",
55
55
  "name": "quillmark-acroform",
56
- "version": "0.128.0",
56
+ "version": "0.130.0",
57
57
  "description": "Typst-free acroform backend for Quillmark: fills existing PDF forms via the quillmark-pdf stamping spine",
58
58
  "scope": "required",
59
59
  "licenses": [
@@ -61,7 +61,7 @@
61
61
  "expression": "Apache-2.0"
62
62
  }
63
63
  ],
64
- "purl": "pkg:cargo/quillmark-acroform@0.128.0?download_url=file://../../backends/acroform",
64
+ "purl": "pkg:cargo/quillmark-acroform@0.130.0?download_url=file://../../backends/acroform",
65
65
  "externalReferences": [
66
66
  {
67
67
  "type": "documentation",
@@ -79,9 +79,9 @@
79
79
  },
80
80
  {
81
81
  "type": "library",
82
- "bom-ref": "path+file:///home/runner/work/quillmark/quillmark/crates/backends/typst#quillmark-typst@0.128.0",
82
+ "bom-ref": "path+file:///home/runner/work/quillmark/quillmark/crates/backends/typst#quillmark-typst@0.130.0",
83
83
  "name": "quillmark-typst",
84
- "version": "0.128.0",
84
+ "version": "0.130.0",
85
85
  "description": "Typst backend for Quillmark",
86
86
  "scope": "required",
87
87
  "licenses": [
@@ -89,7 +89,7 @@
89
89
  "expression": "Apache-2.0"
90
90
  }
91
91
  ],
92
- "purl": "pkg:cargo/quillmark-typst@0.128.0?download_url=file://../../backends/typst",
92
+ "purl": "pkg:cargo/quillmark-typst@0.130.0?download_url=file://../../backends/typst",
93
93
  "externalReferences": [
94
94
  {
95
95
  "type": "documentation",
@@ -107,9 +107,9 @@
107
107
  },
108
108
  {
109
109
  "type": "library",
110
- "bom-ref": "path+file:///home/runner/work/quillmark/quillmark/crates/content#quillmark-content@0.128.0",
110
+ "bom-ref": "path+file:///home/runner/work/quillmark/quillmark/crates/content#quillmark-content@0.130.0",
111
111
  "name": "quillmark-content",
112
- "version": "0.128.0",
112
+ "version": "0.130.0",
113
113
  "description": "Content model (splice-shaped USV text with line attributes, marks, and islands), canonical serialization, edit deltas, and richtext/plaintext codecs for Quillmark",
114
114
  "scope": "required",
115
115
  "licenses": [
@@ -117,7 +117,7 @@
117
117
  "expression": "Apache-2.0"
118
118
  }
119
119
  ],
120
- "purl": "pkg:cargo/quillmark-content@0.128.0?download_url=file://../../content",
120
+ "purl": "pkg:cargo/quillmark-content@0.130.0?download_url=file://../../content",
121
121
  "externalReferences": [
122
122
  {
123
123
  "type": "website",
@@ -131,9 +131,9 @@
131
131
  },
132
132
  {
133
133
  "type": "library",
134
- "bom-ref": "path+file:///home/runner/work/quillmark/quillmark/crates/core#quillmark-core@0.128.0",
134
+ "bom-ref": "path+file:///home/runner/work/quillmark/quillmark/crates/core#quillmark-core@0.130.0",
135
135
  "name": "quillmark-core",
136
- "version": "0.128.0",
136
+ "version": "0.130.0",
137
137
  "description": "Core types and functionality for the Quillmark schema-driven document framework",
138
138
  "scope": "required",
139
139
  "licenses": [
@@ -141,7 +141,7 @@
141
141
  "expression": "Apache-2.0"
142
142
  }
143
143
  ],
144
- "purl": "pkg:cargo/quillmark-core@0.128.0?download_url=file://../../core",
144
+ "purl": "pkg:cargo/quillmark-core@0.130.0?download_url=file://../../core",
145
145
  "externalReferences": [
146
146
  {
147
147
  "type": "documentation",
@@ -159,9 +159,9 @@
159
159
  },
160
160
  {
161
161
  "type": "library",
162
- "bom-ref": "path+file:///home/runner/work/quillmark/quillmark/crates/quillmark#0.128.0",
162
+ "bom-ref": "path+file:///home/runner/work/quillmark/quillmark/crates/quillmark#0.130.0",
163
163
  "name": "quillmark",
164
- "version": "0.128.0",
164
+ "version": "0.130.0",
165
165
  "description": "A schema-driven document framework: turn Markdown into a fully typeset document with a quill",
166
166
  "scope": "required",
167
167
  "licenses": [
@@ -169,7 +169,7 @@
169
169
  "expression": "Apache-2.0"
170
170
  }
171
171
  ],
172
- "purl": "pkg:cargo/quillmark@0.128.0?download_url=file://../../quillmark",
172
+ "purl": "pkg:cargo/quillmark@0.130.0?download_url=file://../../quillmark",
173
173
  "externalReferences": [
174
174
  {
175
175
  "type": "documentation",
@@ -187,9 +187,9 @@
187
187
  },
188
188
  {
189
189
  "type": "library",
190
- "bom-ref": "path+file:///home/runner/work/quillmark/quillmark/crates/quillmark-pdf#0.128.0",
190
+ "bom-ref": "path+file:///home/runner/work/quillmark/quillmark/crates/quillmark-pdf#0.130.0",
191
191
  "name": "quillmark-pdf",
192
- "version": "0.128.0",
192
+ "version": "0.130.0",
193
193
  "description": "Typst-free AcroForm stamping spine for Quillmark: (base_pdf, &[FieldSpec]) -> stamped PDF + regions",
194
194
  "scope": "required",
195
195
  "licenses": [
@@ -197,7 +197,7 @@
197
197
  "expression": "Apache-2.0"
198
198
  }
199
199
  ],
200
- "purl": "pkg:cargo/quillmark-pdf@0.128.0?download_url=file://../../quillmark-pdf",
200
+ "purl": "pkg:cargo/quillmark-pdf@0.130.0?download_url=file://../../quillmark-pdf",
201
201
  "externalReferences": [
202
202
  {
203
203
  "type": "documentation",
@@ -10334,23 +10334,23 @@
10334
10334
  ],
10335
10335
  "dependencies": [
10336
10336
  {
10337
- "ref": "path+file:///home/runner/work/quillmark/quillmark/crates/backends/acroform#quillmark-acroform@0.128.0",
10337
+ "ref": "path+file:///home/runner/work/quillmark/quillmark/crates/backends/acroform#quillmark-acroform@0.130.0",
10338
10338
  "dependsOn": [
10339
10339
  "registry+https://github.com/rust-lang/crates.io-index#hayro@0.8.0",
10340
- "path+file:///home/runner/work/quillmark/quillmark/crates/content#quillmark-content@0.128.0",
10341
- "path+file:///home/runner/work/quillmark/quillmark/crates/core#quillmark-core@0.128.0",
10342
- "path+file:///home/runner/work/quillmark/quillmark/crates/quillmark-pdf#0.128.0",
10340
+ "path+file:///home/runner/work/quillmark/quillmark/crates/content#quillmark-content@0.130.0",
10341
+ "path+file:///home/runner/work/quillmark/quillmark/crates/core#quillmark-core@0.130.0",
10342
+ "path+file:///home/runner/work/quillmark/quillmark/crates/quillmark-pdf#0.130.0",
10343
10343
  "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.229",
10344
10344
  "registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.151"
10345
10345
  ]
10346
10346
  },
10347
10347
  {
10348
- "ref": "path+file:///home/runner/work/quillmark/quillmark/crates/backends/typst#quillmark-typst@0.128.0",
10348
+ "ref": "path+file:///home/runner/work/quillmark/quillmark/crates/backends/typst#quillmark-typst@0.130.0",
10349
10349
  "dependsOn": [
10350
10350
  "registry+https://github.com/rust-lang/crates.io-index#comemo@0.5.1",
10351
- "path+file:///home/runner/work/quillmark/quillmark/crates/content#quillmark-content@0.128.0",
10352
- "path+file:///home/runner/work/quillmark/quillmark/crates/core#quillmark-core@0.128.0",
10353
- "path+file:///home/runner/work/quillmark/quillmark/crates/quillmark-pdf#0.128.0",
10351
+ "path+file:///home/runner/work/quillmark/quillmark/crates/content#quillmark-content@0.130.0",
10352
+ "path+file:///home/runner/work/quillmark/quillmark/crates/core#quillmark-core@0.130.0",
10353
+ "path+file:///home/runner/work/quillmark/quillmark/crates/quillmark-pdf#0.130.0",
10354
10354
  "registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.151",
10355
10355
  "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.21",
10356
10356
  "registry+https://github.com/rust-lang/crates.io-index#toml@1.1.6+spec-1.1.0",
@@ -10362,13 +10362,13 @@
10362
10362
  ]
10363
10363
  },
10364
10364
  {
10365
- "ref": "path+file:///home/runner/work/quillmark/quillmark/crates/bindings/wasm#quillmark-wasm@0.128.0",
10365
+ "ref": "path+file:///home/runner/work/quillmark/quillmark/crates/bindings/wasm#quillmark-wasm@0.130.0",
10366
10366
  "dependsOn": [
10367
10367
  "registry+https://github.com/rust-lang/crates.io-index#console_error_panic_hook@0.1.7",
10368
10368
  "registry+https://github.com/rust-lang/crates.io-index#js-sys@0.3.106",
10369
- "path+file:///home/runner/work/quillmark/quillmark/crates/quillmark#0.128.0",
10370
- "path+file:///home/runner/work/quillmark/quillmark/crates/content#quillmark-content@0.128.0",
10371
- "path+file:///home/runner/work/quillmark/quillmark/crates/core#quillmark-core@0.128.0",
10369
+ "path+file:///home/runner/work/quillmark/quillmark/crates/quillmark#0.130.0",
10370
+ "path+file:///home/runner/work/quillmark/quillmark/crates/content#quillmark-content@0.130.0",
10371
+ "path+file:///home/runner/work/quillmark/quillmark/crates/core#quillmark-core@0.130.0",
10372
10372
  "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.229",
10373
10373
  "registry+https://github.com/rust-lang/crates.io-index#serde-wasm-bindgen@0.6.5",
10374
10374
  "registry+https://github.com/rust-lang/crates.io-index#serde_bytes@0.11.19",
@@ -10379,20 +10379,21 @@
10379
10379
  ]
10380
10380
  },
10381
10381
  {
10382
- "ref": "path+file:///home/runner/work/quillmark/quillmark/crates/content#quillmark-content@0.128.0",
10382
+ "ref": "path+file:///home/runner/work/quillmark/quillmark/crates/content#quillmark-content@0.130.0",
10383
10383
  "dependsOn": [
10384
10384
  "registry+https://github.com/rust-lang/crates.io-index#pulldown-cmark@0.13.4",
10385
10385
  "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.229",
10386
10386
  "registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.151",
10387
- "registry+https://github.com/rust-lang/crates.io-index#similar@3.2.0"
10387
+ "registry+https://github.com/rust-lang/crates.io-index#similar@3.2.0",
10388
+ "registry+https://github.com/rust-lang/crates.io-index#unicase@2.9.0"
10388
10389
  ]
10389
10390
  },
10390
10391
  {
10391
- "ref": "path+file:///home/runner/work/quillmark/quillmark/crates/core#quillmark-core@0.128.0",
10392
+ "ref": "path+file:///home/runner/work/quillmark/quillmark/crates/core#quillmark-core@0.130.0",
10392
10393
  "dependsOn": [
10393
10394
  "registry+https://github.com/rust-lang/crates.io-index#glob@0.3.4",
10394
10395
  "registry+https://github.com/rust-lang/crates.io-index#indexmap@2.14.2",
10395
- "path+file:///home/runner/work/quillmark/quillmark/crates/content#quillmark-content@0.128.0",
10396
+ "path+file:///home/runner/work/quillmark/quillmark/crates/content#quillmark-content@0.130.0",
10396
10397
  "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.229",
10397
10398
  "registry+https://github.com/rust-lang/crates.io-index#serde-saphyr@1.3.0",
10398
10399
  "registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.151",
@@ -10403,18 +10404,18 @@
10403
10404
  ]
10404
10405
  },
10405
10406
  {
10406
- "ref": "path+file:///home/runner/work/quillmark/quillmark/crates/quillmark#0.128.0",
10407
+ "ref": "path+file:///home/runner/work/quillmark/quillmark/crates/quillmark#0.130.0",
10407
10408
  "dependsOn": [
10408
- "path+file:///home/runner/work/quillmark/quillmark/crates/backends/acroform#quillmark-acroform@0.128.0",
10409
- "path+file:///home/runner/work/quillmark/quillmark/crates/core#quillmark-core@0.128.0",
10410
- "path+file:///home/runner/work/quillmark/quillmark/crates/backends/typst#quillmark-typst@0.128.0"
10409
+ "path+file:///home/runner/work/quillmark/quillmark/crates/backends/acroform#quillmark-acroform@0.130.0",
10410
+ "path+file:///home/runner/work/quillmark/quillmark/crates/core#quillmark-core@0.130.0",
10411
+ "path+file:///home/runner/work/quillmark/quillmark/crates/backends/typst#quillmark-typst@0.130.0"
10411
10412
  ]
10412
10413
  },
10413
10414
  {
10414
- "ref": "path+file:///home/runner/work/quillmark/quillmark/crates/quillmark-pdf#0.128.0",
10415
+ "ref": "path+file:///home/runner/work/quillmark/quillmark/crates/quillmark-pdf#0.130.0",
10415
10416
  "dependsOn": [
10416
10417
  "registry+https://github.com/rust-lang/crates.io-index#pdf-writer@0.15.0",
10417
- "path+file:///home/runner/work/quillmark/quillmark/crates/core#quillmark-core@0.128.0",
10418
+ "path+file:///home/runner/work/quillmark/quillmark/crates/core#quillmark-core@0.130.0",
10418
10419
  "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.21"
10419
10420
  ]
10420
10421
  },