Communitygithub.com

swiss-pdf

Konvertiert MD/DOCX/TXT/HTML in A4-PDFs im Schweizer Layout mit klarem Design, automatischem Inhaltsverzeichnis und 7 Stilblöcken.

Was ist swiss-pdf?

swiss-pdf ist ein Skill, der Markdown, Word, TXT- und HTML-Dateien in professionelle A4-PDFs im Stil der Schweizer Typografie umwandelt. Es erzeugt weiße Seiten mit schwarzer Schrift, extrem dünnen Trennlinien, großen Kapitelnummern und einem einzigen Akzent-Farbton (#E5484D). Der Skill unterstützt sieben verschiedene Stilblöcke (note, quote, inverse, warn, stat, check, kv) für hervorgehobene Inhalte, automatische Paginierung, Kopf- und Fußzeilen mit Seitenzahlen sowie ein dynamisches Inhaltsverzeichnis, das nur bei ausreichender Gliederungstiefe erzeugt wird. Die Eingabe kann als Datei per Drag & Drop oder über die Kommandozeile erfolgen. Die PDF-Ausgabe erfolgt über Playwright/Chromium, wobei alle Schriftarten als Base64-CSS in die HTML-Zwischendatei eingebettet werden, um konsistente Ergebnisse ohne zusätzliche Schriftinstallation zu gewährleisten. Der Skill ist plattformunabhängig und funktioniert mit Python, Pandoc und Playwright.

Funktioniert mit✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/echoBai83/swiss-pdf/tree/HEAD

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Was macht swiss-pdf?

Wandelt MD / DOCX / TXT / HTML in A4-PDFs im Schweizer Layout um. Weißer Hintergrund, schwarze Schrift, extrem dünne Trennlinien, große Kapitelnummern, serifenlose Ziffern, einzige Farbe Rot #E5484D.

Das Design stammt aus einer gebundenen Sammlung im Stil der Schweizer Typografie (große Kapitelnummern, extrem dünne Trennlinien, einzelne Akzentfarbe) und wurde in einen automatischen, einspaltigen Seitenumbruch umgesetzt, sodass Dokumente beliebiger Länge direkt verarbeitet werden können.

Verwendung

Variante 1: Drag & Drop (empfohlen)

Datei auf swiss-pdf.bat ziehen → Im selben Verzeichnis wird eine gleichnamige .pdf-Datei erstellt, zusammen mit einer Kopie xxx.pdf-src.html (HTML-Quelle zur Überprüfung).

Variante 2: Kommandozeile

python make.py Eingabedatei                     # PDF erstellen
python make.py Eingabedatei --html              # Nur HTML erstellen (gespeichert als xxx.html, kann im Browser geöffnet und manuell gedruckt werden)
python make.py Eingabedatei -o Ausgabe.pdf
python make.py a.md b.docx c.txt               # Batch-Verarbeitung
python make.py Eingabedatei --no-cover --no-toc
python make.py Eingabedatei --title "Titel" --kick "Anmerkung" --date 2026.11.09

Unterstützte Eingabeformate

FormatKonvertierungBeschreibung
.mdpandocUnterstützt YAML Front-Matter, GFM-Tabellen, Listen, Codeblöcke, Bilder
.docxpandocÜberschriften-Stile → Kapitelüberschriften; Tabellen → formatierte Tabellen; Bilder automatisch extrahiert
.txtEigener ParserAbsätze durch Leerzeilen getrennt; kurze Zeilen mit Nummerierung (一、/ 1. / Kapitel X) → Kapitelüberschriften
.htmlEigener Parser<body> wird extrahiert, script/style entfernt; <title> wird als Dokumenttitel verwendet

Deckblatt: YAML Front-Matter

Direkt am Anfang einer MD-Datei (bei anderen Formaten über Parameter wie --title):

---
title: Stadtverkehrssicherheit – Weißbuch
subtitle: Beobachtungen und Empfehlungen auf Basis einer Stichprobe in drei Städten
kick: Verkehrsforschung
de: Urbane Radverkehrs-Sicherheit
slug: stadtverkehr-sicherheit
nature: Öffentliche Version
project: Forschungsprojekt Langsamverkehr
party_a: Auftraggeber
party_b: Auftragnehmer
stage: Erhebung → Auswertung → Fertigstellung
source: 01_Beobachtungen 02_Interviews 03_Konzept
date: 2026.11.10
version: v2.1
badges: Öffentlich; ! Wichtig; Datenbasiert
---
  • badges werden mit ; getrennt, Präfix ! für schwarzen Hintergrund mit weißer Schrift.
  • Fehlt date, wird automatisch das aktuelle Datum verwendet.
  • Auch ohne Front-Matter funktioniert es; das Deckblatt zeigt dann nur Titel + Datum + Versionsplatzhalter.

Text: Sechs Stilblöcke

In Markdown mit ::: umschlossen (jede Zeile innerhalb des Blocks = ein Eintrag):

::: note
Ergänzender Hinweis, Erläuterung. Grauer Hintergrund.
:::

::: quote
Schlüsselzitat, linke 3pt-Senkrechte.
:::

::: inverse
Schwarzer Hintergrund mit weißer Schrift für den wichtigsten Satz.
:::

::: warn
Roter Rahmen – die einzige Stelle, an der Farbe erlaubt ist.
:::

::: stat
4.280 | Gesamtzahl der Beobachtungen || 24 | Beobachtungspunkte || 3 | Abgedeckte Städte
:::

::: check
Kreuzung während der morgendlichen Hauptverkehrszeit (Ankunft vor 7:30 erforderlich)
Beleuchtete Abschnitte bei Nacht (Zusatzlicht erforderlich)
:::

::: kv
Seiten | Variante A 20 S. / Variante C 32 S.
Empfehlung | Variante C, aber mit ergänzenden Daten aus der zweiten Stadt
:::

stat verwendet Zahl | Beschreibung pro Feld, || trennt Felder. kv verwendet Schlüssel | Wert.

Automatische Verhaltensweisen

VerhaltenRegel
Kapitelnummerierung# Überschrift 1 → große Nummer 00/01/02…; bei bereits nummerierten Überschriften („01 “, „一、“) wird die vorhandene Nummer beibehalten
InhaltsverzeichnisWird nur erzeugt, wenn Kapitel + ##-Abschnitte insgesamt ≥ 5 sind; sonst wird die Seite weggelassen; Kapitelüberschriften sind verankert und im PDF anklickbar
TabellenSpaltenanzahl ≥ 6 → Schriftgröße reduziert (table.wide); rein numerische Zellen rechtsbündig + in serifenloser Schrift
Kopf- und FußzeilenDeckblattseite ohne Kopf-/Fußzeile; Textseiten: Kopfzeile links (Lauftitel), Fußzeile rechts („Seite i / N“)
Druck@page A4, Ränder 14/15/13 mm; Überschriften nicht vom Text getrennt, Tabellenzeilen nicht über Seitenumbrüche getrennt

Zusätzliche Verarbeitung von HTML-Quellen (empirisch ergänzt)

Wenn die Quelle eine „selbst gestaltete Webseite“ ist, normalisiert dieser Skill automatisch, um isolierte Nummerierungen oder doppelte Überschriften nach dem Umbruch zu vermeiden:

QuellstrukturVerarbeitung
<div class="sec-head"><span class="sec-num">3</span><h2>Titel</h2></div>Umwandlung in die .sec-Kopfzeile der Vorlage (Nummer aus span, Titel aus h2)
<h1>03 Titel</h1> / <h1>Titel</h1>Gleich wie oben; bei fehlender Nummer wird sie automatisch hochgezählt
Isolierte Absätze mit reiner Zahl <p>0</p>Verwerfen (häufig als dekorative Kapitelnummer verwendet)
<header class="masthead"> / <nav>Verwerfen (Deckblatt wird separat erstellt, wiederholte Kicker/Titel/Inhaltsverzeichnisse würden den Text stören)
<section>-AbschnitteBeibehalten als Container; Überschrift muss sec-head oder h1 sein, um ins Inhaltsverzeichnis aufgenommen zu werden
<div id="xxx" class="chart"> + echartsScreenshot mit Headless-Browser als PNG und Einbettung; Wartezeit networkidle + 2,5s vor Screenshot

Voraussetzung für Diagramm-Screenshots: Bei Verwendung von echarts per CDN muss eine Internetverbindung bestehen. In Offline-Umgebungen die echarts.min.js in die Quelle einbetten.

Schriftarten und Zeichensetzung

Schriftart: Im Repository integrierte Source Han Sans SC, per @font-face eingebettet

Im Verzeichnis fonts/ befinden sich zwei Dateien. make.py bettet deren Base64-Code beim Generieren des HTML in das <style> ein und registriert sie als Schriftfamilie Swiss Sans SC:

DateiSchriftstärke
SourceHanSansCN-Regular.subset.ttf400
SourceHanSansCN-Bold.subset.ttf700

Der Zeichensatz umfasst ca. 7100 Zeichen (ASCII + chinesische und englische Satzzeichen + alle 6763 chinesischen Schriftzeichen von GB2312). Die Zeichenliste findet sich in fonts/charset.txt. Vorteil: Auf einem Rechner ohne installierte Source Han Sans wird dennoch eine konsistente Ausgabe erzielt – ohne dass der Benutzer Schriftarten installieren muss.

Der Benutzer kann die Schriftarten austauschen oder herunterladen. Drei Möglichkeiten (Details in fonts/README.md):

  1. Dateien ersetzen (empfohlen): Eigene TTF-Dateien auf die beiden Namen umbenennen und überschreiben. Zuerst subsetten, sonst enthält das HTML die vollständigen 10 MB:
    pyftsubset DeineSchrift-Regular.ttf --text-file=fonts/charset.txt --output-file=fonts/SourceHanSansCN-Regular.subset.ttf
    
  2. fonts/ löschen: make.py überspringt dann @font-face und fällt auf den systemeigenen Schriftstapel im CSS zurück (Source Han Sans SC/CN → Noto Sans SC → Noto Sans CJK SC → MonuHan CN → PingFang SC → Segoe UI Symbol).
  3. Nur CSS ändern: Den ersten Schriftartnamen in --sans am Anfang von templates/swiss.css ändern.

⚠️ Es muss .ttf (TrueType-Konturen) sein, nicht .otf (CFF). Chromium stuf bei der PDF-Erstellung CFF-Webfonts zu Type3-Glyphen-Befehlen herunter (jedes Glyph als Zeichenpfad), was die Dateigröße um ein Vielfaches erhöht. Gleiches 4-seitiges Dokument: OTF → 328 KB / 205 Type3; TTF → 79 KB / 1 Type3.

Microsoft YaHei fehlen unter Chromium die Zeichenformen für · (U+00B7), → ↓ ≤ ≥ etc., die zu Quadraten werden. Daher wurde es aus dem primären Schriftstapel entfernt.

Anführungszeichen: Volltext auf nationale gebogene Anführungszeichen

convert.normalize_quotes() verarbeitet sie im letzten Schritt, deckt Überschriften, Deckblatt, Kopfzeilen, Inhaltsverzeichnis, Tabellen und Stilblöcke ab:

EingabeAusgabe
「」“”
『』‘’
Gerade Anführungszeichen im Code " 'Pandoc wandelt Markdown-Anführungszeichen automatisch in gebogene um (+smart); innerhalb von Codeblöcken <code> / <pre> keine Änderung

Die Implementierung ersetzt nur 4 Codepunkte (U+300C/D/E/F → U+201C/D/8/9) und beeinflusst keine HTML-Tag-Attribute oder CSS/JS.

Validierte Praxisbeispiele

EingabeGrößeSeitenDauer
md29 KB15~6s
html105 KB + 2 echarts-Diagramme21~15s
docxÜberschriften-Stile + Tabelle2~6s
txt (aus samples/)1,2 KB2~5s
md langes Dokument (Regression)71 KB21~24s

Systemvoraussetzungen

AbhängigkeitStatus auf eigenem RechnerFalls fehlend
pandoc (≥2.19)pandoc -v ausführen und prüfenMD/DOCX können nicht konvertiert werden
playwright + chromiumOder systemeigener Chrome/EdgePDF kann nicht gerendert werden
python-docx (optional)Nur für die AnalyseBeeinträchtigt den Hauptablauf nicht

Browser festlegen: set SWISS_PDF_CHROME=<Pfad zu chrome.exe>

Dateistruktur

swiss-pdf/
├── SKILL.md              Diese Datei
├── swiss-pdf.bat         Drag-und-Drop-Einstieg
├── make.py               Hauptablauf: Konvertierung → Zusammenbau → Rendern
├── convert.py            Formate → HTML-Fragmente + Block-Syntax
├── templates/
│   └── swiss.css         Alle Stile (Design-Tokens + Druckregeln)
└── samples/              Beispiele in drei Formaten

Grenzen (Was nicht funktioniert)

  • Manueller Seitenumbruch wie in einer Broschüre (jede Seite sorgfältig gestaltet, Doppelseiten-Design). Die Vorlage kann dies nicht leisten. Dieser Skill ist für die schnelle Erstellung von Standarddokumenten gedacht.
  • Bild-Layout hängt von den Bildabmessungen im Originaldokument ab; es wird kein Beschneiden oder Anschnitt vorgenommen.
  • Seitennummern im Inhaltsverzeichnis (wie bei gedruckten Büchern) werden nicht realisiert (Elemente auf der Seite können die Seitenzahl nicht ermitteln). Kapitelüberschriften sind jedoch anklickbar; die Fußzeile zeigt „Seite i / N“.
  • Zu kurze Tabellenblöcke können ganz auf die nächste Seite verschoben werden (um das Auseinanderreißen von Schlüssel-Wert-Tabellen zu vermeiden, sind .kv-Blöcke als untrennbar markiert).
  • Komplexe Word-Formatierungen (Textfelder, WordArt, mehrstufige Nummerierungslisten) werden bei der Konvertierung durch Pandoc vereinfacht.

Verwandte Skills