#!/usr/bin/env python3 """ Generate personalized brevet cards from CSV data. """ import csv import sys from pathlib import Path def escape_latex(text): """Escape special LaTeX characters.""" if not text: return "" replacements = { '&': r'\&', '%': r'\%', '$': r'\$', '#': r'\#', '_': r'\_', '{': r'\{', '}': r'\}', '~': r'\textasciitilde{}', '^': r'\textasciicircum{}', '\\': r'\textbackslash{}', } result = str(text) for char, replacement in replacements.items(): result = result.replace(char, replacement) return result def generate_card_from_template(template, data): """Replace placeholders in template with participant data.""" name = f"{escape_latex(data['Vorname'])} {escape_latex(data['Nachname'])}" street = escape_latex(data['Straße']) plz_ort = f"{escape_latex(data['PLZ'])} {escape_latex(data['Ort'])}" land = escape_latex(data['Land']) medaille = "Ja" if data['Medaille'].lower() == 'ja' else "Nein" startnr = escape_latex(data['Startnr']) # Replace placeholders card = template.replace('{{NAME}}', name) card = card.replace('{{STREET}}', street) card = card.replace('{{PLZ_ORT}}', plz_ort) card = card.replace('{{LAND}}', land) card = card.replace('{{MEDAILLE}}', medaille) card = card.replace('{{STARTNR}}', startnr) return card def main(): csv_file = Path("Export Brevetkarte.csv") template_file = Path("brevetkarte-template.tex") output_file = Path("brevetkarte-personalized.tex") if not csv_file.exists(): print(f"Error: {csv_file} not found!", file=sys.stderr) sys.exit(1) if not template_file.exists(): print(f"Error: {template_file} not found!", file=sys.stderr) sys.exit(1) # Read template print(f"Reading template from {template_file}...") template = template_file.read_text(encoding='utf-8') # Read CSV data print(f"Reading participant data from {csv_file}...") participants = [] with open(csv_file, 'r', encoding='utf-8-sig') as f: # utf-8-sig handles BOM reader = csv.DictReader(f) for row in reader: if row['Startnr']: # Skip empty rows participants.append(row) if not participants: print("No participants found in CSV file!", file=sys.stderr) sys.exit(1) print(f"Found {len(participants)} participant(s)") # Generate document with all cards cards = [] for i, participant in enumerate(participants): card = generate_card_from_template(template, participant) cards.append(card) # Combine cards with spacing/page breaks document_parts = [] for i, card in enumerate(cards): document_parts.append(card) # Add vertical space between cards on same page if i % 2 == 0 and i < len(cards) - 1: document_parts.append("\n\\vspace{0.8cm}\n\n") # Add page break after every 2 cards (except at the end) if i % 2 == 1 and i < len(cards) - 1: document_parts.append("\n\\newpage\n\n") # Close document document_parts.append("\n\\end{document}\n") # Write output document = ''.join(document_parts) output_file.write_text(document, encoding='utf-8') print(f"Generated {output_file}") print(f"Total pages: {(len(participants) + 1) // 2}") print(f"Compile with: make build-personalized") if __name__ == "__main__": main()