Spaces:
Paused
Paused
File size: 2,390 Bytes
f66643d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | from __future__ import annotations
from .config import SizingConfig
# Normalise hyphenated Surya labels to CamelCase (matches actual JSON output)
_NORMALISE: dict[str, str] = {
"Section-header": "SectionHeader",
"List-item": "ListItem",
"Page-header": "PageHeader",
"Page-footer": "PageFooter",
"Table-of-contents": "TableOfContents",
"Text-inline-math": "TextInlineMath",
"Formula": "Equation",
"Picture": "Figure",
}
def normalize_label(label: str) -> str:
return _NORMALISE.get(label, label)
# Minor/structural labels whose box should never legitimately span most of a
# page. When one does, it is almost certainly a layout mis-detection, so we keep
# the original and do not translate/overlay it. Real content — body text
# (Text/ListItem), tables, equations, TOC — may legitimately be large and is
# never skipped by size. (PageHeader/PageFooter/Figure/Code are BYPASS and are
# already skipped upstream; listed here only to document intent.)
OVERSIZE_KEEP_ORIGINAL_LABELS: frozenset[str] = frozenset(
{
"SectionHeader",
"PageHeader",
"PageFooter",
"Caption",
"Footnote",
"Title",
}
)
def skip_oversize_element(
label: str,
bbox_pdf: list[float],
page_width: float,
page_height: float,
threshold: float = 0.5,
) -> bool:
"""Whether a large element should be left as the original (not translated).
Returns True only when the element's label is a minor/structural one
(:data:`OVERSIZE_KEEP_ORIGINAL_LABELS`) *and* its box covers at least
``threshold`` of the page area. This single predicate is used by BOTH the
overlay builder and the native-text redaction pass so they always agree on
which elements to skip — a mismatch would erase content without redrawing it.
"""
if normalize_label(label) not in OVERSIZE_KEEP_ORIGINAL_LABELS:
return False
x0, y0, x1, y1 = bbox_pdf
area = max(0.0, x1 - x0) * max(0.0, y1 - y0)
page_area = page_width * page_height
return page_area > 0 and area >= threshold * page_area
def group_for_label(label: str, cfg: SizingConfig) -> str | None:
norm = normalize_label(label)
for group, members in cfg.cluster_groups.items():
if norm in members:
return group
return None
def style_key(label: str) -> str:
return normalize_label(label)
|