Skip to content

fix(sheet): preserve merges extending past the populated range - #13

Closed
ghost wants to merge 2 commits into
mainfrom
unknown repository
Closed

fix(sheet): preserve merges extending past the populated range#13
ghost wants to merge 2 commits into
mainfrom
unknown repository

Conversation

@ghost

@ghost ghost commented Aug 5, 2026

Copy link
Copy Markdown

Fixes #8

Why

For an XLSX worksheet whose only populated cell anchors a merge extending beyond the populated range, to_document() clipped the merge to the populated range and lost the span. The issue's reproduction (F1 = "Merged heading", merge F1:O3) returned a 1x1 table with row_span=1, col_span=1 instead of the source's 3x10 span. A valid source merge must not silently collapse to an ordinary cell.

What

  • Sheet parser: when a merge's top-left anchor sits inside the used range but its declared extent runs past it, the grid is grown to the merge's far boundary so the span is expressed in full (the covered cells are the merge's real structure, even when empty). Growth is capped at the existing MAX_EXPANSION budget, so an oversized region keeps the previous clipped behavior instead of forcing a huge grid; a full-sheet merge can never balloon the output.
  • GridBuilder: added an opt-in keep_covered_extent() so trailing rows that consist only of covered positions are kept rather than trimmed as filler. Only the spreadsheet parser opts in, so HTML/ODF span semantics are unchanged.

Markdown output is unaffected (GFM has no span syntax and the renderer already trims trailing blank rows/columns); this preserves the document model structure, exactly what the issue asks for.

Tests

  • merge_spanning_past_the_populated_range_is_preserved — the issue's F1:O3 reproduction now yields a 3x10 grid with a 3x10 origin span.
  • merge_past_the_range_keeps_content_below — data below the merge survives alongside the full span.
  • oversized_merge_falls_back_to_the_populated_range — the budget cap falls back to clipped behavior without erroring.
  • covered_extent_rows_survive_when_preserved / covered_extent_rows_trim_without_the_flag — GridBuilder flag coverage both ways.

All gates pass locally: cargo fmt --all --check, cargo clippy -p anydoc --all-targets --all-features -- -D warnings, cargo test --locked.

@ghost

ghost commented Aug 5, 2026

Copy link
Copy Markdown
Author

Added the integration coverage suggested in #16's closing comment: a real handmade-merge-overhang.xlsx fixture (merge F1:O3 anchored at the only populated cell, with data below) plus xlsx_merge_overhang_is_retained, an end-to-end to_document() test asserting the 3x10 span survives. The fixture's corpus snapshot shows the merge's covered rows retained in the model.

@ghost ghost closed this by deleting the head repository Aug 5, 2026
This pull request was closed.
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.

XLSX merged-cell spans are clipped to the populated range

0 participants