XmLLM / src /app /enrichers /text_consistency.py
Claude
Code quality: fix all ruff warnings, add CI/CD, improve test coverage
bbbfba8 unverified
Raw
History Blame Contribute Delete
2.25 kB
"""text_consistency enricher β€” checks that word texts aggregate correctly.
Adds warnings to pages where the concatenation of words in a line
doesn't produce sensible text (e.g. empty words, suspicious patterns).
This enricher does NOT modify text β€” it only adds warnings.
"""
from __future__ import annotations
from typing import TYPE_CHECKING
from src.app.enrichers import BaseEnricher
if TYPE_CHECKING:
from src.app.domain.models import CanonicalDocument
from src.app.policies.document_policy import DocumentPolicy
class TextConsistencyEnricher(BaseEnricher):
@property
def name(self) -> str:
return "text_consistency"
def enrich(
self, doc: CanonicalDocument, policy: DocumentPolicy
) -> CanonicalDocument:
new_pages = []
changed = False
for page in doc.pages:
warnings = list(page.warnings)
for region in page.text_regions:
for line in region.lines:
line_warnings = self._check_line(region.id, line.id, line)
if line_warnings:
warnings.extend(line_warnings)
changed = True
new_pages.append(page.model_copy(update={"warnings": warnings}))
if changed:
return doc.model_copy(update={"pages": new_pages})
return doc
@staticmethod
def _check_line(region_id: str, line_id: str, line: object) -> list[str]:
"""Check text consistency within a line."""
warnings: list[str] = []
words = getattr(line, "words", [])
if not words:
return warnings
for i, word in enumerate(words):
text = getattr(word, "text", "")
if not text.strip():
warnings.append(
f"{region_id}/{line_id}: word {getattr(word, 'id', i)} has blank text"
)
# Check for suspiciously long "words" (likely unsplit lines)
if len(text) > 100:
warnings.append(
f"{region_id}/{line_id}: word {getattr(word, 'id', i)} "
f"is suspiciously long ({len(text)} chars) β€” may be an unsplit line"
)
return warnings