Spaces:
Sleeping
Sleeping
File size: 3,150 Bytes
3213f50 bbbfba8 3213f50 bbbfba8 3213f50 bb6107f 3213f50 | 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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | """hyphenation_basic enricher — detects hyphenated words at line boundaries.
If a word ends with '-' at the end of a line, and the next line starts with
a lowercase word, marks both as hyphenated with the combined full_form.
"""
from __future__ import annotations
from typing import TYPE_CHECKING
from src.app.domain.models import CanonicalDocument, Hyphenation, TextLine
from src.app.enrichers import BaseEnricher
if TYPE_CHECKING:
from src.app.policies.document_policy import DocumentPolicy
class HyphenationBasicEnricher(BaseEnricher):
@property
def name(self) -> str:
return "hyphenation_basic"
def enrich(
self, doc: CanonicalDocument, policy: DocumentPolicy
) -> CanonicalDocument:
if not policy.allow_hyphenation_detection:
return doc
new_pages = []
changed = False
for page in doc.pages:
new_regions = []
for region in page.text_regions:
new_lines = list(region.lines)
modified = self._process_lines(new_lines)
if modified:
changed = True
new_regions.append(region.model_copy(update={"lines": new_lines}))
new_pages.append(page.model_copy(update={"text_regions": new_regions}))
if changed:
return doc.model_copy(update={"pages": new_pages})
return doc
@staticmethod
def _process_lines(lines: list[TextLine]) -> bool:
"""Process adjacent lines for hyphenation. Mutates the list in place."""
modified = False
for i in range(len(lines) - 1):
line_a = lines[i]
line_b = lines[i + 1]
if not line_a.words or not line_b.words:
continue
last_word = line_a.words[-1]
first_word = line_b.words[0]
# Skip if already hyphenated
if last_word.hyphenation is not None:
continue
# Check: last word ends with '-' and next word starts lowercase
if not last_word.text.endswith("-"):
continue
if not first_word.text or not first_word.text[0].islower():
continue
# Build full form
stem = last_word.text.rstrip("-")
full_form = stem + first_word.text
# Update last word of line A
new_last = last_word.model_copy(update={
"hyphenation": Hyphenation(
is_hyphenated=True, part=1, full_form=full_form
),
})
new_words_a = list(line_a.words[:-1]) + [new_last]
lines[i] = line_a.model_copy(update={"words": new_words_a})
# Update first word of line B
new_first = first_word.model_copy(update={
"hyphenation": Hyphenation(
is_hyphenated=True, part=2, full_form=full_form
),
})
new_words_b = [new_first] + list(line_b.words[1:])
lines[i + 1] = line_b.model_copy(update={"words": new_words_b})
modified = True
return modified
|