- --lang ohne Angabe aus der ersten OCR-Sprache ableiten (eng -> en) - Fehlen Titel/Autor in den PDF-Metadaten: aus dem Dateinamen nach dem Muster "Autor_-_Titel" übernehmen, sonst Dateiname mit Leerzeichen - --jobs: halbe Kernzahl, höchstens 8 (bisher 4) - Tests (tests/test_defaults.py), README und Bedienungsanleitung Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
105 lines
5.4 KiB
Markdown
105 lines
5.4 KiB
Markdown
# ljutsch – PDF → Markdown → EPUB
|
||
|
||
Werkzeug, um PDF-Bücher in sauberes Markdown und anschließend in ein EPUB für den
|
||
PocketBook-Reader umzuwandeln – mit Überschriften, 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`).
|
||
|
||
Entwickelt an *Operation Ljutsch* (Band 1 und 2), außerdem erprobt an einem deutschen
|
||
Sachbuch, einem englischen Handbuch, einem Mathematikbuch, einem Bericht mit Fußnoten und
|
||
einem englischen Scan von 1893 (Ergebnisse siehe [Grenzen](#grenzen)).
|
||
|
||
## 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
|
||
|
||
Ausführliche Schritt-für-Schritt-Anleitung, auch für den Weg „Markdown von Hand bearbeiten,
|
||
dann EPUB“: **[BEDIENUNGSANLEITUNG.md](BEDIENUNGSANLEITUNG.md)**.
|
||
|
||
```bash
|
||
# digitales oder gescanntes PDF -> Markdown (OCR wird automatisch entschieden)
|
||
python3 pdf2md.py buch.pdf buch.md
|
||
|
||
# zusätzlich Bilder und EPUB (Titel/Autor aus den PDF-Metadaten bzw. dem Dateinamen
|
||
# "Autor_-_Titel.pdf", Seite 1 als Cover)
|
||
python3 pdf2md.py --epub buch.pdf buch.md
|
||
|
||
# Scan in Deutsch und Englisch, 8 parallele OCR-Prozesse
|
||
python3 pdf2md.py --ocr-language deu+eng --jobs 8 scan.pdf scan.md
|
||
|
||
# englisches Buch; alter Scan mit schlechter OCR-Ebene neu erkennen
|
||
python3 pdf2md.py --epub --ocr-language eng --ocr always scan.pdf scan.md # EPUB-Sprache: en
|
||
```
|
||
|
||
| 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: halbe Kernzahl, höchstens 8); reine Textdokumente laufen immer sequenziell |
|
||
| `--images` | Grafiken in `<name>_images/` speichern und verlinken |
|
||
| `--image-format jpg\|png` | Bildformat (Standard jpg; png verlustfrei, aber ca. 3× größer) |
|
||
| `--epub`, `--epub-file PFAD` | EPUB 3 mit pandoc erzeugen (schaltet `--images` ein) |
|
||
| `--lang` | Sprache im EPUB (Standard: aus `--ocr-language`, `deu`→`de`, `eng`→`en`) |
|
||
| `--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. Weiche Trennstriche (U+00AD) und `¬` am Zeilenende
|
||
werden ebenfalls aufgelöst (`wach|senden` → `wachsenden`).
|
||
- **Ü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; liegt das Verzeichnis
|
||
als Tabelle vor, bleibt die Tabelle erhalten.
|
||
- **OCR-Ebenen** in Courier werden nicht als Programmcode (`` `…` ``) gesetzt.
|
||
- **Links:** URLs werden als `<https://…>` geschrieben und sind damit in Markdown-Viewern
|
||
und im EPUB anklickbar. Beim Zeilenumbruch zerbrochene URLs (`deutsche-|sehen`,
|
||
`…/ youtube-…`) werden mit den Linkzielen der PDF abgeglichen und repariert;
|
||
Tracking-Parameter (`utm_…`) entfallen. Ohne Linkziel wird die URL aus dem gedruckten
|
||
Text zusammengesetzt.
|
||
- **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. Einige Schwächen der
|
||
Bibliothek gleicht `pdf2md.py` per Patch aus (Bindestriche und weiche Trennstriche am
|
||
Zeilenende, Absätze in Scan-Blöcken, OCR-Ebenen in Courier). 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. Bei alten Scans mit
|
||
mitgelieferter OCR-Ebene liefert `--ocr always` meist deutlich besseren Text.
|
||
- **Mathematische Formeln** werden als Bilder übernommen; für Mathebücher ist ein anderes
|
||
Werkzeug besser geeignet (z. B. Marker, Nougat).
|
||
- **Was am PDF liegt, bleibt:** fehlende Ligaturen ohne Textzuordnung („Offzielle“),
|
||
gesperrt gesetzte Überschriften („M e i n k l e i nes …“), flache PDF-Gliederungen
|
||
(alle Kapitel auf einer Ebene).
|
||
- Links mit anderem Text als der URL (z. B. „hier“) werden nicht übernommen.
|
||
- Reine Zahlen können als Überschrift erscheinen (Fußnotenzeichen, römische Seitenzahlen).
|
||
Weitere bekannte Schwächen: [TODO.md](TODO.md).
|
||
- Bilder werden als JPEG (Qualität 95) gespeichert; EPUB Band 1 ca. 5 MB.
|
||
|
||
## Dateien
|
||
|
||
- `pdf2md.py` – aktuelle Version
|
||
- `tests/` – pytest-Suite
|