Skip to content

doc-codec: table column-grid union has no tolerance for real-world twip/inset variance #898

Description

@Mearman

table/read.ts's assembleBlocks reconstructs a table's shared column grid as the exact-integer union of every row's own rgdxaCenter boundary values (fixed in #895, see doc-codec's own README Tables section). That union has no tolerance: two rows that are meant to describe the identical grid but differ by even one twip, or that carry a different left inset (a real Word pattern, e.g. -108 vs 0), produce a phantom extra column and a spurious colSpan on cells in both rows, instead of recognising the rows as sharing one column layout.

Confirmed by hand-assembling bytes and comparing against #897's own head/base:

  • Two rows with boundaries differing by one twip: reads back as columnWidthsPt=[50,0.05,49.95,50] (a phantom 0.05pt column) with a spurious colSpan:2 on cells in both rows, instead of [50,50,50] with no spans.
  • Two rows with a different left inset (-108 vs 0): reads back as [5.4,50,100] with a spurious colSpan:2, instead of [55.4,100].

None of doc-codec's own LibreOffice-verified fixtures trip this, since LibreOffice's own writer uses identical boundaries across a table's rows -- but doc-codec has no real-world conformance corpus (its vitest.config.ts states this explicitly), so nothing else would catch a genuine third-party .doc that does vary by a twip or an inset between rows.

A fix needs a tolerance or snapping strategy for the grid union (e.g. treating two boundaries within some small twip delta as the same column) rather than raw exact-integer equality -- worth designing deliberately rather than picking an arbitrary threshold.

Not a regression: the exact-integer union in #897 is strictly better than the code it replaced for every other case tested (independent per-row layouts, vertical merges across rows with different physical cell counts, vertical-merge anchor placement). This is a pre-existing sharp edge in the reconstruction approach, surfaced by an adversarial review of #897 rather than something #897 introduced.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions