Go PDF parser: cross-page tables drop continuation-page rows (Grid not rebuilt after MergeTablesAcrossPages)
#18.347 aperta il 17 ago 2026
Metriche repository
- Star
- (80.527 stelle)
- Metriche merge PR
- (Merge medio 3g 1h) (600 PR mergiate in 30 g)
Descrizione
[!NOTE] Internal tracking issue. Suggestions from external contributors are welcome, but please do not open a PR yet — the fix is still being scoped.
Summary
In the Go PDF parser, a table that spans multiple pages is merged across pages by MergeTablesAcrossPages (internal/deepdoc/parser/pdf/table/table_merge.go:103), but the merged TableItem.Grid is never recomputed. The HTML emitted by ConstructTable (internal/deepdoc/parser/pdf/table/table_construct.go:48-49) reads the stale pre-merge Grid, so only the anchor (first) page's rows appear in the output. Continuation-page cells are appended to TableItem.Cells but never enter the table HTML.
Root cause
- Extraction builds
Gridonce per page:table_extract.go:141-143callstb.GroupCells(cells)and stores the result onTableItem.Grid. For a multi-page table,Gridtherefore contains only the anchor page's rows. MergeTablesAcrossPages(table_post.go:289->table_merge.go:103) appends continuation-page raw TSR cells toanchor.Cellsand concatenatesanchor.Positions, but does not recomputeanchor.Grid.ConstructTable(table_post.go:64/156->table_construct.go:48-49) readsitem.Grid, so merged cross-page tables emit only the first page's rows.
The Python reference accumulates all pages' boxes into a single list and builds one rows structure over every page (deepdoc/vision/table_structure_recognizer.py:181-192, cross-page branch at :196-200), so it keeps all continuation-page rows.
Observed impact (parity vs Python)
中加纯债: Go 192 cells vs Py 292 cells (51% cell match), Go 27 rows vs Py 51 rows — the missing ~24 rows are continuation pages.- Flagged as
⚠️ cellsinTestBatchCompareWithPython(internal/deepdoc/parser/pdf/tool/compare_test.go). - Table HTML for any multi-page table is truncated to the first page; downstream chunk/table extraction sees an incomplete table.
(There is also a smaller secondary gap: Python's y-overlap row split at table_structure_recognizer.py:186 has no equivalent in Go GroupCells. This is minor compared to the missing continuation pages.)
Proposed direction (not yet implemented)
After MergeTablesAcrossPages appends continuation cells, rebuild anchor.Grid from the merged anchor.Cells using the same builder that built the per-page grids — mirroring Python's "accumulate all pages into one rows list". Keep MergeTablesAcrossPages a pure function; do the recompute in the post pipeline (table_post.go:289) after the merge.
Key implementation subtlety: per-page cells live in per-page crop coordinates. Before re-running GroupCells, continuation-page cell coordinates must be normalized by the cumulative height of preceding pages (Python stacks page crops into one tall image, pdf_parser.py:1436-1444, so all rows share one Y axis). Verify whether such offsetting already exists before coding.
Scope
- Internal use only.
- External contributors: suggestions and discussion welcome, but no PR until scoped.