Weiche Trennstriche auflösen, Courier-OCR-Ebenen nicht als Code setzen
- Zeilenende mit U+00AD oder "¬" wird wie Silbentrennung behandelt
("wach senden" -> "wachsenden")
- Unsichtbarer Text (OCR-Ebene) verliert das Monospace-Flag, sonst setzt
pymupdf4llm jedes Wort in Backticks
- Tests für beide Fälle und für sichtbaren Monospace-Text
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
a21d900e6b
commit
217d1ee09b
1 changed files with 49 additions and 7 deletions
25
pdf2md.py
25
pdf2md.py
|
|
@ -472,28 +472,39 @@ def load_outline(doc: pymupdf.Document) -> dict[str, int]:
|
|||
|
||||
|
||||
# ===========================================================================
|
||||
# Korrektur für pymupdf4llm: Bindestrich-Komposita am Zeilenende
|
||||
# Korrektur für pymupdf4llm: Trennstriche am Zeilenende, OCR-Ebenen
|
||||
# ===========================================================================
|
||||
# pymupdf4llm entfernt jeden Bindestrich am Zeilenende ("Militär-" + Zeile
|
||||
# "Geheimdienst" -> "MilitärGeheimdienst"). Für Großbuchstaben und
|
||||
# Konjunktionen ("Arbeits- und") markieren wir den Strich vorher, sodass er
|
||||
# erhalten bleibt. Echte Silbentrennung (Kleinbuchstabe) bleibt unverändert.
|
||||
# Weiche Trennstriche (U+00AD) und "¬" kennt pymupdf4llm nicht ("wach senden");
|
||||
# sie trennen immer innerhalb eines Wortes und werden zu "-", das dann entfällt.
|
||||
#
|
||||
# Unsichtbarer Text (OCR-Ebene eines Scans) ist oft in Courier gesetzt;
|
||||
# pymupdf4llm hielte ihn sonst für Programmcode und setzte jedes Wort in `…`.
|
||||
|
||||
KEEP_HYPHEN = "\ue000" # Strich behalten, ohne Leerzeichen anschließen
|
||||
KEEP_HYPHEN_SPACE = "\ue001" # Strich und Leerzeichen behalten
|
||||
|
||||
|
||||
SOFT_HYPHENS = ("\u00ad", "¬")
|
||||
MONOSPACE_FLAG = 8
|
||||
|
||||
|
||||
def _mark_line_end_hyphens(spans: list[dict]) -> list[dict]:
|
||||
marked = []
|
||||
for i, span in enumerate(spans):
|
||||
nxt = spans[i + 1] if i + 1 < len(spans) else None
|
||||
if not span.get("char_flags", VISIBLE_TEXT) & VISIBLE_TEXT:
|
||||
span = {**span, "flags": span.get("flags", 0) & ~MONOSPACE_FLAG}
|
||||
text = span["text"].rstrip()
|
||||
if (
|
||||
nxt is not None
|
||||
and text.endswith("-")
|
||||
and (span.get("block"), span.get("line"))
|
||||
!= (nxt.get("block"), nxt.get("line"))
|
||||
):
|
||||
line_end = nxt is not None and (span.get("block"), span.get("line")) != (
|
||||
nxt.get("block"), nxt.get("line")
|
||||
)
|
||||
if line_end and text.endswith(SOFT_HYPHENS):
|
||||
span = {**span, "text": text[:-1] + "-"}
|
||||
elif line_end and text.endswith("-"):
|
||||
word = FIRST_WORD.match(nxt["text"].lstrip())
|
||||
if word and word.group(0).lower() in CONJUNCTIONS:
|
||||
span = {**span, "text": text + KEEP_HYPHEN_SPACE}
|
||||
|
|
|
|||
Loading…
Reference in a new issue