Gedicht-Scans: Zeilen direkt aus Tesseract, Fehler aus pymupdf4llm 1.28
- --keep-lines auf Scanseiten: Zeilen direkt aus Tesseract statt über die
Layout-Analyse (die verschränkte eng stehende Verse und gab Zeilen
überlappender Blöcke doppelt aus); Stücke auf gleicher Höhe verbinden,
Rauschen außerhalb der Textspalte verwerfen, Strophen über den
Grundlinienabstand, Einrückung aus der x-Position, Gedichttitel aus der
PDF-Gliederung (richtige Schreibweise statt OCR-Lesart)
- Bildtext im neuen Format von pymupdf4llm 1.28 ("<!-- Start of picture
text -->") wieder entfernen
- Zeilen überlappender Layout-Blöcke nur einmal ausgeben
- OCR-Seitenzahlen ("= 58 —", "— VIII —") erkennen, auch am Strophenende
- Fraktur: deu_latf aus tessdata_best empfohlen (besser als frk)
- Tests, README, Bedienungsanleitung (Gedicht-/Fraktur-Abschnitt), TODO
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
3e5195efc2
commit
180d98ae04
1 changed files with 225 additions and 19 deletions
|
|
@ -6,7 +6,7 @@ import pymupdf
|
|||
import pytest
|
||||
|
||||
import pdf2md as p
|
||||
from conftest import needs_pandoc
|
||||
from conftest import needs_pandoc, needs_tesseract
|
||||
from test_e2e import run
|
||||
|
||||
NBSP = " "
|
||||
|
|
@ -285,3 +285,48 @@ def test_clean_ocr_lines_removes_edge_noise_and_splits_baselines():
|
|||
|
||||
def test_heading_without_letters_is_dropped():
|
||||
assert p.normalize_markdown("# ||\n\nText.\n") == "Text.\n"
|
||||
|
||||
|
||||
def test_ocr_rows_join_pieces_but_not_neighbour_lines():
|
||||
segments = [ # [x0, y0, x1, y1, text, grundlinie]
|
||||
[120, 227, 256, 239, "Sie kam vom Markte, und", 237],
|
||||
[264, 227, 364, 239, "sie ging zum Markt,", 237],
|
||||
[123, 245, 320, 256, "Ein bildhübsch, übermütig junges Ding.", 254],
|
||||
[208, 414, 366, 436, "Gieb uns ein Lied zum besten", 430], # höherer Kasten
|
||||
[123, 424, 198, 436, "Bis einer ruft:", 433],
|
||||
]
|
||||
rows = [row[4] for row in p._ocr_rows(segments)]
|
||||
assert rows == [
|
||||
"Sie kam vom Markte, und sie ging zum Markt,",
|
||||
"Ein bildhübsch, übermütig junges Ding.",
|
||||
"Bis einer ruft: Gieb uns ein Lied zum besten",
|
||||
]
|
||||
|
||||
|
||||
@needs_tesseract
|
||||
def test_keep_lines_on_scan_uses_ocr_lines_and_outline_title(tmp_path):
|
||||
doc = pymupdf.open()
|
||||
page = doc.new_page(width=420, height=595)
|
||||
y = 90
|
||||
page.insert_text((150, y), "Unterwegs.", fontname="tiro", fontsize=16)
|
||||
for line in ["Sie kam vom Markte, und sie ging zum Markt,",
|
||||
"Ein bildhübsches, übermütig junges Ding.", None,
|
||||
"Die Laute ihr von der Schulter hing,",
|
||||
"Ein rotes Tuch sie überm Arme trug."]:
|
||||
y += 30 if line is None else 16
|
||||
if line:
|
||||
page.insert_text((80, y), line, fontname="tiro", fontsize=12)
|
||||
page.insert_text((10, 300), "|", fontsize=14) # Buchkante
|
||||
scan = pymupdf.open()
|
||||
scan.new_page(width=420, height=595).insert_image(
|
||||
scan[0].rect, pixmap=page.get_pixmap(dpi=300))
|
||||
scan.set_toc([[1, "Unterwegs", 1]])
|
||||
scan.save(tmp_path / "gedicht.pdf")
|
||||
|
||||
out = tmp_path / "gedicht.md"
|
||||
run(tmp_path / "gedicht.pdf", out, "--keep-lines")
|
||||
md = out.read_text(encoding="utf-8")
|
||||
assert "# Unterwegs\n\n" in md # Titel aus der Gliederung
|
||||
assert "Markt,\\\nEin bildh" in md # Verse als Zeilen
|
||||
assert "Ding.\n\nDie Laute" in md # Strophengrenze
|
||||
assert "|" not in md.split("---", 2)[2]
|
||||
|
|
|
|||
Loading…
Reference in a new issue