odf-kit 0.9.5 → 0.9.7

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
@@ -5,57 +5,184 @@ All notable changes to odf-kit will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
- ## [0.3.0] - 2026-02-23
8
+ ## [0.9.7] - 2026-04-10
9
+
10
+ ### Added
11
+
12
+ - **Number formats** — `numberFormat` option on `OdsCellOptions` for professional numeric display. Formats: `"integer"` (1,234), `"decimal:N"` (1,234.56), `"percentage"` / `"percentage:N"` (12.34%), `"currency:CODE"` / `"currency:CODE:N"` (€1,234.56). Applies at row level (default for all cells) or per cell. Style deduplication — identical formats share one ODF style element.
13
+ - **Percentage cells** — `type: "percentage"` on `OdsCellObject`. Stores raw decimal, displays as percentage.
14
+ - **Currency cells** — `type: "currency"` on `OdsCellObject` with `numberFormat: "currency:CODE"`. Supports 30+ ISO 4217 currency codes with correct symbols.
15
+ - **Merged cells** — `colSpan` and `rowSpan` on `OdsCellObject`. Automatically emits `table:covered-table-cell` elements for spanned positions. Supports combined colSpan + rowSpan and merges at any column position.
16
+ - **Freeze rows/columns** — `sheet.freezeRows(N)` and `sheet.freezeColumns(N)` on `OdsSheet`. Generates `settings.xml` in the ODS ZIP with LibreOffice-compatible freeze configuration. `settings.xml` only emitted when at least one sheet has freeze settings.
17
+ - **Hyperlinks in ODS cells** — `href` on `OdsCellObject`. Cell text rendered as `text:a` link with `xlink:href`. `xmlns:xlink` namespace declared on document root.
18
+ - **Sheet tab color** — `sheet.setTabColor(color)` on `OdsSheet`. Accepts hex (`"#FF0000"`) or CSS named colors. Emits `table:tab-color` on the sheet's table style.
19
+ - **`OdsCellType`** exported from public API.
20
+ - 32 new tests (849 total).
9
21
 
10
- Template engine.
22
+ ## [0.9.6] - 2026-04-10
11
23
 
12
24
  ### Added
13
25
 
14
- - **Template engine** Fill existing `.odt` templates with data using `fillTemplate()`. Load a `.odt` file created in LibreOffice, replace `{placeholders}` with values from a JSON/object data source, and get a new `.odt` file back.
15
- - **Simple replacement** `{tag}` placeholders replaced with values, with automatic XML escaping of `& < > " '`
16
- - **Loops** `{#items}...{/items}` repeats content for each item in an array. Items inherit parent data; item properties override.
17
- - **Conditionals** `{#showSection}...{/showSection}` includes or removes content based on truthy/falsy values.
18
- - **Dot notation** `{user.address.city}` resolves nested object paths.
19
- - **Placeholder healer** Automatically reassembles placeholders that LibreOffice fragments across multiple `<text:span>` elements. Handles 2-span, multi-span, every-character, shared-segment, and bare-text fragmentation patterns. Removes editing artifacts (`<text:s/>`, `<text:bookmark/>`) trapped inside fragments.
20
- - **Boundary expansion** — Section markers (`{#tag}`, `{/tag}`) expand outward through wrapping XML elements to prevent orphaned empty tags after removal.
21
- - **Header/footer templates** Placeholders in `styles.xml` (headers and footers) are processed alongside `content.xml`.
22
- - **120 new tests** — healer (51), replacer (56), template pipeline and integration (13). Total: 222 tests.
26
+ - **`tiptapToOdt()`**Convert TipTap/ProseMirror JSON directly to ODT. Accepts the JSON object returned by `editor.getJSON()` in TipTap and returns a valid `.odt` file as `Uint8Array`. No dependency on `@tiptap/core` walks the JSON tree as a plain object.
27
+ - **Supported block nodes:** `doc`, `paragraph`, `heading` (levels 1–6), `bulletList`, `orderedList`, `listItem` (nested), `blockquote`, `codeBlock`, `horizontalRule`, `hardBreak`, `image`, `table`, `tableRow`, `tableCell`, `tableHeader`.
28
+ - **Supported marks:** `bold`, `italic`, `underline`, `strike`, `code`, `link`, `textStyle` (color, fontSize, fontFamily), `highlight`, `superscript`, `subscript`.
29
+ - **Image support:** Data URIs decoded and embedded directly. Other URLs looked up in the `images` option (`Record<src, Uint8Array>`). Unknown URLs emit a placeholder paragraph.
30
+ - **`unknownNodeHandler`** callback in `TiptapToOdtOptions` handle custom TipTap extensions without waiting for odf-kit to add support.
31
+ - **`TiptapNode`**, **`TiptapMark`**, **`TiptapToOdtOptions`** types exported.
32
+ - All `HtmlToOdtOptions` apply (page format, margins, orientation, metadata).
33
+ - 31 new tests (817 total).
23
34
 
24
- ### Credits
35
+ ## [0.9.5] - 2026-04-09
25
36
 
26
- Template syntax follows [Mustache](https://mustache.github.io/) conventions (`{tag}`, `{#section}{/section}`), proven in document templating by [docxtemplater](https://docxtemplater.com/). odf-kit's template engine is a clean-room implementation purpose-built for ODF — no code from either project was used.
37
+ ### Added
27
38
 
28
- ## [0.2.0] - 2026-02-21
39
+ - **`markdownToOdt()`** — Convert Markdown directly to ODT. Accepts any CommonMark Markdown string and returns a valid `.odt` file as `Uint8Array`. Supports all `HtmlToOdtOptions` (page format, margins, orientation, metadata). Internally converts Markdown → HTML via `marked`, then HTML → ODT via `htmlToOdt()`.
40
+ - **`marked`** added as first runtime dependency (23kB, zero transitive dependencies).
41
+ - 17 new tests.
42
+
43
+ ## [0.9.4] - 2026-04-06
44
+
45
+ ### Fixed
46
+
47
+ - **ODS datetime detection** — `Date` objects with a nonzero UTC time component now render as datetime (`YYYY-MM-DDTHH:MM:SS`) rather than date-only (`YYYY-MM-DD`). Auto-detected: if `getUTCHours()`, `getUTCMinutes()`, `getUTCSeconds()`, or `getUTCMilliseconds()` are nonzero, the cell uses `office:date-value` with full datetime format and a matching `number:date-style`.
48
+ - **ODS formula namespace** — Added `xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2"` to the `office:document-content` root element. Previously the `of:` prefix used in formula values was undeclared, causing LibreOffice to display `Err:510` in formula cells.
49
+
50
+ ## [0.9.2] - 2026-04-05
51
+
52
+ ### Added
53
+
54
+ - **`htmlToOdt()`** — Convert HTML to ODT. Accepts any HTML string (full document or fragment) and returns a valid `.odt` file as `Uint8Array`. Supports headings (h1–h6), paragraphs, bold, italic, underline, strikethrough, lists (ordered and unordered, nested), tables, hyperlinks, blockquotes, code blocks, horizontal rules, and inline CSS (color, font-size, font-family, text-align, background-color on cells).
55
+ - **Page format presets** — `A4` (default), `letter`, `legal`, `A3`, `A5`. Individual margin overrides apply on top of preset defaults.
56
+ - **`HtmlToOdtOptions`** — `pageFormat`, `orientation`, `marginTop/Bottom/Left/Right`, `metadata` (title, creator, description).
57
+ - **`addLineBreak()`** on `ParagraphBuilder` — inserts a `text:line-break` within a paragraph.
58
+ - **`borderBottom`** on `ParagraphOptions` — bottom border on a paragraph (useful for horizontal rules and section dividers).
59
+ - 62 new tests (769 total).
60
+
61
+ ## [0.9.1] - 2026-04-04
62
+
63
+ ### Fixed
64
+
65
+ - Added `"./ods"` sub-export to `package.json` exports map. v0.9.0 was published without this entry, making `import { OdsDocument } from "odf-kit/ods"` fail with a module resolution error.
66
+
67
+ ## [0.9.0] - 2026-04-04
68
+
69
+ ### Added
70
+
71
+ - **ODS spreadsheet generation** — `OdsDocument` and `OdsSheet` for creating `.ods` files.
72
+ - **`OdsDocument`** — `addSheet(name)`, `setDateFormat()`, `save()`.
73
+ - **`OdsSheet`** — `addRow(values, options?)`, `setColumnWidth(index, width)`, `setRowHeight(index, height)`.
74
+ - **Auto-typed cells** — `number` → float, `Date` → date, `boolean` → boolean, `null`/`undefined` → empty. String values are always string type; formula cells require explicit `{ value, type: "formula" }`.
75
+ - **Date formatting** — Three built-in formats: `"YYYY-MM-DD"` (ISO, default), `"DD/MM/YYYY"` (European), `"MM/DD/YYYY"` (US). Set document-level default via `setDateFormat()` or override per-cell via `dateFormat` in cell options.
76
+ - **Cell formatting** — `bold`, `italic`, `fontSize`, `fontFamily`, `color`, `backgroundColor`, `border`, `borderTop/Bottom/Left/Right`, `align`, `verticalAlign`, `padding`, `wrap`.
77
+ - **Row formatting** — Pass formatting options as second argument to `addRow()` — applies to all cells in the row as defaults. Cell-level options override row defaults.
78
+ - **Multiple sheets** — `addSheet()` creates additional tabs.
79
+ - **Style deduplication** — Identical cell styles across all sheets share a single ODF style element.
80
+ - **Package restructure** — New sub-exports: `odf-kit/odt`, `odf-kit/ods`, `odf-kit/template`, `odf-kit/reader`, `odf-kit/typst`. Existing `import { OdtDocument } from "odf-kit"` continues to work unchanged.
81
+ - 57 new tests (707 total).
82
+
83
+ ## [0.8.4] - 2026-04-03
84
+
85
+ ### Fixed
86
+
87
+ - **ReDoS in healer/replacer** — Replaced catastrophic backtracking regex patterns with linear alternatives.
88
+ - **Double-escaping in xml-parser** — Fixed entity double-encoding when parsing XML with pre-escaped content.
89
+ - **CI permissions** — Tightened GitHub Actions workflow permissions.
90
+
91
+ ## [0.8.3] - 2026-03-26
92
+
93
+ ### Added
94
+
95
+ - **Image wrap mode** — `wrapMode: "left" | "right" | "none"` on `ImageOptions`. Left/right wrap positions the image with text flowing around it. Requires graphic style subsystem (new in this release).
96
+ - **Image margins** — `marginTop`, `marginBottom`, `marginLeft`, `marginRight` on `ImageOptions`.
97
+ - **Image border** — `border` on `ImageOptions` (CSS shorthand, e.g. `"0.5pt solid #000000"`).
98
+ - **Image opacity** — `opacity` on `ImageOptions` (0–1).
29
99
 
30
- Zero-dependency migration.
100
+ ## [0.8.2] - 2026-03-26
101
+
102
+ ### Added
103
+
104
+ - **Image accessibility** — `alt` → `<svg:title>`, `description` → `<svg:desc>` inside `draw:frame`.
105
+ - **`name`** override for `draw:name` on images.
106
+ - **`anchor: "page"`** support on `ImageOptions`.
107
+ - 6 new tests.
108
+
109
+ ## [0.8.1] - 2026-03-20
31
110
 
32
111
  ### Changed
33
112
 
34
- - **Replaced jszip with fflate** — Zero transitive runtime dependencies. Faster compression/decompression, smaller bundle (~8kB). MIT license.
35
- - All 102 existing tests re-validated with fflate. Generated files verified in LibreOffice.
113
+ - **README overhaul** — Full rewrite covering all four modes (build, fill, read, typst). Added Guides section with links to all guide and tool pages.
114
+ - Fixed `package.json` description field.
115
+ - Fixed dev vulnerabilities (ajv, flatted).
36
116
 
37
- ## [0.1.0] - 2026-02-11
117
+ ## [0.8.0] - 2026-03-20
118
+
119
+ ### Added
120
+
121
+ - **Typst emitter** — `odtToTypst()` and `modelToTypst()` via new `odf-kit/typst` sub-export. Converts ODT files to [Typst](https://typst.app) markup. Zero-dependency, pure TypeScript, browser-safe. Returns a `.typ` string.
122
+
123
+ ## [0.7.0] - 2026-03-15
124
+
125
+ ### Added
126
+
127
+ - **ODT reader** — `readOdt()` parses `.odt` files into a structured `OdtDocumentModel`. Tier 1 (raw XML), Tier 2 (semantic model), and Tier 3 (rendered output). Available via `odf-kit/reader`.
128
+ - **`odtToHtml()`** — Convert ODT to an HTML string.
129
+ - **HTML renderer** — Full fidelity rendering of headings, paragraphs, formatting, lists, tables, images (as base64 data URIs), hyperlinks.
130
+
131
+ ## [0.4.0] - 2026-03-05
132
+
133
+ ### Added
134
+
135
+ - **Advanced text formatting** — Underline, strikethrough, superscript, subscript, highlight color (hex and named CSS colors).
136
+ - **Hyperlinks** — External URLs (`https://...`) and internal bookmark links (`#name`). Optional text formatting on links.
137
+ - **Bookmarks** — `addBookmark(name)` on `ParagraphBuilder`.
138
+ - **Images** — Embedded PNG, JPEG, GIF, SVG, WebP, BMP, TIFF. Standalone (paragraph anchor) or inline (as-character). Stored in ZIP under `Pictures/` with correct MIME types in manifest.
139
+ - **`draw` and `xlink` namespaces** added to content.xml.
140
+ - 109 new tests.
38
141
 
39
- Initial release. Complete ODT (text document) support.
142
+ ## [0.3.0] - 2026-02-23
40
143
 
41
144
  ### Added
42
145
 
43
- - **Core** — ODF ZIP packaging (mimetype stored uncompressed as first entry), XML generation, namespace management, manifest, metadata
44
- - **Paragraphs and headings** — Plain text or formatted via builder callback, heading levels 1–6
45
- - **Text formatting** — Bold, italic, underline, strikethrough, superscript, subscript, font size, font family, text color, highlight color. Boolean shortcuts (`bold: true`) and CSS-style properties (`fontWeight: "bold"`) both accepted. Style deduplication for identical formatting.
46
- - **Tables** — Array-of-arrays for simple tables, builder callback for full control. Column widths, cell borders (table-level, cell-level, per-side), background colors (hex and named CSS colors), cell merging (colSpan/rowSpan), rich text in cells.
47
- - **Page layout** — Page size (A4 default), margins, orientation (portrait/landscape). Landscape auto-swaps A4 dimensions.
48
- - **Headers and footers** — Plain text (with `###` for page numbers) or formatted via builder callback with `addPageNumber()`.
49
- - **Page breaks** — `addPageBreak()` inserts a new page.
50
- - **Lists** Bullet and numbered lists. String array for simple lists, builder callback for formatting and nesting (up to 6 levels).
51
- - **Tab stops** — Left, center, right alignment with configurable positions.
52
- - **Images** — Embedded PNG, JPEG, GIF, SVG, WebP, BMP, TIFF. Standalone (paragraph anchor) or inline (as-character anchor). Images stored in ZIP under `Pictures/` with correct MIME types in manifest.
53
- - **Hyperlinks** — External URLs and internal bookmark links (`#name`). Optional text formatting on links.
54
- - **Bookmarks** — Named anchor points for internal navigation via `addBookmark()`.
55
- - **Method chaining** — All methods return `this` for fluent API usage.
56
- - **TypeScript** — Full type definitions with JSDoc comments. ESM-only, Node.js 22+.
57
- - **Testing** — 102 tests covering all features. Validated against LibreOffice 24.2.
146
+ - **Template engine** — Fill existing `.odt` templates with data using `fillTemplate()`. Replaces `{placeholders}` with values from a data object.
147
+ - **Simple replacement** — `{tag}` placeholders with automatic XML escaping.
148
+ - **Loops** — `{#items}...{/items}` repeats content for each array item.
149
+ - **Conditionals** — `{#showSection}...{/showSection}` includes or removes content.
150
+ - **Dot notation** — `{user.address.city}` resolves nested object paths.
151
+ - **Placeholder healer** — Reassembles placeholders fragmented by LibreOffice across multiple `<text:span>` elements.
152
+ - **Header/footer templates** — Placeholders in `styles.xml` processed alongside `content.xml`.
153
+ - 120 new tests (222 total).
154
+
155
+ ## [0.2.0] - 2026-02-21
156
+
157
+ ### Changed
158
+
159
+ - **Replaced jszip with fflate** — Zero transitive runtime dependencies. Faster, smaller (~8kB). MIT license.
160
+
161
+ ## [0.1.0] - 2026-02-11
162
+
163
+ Initial release. Complete ODT generation support.
164
+
165
+ ### Added
58
166
 
167
+ - Core ODF ZIP packaging, XML generation, namespace management, manifest, metadata.
168
+ - Paragraphs, headings (levels 1–6), text formatting (bold, italic, font size, color, etc.).
169
+ - Tables, page layout, headers/footers, page breaks, lists, tab stops.
170
+ - Method chaining. Full TypeScript types. ESM-only, Node.js 22+. 102 tests.
171
+
172
+ [0.9.7]: https://github.com/GitHubNewbie0/odf-kit/releases/tag/v0.9.7
173
+ [0.9.6]: https://github.com/GitHubNewbie0/odf-kit/releases/tag/v0.9.6
174
+ [0.9.5]: https://github.com/GitHubNewbie0/odf-kit/releases/tag/v0.9.5
175
+ [0.9.4]: https://github.com/GitHubNewbie0/odf-kit/releases/tag/v0.9.4
176
+ [0.9.2]: https://github.com/GitHubNewbie0/odf-kit/releases/tag/v0.9.2
177
+ [0.9.1]: https://github.com/GitHubNewbie0/odf-kit/releases/tag/v0.9.1
178
+ [0.9.0]: https://github.com/GitHubNewbie0/odf-kit/releases/tag/v0.9.0
179
+ [0.8.4]: https://github.com/GitHubNewbie0/odf-kit/releases/tag/v0.8.4
180
+ [0.8.3]: https://github.com/GitHubNewbie0/odf-kit/releases/tag/v0.8.3
181
+ [0.8.2]: https://github.com/GitHubNewbie0/odf-kit/releases/tag/v0.8.2
182
+ [0.8.1]: https://github.com/GitHubNewbie0/odf-kit/releases/tag/v0.8.1
183
+ [0.8.0]: https://github.com/GitHubNewbie0/odf-kit/releases/tag/v0.8.0
184
+ [0.7.0]: https://github.com/GitHubNewbie0/odf-kit/releases/tag/v0.7.0
185
+ [0.4.0]: https://github.com/GitHubNewbie0/odf-kit/releases/tag/v0.4.0
59
186
  [0.3.0]: https://github.com/GitHubNewbie0/odf-kit/releases/tag/v0.3.0
60
187
  [0.2.0]: https://github.com/GitHubNewbie0/odf-kit/releases/tag/v0.2.0
61
188
  [0.1.0]: https://github.com/GitHubNewbie0/odf-kit/releases/tag/v0.1.0