Skip to content

Commit fd2867d

Browse files
committed
fix(file-parsers): require a shared header to name every grid column
1 parent d60ddd9 commit fd2867d

2 files changed

Lines changed: 28 additions & 9 deletions

File tree

‎apps/sim/lib/file-parsers/pdf-layout.test.ts‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,25 @@ describe('PdfPageCollector', () => {
265265
expect(findInterleavedBands(merged)[0]?.blocks).toHaveLength(3)
266266
})
267267

268+
it('keeps column groups under a repeated one-item label row by row', () => {
269+
const items: BufferedItem[] = []
270+
const rows = [
271+
['Total Amount Due', 'Total Amount Due'],
272+
['100 12', '300 34'],
273+
['200 56', '400 78'],
274+
]
275+
rows.forEach((groups, i) => {
276+
groups.forEach((group, g) => {
277+
const x = 40 + g * 260
278+
if (i === 0) items.push(placed(group, x, 700))
279+
else
280+
group.split(' ').forEach((cell, c) => items.push(placed(cell, x + c * 60, 700 - i * 12)))
281+
})
282+
})
283+
284+
expect(findInterleavedBands(items)).toEqual([])
285+
})
286+
268287
it('keeps column groups that share only a single-cell label row by row', () => {
269288
const items: BufferedItem[] = []
270289
const rows = [

‎apps/sim/lib/file-parsers/pdf-layout.ts‎

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ function splitBand(band: Band, bodyHeight: number): LayoutRow[][] | undefined {
286286
gridBlocks.push(rows)
287287
grids.push(grid)
288288
}
289-
if (gridBlocks.length < 2 || !sharesHeader(gridBlocks)) return undefined
289+
if (gridBlocks.length < 2 || !sharesHeader(gridBlocks, grids)) return undefined
290290
if (!grids.every((grid) => isCongruent(grids[0], grid, bodyHeight))) return undefined
291291
return blocks
292292
}
@@ -326,20 +326,20 @@ function extentWidth(intervals: readonly Interval[]): number {
326326
}
327327

328328
/**
329-
* Whether every block repeats one header row of two or more words near its top
330-
* — `Su Mo Tu We Th Fr Sa` on each month, `Assets Liabilities` on each account,
331-
* whether drawn as one text item or one per cell. Independent blocks cut from
332-
* one template carry it; column groups of a single table do not, and a lone
333-
* generic label such as `Amount` never counts.
329+
* Whether every grid repeats one header row near its top that names each of
330+
* its columns — `Su Mo Tu We Th Fr Sa` over seven day columns, `Assets
331+
* Liabilities` over two — whether drawn as one text item or one per cell.
332+
* Independent blocks cut from one template carry it; a table's column groups
333+
* do not, and a label that does not name every column never counts.
334334
*/
335-
function sharesHeader(blocks: readonly LayoutRow[][]): boolean {
335+
function sharesHeader(blocks: readonly LayoutRow[][], grids: readonly Interval[][]): boolean {
336336
const headers = blocks.map(
337-
(rows) =>
337+
(rows, i) =>
338338
new Set(
339339
rows
340340
.slice(0, HEADER_SEARCH_ROWS)
341341
.map(rowText)
342-
.filter((text) => LETTER.test(text) && text.split(/\s+/).length >= 2)
342+
.filter((text) => LETTER.test(text) && text.split(/\s+/).length === grids[i].length)
343343
)
344344
)
345345
const [first, ...rest] = headers

0 commit comments

Comments
 (0)