diff --git a/BEDIENUNGSANLEITUNG.md b/BEDIENUNGSANLEITUNG.md index e4d4d90..8fa4a26 100644 --- a/BEDIENUNGSANLEITUNG.md +++ b/BEDIENUNGSANLEITUNG.md @@ -319,7 +319,7 @@ Original-E-Books. | Word | `pandoc meinbuch.md -o meinbuch.docx` | | LibreOffice | `pandoc meinbuch.md -o meinbuch.odt` | | PDF mit LaTeX | `pandoc meinbuch.md -s -o meinbuch.html && pandoc meinbuch.html --toc --pdf-engine=xelatex -o meinbuch.pdf` | -| PDF ohne LaTeX | `pandoc meinbuch.md --toc --pdf-engine=weasyprint -o meinbuch.pdf` | +| PDF ohne LaTeX | `pandoc meinbuch.md -s --toc --css ~/Python_Programs/epub2md/pandoc/print.css --pdf-engine=weasyprint -o meinbuch.pdf` | | Kindle (AZW3) | `pandoc meinbuch.md --toc -o meinbuch.epub && ebook-convert meinbuch.epub meinbuch.azw3` | **Zum PDF:** @@ -327,8 +327,11 @@ Original-E-Books. - **Mit LaTeX** immer den Zwischenschritt über HTML nehmen, wie in der Tabelle. Beim direkten Weg von Markdown nach LaTeX lässt Pandoc komplexe Tabellen weg, und Querverweise im PDF funktionieren nicht. Bei Büchern mit Formeln ist der LaTeX-Weg die beste Wahl. -- **Mit weasyprint** genügt ein Schritt; Tabellen bleiben erhalten. Für Bücher mit vielen Formeln ist der - LaTeX-Weg sicherer. +- **Mit weasyprint** genügt ein Schritt; Tabellen, Farben, Infokästen und die Gestaltung aus `--styles html` + bleiben erhalten. Für Bücher mit vielen Formeln ist der LaTeX-Weg sicherer. +- **`print.css`** (im Ordner `pandoc/` von epub2md) sorgt beim weasyprint-Weg für ein Buchlayout: A4, + Seitenzahlen, jedes Kapitel auf einer neuen Seite, Silbentrennung und umbrechende lange Codezeilen. Ohne + sie übernimmt weasyprint das Bildschirmlayout, und lange Codezeilen werden am Seitenrand abgeschnitten. Bei Büchern mit Formeln für HTML zusätzlich `--mathml` angeben, sonst bleiben Matrizen als TeX-Text stehen. @@ -342,6 +345,7 @@ F=~/Python_Programs/epub2md/pandoc/callouts.lua # Pfad zu deinem epub2md-Ord pandoc meinbuch.md -s --toc --lua-filter $F -o meinbuch.html pandoc meinbuch.md --toc --lua-filter $F -o meinbuch.epub pandoc meinbuch.md -s --lua-filter $F -o meinbuch.html && pandoc meinbuch.html --toc --lua-filter $F --pdf-engine=xelatex -o meinbuch.pdf +pandoc meinbuch.md -s --toc --lua-filter $F --css ~/Python_Programs/epub2md/pandoc/print.css --pdf-engine=weasyprint -o meinbuch.pdf ``` In HTML, EPUB und im PDF über weasyprint werden daraus gerahmte, farbige Kästen mit Titel („Tipp: …“). Im diff --git a/CHANGELOG.md b/CHANGELOG.md index fcabe44..b5ac697 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,11 @@ Versionsnummern nach [Semantic Versioning](https://semver.org/lang/de/). - Seitenmarken (`--page-markers`) aus einem Kastentitel stehen jetzt vor dem Kasten statt im fetten Titel, wie bei Überschriften. +### Neu + +- `pandoc/print.css`: Druck-Layout für PDFs mit weasyprint (A4, Seitenzahlen, Kapitel auf neuer Seite, + Silbentrennung außer in Code, umbrechende Codezeilen). Die Buch-README enthält den passenden Befehl. + ### Behoben - `pandoc/callouts.lua`: Die Kästen blieben ohne Rahmen, wenn man Pandoc zusätzlich `-H`/`--include-in-header` diff --git a/README.md b/README.md index a9853b7..40a2c51 100644 --- a/README.md +++ b/README.md @@ -339,6 +339,17 @@ pandoc mathematikbuch.md --mathml -s -o mathematikbuch.html pandoc mathematikbuch.html --toc --pdf-engine=xelatex -o mathematikbuch.pdf ``` +**PDF mit weasyprint** (ohne LaTeX; Farben, Kästen und `--styles html` bleiben erhalten): + +```bash +pandoc buch.md -s --toc --lua-filter $F --css ~/Python_Programs/epub2md/pandoc/print.css \ + --pdf-engine=weasyprint -o buch.pdf +``` + +`pandoc/print.css` liefert das Buchlayout: A4, Seitenzahlen, Kapitel auf neuer Seite, Silbentrennung (nicht in +Code) und umbrechende Codezeilen. Mit `--css` lässt Pandoc sein eigenes Stylesheet weg, deshalb bringt +`print.css` auch Grundschrift, Zeilenabstand und Titelkopf mit. Getestet mit dem Python-Buch (342 Seiten). + **Infokästen:** Pandoc kennt die Schreibweise `> [!TIP]` erst ab neueren Versionen (Erweiterung `alerts`); 3.1.3 (Ubuntu 24.04) zeigt „[!TIP]“ als Text. Der Filter `pandoc/callouts.lua` behebt das: In HTML und EPUB entstehen gerahmte, farbige Kästen mit Titel („Tipp: …“, bei `lang: en` „Tip: …“), in LaTeX/PDF, Word @@ -438,7 +449,8 @@ epub2md/ └── utils.py Slugs, YAML-Emitter, Pfadhelfer pandoc/ ├── callouts.lua Pandoc-Filter: '> [!TIP]'-Kästen → gerahmte Kästen (HTML/EPUB) bzw. Zitatblock mit Titel -└── callouts.css Gestaltung der Kästen (vom Filter eingebunden; muss neben callouts.lua liegen) +├── callouts.css Gestaltung der Kästen (vom Filter eingebunden; muss neben callouts.lua liegen) +└── print.css Druck-Layout für PDFs mit weasyprint (A4, Seitenzahlen, Kapitel auf neuer Seite, Codeumbruch) ``` Statt BeautifulSoup wird direkt lxml verwendet: Es ist für die XHTML-Bäume ausreichend, schneller und diff --git a/epub2md/writer.py b/epub2md/writer.py index 3a25bc1..17cae9e 100644 --- a/epub2md/writer.py +++ b/epub2md/writer.py @@ -17,6 +17,7 @@ from .references import LinkResolver from .utils import rel_link, to_yaml, url_path CALLOUT_FILTER = Path(__file__).resolve().parent.parent / "pandoc" / "callouts.lua" +PRINT_CSS = Path(__file__).resolve().parent.parent / "pandoc" / "print.css" SPECIAL_LABELS = { "glossary": "Glossar", @@ -146,6 +147,12 @@ def readme(md: BookMetadata, chapters: list[Chapter], endnotes: Chapter | None, 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 --toc{math}{lua} --css {shlex.quote(str(PRINT_CSS))} " + f"--pdf-engine=weasyprint -o {shlex.quote(stem + '.pdf')}", + ] out.append("## Weiterverarbeitung") out.append("```bash\n" + "\n".join(commands) + "\n```") if callouts: diff --git a/pandoc/print.css b/pandoc/print.css new file mode 100644 index 0000000..af35eb3 --- /dev/null +++ b/pandoc/print.css @@ -0,0 +1,19 @@ +/* Print layout for PDFs from epub2md output via Pandoc + weasyprint: + pandoc buch.md -s --toc --lua-filter pandoc/callouts.lua --css pandoc/print.css --pdf-engine=weasyprint -o buch.pdf */ +@page { size: A4; margin: 2cm 1.8cm; @bottom-center { content: counter(page); font-size: 9pt; } } +body { max-width: none; font-size: 10.5pt; line-height: 1.4; hyphens: auto; text-align: justify; + font-family: "DejaVu Serif", "Liberation Serif", Georgia, serif; } +#title-block-header, #title-block-header h1.title { text-align: center; margin-bottom: 2em; } +h1, h2, h3, h4 { text-align: left; hyphens: manual; page-break-after: avoid; } +pre, code { font-family: "DejaVu Sans Mono", "Liberation Mono", monospace; hyphens: none; } +pre { background: #f6f8fa; padding: 0.5em 0.8em; border-radius: 0.3em; page-break-inside: auto; } +blockquote { margin: 1em 0 1em 1.5em; padding-left: 0.8em; border-left: 2px solid #ccc; color: #444; } +nav#TOC ul { list-style: none; padding-left: 1.2em; } +a { color: inherit; text-decoration: none; } +pre, pre code { white-space: pre-wrap; overflow-wrap: anywhere; font-size: 8.5pt; } /* long code lines wrap */ +pre { overflow: visible; } +img { max-width: 100%; height: auto; } +h1 { page-break-before: always; } /* every chapter on a new page */ +#title-block-header h1, #TOC h1 { page-break-before: auto; } +nav#TOC { page-break-after: always; } +table { font-size: 9pt; } diff --git a/tests/test_styles.py b/tests/test_styles.py index f3d3884..2964d5b 100644 --- a/tests/test_styles.py +++ b/tests/test_styles.py @@ -190,6 +190,7 @@ def test_book_readme_suggests_callout_filter(convert): body = '

K

Merke

Wichtiger Satz.

' readme = (convert(Book(docs=[Doc("c.xhtml", body)])).out / "README.md").read_text(encoding="utf-8") assert "--lua-filter" in readme and "pandoc/callouts.lua" in readme and "1 Infokasten " in readme + assert "pandoc/print.css --pdf-engine=weasyprint" in readme plain = convert(Book(docs=[Doc("c.xhtml", body)]), "--boxes", "plain").out / "README.md" assert "--lua-filter" not in plain.read_text(encoding="utf-8")