Skip to content

feat(cli): one length grammar for every size flag - #25

Merged
kklimuk merged 2 commits into
mainfrom
claude/standardize-sizing
Oct 27, 2026
Merged

kklimuk merged 2 commits into
mainfrom
claude/standardize-sizing

Conversation

@kklimuk

@kklimuk kklimuk commented Oct 27, 2026

Copy link
Copy Markdown
Owner

Every size flag now goes through one parser (src/cli/parse-length.ts) with one unit table: in/", cm, mm, pt, tw/twip(s)/dxa, plus px (96 dpi) on image sizes only.

What was wrong

Each size flag had its own parser, and several quietly misread units. On main:

  • images add --width 3cm gave a 3-inch image, exit 0.
  • tables create --widths 2.5in,1in gave columns 2 and 1 twips wide.
  • read printed widths="2.375,4.618in", and set-widths couldn't take that back as input.

What changed

  • Units work on every size flag. A bare number keeps its old meaning per flag (images: inches; table widths: twips; spacing: points; indents/margins: inches, or twips when >9; row height and cell margins need a unit).
  • A unit on only the last value of a list applies to every value, so what read prints for widths and margins can be passed straight back.
  • Refused with an "add the unit you mean" hint instead of writing a wrong size:
    • small bare twips (--widths 2,1)
    • borrowed-unit lists that land past 22in (--widths 1440,1in)
    • values that round to 0 twips
  • --size 210x297mm works, and edit --tabs positions accept any unit.
  • Docs: REFERENCE.md "Lengths and units", and a "one parser" rule in src/cli/CLAUDE.md. Fixtures use cm/mm/px.

Behavior changes for existing users

  • --margins 1,1,1,15mm now means 1mm on the first three sides (was 1 inch).
  • --widths values 1–9 and fractions without a unit are now usage errors.
  • Spellings that only worked because the old parser ignored trailing text (3inches) are now usage errors.

Verification

  • bun run check ✅, bun test ✅ (1937 tests), bun run test:integration ✅ (24 tests, LibreOffice)
  • Before/after on main for the three bugs above
  • /code-review high --fix: fixed 6 of its 9 findings. The 3 skipped:
    • accepting 3inches-style spellings, which is a design choice
    • --cell-margins keeping a unit per side
    • a repeated constant

🤖 Generated with Claude Code

kklimuk and others added 2 commits October 27, 2026 13:35
Size/length flags parsed units ad hoc, and two silently misparsed:
`images add --width 3cm` was a 3-INCH image (parseFloat dropped the
suffix; `100px` was 100 inches), and `tables create --widths 2.5in,1in`
wrote gridCols of 2 and 1 TWIPS (parseInt) — both exit 0. `set-widths`
and `insert-column --width` took only integer twips, so the
`docx:table widths="2.375,4.618in"` value `read` prints couldn't be fed
back, and `--size WxH` was inches-only.

New src/cli/parse-length.ts (`parseLength` / `parseLengthList`) replaces
`parseMeasure` + `parseUnitMeasure`: one unit table (in, ", cm, mm, pt,
tw/twip/twips/dxa; px at 96 dpi for image sizes only), per-flag options
for the bare unit (in / pt / tw / unit-required), signed, positive, and
the existing bare-inch>9-is-twips guard. Bare numbers keep their old
meaning per flag; suffixes now mean what they say; junk is exit 2.

- images add --width/--height: bare inches, any unit incl. px
- tables create --widths/--table-width, set-widths, insert-column
  --width: bare whole twips, any unit; a bare 1-9 or fraction is refused
  (an inch value missing its suffix); % still works where it did
- --size WxH: 210x297mm, 21cmx29.7cm, 8.5x11in, bare inches
- --margins, spacing/indents, --row-height, --cell-margins: same table
- edit --tabs left@POS: any unit (was `in` only), unit still required
- a list whose only suffix is on its last entry shares it, so the
  widths/margins `read` prints re-apply verbatim

Help text, REFERENCE.md ("Lengths and units"), and src/cli/CLAUDE.md
document the rule; images/tables-mutations fixtures dogfood cm/px/in
suffixes and an A4 `210x297mm` page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Refuse a list whose bare values only got huge by borrowing the last
  value's unit (`--widths 1440,1in`, `--margins 1440,1440,1440,1in`).
- Check `positive` after rounding, so `--row-height 0.01pt` and
  `--widths 0.0001in,1in` no longer write zero twips.
- Only share a trailing unit the flag accepts, so `1,2,3em` names `3em`.
- `--size 12240dxax15840dxa` splits on the right `x`.
- `tables --help` shows `--widths "20%,30%,50%"` (bare is twips now).
- Drop the inches/points-to-twips wrappers; `readMeasure` takes options.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kklimuk
kklimuk merged commit 26de22f into 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.

1 participant