feat: Buchanfang Cover → Titel → Impressum → Inhaltsverzeichnis für alle Bücher

- Kapitelerkennung: erstes Kapitel nur aus einem Bild = Cover ("[Titelinfo]",
  "Deckblatt"), Titel "Titel" = Titelseite
- epub2md_merge: Vorspann reicht bis vor den Hauptteil (Teil, Vorwort,
  Einleitung, nummerierter Titel, > 1000 Wörter), kurze Zwischenseiten
  (Auflage, Verlagsbrief, "Über dieses Buch") bleiben davor
- book.lua: Cover am Inhalt erkannt; LaTeX-Weg (Filter in beiden Schritten):
  \tableofcontents hinter dem Vorspann, \clearpage je Kapitel, kein \maketitle
  vor dem Cover, A4, seitengroßes Cover, DejaVu-Schriften und Mathe-Symbole
  für fehlende Glyphen (Mathebuch: >10.000 fehlende Zeichen → 0)
- Buch-README: bei Formeln LaTeX-Weg empfohlen, sonst weasyprint
- Alle sechs Beispielbücher geprüft: Seite 1 Cover, Verzeichnis nach dem Vorspann

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-10-06 06:48:18 +02:00
commit 86aa93c12c

View file

@ -139,23 +139,26 @@ def readme(md: BookMetadata, chapters: list[Chapter], endnotes: Chapter | None,
if callouts and CALLOUT_FILTER.is_file(): # '> [!TIP]' boxes: Pandoc needs the filter to draw real boxes
lua = f" --lua-filter {shlex.quote(str(CALLOUT_FILTER))}"
# book.lua: table of contents after cover/title page/imprint instead of Pandoc's --toc at the very top
toc = f" --lua-filter {shlex.quote(str(BOOK_FILTER))}" if BOOK_FILTER.is_file() else " --toc"
book = f" --lua-filter {shlex.quote(str(BOOK_FILTER))}" if BOOK_FILTER.is_file() else ""
toc = book or " --toc"
md_, html_, pdf_ = (shlex.quote(stem + ext) for ext in (".md", ".html", ".pdf"))
latex = [
"# PDF mit LaTeX über HTML: Pandoc übernimmt dann auch HTML-Tabellen und interne Sprungziele",
f"pandoc {md_} -s{math}{book}{lua} -o {html_} && pandoc {html_}{toc}{lua} --pdf-engine=xelatex -o {pdf_}",
]
weasy = [
"# PDF mit weasyprint: Farben, Kästen und HTML-Stile bleiben erhalten" + ("" if math else " (empfohlen)"),
f"pandoc {md_} -s{math}{toc}{lua} --css {shlex.quote(str(PRINT_CSS))} --pdf-engine=weasyprint -o {pdf_}",
] if PRINT_CSS.is_file() else []
if math:
latex[0] += " (empfohlen: weasyprint kann keine Formeln setzen)"
commands = [
"# Gesamtdatei erzeugen (im selben Arbeitsverzeichnis wie die Konvertierung)",
f"python3 epub2md_merge.py {shlex.quote(output_dir)}",
"# danach in diesem Ordner:",
f"pandoc {shlex.quote(stem + '.md')} -s{math}{toc}{lua} -o {shlex.quote(stem + '.html')}",
f"pandoc {shlex.quote(stem + '.md')} --toc{lua} -o {shlex.quote(stem + '.epub')}",
"# PDF über HTML: Pandoc übernimmt dann auch HTML-Tabellen und interne Sprungziele",
f"pandoc {shlex.quote(stem + '.md')} -s{math}{lua} -o {shlex.quote(stem + '.html')} && "
f"pandoc {shlex.quote(stem + '.html')} --toc{lua} --pdf-engine=xelatex -o {shlex.quote(stem + '.pdf')}",
]
if PRINT_CSS.is_file():
commands += [
"# PDF ohne LaTeX mit weasyprint: Farben, Kästen und HTML-Stile bleiben erhalten",
f"pandoc {shlex.quote(stem + '.md')} -s{math}{toc}{lua} --css {shlex.quote(str(PRINT_CSS))} "
f"--pdf-engine=weasyprint -o {shlex.quote(stem + '.pdf')}",
]
f"pandoc {md_} -s{math}{toc}{lua} -o {html_}",
f"pandoc {md_} --toc{lua} -o {shlex.quote(stem + '.epub')}",
] + (latex + weasy if math else weasy + latex)
out.append("## Weiterverarbeitung")
out.append("```bash\n" + "\n".join(commands) + "\n```")
if callouts: