pdf2md/README.md
Dieter Schlüter 354dfca871 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>
2026-10-02 00:33:21 +02:00

3.5 KiB
Raw Blame History

ljutsch – PDF → Markdown → EPUB

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. 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).

Installation (Ubuntu 24.04)

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

# 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

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