Skip to content

Commit d6480df

Browse files
src/table.py: find_tables(): keep quad corrections on for the line-based finder.
find_tables() sets minimum glyph heights so every char on a line shares one top and bottom, but those only apply while quad corrections are on. Importing pymupdf4llm turns them off for the whole process (eagerly on `import pymupdf` in 2.0), and since #5205 find_tables() itself turns them off before get_layout() whenever use_layout is set. The line-based finder then built its chars from exact glyph boxes: a "." sits lower than the digits around it, is grouped onto a line of its own, and "0.74" is extracted as "0 74\n.". Turn corrections on before make_chars() when no layout boxes are used. The layout path, which turns them off on purpose, is unchanged. tests/test_tables.py: test_5198(): new. Fixes #5198. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 1d34e04 commit d6480df

2 files changed

Lines changed: 51 additions & 0 deletions

File tree

‎src/table.py‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3225,6 +3225,15 @@ def find_tables(
32253225
tset = TableSettings.resolve(settings=settings)
32263226
page.table_settings = tset
32273227

3228+
if not boxes:
3229+
# Without layout boxes this is the line-based finder, whose
3230+
# characters need the minimum glyph heights set above. Those
3231+
# only take effect with quad corrections on; without them each
3232+
# char keeps its exact glyph box, a "." sits lower than the
3233+
# digits around it and is grouped onto a line of its own
3234+
# ("0.74" becomes "0 74\n."). Turn corrections on, whatever
3235+
# get_layout() above or an import of pymupdf4llm left them at.
3236+
pymupdf.TOOLS.unset_quad_corrections(False)
32283237
TEXTPAGE = make_chars(page, clip=clip) # create character list of page
32293238
make_edges(
32303239
page,

‎tests/test_tables.py‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1962,3 +1962,45 @@ def test_find_tables_union_keeps_one_coherent_table_group_without_content_suppor
19621962
assert (tables[0].row_count, tables[0].col_count) == (1, 2)
19631963
finally:
19641964
doc.close()
1965+
1966+
1967+
def test_5198():
1968+
"""Cell text keeps decimal points when quad corrections are off.
1969+
1970+
Importing pymupdf4llm turns quad corrections off for the whole process.
1971+
find_tables() then built its characters from exact glyph boxes, so the
1972+
"." of "0.74" sat lower than the digits, was grouped onto a line of its
1973+
own and the cell read "0 74\\n.".
1974+
"""
1975+
doc = pymupdf.open()
1976+
page = doc.new_page(width=595, height=842)
1977+
x0, y0, x1, y1, xm, ym = 72, 72, 472, 152, 272, 112
1978+
for p1, p2 in [
1979+
((x0, y0), (x1, y0)),
1980+
((x0, ym), (x1, ym)),
1981+
((x0, y1), (x1, y1)),
1982+
((x0, y0), (x0, y1)),
1983+
((xm, y0), (xm, y1)),
1984+
((x1, y0), (x1, y1)),
1985+
]:
1986+
page.draw_line(p1, p2)
1987+
for text, point in [
1988+
("P for interaction", (80, 100)),
1989+
("Cooking fuel type", (280, 100)),
1990+
("0.74", (80, 140)),
1991+
("12.5 mg", (280, 140)),
1992+
]:
1993+
page.insert_text(point, text, fontsize=11)
1994+
1995+
quad_before = bool(pymupdf.TOOLS.unset_quad_corrections())
1996+
pymupdf.TOOLS.unset_quad_corrections(True) # as importing pymupdf4llm does
1997+
try:
1998+
tables = page.find_tables(use_layout=False).tables
1999+
assert [t.extract() for t in tables] == [
2000+
[["P for interaction", "Cooking fuel type"], ["0.74", "12.5 mg"]]
2001+
]
2002+
# find_tables() restores the setting it found
2003+
assert pymupdf.TOOLS.unset_quad_corrections() is True
2004+
finally:
2005+
pymupdf.TOOLS.unset_quad_corrections(quad_before)
2006+
doc.close()

0 commit comments

Comments
 (0)