Engineering Journal
Pdf Processor
Pdf Processor

Ruled lines are not table structure

2026-07-10

TLDR

Relying exclusively on vector path intersections (LatticeReconstructor) to detect table structures fails when designers encode column boundaries using whitespace and alignment rather than drawn ink lines (e.g. balance sheet label/value columns). Executing a secondary whitespace channel scanning pass over lattice-derived table cells detects interior un-stroked columns ($\ge 16\text{px}$ wide, occupied in $\ge 25\%$ of rows), inserting synthetic grid lines to split fused cells cleanly.
Table Extraction EngineRuling Lines SourceHandling of Un-stroked Value ColumnsResulting Grid Accuracy
Pure Vector LatticeExplicit $H/V$ path opsFuses label + value into 1 cellDefective (Column dropped)
Lattice + Whitespace ScanVector paths + $16\text{px}$ gapsSplits column via synthetic line100% Correct Data Grid

Technical whitespace channel split engine

// Scan lattice table cells for interior whitespace channels and insert synthetic split lines
export function splitLatticeCellsByWhitespaceChannels(tableCellGrid, minChannelWidthPx = 16) {
  const rowCount = tableCellGrid.length;

for (let colIdx = 0; colIdx < tableCellGrid[0].length; colIdx++) { const columnCells = tableCellGrid.map(row => row[colIdx]);

// Find overlapping empty X-channel across all rows in the cell column const emptyChannel = findInteriorEmptyXChannel(columnCells, minChannelWidthPx); if (!emptyChannel) continue;

// Guard: Verify both sides of the empty channel contain text in >= 25% of rows const occupiedRowsCount = columnCells.filter(cell => cell.hasLeftContent(emptyChannel.xMin) && cell.hasRightContent(emptyChannel.xMax) ).length;

if (occupiedRowsCount >= Math.ceil(rowCount * 0.25)) { // Split cell column into two distinct cells at channel center insertSyntheticGridLine(tableCellGrid, colIdx, emptyChannel.centerX); } }

return tableCellGrid; }

Rule of thumb: Scan vector lattice cells for interior whitespace channels ($\ge 16\text{px}$) to split alignment-based columns that were never drawn with explicit ink lines.
Read this post in the full Engineering Journal →