feat: pandoc/print.css – Druck-Layout für PDFs mit weasyprint
- A4, Seitenzahlen, jedes Kapitel auf neuer Seite, Inhaltsverzeichnis auf eigener Seite, Silbentrennung (nicht in Code), umbrechende Codezeilen; bringt Grundschrift und Titelkopf mit, da --css Pandocs Standard-CSS ersetzt - Buch-README: zusätzlicher weasyprint-Befehl mit Filter und print.css - Doku: Bedienungsanleitung und README um den weasyprint-Weg ergänzt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
c761a53728
commit
13617c8d3e
6 changed files with 52 additions and 4 deletions
|
|
@ -319,7 +319,7 @@ Original-E-Books.
|
||||||
| Word | `pandoc meinbuch.md -o meinbuch.docx` |
|
| Word | `pandoc meinbuch.md -o meinbuch.docx` |
|
||||||
| LibreOffice | `pandoc meinbuch.md -o meinbuch.odt` |
|
| 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 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` |
|
| Kindle (AZW3) | `pandoc meinbuch.md --toc -o meinbuch.epub && ebook-convert meinbuch.epub meinbuch.azw3` |
|
||||||
|
|
||||||
**Zum PDF:**
|
**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
|
- **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
|
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.
|
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
|
- **Mit weasyprint** genügt ein Schritt; Tabellen, Farben, Infokästen und die Gestaltung aus `--styles html`
|
||||||
LaTeX-Weg sicherer.
|
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.
|
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 -s --toc --lua-filter $F -o meinbuch.html
|
||||||
pandoc meinbuch.md --toc --lua-filter $F -o meinbuch.epub
|
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 --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
|
In HTML, EPUB und im PDF über weasyprint werden daraus gerahmte, farbige Kästen mit Titel („Tipp: …“). Im
|
||||||
|
|
|
||||||
|
|
@ -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,
|
- Seitenmarken (`--page-markers`) aus einem Kastentitel stehen jetzt vor dem Kasten statt im fetten Titel,
|
||||||
wie bei Überschriften.
|
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
|
### Behoben
|
||||||
|
|
||||||
- `pandoc/callouts.lua`: Die Kästen blieben ohne Rahmen, wenn man Pandoc zusätzlich `-H`/`--include-in-header`
|
- `pandoc/callouts.lua`: Die Kästen blieben ohne Rahmen, wenn man Pandoc zusätzlich `-H`/`--include-in-header`
|
||||||
|
|
|
||||||
14
README.md
14
README.md
|
|
@ -339,6 +339,17 @@ pandoc mathematikbuch.md --mathml -s -o mathematikbuch.html
|
||||||
pandoc mathematikbuch.html --toc --pdf-engine=xelatex -o mathematikbuch.pdf
|
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`);
|
**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
|
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
|
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
|
└── utils.py Slugs, YAML-Emitter, Pfadhelfer
|
||||||
pandoc/
|
pandoc/
|
||||||
├── callouts.lua Pandoc-Filter: '> [!TIP]'-Kästen → gerahmte Kästen (HTML/EPUB) bzw. Zitatblock mit Titel
|
├── 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
|
Statt BeautifulSoup wird direkt lxml verwendet: Es ist für die XHTML-Bäume ausreichend, schneller und
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ from .references import LinkResolver
|
||||||
from .utils import rel_link, to_yaml, url_path
|
from .utils import rel_link, to_yaml, url_path
|
||||||
|
|
||||||
CALLOUT_FILTER = Path(__file__).resolve().parent.parent / "pandoc" / "callouts.lua"
|
CALLOUT_FILTER = Path(__file__).resolve().parent.parent / "pandoc" / "callouts.lua"
|
||||||
|
PRINT_CSS = Path(__file__).resolve().parent.parent / "pandoc" / "print.css"
|
||||||
|
|
||||||
SPECIAL_LABELS = {
|
SPECIAL_LABELS = {
|
||||||
"glossary": "Glossar",
|
"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 + '.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')}",
|
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("## Weiterverarbeitung")
|
||||||
out.append("```bash\n" + "\n".join(commands) + "\n```")
|
out.append("```bash\n" + "\n".join(commands) + "\n```")
|
||||||
if callouts:
|
if callouts:
|
||||||
|
|
|
||||||
19
pandoc/print.css
Normal file
19
pandoc/print.css
Normal file
|
|
@ -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; }
|
||||||
|
|
@ -190,6 +190,7 @@ def test_book_readme_suggests_callout_filter(convert):
|
||||||
body = '<h1>K</h1><div class="box"><h3 class="boxheading">Merke</h3><p>Wichtiger Satz.</p></div>'
|
body = '<h1>K</h1><div class="box"><h3 class="boxheading">Merke</h3><p>Wichtiger Satz.</p></div>'
|
||||||
readme = (convert(Book(docs=[Doc("c.xhtml", body)])).out / "README.md").read_text(encoding="utf-8")
|
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 "--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"
|
plain = convert(Book(docs=[Doc("c.xhtml", body)]), "--boxes", "plain").out / "README.md"
|
||||||
assert "--lua-filter" not in plain.read_text(encoding="utf-8")
|
assert "--lua-filter" not in plain.read_text(encoding="utf-8")
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue