otomate 0.3.2 → 0.3.3

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/LICENSE ADDED
@@ -0,0 +1,63 @@
1
+ Business Source License 1.1
2
+
3
+ Parameters
4
+
5
+ Licensor: Alessio G.
6
+ Licensed Work: otomate — Universal Document Diffing Library
7
+ The Licensed Work is (c) 2026 Alessio G.
8
+ Additional Use Grant: You may make production use of the Licensed Work,
9
+ provided such use does not include offering the
10
+ Licensed Work to third parties on a hosted or
11
+ embedded basis which is competitive with the
12
+ Licensor's products.
13
+ Change Date: 2030-04-03
14
+ Change License: MIT
15
+
16
+ For information about alternative licensing arrangements for the Licensed
17
+ Work, please contact the Licensor.
18
+
19
+ Notice
20
+
21
+ Business Source License 1.1
22
+
23
+ Terms
24
+
25
+ The Licensor hereby grants you the right to copy, modify, create derivative
26
+ works, redistribute, and make non-production use of the Licensed Work. The
27
+ Licensor may make an Additional Use Grant, above, permitting limited
28
+ production use.
29
+
30
+ Effective on the Change Date, or the fourth anniversary of the first publicly
31
+ available distribution of a specific version of the Licensed Work under this
32
+ License, whichever comes first, the Licensor hereby grants you rights under
33
+ the terms of the Change License, and the rights granted in the paragraph
34
+ above terminate.
35
+
36
+ If your use of the Licensed Work does not comply with the requirements
37
+ currently in effect as described in this License, you must purchase a
38
+ commercial license from the Licensor, its affiliated entities, or authorized
39
+ resellers, or you must refrain from using the Licensed Work.
40
+
41
+ All copies of the original and modified Licensed Work, and derivative works
42
+ of the Licensed Work, are subject to this License. This License applies
43
+ separately for each version of the Licensed Work and the Change Date may vary
44
+ for each version of the Licensed Work released by Licensor.
45
+
46
+ You must conspicuously display this License on each original or modified copy
47
+ of the Licensed Work. If you receive the Licensed Work in original or
48
+ modified form from a third party, the terms and conditions set forth in this
49
+ License apply to your use of that work.
50
+
51
+ Any use of the Licensed Work in violation of this License will automatically
52
+ terminate your rights under this License for the current and all other
53
+ versions of the Licensed Work.
54
+
55
+ This License does not grant you any right in any trademark or logo of
56
+ Licensor or its affiliates (provided that you may use a trademark or logo of
57
+ Licensor as expressly required by this License).
58
+
59
+ TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
60
+ AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
61
+ EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
62
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
63
+ TITLE.
package/README.md CHANGED
@@ -283,6 +283,7 @@ pnpm dev
283
283
  | `code` | `<code>` | monospace font | Inline code |
284
284
  | `link` | `<a>` | `w:hyperlink` | Hyperlink (with URL) |
285
285
  | `highlight` | `<mark>` | `w:highlight` | Highlighted text |
286
+ | `custom` | `<span class="…">` / `<span style="…">` | resolved `w:rPr` | Span classes/style → run properties via `cssClasses` |
286
287
 
287
288
  ## CSS → docx Style Mapping
288
289
 
@@ -305,10 +306,16 @@ When CSS rules are provided, otomate generates real Word styles with OOXML forma
305
306
  | `padding-left` / `padding-right` | `w:ind left/right` | Added on top of margin values |
306
307
  | `text-indent` | `w:ind firstLine` | Converted to twips |
307
308
  | `line-height` | `w:spacing line` | |
308
- | `border` | `w:pBdr` (all sides) | Shorthand; per-side overrides take priority |
309
- | `border-top` / `border-bottom` / `border-left` / `border-right` | `w:pBdr` | solid→single, dashed, dotted, double |
309
+ | `border` | `w:pBdr` (paragraph) / `w:tcBorders` (table cell) | Shorthand; per-side overrides take priority |
310
+ | `border-top` / `border-bottom` / `border-left` / `border-right` | `w:pBdr` (paragraph) / `w:tcBorders` (table cell) | solid→single, dashed, dotted, double |
311
+ | `vertical-align` | `w:vAlign` | Table cells only — top/middle/bottom |
312
+ | `height` | `w:trHeight` | Table rows only |
310
313
 
311
- Container CSS (on `div` elements) cascades to all child paragraphs, headings, and list items.
314
+ **Element-level CSS resolution.** Classes are resolved at the OOXML element they describe rather than smeared inline:
315
+
316
+ - **Divs** — classes propagate to children as run/paragraph properties; inline-only divs become a paragraph; mixed-content divs auto-wrap consecutive inline children into implicit paragraphs; empty divs are dropped.
317
+ - **Tables** — classes on `<table>`, `<tr>`, and `<td>`/`<th>` cascade in CSS specificity order. Cell `background-color` lands on `w:tcPr/w:shd`, borders on `w:tcBorders`, vertical-align on `w:vAlign`, row height on `w:trHeight`. Run/paragraph properties (color, font, weight, alignment) propagate to cell content.
318
+ - **Spans** — class names and inline `style` attributes survive as `custom` marks and resolve to `w:rPr` at write time.
312
319
 
313
320
  ## Lossless Round-Trip Strategy
314
321
 
package/SKILL.md CHANGED
@@ -54,7 +54,7 @@ The `otomate` umbrella re-exports everything from these sub-packages:
54
54
 
55
55
  Direct sub-package imports (`import { readDocx } from "@otomate/docx"`) work too and have the same shapes. Prefer the umbrella unless you need to tree-shake aggressively.
56
56
 
57
- ## The five entry points
57
+ ## The seven entry points
58
58
 
59
59
  ### `readHtml(html, options?): Root`
60
60
  **Sync.** Parses an HTML string into a UDM tree.
@@ -87,6 +87,12 @@ Direct sub-package imports (`import { readDocx } from "@otomate/docx"`) work too
87
87
  - All `DocxWriteOptions` fields (e.g. `cssClasses`) are also accepted
88
88
  - Returns: `Promise<Uint8Array>`
89
89
 
90
+ ### `diff(oldTree, newTree): DiffResult`
91
+ **Sync.** Tree-diffs two UDM trees with the three-phase algorithm (top-down hash matching → bottom-up Dice scoring → Myers word-level text diff). Returns a serializable `DiffResult` with typed `operations` (`insert`, `delete`, `move`, `update`, `updateText`). Pair with `writeDiffDocx` to materialize tracked changes, or consume the operations directly.
92
+
93
+ ### `inject(tree, data): Root`
94
+ **Sync.** Replaces `{{placeholders}}` in a UDM tree with values from a free-form JSON object. Supports `{{name}}`, `{{obj.nested}}`, `{{#each items}}…{{/each}}`, `{{#if cond}}…{{else}}…{{/if}}`, and `{{@richField}}` for replacing a paragraph with block-level content. Word content controls (`<w:sdt>`) are surfaced as placeholders automatically by `readDocx`. Returns a new tree — does not mutate the input.
95
+
90
96
  ## Pattern recipes
91
97
 
92
98
  ### R1. HTML (from a CMS) → branded Word doc with CSS
@@ -280,9 +286,13 @@ All types live in `@otomate/core` and are re-exported from `otomate`. Required f
280
286
  | `image` | **`type: "image"`**, **`url: string`** | `alt?: string`, `title?: string` |
281
287
  | `inlineCode` | **`type: "inlineCode"`**, **`value: string`** | — |
282
288
 
289
+ `InlineNode` in the type system also includes `footnoteReference` and `inlineMath`. They survive parse + diff + UDM round-trip, but the docx writer does not yet render them — they currently emit nothing in `.docx` output. Use sparingly until first-class support lands.
290
+
283
291
  ### Marks (applied to `text` nodes via `marks[]`)
284
292
 
285
- Built-in: `strong`, `emphasis`, `strikethrough`, `underline`, `superscript`, `subscript`, `code`, `link` (needs `attrs.url`), `highlight` (optional `attrs.color`). Custom mark types are allowed — the writer preserves them via the UDM snapshot.
293
+ Built-in: `strong`, `emphasis`, `strikethrough`, `underline`, `superscript`, `subscript`, `code`, `link` (needs `attrs.url`), `highlight` (optional `attrs.color`).
294
+
295
+ **`custom` marks** — produced by the HTML reader for any `<span>` carrying a `class` and/or `style` attribute. The mark shape is `{ type: "custom", attrs: { className?: string[]; style?: string; id?: string; "data-*"?: unknown } }`. At write time, `attrs.className` is resolved against `cssClasses` and `attrs.style` is parsed inline; both flow through `cssToRunProps` to populate `w:rPr` (color, font, weight, italic, underline, strike, sz, shading). When the same property is set in both class CSS and `style`, `style` wins (CSS specificity by proximity). User-defined custom mark types beyond this are also preserved via the UDM snapshot.
286
296
 
287
297
  ## CSS → OOXML cheat-sheet
288
298
 
@@ -315,6 +325,19 @@ These CSS properties are understood by `writeDocx` (via `@otomate/css-docx`). An
315
325
  | `background-color: #fafafa` | `w:shd` |
316
326
  | `background: #fafafa` (shorthand) | `w:shd` — first color token wins |
317
327
 
328
+ **Table cell properties** (resolved when a CSS class is set on `<table>`, `<tr>`, `<td>`, or `<th>` — cascade order: `cssElements["table"]` → table class → `cssElements["tr"]` → row class → `cssElements["td"|"th"]` → cell class)
329
+
330
+ | CSS | OOXML | Where it lands |
331
+ |---|---|---|
332
+ | `background-color: #fafafa` | `w:shd` | `w:tcPr` (cell shading, not propagated to runs) |
333
+ | `border` / `border-{top,right,bottom,left}` | `w:tcBorders` | `w:tcPr` (per side) |
334
+ | `vertical-align: top \| middle \| bottom` | `w:vAlign` | `w:tcPr` |
335
+ | `height: 30pt` (on a row) | `w:trHeight` | `w:trPr` (`w:hRule="atLeast"`) |
336
+ | `color`, `font-*`, `font-weight`, `font-style` | `w:rPr` on cell content | propagated to every run inside the cell |
337
+ | `text-align`, `margin-*`, `border` (paragraph) | `w:pPr` on cell content | propagated to every paragraph inside the cell |
338
+
339
+ Divs follow the same model: a class on a `<div>` cascades into every child paragraph/run. Inline-only divs become a single paragraph; mixed-content divs auto-wrap consecutive inline children into implicit paragraphs; empty divs produce no output.
340
+
318
341
  **Color formats accepted**: named colors, `#rgb`, `#rrggbb`, `#rrggbbaa`, `rgb()`, `rgba()`, `hsl()`, `hsla()`. Alpha is dropped (OOXML has no alpha channel).
319
342
 
320
343
  **Length units accepted**: `px`, `pt`, `em`, `rem`, `cm`, `mm`, `in`. Percentages (`%`) are **not** supported for paragraph spacing — OOXML has no basis to resolve them against.