From 74269c4fbbd0034057dc2fff9a462630db9cae96 Mon Sep 17 00:00:00 2001
From: Peter Adam
Date: Sat, 28 Feb 2026 10:53:36 +0100
Subject: [PATCH] Add back side template and update README with event.yml
workflow
Co-Authored-By: Claude Sonnet 4.6
---
README.md | 185 ++++++++++++----------------
brevetkarte-rueckseite-template.tex | 121 ++++++++++++++++++
2 files changed, 200 insertions(+), 106 deletions(-)
create mode 100644 brevetkarte-rueckseite-template.tex
diff --git a/README.md b/README.md
index 44767e2..dd36a45 100644
--- a/README.md
+++ b/README.md
@@ -2,138 +2,111 @@
LaTeX-basierter Generator für Audax Randonneurs Allemagne Brevetkarten mit Vorder- und Rückseite für den Duplexdruck.
-## Schnellstart
-
-```bash
-# Alles bauen und beide PDFs erzeugen
-make build
-
-# Die PDFs werden erstellt als:
-# - brevetkarte.pdf (Vorderseite mit Teilnehmerinfos)
-# - brevetkarte-rueckseite.pdf (Rückseite mit Kontrollen)
-```
-
## Voraussetzungen
- Docker
- Make
+- Python 3 + PyYAML (`pip install pyyaml`)
+
+## Konfigurationsdateien
+
+Vor dem ersten Build zwei Dateien aus den Beispielen anlegen und befüllen:
+
+```bash
+cp "Export Brevetkarte.csv.example" "Export Brevetkarte.csv"
+cp event.yml.example event.yml
+```
+
+Beide Dateien sind in `.gitignore` eingetragen und werden nicht ins Repository übernommen.
+
+### event.yml
+
+Enthält alle veranstaltungsspezifischen Daten:
+
+```yaml
+event:
+ title: "Name der Veranstaltung"
+ km: "200"
+ date: "1. Januar 2025"
+ start_location: "Stadt, Ort"
+ club: "Clubname"
+ club_nr: "000000"
+ startzeit: "8:00"
+
+backside:
+ "1_1": |
+ \vspace{2mm}
+ \textbf{Nr. 1:} Km 0 -- Startort\\
+ ...
+ "1_2": "" # leer = Stempelfeld
+ ...
+```
+
+Die `backside`-Sektion belegt die 12 Zellen der Rückseite (3 Zeilen × 4 Spalten, Schlüssel `"Zeile_Spalte"`). Der Inhalt ist freies LaTeX. Leere Zellen (`""`) dienen als Stempelfelder.
+
+### Export Brevetkarte.csv
+
+Teilnehmerdaten im Format:
+
+```
+Startnr, Nachname, Vorname, Straße, PLZ, Ort, Land, Medaille
+```
+
+Siehe `Export Brevetkarte.csv.example` für das vollständige Format.
## Verwendung
-### Beide PDFs bauen
+### Personalisierte Karten erzeugen und bauen
+
```bash
-make build
+make build-personalized
```
-Dies führt folgende Schritte aus:
-1. Docker-Image mit TeX Live bauen
-2. `brevetkarte.tex` zu `brevetkarte.pdf` kompilieren (Vorderseite)
-3. `brevetkarte-rueckseite.tex` zu `brevetkarte-rueckseite.pdf` kompilieren (Rückseite)
+Führt folgende Schritte aus:
+1. `generate_cards.py` liest `Export Brevetkarte.csv` + `event.yml`
+2. Erzeugt `brevetkarte-personalized.tex` (Vorderseite, eine Karte pro Teilnehmer)
+3. Erzeugt `brevetkarte-rueckseite.tex` (Rückseite mit Kontrollpunkten aus event.yml)
+4. Kompiliert beide .tex-Dateien zu PDFs
-### Einzelne Seiten bauen
+### Einzelne Schritte
```bash
-# Nur Vorderseite bauen
-make build-front
+# Nur tex-Dateien generieren (ohne Docker)
+make generate
-# Nur Rückseite bauen
+# Nur Rückseite kompilieren (nach generate)
make build-back
-# Beide Seiten bauen
-make build-pdf
+# Statische Demo-Vorderseite bauen (ohne CSV, für Tests)
+make build-front
```
-### Personalisierte Karten aus CSV
-
-```bash
-# 1. Beispiel-CSV kopieren und Teilnehmerdaten eintragen
-cp "Export Brevetkarte.csv.example" "Export Brevetkarte.csv"
-# "Export Brevetkarte.csv" mit den Teilnehmern befüllen
-
-# 2. Personalisierte Karten erzeugen und bauen
-make build-personalized
-# Ausgabe: brevetkarte-personalized.pdf
-```
-
-Die CSV-Datei `Export Brevetkarte.csv` wird nicht von git erfasst (sie kann personenbezogene Daten enthalten). Die Datei `Export Brevetkarte.csv.example` zeigt das erwartete Format.
-
### Weitere Befehle
```bash
-# Nur das Docker-Image bauen
-make build-image
-
-# Interaktive Shell im Container öffnen
-make shell
-
-# Erzeugte Dateien löschen (.aux, .log, .pdf)
-make clean
-
-# Alles löschen inkl. Docker-Image
-make clean-all
-
-# Von Grund auf neu bauen
-make rebuild
-
-# Hilfe anzeigen
-make help
+make build-image # Docker-Image bauen
+make shell # Interaktive Shell im Container
+make clean # Erzeugte Dateien löschen (.aux, .log, .pdf)
+make clean-all # Alles löschen inkl. Docker-Image
+make help # Alle Befehle anzeigen
```
## Dateien
-- `brevetkarte.tex` - LaTeX-Quelle für die Vorderseite (zwei identische Blanko-Karten)
-- `brevetkarte-template.tex` - Vorlage für personalisierte Karten (Platzhalter werden aus CSV ersetzt)
-- `brevetkarte-rueckseite.tex` - LaTeX-Quelle für die Rückseite (Kontrollen)
-- `Export Brevetkarte.csv.example` - Beispiel-CSV mit dem Teilnehmerdatenformat
-- `generate_cards.py` - Erzeugt `brevetkarte-personalized.tex` aus CSV und Vorlage
-- `cyclist-logo.png` - Audax Randonneurs Logo
-- `Dockerfile` - Docker-Image-Definition (debian:bookworm-slim + TeX-Live-Pakete)
-- `Makefile` - Build-Automatisierung
-
-## Ausgabe
-
-### Vorderseite (brevetkarte.pdf)
-Enthält zwei identische Brevetkarten, die in der Mitte geschnitten werden können. Jede Karte enthält:
-- Teilnehmerinformationen (Name, Adresse usw.)
-- Veranstaltungsdetails (200 km „Auf eine Pommes nach Belgien")
-- Randonneur-Mondiaux-Regeln
-- Homologationsbereich
-- Startzeit: 8:30
-
-### Rückseite (brevetkarte-rueckseite.pdf)
-Enthält die Kontrollentabelle (4 Spalten × 6 Zeilen):
-- **Zeilen 1–3**: Kontrollen für die obere Karte
- - Nr. 1: Start (Km 0 – Unisport, Bonn)
- - Nr. 2: Km 57 – Nationalpark-Tor, Heimbach
- - Nr. 3: Km 100 – Friterie „Au Petit Creux", Waimes
- - Nr. 4: Km 165 – Mahlberg
- - Nr. 5: Km 205 – Ziel (Unisport, Bonn)
-- **Zeilen 4–6**: Kontrollen für die untere Karte (wie oben, aber Nr. 5: Km 214)
-- Leere Spalten für Stempel/Unterschriften
-- Kontrollfrage zur Verifikation
+| Datei | Beschreibung |
+|---|---|
+| `event.yml.example` | Vorlage für Veranstaltungsdaten (→ als `event.yml` kopieren) |
+| `Export Brevetkarte.csv.example` | Vorlage für Teilnehmerdaten (→ als `Export Brevetkarte.csv` kopieren) |
+| `brevetkarte-template.tex` | Vorlage Vorderseite (Platzhalter aus CSV + event.yml) |
+| `brevetkarte-rueckseite-template.tex` | Vorlage Rückseite (Zellplatzhalter aus event.yml) |
+| `brevetkarte.tex` | Statische Demo-Vorderseite (ohne Personalisierung) |
+| `generate_cards.py` | Generiert personalisierte .tex-Dateien |
+| `cyclist-logo.png` | Audax Randonneurs Logo |
+| `Dockerfile` | Docker-Image-Definition (debian:bookworm-slim + TeX Live) |
+| `Makefile` | Build-Automatisierung |
## Duplexdruck
-Die PDFs sind für den Duplexdruck (beidseitiger Druck) ausgelegt:
-1. `brevetkarte.pdf` auf einer Seite drucken
+1. `brevetkarte-personalized.pdf` auf einer Seite drucken
2. `brevetkarte-rueckseite.pdf` auf der Rückseite drucken
-3. Spalten und Zeilen sind so ausgerichtet, dass:
- - Vorderseitenspalten mit Rückseitenspalten übereinstimmen
- - Obere Karte (Zeilen 1–3) mit der oberen Vorderseitenkarte fluchtet
- - Untere Karte (Zeilen 4–6) mit der unteren Vorderseitenkarte fluchtet
-4. Blatt horizontal in der Mitte schneiden, um zwei separate Brevetkarten zu erhalten
-
-## Anpassung
-
-`brevetkarte.tex` bearbeiten für die Vorderseite:
-- Veranstaltungsname, Datum und Ort
-- Distanz (200 km)
-- Startzeit
-- Vereinsinformationen
-- Brevetformat
-
-`brevetkarte-rueckseite.tex` bearbeiten für die Rückseite:
-- Kontrollpunkte
-- Kontrollzeiten (von/bis)
-- Distanzen
-- Kontrollfragen
+3. Blatt horizontal in der Mitte schneiden → zwei separate Brevetkarten
\ No newline at end of file
diff --git a/brevetkarte-rueckseite-template.tex b/brevetkarte-rueckseite-template.tex
new file mode 100644
index 0000000..9f7b8a5
--- /dev/null
+++ b/brevetkarte-rueckseite-template.tex
@@ -0,0 +1,121 @@
+\documentclass[a4paper,10pt,landscape]{article}
+\usepackage[utf8]{inputenc}
+\usepackage[T1]{fontenc}
+\usepackage[landscape,top=0.8cm,bottom=0.8cm,left=0.8cm,right=0.8cm]{geometry}
+\usepackage{array}
+\usepackage{helvet}
+
+% Set sans-serif font as default
+\renewcommand{\familydefault}{\sfdefault}
+
+\setlength{\parindent}{0pt}
+\setlength{\tabcolsep}{3pt}
+\pagestyle{empty}
+
+\newcommand{\rowheight}{2.833cm}
+
+\begin{document}
+
+% Upper card table (rows 1-3)
+\noindent
+\begin{tabular}{|p{6.6cm}|p{6.6cm}|p{6.6cm}|p{6.6cm}|}
+\hline
+% Row 1
+\parbox[c][\rowheight][t]{6.5cm}{%
+{{CELL_1_1}}}
+&
+\parbox[c][\rowheight][t]{6.5cm}{%
+{{CELL_1_2}}}
+&
+\parbox[c][\rowheight][t]{6.5cm}{%
+{{CELL_1_3}}}
+&
+\parbox[c][\rowheight][t]{6.5cm}{%
+{{CELL_1_4}}}
+\\
+\hline
+
+% Row 2
+\parbox[c][\rowheight][t]{6.5cm}{%
+{{CELL_2_1}}}
+&
+\parbox[c][\rowheight][t]{6.5cm}{%
+{{CELL_2_2}}}
+&
+\parbox[c][\rowheight][t]{6.5cm}{%
+{{CELL_2_3}}}
+&
+\parbox[c][\rowheight][t]{6.5cm}{%
+{{CELL_2_4}}}
+\\
+\hline
+
+% Row 3
+\parbox[c][\rowheight][t]{6.5cm}{%
+{{CELL_3_1}}}
+&
+\parbox[c][\rowheight][t]{6.5cm}{%
+{{CELL_3_2}}}
+&
+\parbox[c][\rowheight][t]{6.5cm}{%
+{{CELL_3_3}}}
+&
+\parbox[c][\rowheight][t]{6.5cm}{%
+{{CELL_3_4}}}
+\\
+\hline
+\end{tabular}
+
+\vspace{1.8cm}
+
+% Lower card table (rows 1-3, identical)
+\noindent
+\begin{tabular}{|p{6.6cm}|p{6.6cm}|p{6.6cm}|p{6.6cm}|}
+\hline
+% Row 1
+\parbox[c][\rowheight][t]{6.5cm}{%
+{{CELL_1_1}}}
+&
+\parbox[c][\rowheight][t]{6.5cm}{%
+{{CELL_1_2}}}
+&
+\parbox[c][\rowheight][t]{6.5cm}{%
+{{CELL_1_3}}}
+&
+\parbox[c][\rowheight][t]{6.5cm}{%
+{{CELL_1_4}}}
+\\
+\hline
+
+% Row 2
+\parbox[c][\rowheight][t]{6.5cm}{%
+{{CELL_2_1}}}
+&
+\parbox[c][\rowheight][t]{6.5cm}{%
+{{CELL_2_2}}}
+&
+\parbox[c][\rowheight][t]{6.5cm}{%
+{{CELL_2_3}}}
+&
+\parbox[c][\rowheight][t]{6.5cm}{%
+{{CELL_2_4}}}
+\\
+\hline
+
+% Row 3
+\parbox[c][\rowheight][t]{6.5cm}{%
+{{CELL_3_1}}}
+&
+\parbox[c][\rowheight][t]{6.5cm}{%
+{{CELL_3_2}}}
+&
+\parbox[c][\rowheight][t]{6.5cm}{%
+{{CELL_3_3}}}
+&
+\parbox[c][\rowheight][t]{6.5cm}{%
+{{CELL_3_4}}}
+\\
+\hline
+\end{tabular}
+
+\end{document}
\ No newline at end of file