From 0f88e0af8fe5073f9814ea12ef8a34430f7aee23 Mon Sep 17 00:00:00 2001
From: santhreal <64453045+santhreal@users.noreply.github.com>
Date: Fri, 17 Jul 2026 10:46:44 -0700
Subject: [PATCH 1/3] fix(uspto): parse proportional and missing CALS colwidth
The USPTO table parser stripped only pt/mm units then cast colwidth to
int/float. A proportional width (1*, standard CALS) reached float(1*)
and raised ValueError, and a colspec with no colwidth reached re.sub(None)
and raised TypeError. Both crashes are caught at the call site, so every
affected table is dropped from the output document.
Extract the leading numeric magnitude instead, defaulting to 1.0 when the
width is absent, so proportional and unit-less tables parse with correct
relative offsets rather than being silently lost.
Signed-off-by: santhreal <64453045+santhreal@users.noreply.github.com>
---
docling/backend/xml/uspto_backend.py | 16 +++++++++-------
tests/test_backend_patent_uspto.py | 23 +++++++++++++++++++++++
2 files changed, 32 insertions(+), 7 deletions(-)
diff --git a/docling/backend/xml/uspto_backend.py b/docling/backend/xml/uspto_backend.py
index 025706ab61..495e9ac073 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:
+ # CALS colwidth may be fixed ("36pt"), proportional ("2*"), or absent; take the leading magnitude.
+ 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 d83a7b0cdf..7b978600f2 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",
+ [
+ '