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
83
README.md
83
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,
|
Gedacht für die Weiterverarbeitung mit Markdown-Renderern, Pandoc, Obsidian/Zettelkasten, Git,
|
||||||
RAG-/Embedding-Pipelines, Volltextsuche und lokale LLMs.
|
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
|
## Grenzen
|
||||||
|
|
||||||
- **Kein DRM:** Verschlüsselte EPUBs (`META-INF/encryption.xml` mit verschlüsselten Inhalten) werden mit
|
- **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
|
│ ├── 003-1-einleitung.md
|
||||||
│ ├── …
|
│ ├── …
|
||||||
│ └── 999-anmerkungen.md # nur bei --footnotes end-of-book
|
│ └── 999-anmerkungen.md # nur bei --footnotes end-of-book
|
||||||
└── diagnostics/
|
├── diagnostics/
|
||||||
├── warnings.md # Warnungen/Hinweise gruppiert, für Menschen
|
│ ├── warnings.md # Warnungen/Hinweise gruppiert, für Menschen
|
||||||
└── unsupported-elements.md
|
│ └── unsupported-elements.md
|
||||||
|
└── mein-buch.md # Gesamtdatei, erst nach epub2md_merge.py
|
||||||
```
|
```
|
||||||
|
|
||||||
- Dateinamen: fortlaufend dreistellig nummeriert (`001-…`) plus Slug aus dem Kapiteltitel. Gleiche Titel
|
- Dateinamen: fortlaufend dreistellig nummeriert (`001-…`) plus Slug aus dem Kapiteltitel. Gleiche Titel
|
||||||
|
|
@ -219,14 +235,20 @@ python3 epub2md_merge.py output/programmierhandbuch
|
||||||
# → output/programmierhandbuch/<Original-Name>.md
|
# → output/programmierhandbuch/<Original-Name>.md
|
||||||
|
|
||||||
python3 epub2md_merge.py output/programmierhandbuch -o buecher/handbuch.md --toc --force
|
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 |
|
| Option | Wirkung |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `-o`, `--output DATEI.md` | anderer Zielort; Medienpfade werden relativ zum Ziel umgeschrieben |
|
| `-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) |
|
| `--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 |
|
| `--toc` | Inhaltsverzeichnis mit Sprunglinks auf die Kapitel einfügen |
|
||||||
| `--force` | bestehende Zieldatei überschreiben (sonst Abbruch mit Exit 1) |
|
| `--force` | bestehende Zieldatei überschreiben (sonst Abbruch mit Exit 1) |
|
||||||
|
| `--version` | Programmversion |
|
||||||
|
|
||||||
Beim Zusammenfügen passiert Folgendes:
|
Beim Zusammenfügen passiert Folgendes:
|
||||||
|
|
||||||
|
|
@ -238,27 +260,48 @@ Beim Zusammenfügen passiert Folgendes:
|
||||||
- Medienpfade (`../media/…`) werden auf den Ort der Gesamtdatei umgeschrieben.
|
- Medienpfade (`../media/…`) werden auf den Ort der Gesamtdatei umgeschrieben.
|
||||||
- Fußnotendefinitionen, die in mehreren Kapiteln stehen, erscheinen nur einmal.
|
- Fußnotendefinitionen, die in mehreren Kapiteln stehen, erscheinen nur einmal.
|
||||||
- Codeblöcke und Inline-Code werden nie verändert.
|
- 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
|
## 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
|
```bash
|
||||||
pandoc output/programmierbuch/chapters/*.md \
|
pandoc output/programmierbuch/chapters/*.md \
|
||||||
--metadata-file=output/programmierbuch/metadata.yaml \
|
--metadata-file=output/programmierbuch/metadata.yaml \
|
||||||
-o programmierbuch.html
|
-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
|
- 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.
|
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`.
|
- 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
|
- Das YAML-Frontmatter jeder Kapiteldatei wird von Pandoc als Metadaten gelesen. Wer die Kapiteldateien
|
||||||
ggf. `--no-frontmatter` verwenden.
|
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
|
## 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),
|
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.
|
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
|
## Architektur
|
||||||
|
|
||||||
```text
|
```text
|
||||||
|
|
@ -306,6 +361,7 @@ epub2md/
|
||||||
├── mathml.py konservative MathML→TeX-Konvertierung, TeX-Erkennung
|
├── mathml.py konservative MathML→TeX-Konvertierung, TeX-Erkennung
|
||||||
├── media.py Medienregistry mit stabilen Namen
|
├── media.py Medienregistry mit stabilen Namen
|
||||||
├── linkcheck.py Validierung aller relativen Links/Anker der Ausgabe
|
├── 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
|
├── writer.py README, metadata.yaml, Frontmatter, Diagnose-Markdown
|
||||||
├── diagnostics.py zentrale Sammlung von Warnungen/Fehlern
|
├── diagnostics.py zentrale Sammlung von Warnungen/Fehlern
|
||||||
├── models.py Dataclasses (Kapitel, Medien, Noten, Metadaten …)
|
├── models.py Dataclasses (Kapitel, Medien, Noten, Metadaten …)
|
||||||
|
|
@ -319,12 +375,15 @@ Eingabe und Optionen ergeben identische Kapiteldateien.
|
||||||
## Tests
|
## Tests
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
pip install -r requirements-dev.txt
|
||||||
python3 -m pytest -q
|
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,
|
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
|
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
|
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
|
vorhanden. Dabei werden keine Buchtexte verglichen. `Beispiele/` ist per `.gitignore` vom Repository
|
||||||
ausgeschlossen.
|
ausgeschlossen.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue