diff --git a/docling/backend/xml/uspto_backend.py b/docling/backend/xml/uspto_backend.py index dc25ed1995..8d8dd54fd1 100644 --- a/docling/backend/xml/uspto_backend.py +++ b/docling/backend/xml/uspto_backend.py @@ -1525,6 +1525,14 @@ def __init__(self, input: str) -> None: self.empty_text = "" self._soup = BeautifulSoup(input, features="xml") + @staticmethod + def _parse_colwidth(colwidth: str | None) -> float: + """Parse CALS colwidth magnitude from fixed ("36pt"), proportional ("2*"), or absent values.""" + if not colwidth: + return 1.0 + match = re.match(r"\s*([0-9]*\.?[0-9]+)", colwidth) + return float(match.group(1)) if match else 1.0 + def _create_tg_range(self, tgs: list[ColInfo]) -> dict[int, ColInfoType]: """Create a unified range along the table groups. @@ -1548,13 +1556,7 @@ def _create_tg_range(self, tgs: list[ColInfo]) -> dict[int, ColInfoType]: } offst = 0 for info in tg["colinfo"]: - cw = info["colwidth"] - cw = re.sub("pt", "", cw, flags=re.I) - cw = re.sub("mm", "", cw, flags=re.I) - try: - cw = int(cw) - except BaseException: - cw = float(cw) + cw = self._parse_colwidth(info["colwidth"]) colinfo[itg]["colwidth"].append(cw) colinfo[itg]["offset"].append(offst) offst += cw diff --git a/tests/test_backend_patent_uspto.py b/tests/test_backend_patent_uspto.py index b117b1293f..06b5f7728c 100644 --- a/tests/test_backend_patent_uspto.py +++ b/tests/test_backend_patent_uspto.py @@ -143,6 +143,29 @@ def test_tables(tables): assert len(file_table.table_cells) == 130 +@pytest.mark.parametrize( + "colspecs", + [ + '', + '', + '', + ], +) +def test_table_colwidth_variants(colspecs): + """CALS colwidth may be proportional ("1*") or absent; both must parse, not drop the table.""" + xml = ( + f'{colspecs}' + "ab" + "
" + ) + table = XmlTable(xml).parse() + assert table is not None + assert table.num_rows == 1 + assert table.num_cols == 2 + assert [cell.text for cell in table.table_cells] == ["a", "b"] + assert [cell.start_col_offset_idx for cell in table.table_cells] == [0, 1] + + def test_table_out_of_range_namest_does_not_crash(): """An entry whose numeric namest points past the declared columns must degrade, not crash.""" xml = (