From 3e44a2d4840e6ca676d95fbd49c3b38b1b12ffec Mon Sep 17 00:00:00 2001 From: dschlueter Date: Mon, 5 Oct 2026 20:27:36 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20README=20um=20Schnellstart,=20Merge-Det?= =?UTF-8?q?ails,=20Pandoc-Workflow=20und=20Einschr=C3=A4nkungen=20erg?= =?UTF-8?q?=C3=A4nzt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- README.md | 85 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 72 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 6be2eac..687e7e6 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,21 @@ YAML-Metadaten, Inhaltsverzeichnis, maschinenlesbarem Manifest und einem Konvert Gedacht für die Weiterverarbeitung mit Markdown-Renderern, Pandoc, Obsidian/Zettelkasten, Git, RAG-/Embedding-Pipelines, Volltextsuche und lokale LLMs. +Das Projekt enthält zwei Programme: + +| Programm | Zweck | +| --- | --- | +| `epub2md.py` | EPUB → Verzeichnis mit Kapitel-Markdown, Medien, Metadaten und Bericht | +| `epub2md_merge.py` | Ausgabeverzeichnis → **eine** vollständige Markdown-Datei des Buches | + +## Schnellstart + +```bash +pip install -r requirements.txt +python3 epub2md.py Beispiele/buch.epub output/buch # Kapitel-Dateien erzeugen +python3 epub2md_merge.py output/buch # → output/buch/buch.md (Gesamtdatei) +``` + ## Grenzen - **Kein DRM:** Verschlüsselte EPUBs (`META-INF/encryption.xml` mit verschlüsselten Inhalten) werden mit @@ -115,9 +130,10 @@ output/mein-buch/ │ ├── 003-1-einleitung.md │ ├── … │ └── 999-anmerkungen.md # nur bei --footnotes end-of-book -└── diagnostics/ - ├── warnings.md # Warnungen/Hinweise gruppiert, für Menschen - └── unsupported-elements.md +├── diagnostics/ +│ ├── warnings.md # Warnungen/Hinweise gruppiert, für Menschen +│ └── unsupported-elements.md +└── mein-buch.md # Gesamtdatei, erst nach epub2md_merge.py ``` - Dateinamen: fortlaufend dreistellig nummeriert (`001-…`) plus Slug aus dem Kapiteltitel. Gleiche Titel @@ -202,7 +218,7 @@ weil CommonMark keine `[^…]`-Syntax kennt. Einrückung, Tabs, `<`, `>`, `&`, `$`, `|`, Backslashes und Backticks bleiben exakt erhalten. Die Sprache kommt aus Klassen/Attributen (`language-python`, `data-lang`, …) oder starken Inhaltssignalen (`#include`, `def …:`, Shebang, …). Ist sie unsicher, bleibt das Label leer. Bei einsprachigen - Büchern kann `--code-language python` (o. Ä.) alle übrigen Blöcke kennzeichnen. Achtung: Das betrifft + Büchern kann `--code-language python` (o. Ä.) alle übrigen Blöcke kennzeichnen. Achtung: Das betrifft auch Programmausgaben und Shell-Befehle im Buch. - **Gescannte Texte:** nur Bilder, kein Text (keine OCR). - **DRM:** wird erkannt und abgelehnt. @@ -219,14 +235,20 @@ python3 epub2md_merge.py output/programmierhandbuch # → output/programmierhandbuch/.md python3 epub2md_merge.py output/programmierhandbuch -o buecher/handbuch.md --toc --force +# alternativ: python3 -m epub2md.merge … ``` +Eingabe ist ein von `epub2md.py` erzeugtes Verzeichnis. Die Reihenfolge stammt aus `manifest.json`, +der Dateiname aus `conversion-report.json`. Fehlen diese Dateien, werden `chapters/*.md` alphabetisch +verwendet und das Verzeichnis gibt den Namen vor. + | Option | Wirkung | | --- | --- | | `-o`, `--output DATEI.md` | anderer Zielort; Medienpfade werden relativ zum Ziel umgeschrieben | | `--frontmatter` / `--no-frontmatter` | ein YAML-Kopf mit Buchmetadaten (`title`, `author`, `lang`, …) für Pandoc (Standard: an) | | `--toc` | Inhaltsverzeichnis mit Sprunglinks auf die Kapitel einfügen | | `--force` | bestehende Zieldatei überschreiben (sonst Abbruch mit Exit 1) | +| `--version` | Programmversion | Beim Zusammenfügen passiert Folgendes: @@ -238,27 +260,48 @@ Beim Zusammenfügen passiert Folgendes: - Medienpfade (`../media/…`) werden auf den Ort der Gesamtdatei umgeschrieben. - Fußnotendefinitionen, die in mehreren Kapiteln stehen, erscheinen nur einmal. - Codeblöcke und Inline-Code werden nie verändert. +- Kapitelüberschriften bleiben `#`, jedes Kapitel beginnt also mit einer H1. Pandoc behandelt sie als + Kapitel. +- Der Buch-Kopf enthält nur Felder, die im EPUB vorhanden sind (`title`, `subtitle`, `author`, `lang`, + `publisher`, `date`, `identifier`, `rights`, `description`). -Am Ende werden alle Links der Gesamtdatei geprüft. +Am Ende werden alle Links der Gesamtdatei geprüft. Ein Link auf einen nicht vorhandenen Anker zeigt auf +den Kapitelanfang und erzeugt eine Warnung auf stderr. Die Zusammenfassung nennt Kapitelanzahl, +umbenannte Anker, entfernte doppelte Fußnoten und ungültige Links. + +Rückgabecodes: `0` Erfolg, `1` Verzeichnis ungültig/leer, Kapiteldatei fehlt oder Zieldatei existiert, +`4` unerwarteter interner Fehler. ## Weiterverarbeitung mit Pandoc +Am einfachsten geht das über die Gesamtdatei aus `epub2md_merge.py`. Sie hat einen Buch-Kopf und +konsistente Anker: + +```bash +cd output/programmierbuch # Medienpfade sind relativ zur Gesamtdatei +pandoc programmierbuch.md --toc -s -o programmierbuch.html +pandoc programmierbuch.md --toc -o programmierbuch.epub + +cd output/mathematikbuch +pandoc mathematikbuch.md --mathml -s -o mathematikbuch.html +pandoc mathematikbuch.md --pdf-engine=xelatex -o mathematikbuch.pdf +``` + +Alternativ direkt aus den Kapiteldateien: + ```bash pandoc output/programmierbuch/chapters/*.md \ --metadata-file=output/programmierbuch/metadata.yaml \ -o programmierbuch.html - -pandoc output/mathematikbuch/chapters/*.md \ - --metadata-file=output/mathematikbuch/metadata.yaml \ - --pdf-engine=xelatex \ - -o mathematikbuch.pdf ``` - Für HTML mit Formeln `--mathml`, `--mathjax` oder `--katex` verwenden. Pandocs Standard-HTML kann Matrizen nicht in Unicode umsetzen, meldet „Could not convert TeX math“ und belässt das TeX. - Ausgaben mit `--math tex` (`\(…\)`) brauchen `-f markdown+tex_math_single_backslash`. -- Das YAML-Frontmatter jeder Kapiteldatei wird von Pandoc als Metadaten gelesen. Für ein Gesamtdokument - ggf. `--no-frontmatter` verwenden. +- Das YAML-Frontmatter jeder Kapiteldatei wird von Pandoc als Metadaten gelesen. Wer die Kapiteldateien + direkt zusammen verarbeitet, sollte mit `--no-frontmatter` konvertieren oder die Gesamtdatei verwenden. +- Einzelne TeX-Befehle aus EPUBs (z. B. `\O` oder `@`-Konstrukte) kennt Pandocs Formelparser nicht. Er + belässt sie als TeX, mit der Warnung „Could not convert TeX math“. ## Bericht und Diagnose @@ -288,6 +331,18 @@ Verlustfreiheit behauptet (`lossless: false`). es nur, wenn es eine frühere epub2md-Ausgabe ist (`conversion-report.json`/`manifest.json` vorhanden), nicht das Arbeits- oder Home-Verzeichnis ist und die Eingabedatei nicht darin liegt. +## Bekannte Einschränkungen + +- Überschriftslose Dokumente ohne NAV-Eintrag und ohne `` werden nach dem Dateinamen benannt + (z. B. `cinnertitle`). +- Aneinanderstoßende Inline-Elemente, zwischen denen auch in der Quelle kein Leerraum steht, laufen + zusammen (z. B. Autor- und Titelzeilen in Springer-Kapitelköpfen). +- Druck-Fortsetzungszeichen (`↪`) in Listings und fehlerhafte Einrückungen der Vorlage werden + zeichengetreu übernommen. +- Formelbilder ohne TeX-Alternativtext bleiben Bilder. +- Audio/Video sind implementiert, aber nur mit synthetischen Daten geprüft. Für Bildbände gibt es + bislang keine Testbücher. + ## Architektur ```text @@ -306,6 +361,7 @@ epub2md/ ├── mathml.py konservative MathML→TeX-Konvertierung, TeX-Erkennung ├── media.py Medienregistry mit stabilen Namen ├── linkcheck.py Validierung aller relativen Links/Anker der Ausgabe +├── merge.py Gesamtdatei: Reihenfolge, Anker-Umbenennung, Pfade, Fußnoten-Deduplizierung ├── writer.py README, metadata.yaml, Frontmatter, Diagnose-Markdown ├── diagnostics.py zentrale Sammlung von Warnungen/Fehlern ├── models.py Dataclasses (Kapitel, Medien, Noten, Metadaten …) @@ -319,12 +375,15 @@ Eingabe und Optionen ergeben identische Kapiteldateien. ## Tests ```bash +pip install -r requirements-dev.txt python3 -m pytest -q +ruff check epub2md tests && mypy epub2md --ignore-missing-imports # optional, falls installiert ``` Die Tests erzeugen synthetische Minimal-EPUBs (EPUB 2/3, NAV/NCX, Code, Tabellen, MathML, SVG, Fußnoten, Glossar/Literatur/Register, unsichere ZIP-Pfade, DRM, XXE, defekte Container, Kodierung) und -prüfen die tatsächliche CLI-Ausgabe. Liegen EPUBs unter `Beispiele/`, werden sie zusätzlich auf +prüfen die tatsächliche CLI-Ausgabe. `tests/test_merge.py` prüft die Gesamtdatei: Reihenfolge, +Anker-Umbenennung, Pfade, Fußnoten, unveränderter Code und Überschreibschutz. Liegen EPUBs unter `Beispiele/`, werden sie zusätzlich auf Struktur-Invarianten geprüft: keine kaputten Links, balancierte Code-Fences, gültiges YAML, alle Medien vorhanden. Dabei werden keine Buchtexte verglichen. `Beispiele/` ist per `.gitignore` vom Repository ausgeschlossen.