diff --git a/Dockerfile b/Dockerfile index 1427d3e..f913a00 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,6 +7,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ make \ python3 \ python3-yaml \ + pdftk-java \ && rm -rf /var/lib/apt/lists/* WORKDIR /workspace \ No newline at end of file diff --git a/Makefile b/Makefile index 0ca5cc9..b5788bc 100644 --- a/Makefile +++ b/Makefile @@ -7,9 +7,11 @@ TEX_FILE_BACK := brevetkarte-rueckseite.tex PDF_FILE_PERSONALIZED := brevetkarte-personalized.pdf PDF_FILE_BLANKO := brevetkarte-blanko.pdf PDF_FILE_BACK := brevetkarte-rueckseite.pdf +PDF_FILE_DUPLEX := brevetkarte-duplex.pdf +PDF_FILE_BLANKO_DUPLEX := brevetkarte-blanko-duplex.pdf CSV_FILE := export_brevetcard.csv -.PHONY: all build clean build-image build-back generate build-personalized build-blanko run shell help +.PHONY: all build clean build-image build-back generate build-personalized build-blanko build-duplex build-blanko-duplex run shell help # Default target all: build-personalized build-blanko @@ -75,6 +77,24 @@ build-blanko: build-image pdflatex -interaction=nonstopmode $(TEX_FILE_BACK) @echo "PDF generated: $(PDF_FILE_BACK)" +# Build duplex PDF (personalized front + back interleaved for duplex printing) +build-duplex: build-personalized + @echo "Combining front and back for duplex printing..." + docker run --rm \ + -v $(PWD):/workspace \ + $(IMAGE_NAME) \ + pdftk A=$(PDF_FILE_PERSONALIZED) B=$(PDF_FILE_BACK) shuffle A B output $(PDF_FILE_DUPLEX) + @echo "PDF generated: $(PDF_FILE_DUPLEX)" + +# Build duplex PDF (blank front + back interleaved for duplex printing) +build-blanko-duplex: build-blanko + @echo "Combining blank front and back for duplex printing..." + docker run --rm \ + -v $(PWD):/workspace \ + $(IMAGE_NAME) \ + pdftk A=$(PDF_FILE_BLANKO) B=$(PDF_FILE_BACK) shuffle A B output $(PDF_FILE_BLANKO_DUPLEX) + @echo "PDF generated: $(PDF_FILE_BLANKO_DUPLEX)" + # Run container interactively run: docker run --rm -it \ @@ -92,7 +112,7 @@ shell: # Clean generated files clean: @echo "Cleaning generated files..." - rm -f *.aux *.log *.out *.toc *.pdf brevetkarte-personalized.tex brevetkarte-blanko.tex brevetkarte-rueckseite.tex + rm -f *.aux *.log *.out *.toc *.pdf brevetkarte-personalized.tex brevetkarte-blanko.tex brevetkarte-rueckseite.tex $(PDF_FILE_DUPLEX) $(PDF_FILE_BLANKO_DUPLEX) # Clean everything including Docker image clean-all: clean @@ -112,6 +132,8 @@ help: @echo " make generate - Generate tex files from CSV + event.yml" @echo " make build-personalized - Generate and compile front + back side PDFs" @echo " make build-blanko - Generate and compile blank card (no CSV needed)" + @echo " make build-duplex - Build duplex PDF (front+back interleaved)" + @echo " make build-blanko-duplex - Build blank duplex PDF" @echo " make build-back - Compile back side PDF only (after generate)" @echo " make shell - Open interactive shell in container" @echo " make clean - Remove generated files (aux, log, pdf)" diff --git a/README.md b/README.md index 6207783..17d2810 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,15 @@ Führt folgende Schritte aus: 3. Erzeugt `brevetkarte-rueckseite.tex` (Rückseite mit Kontrollpunkten aus event.yml) 4. Kompiliert beide .tex-Dateien zu PDFs +### Duplex-PDF erzeugen + +```bash +make build-duplex # personalisierte Karten +make build-blanko-duplex # Blanko-Karten +``` + +Erzeugt ein einzelnes PDF mit abwechselnden Vorder- und Rückseiten für den direkten Duplexdruck: Seite 1 Vorderseite, Seite 2 Rückseite, Seite 3 nächste Vorderseite, usw. Erfordert kein manuelles Zusammenführen zweier Dateien. + ### Blanko-Karten erzeugen und bauen ```bash diff --git a/generate_cards.py b/generate_cards.py index 47c1c5d..ea2a00e 100755 --- a/generate_cards.py +++ b/generate_cards.py @@ -59,7 +59,7 @@ def apply_event_placeholders(text, config): return text -def generate_backside(template, config): +def generate_backside(template, config, num_pages=1): """Fill back side template with cell content from event config.""" cells = config.get('backside', {}) result = template @@ -71,7 +71,18 @@ def generate_backside(template, config): if content is None: content = "" result = result.replace(placeholder, content.strip()) - return result + + if num_pages <= 1: + return result + + # Repeat body between \begin{document} and \end{document} num_pages times + begin_marker = '\\begin{document}\n' + end_marker = '\\end{document}' + begin_idx = result.find(begin_marker) + len(begin_marker) + end_idx = result.rfind(end_marker) + preamble = result[:begin_idx] + body = result[begin_idx:end_idx].rstrip() + return preamble + ('\n\n\\newpage\n\n').join([body] * num_pages) + '\n' + result[end_idx:] def generate_card_from_template(template, data): @@ -142,7 +153,7 @@ def main(): blanko_output_file.write_text(blanko_output, encoding='utf-8') print(f"Generated {blanko_output_file}") backside_template = backside_template_file.read_text(encoding='utf-8') - backside_output = generate_backside(backside_template, event_config) + backside_output = generate_backside(backside_template, event_config, num_pages=1) backside_output_file.write_text(backside_output, encoding='utf-8') print(f"Generated {backside_output_file}") return @@ -179,10 +190,11 @@ def main(): output_file.write_text(''.join(document_parts), encoding='utf-8') print(f"Generated {output_file}") - # Generate personalized back side + # Generate personalized back side (one page per front page for duplex) + num_pages = (len(participants) + 1) // 2 print(f"Reading back side template from {backside_template_file}...") backside_template = backside_template_file.read_text(encoding='utf-8') - backside_output = generate_backside(backside_template, event_config) + backside_output = generate_backside(backside_template, event_config, num_pages=num_pages) backside_output_file.write_text(backside_output, encoding='utf-8') print(f"Generated {backside_output_file}")