pdf2md v5: gescannte und digitale PDFs, EPUB-Export, Tests

- Seitenklassifizierung (Text / Scan / OCR-Ebene / leer) mit OCR-Plan pro Seite:
  Scans per Tesseract, gerade OCR-Ebenen übernehmen, schiefe neu erkennen,
  Foto-/Coverseiten nur nach Probe-OCR; --ocr auto|always|never, --jobs
- Nachbearbeitung: Satzende-Erkennung mit « “ ‹, Silbentrennung, Überschriften-
  ebenen aus PDF-Lesezeichen, Rückstufung von Satzresten, Inhaltsverzeichnis
  trennen, Seitenzahlen/Kolumnentitel/Bildtext entfernen
- Patches für pymupdf4llm: Bindestrich-Komposita am Zeilenende, Absätze per
  Einzug in Scan-Blöcken
- --epub über pandoc (Metadaten, Cover, Kapitelaufteilung)
- pytest-Suite mit synthetischen Test-PDFs (79 Tests)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-10-02 00:33:21 +02:00
commit 354dfca871

View file

@ -2,7 +2,77 @@
Werkzeug, um PDF-Bücher (hier: *Operation Ljutsch*, Band 1 und 2) in sauberes Markdown
und anschließend in ein EPUB für den PocketBook-Reader umzuwandeln – mit Überschriften,
Bildern und echten Absätzen.
Bildern und echten Absätzen. Funktioniert für **digitale** PDFs (Textebene vorhanden)
ebenso wie für **gescannte** PDFs (nur Bilder, per OCR) und für Scans, die bereits eine
OCR-Ebene haben (z. B. von `ocrmypdf`).
- `pdf2md_v1.py` … `pdf2md_v4.py` – bisherige Entwicklungsstände (siehe `Info/`)
## Installation (Ubuntu 24.04)
```bash
sudo apt install tesseract-ocr tesseract-ocr-deu pandoc
pip install -r requirements.txt # pymupdf4llm, pymupdf-layout, pytest
```
`tesseract-ocr` wird nur für Scans gebraucht, `pandoc` nur für `--epub`.
## Verwendung
```bash
# digitales oder gescanntes PDF -> Markdown (OCR wird automatisch entschieden)
python3 pdf2md_v5.py buch.pdf buch.md
# zusätzlich Bilder und EPUB (Titel/Autor aus den PDF-Metadaten, Seite 1 als Cover)
python3 pdf2md_v5.py --epub buch.pdf buch.md
# Scan in Deutsch und Englisch, 8 parallele OCR-Prozesse
python3 pdf2md_v5.py --ocr-language deu+eng --jobs 8 scan.pdf scan.md
```
| Option | Bedeutung |
| :-- | :-- |
| `--ocr auto` (Standard) | Scanseiten per OCR lesen; vorhandene, gerade OCR-Ebenen übernehmen, schiefe neu erkennen; reine Bildseiten in digitalen PDFs (Fotos, Cover) nur nach erfolgreicher Probe-OCR |
| `--ocr always` / `--ocr never` (`--no-ocr`) | alle Seiten neu erkennen / keine OCR |
| `--ocr-language`, `--ocr-dpi` | Tesseract-Sprache(n) (`deu`), Auflösung (300) |
| `--jobs N` | parallele OCR-Prozesse (Standard 4); reine Textdokumente laufen immer sequenziell |
| `--images` | Grafiken als PNG in `<name>_images/` speichern und verlinken |
| `--epub`, `--epub-file PFAD` | EPUB 3 mit pandoc erzeugen (schaltet `--images` ein) |
| `--lang` | Sprache im EPUB (`de`) |
| `--keep-headers`, `--keep-footers` | Kolumnentitel bzw. Seitenzahlen nicht entfernen |
## Was die Nachbearbeitung macht
- **Absätze:** Zeilen werden verbunden; eine Absatzgrenze gilt nur nach Satzende
(`.` `!` `?` `…`, auch mit `«` `“` `»` usw. dahinter). Auf Scans werden Absätze am
Einzug erkannt.
- **Silbentrennung:** `Geheim-|dienst` → `Geheimdienst`, `Militär-|Geheimdienst` bleibt mit
Bindestrich, `Arbeits- und` bleibt.
- **Überschriften:** Ebenen aus den PDF-Lesezeichen (Teile `##`, Kapitel `###`);
Satzreste, die fälschlich als Überschrift erkannt wurden, kommen zurück in den Text.
- **Inhaltsverzeichnis:** zusammengeklebte Einträge werden getrennt.
- **Seitenzahlen, Kolumnentitel, Text in Fotos** werden entfernt.
## Tests
```bash
python3 -m pytest # ca. 30 s; OCR-/EPUB-Tests werden ohne Tesseract/pandoc übersprungen
```
Die Test-PDFs (digital, gescannt, mit OCR-Ebene, gemischt, Fotoseite) werden zur Laufzeit
synthetisch erzeugt.
## Grenzen
- Die Ergebnisqualität hängt von pymupdf4llm/pymupdf-layout ab. Zwei Schwächen der
Bibliothek gleicht `pdf2md_v5.py` per Patch aus (Bindestriche am Zeilenende, Absätze in
Scan-Blöcken). Eine weitere ist bekannt: Bei Schriften mit Ligaturen (ff, fi) mit
übergroßer Glyphenbox kann pymupdf4llm einzelne Zeilen verlieren. Bei den Ljutsch-Bänden
tritt das nicht auf (geprüft per Wortabgleich PDF ↔ Markdown).
- OCR-Fehler (z. B. fehlende Leerzeichen) werden nicht korrigiert.
- Bilder werden als PNG gespeichert; das EPUB wird dadurch relativ groß (Band 1 ca. 13 MB).
## Dateien
- `pdf2md_v5.py` – aktuelle Version
- `pdf2md_v1.py` … `pdf2md_v4.py` – frühere Entwicklungsstände (siehe `Info/`)
- `Info/` – Recherche und Entstehungsgeschichte der Skripte
- `tests/` – pytest-Suite