feat(ods): carry named ranges, which the grammar unblocked - #557
Merged
Conversation
`SPEC-COVERAGE.md` had `table:named-expressions` as an open item — in the ODF grammar, in a LibreOffice document, and nowhere in `src/`. PARITY listed named ranges among the things ODS models in neither direction. The reason it waited is worth recording. The LibreOffice fixture writes `<table:named-expressions/>` *empty*, so the corpus had no example of the populated form, and implementing against the spec alone would have left the round trip checking itself — the closed loop the corpus exists to break. What changed is #552: the output can now be validated against the OASIS grammar, which is the authority the corpus was standing in for. That was not a formality. The round trip went green and the document was invalid: ODF spells a sheet name with a space `$'My Sheet'.$A$1`, and hucre wrote `$My Sheet.$A$1`. The grammar's own regular expression for `cell-range-address` allows a run with no dot, space or apostrophe, or a quoted string, and nothing else. This reader accepted the bare form happily, so only jing could say. Written into the epilogue of `<office:spreadsheet>`, after every `<table:table>`, which is where the sequence puts it. Workbook-level only. ODF scopes a name to a sheet by putting the block inside that `<table:table>`, which `NamedRange.scope` could drive and does not yet; PARITY says so. A `<table:named-expression>` — a formula rather than a range — has no field in `NamedRange` and is skipped rather than half-read, and a range that will not parse is dropped rather than written malformed, because the attribute is required. The document with a quoted sheet name is now part of what `validate-odf.mjs` checks, so the case that only the schema could catch stays caught. The `readOds` bundle grows 27.6 -> 27.7 KB minified (9.7 KB gzipped either way, at that rounding), and `everything` with it. Those two budgets are raised. `--update` also wanted to raise `readXlsx` and `read+write`, which grew 0.8% from earlier merges and still fit their existing budgets — re-baselining those here would absorb someone else's growth into an unrelated PR, so they are left where they were. pnpm test green — 10,578 tests, 233 files.
productdevbook
force-pushed
the
feat/ods-named-ranges
branch
from
August 13, 2026 15:44
dc2f0f3 to
0097e8e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SPEC-COVERAGE.mdhadtable:named-expressionsas an open item — in the ODF grammar, in a LibreOffice document, and nowhere insrc/.PARITY.mdlisted named ranges among the things ODS models in neither direction.Why it waited, and what unblocked it
The LibreOffice fixture writes
<table:named-expressions/>empty, so the corpus had no example of the populated form. Implementing against the spec alone would have left the round trip checking itself — the closed loop the corpus exists to break.What changed is #552: the output can now be validated against the OASIS grammar, which is the authority the corpus was standing in for.
That was not a formality
The round trip went green and the document was invalid.
ODF spells a sheet name containing a space as
$'My Sheet'.$A$1. hucre wrote$My Sheet.$A$1. The grammar's own regular expression forcell-range-addressallows a run with no dot, space or apostrophe, or a quoted string — nothing else:This reader accepted the bare form happily, so only
jingcould say. That is the whole argument for the check, demonstrated on the first feature written after it existed.What landed
Written into the epilogue of
<office:spreadsheet>, after every<table:table>— where the sequence puts it.Deliberate limits, all recorded in
PARITY.md:<table:table>, whichNamedRange.scopecould drive and does not yet.<table:named-expression>— a formula rather than a range — has no field inNamedRangeand is skipped rather than half-read.table:cell-range-addressis required, so a half-built one would invalidate the document for a name nobody can resolve.The document with a quoted sheet name is now part of what
validate-odf.mjschecks, so the case only the schema could catch stays caught.pnpm testgreen — 10,578 tests, 233 files.🤖 Generated with Claude Code