docs: README um Schnellstart, Merge-Details, Pandoc-Workflow und Einschränkungen ergänzt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
88888e5587
commit
3e44a2d484
1 changed files with 72 additions and 13 deletions
85
README.md
85
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/<Original-Name>.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 `<title>` 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.
|
||||
|
|
|
|||
Loading…
Reference in a new issue