Skip to content

feat(tables): format --cell-margins sets table-default and per-cell padding - #23

Merged
kklimuk merged 2 commits into
kklimuk:mainfrom
xsvm:feat/table-cell-margins
Oct 27, 2026
Merged

kklimuk merged 2 commits into
kklimuk:mainfrom
xsvm:feat/table-cell-margins

Conversation

@xsvm

@xsvm xsvm commented Oct 26, 2026

Copy link
Copy Markdown
Contributor

Summary

tables format can shade, align, border and size cells, but not pad them. Rebuilding
tables to match a template that sets <w:tblCellMar> (15 twips in my case) left them
visibly different, with raw edit as the only fix — and read didn't show the
template's margins at all, so an agent couldn't tell why.

  • --cell-margins M | T,R,B,L | none (units required, 0 allowed)
    • --at tN → table default <w:tblCellMar> (Word's "Default cell margins"; rows added
      later inherit it). Untracked + audit comment under tracking, like --align/--style.
    • row / column / cell / range → per-cell <w:tcMar>, tracked as a real tcPrChange.
  • Read-back: Table.cellMargins / TableCell.margins in the AST, cell-margins= /
    margins= on docx:table / docx:cell notes, printed in the flag's own shape so the
    value can be re-applied verbatim. Reads Word's left/right-only form and strict start/end.
  • Fixture: tables-mutations t0 now sets a table default + one cell override.
  • Weak-agent: invoice scenario asks for ~4pt left/right padding.

Test plan

  • bun run check
  • bun run test:unit (6 new cases in tests/cli/tables.test.ts)
  • DOCX_LO_ALL=1 bun run test:integration (fork CI, LibreOffice round-trip)
  • Real template: read now flags the margin mismatch; one call per table makes
    the rebuilt tables' XML identical to the original's, and docx validate passes

…adding

`tables format` could shade, align, border and size cells but not pad them,
so a table rebuilt to match a template's 15-twip margins came out visibly
different with no fix short of `raw edit`.

--cell-margins takes one measure or top,right,bottom,left (units required,
0 allowed, `none` clears). With --at tN it writes the table default
<w:tblCellMar> (Word's "Default cell margins", inherited by rows added
later); a row/column/cell/range writes each cell's <w:tcMar>, which tracks
as a real tcPrChange. The table default rides the audit-comment path like
--align/--style.

Both read back: Table.cellMargins / TableCell.margins in the AST and
`cell-margins=` / `margins=` on the docx:table / docx:cell notes, in the
flag's own shape so an agent can re-apply a template's value verbatim.
The reader accepts Word's left/right-only form and strict start/end.

Folded into the tables-mutations fixture and the invoice weak-agent
scenario.
@kklimuk

kklimuk commented Oct 27, 2026

Copy link
Copy Markdown
Owner

@xsvm taking a look

…ed units

Review follow-ups on --cell-margins:

- read hints are deviation-only against what the padding inherits: a table's
  against its style chain (new Table.styleCellMargins, resolved by
  StylesView.tableCellMargins: tblStyle -> basedOn, else the default table
  style only when no style is named — verified in Word), a cell's against the
  table's effective padding. Restated defaults (LibreOffice's 0,108,0,108)
  print nothing.
- Uniform per-cell padding folds into one table-note cell-margins (mnda: 42
  cell hints -> 2 table notes). A whole-table set now also clears cells' own
  <w:tcMar> so the folded value re-applies (it used to exit 0 with no visible
  change); under tracking that stays one untracked change + audit comment.
- `-` in --cell-margins keeps that side as it is (merged in place, strict
  start/end preserved); an all-`-` value is a usage error.
- --cell-margins and --row-height take the shared unit table (in, ", cm, mm,
  pt, tw/dxa) via parseUnitMeasure; bare numbers still rejected.
- docx styles --at shows a table style's cell-margins.
- insert-row copies the neighbor cell's padding along with its borders.
- Nested tables get their docx:table note inline in the outer cell.
- Invoice weak-agent scenario change reverted: its table already renders
  5.4pt padding, so the "tight against the walls" premise was false.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kklimuk
kklimuk merged commit 10bab76 into kklimuk:main Oct 27, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants