Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ca995a1c1f | |||
| f811c3fd80 | |||
| 0c4d630d8e |
@@ -5,6 +5,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
texlive-pictures \
|
texlive-pictures \
|
||||||
texlive-fonts-recommended \
|
texlive-fonts-recommended \
|
||||||
make \
|
make \
|
||||||
|
python3 \
|
||||||
|
python3-yaml \
|
||||||
|
pdftk-java \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
WORKDIR /workspace
|
WORKDIR /workspace
|
||||||
@@ -7,9 +7,11 @@ TEX_FILE_BACK := brevetkarte-rueckseite.tex
|
|||||||
PDF_FILE_PERSONALIZED := brevetkarte-personalized.pdf
|
PDF_FILE_PERSONALIZED := brevetkarte-personalized.pdf
|
||||||
PDF_FILE_BLANKO := brevetkarte-blanko.pdf
|
PDF_FILE_BLANKO := brevetkarte-blanko.pdf
|
||||||
PDF_FILE_BACK := brevetkarte-rueckseite.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
|
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
|
# Default target
|
||||||
all: build-personalized build-blanko
|
all: build-personalized build-blanko
|
||||||
@@ -29,13 +31,16 @@ build-back: build-image
|
|||||||
@echo "PDF generated: $(PDF_FILE_BACK)"
|
@echo "PDF generated: $(PDF_FILE_BACK)"
|
||||||
|
|
||||||
# Generate all tex files from CSV + event.yml
|
# Generate all tex files from CSV + event.yml
|
||||||
generate:
|
generate: build-image
|
||||||
@echo "Generating cards from $(CSV_FILE) + event.yml..."
|
@echo "Generating cards from $(CSV_FILE) + event.yml..."
|
||||||
@if [ ! -f "$(CSV_FILE)" ]; then \
|
@if [ ! -f "$(CSV_FILE)" ]; then \
|
||||||
echo "Error: $(CSV_FILE) not found!"; \
|
echo "Error: $(CSV_FILE) not found!"; \
|
||||||
exit 1; \
|
exit 1; \
|
||||||
fi
|
fi
|
||||||
python3 generate_cards.py
|
docker run --rm \
|
||||||
|
-v $(PWD):/workspace \
|
||||||
|
$(IMAGE_NAME) \
|
||||||
|
python3 generate_cards.py
|
||||||
|
|
||||||
# Build personalized front + event back side PDFs
|
# Build personalized front + event back side PDFs
|
||||||
build-personalized: generate build-image
|
build-personalized: generate build-image
|
||||||
@@ -55,7 +60,10 @@ build-personalized: generate build-image
|
|||||||
# Build blank (blanko) front + event back side PDFs (no CSV required)
|
# Build blank (blanko) front + event back side PDFs (no CSV required)
|
||||||
build-blanko: build-image
|
build-blanko: build-image
|
||||||
@echo "Generating blank card..."
|
@echo "Generating blank card..."
|
||||||
python3 generate_cards.py --blanko
|
docker run --rm \
|
||||||
|
-v $(PWD):/workspace \
|
||||||
|
$(IMAGE_NAME) \
|
||||||
|
python3 generate_cards.py --blanko
|
||||||
@echo "Compiling blank front side to PDF..."
|
@echo "Compiling blank front side to PDF..."
|
||||||
docker run --rm \
|
docker run --rm \
|
||||||
-v $(PWD):/workspace \
|
-v $(PWD):/workspace \
|
||||||
@@ -69,6 +77,24 @@ build-blanko: build-image
|
|||||||
pdflatex -interaction=nonstopmode $(TEX_FILE_BACK)
|
pdflatex -interaction=nonstopmode $(TEX_FILE_BACK)
|
||||||
@echo "PDF generated: $(PDF_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 container interactively
|
||||||
run:
|
run:
|
||||||
docker run --rm -it \
|
docker run --rm -it \
|
||||||
@@ -86,7 +112,7 @@ shell:
|
|||||||
# Clean generated files
|
# Clean generated files
|
||||||
clean:
|
clean:
|
||||||
@echo "Cleaning generated files..."
|
@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 everything including Docker image
|
||||||
clean-all: clean
|
clean-all: clean
|
||||||
@@ -106,6 +132,8 @@ help:
|
|||||||
@echo " make generate - Generate tex files from CSV + event.yml"
|
@echo " make generate - Generate tex files from CSV + event.yml"
|
||||||
@echo " make build-personalized - Generate and compile front + back side PDFs"
|
@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-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 build-back - Compile back side PDF only (after generate)"
|
||||||
@echo " make shell - Open interactive shell in container"
|
@echo " make shell - Open interactive shell in container"
|
||||||
@echo " make clean - Remove generated files (aux, log, pdf)"
|
@echo " make clean - Remove generated files (aux, log, pdf)"
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ LaTeX-basierter Generator für Audax Randonneurs Allemagne Brevetkarten mit Vord
|
|||||||
|
|
||||||
- Docker
|
- Docker
|
||||||
- Make
|
- Make
|
||||||
- Python 3 + PyYAML (`pip install pyyaml`)
|
|
||||||
|
|
||||||
## Konfigurationsdateien
|
## Konfigurationsdateien
|
||||||
|
|
||||||
@@ -68,6 +67,25 @@ Führt folgende Schritte aus:
|
|||||||
3. Erzeugt `brevetkarte-rueckseite.tex` (Rückseite mit Kontrollpunkten aus event.yml)
|
3. Erzeugt `brevetkarte-rueckseite.tex` (Rückseite mit Kontrollpunkten aus event.yml)
|
||||||
4. Kompiliert beide .tex-Dateien zu PDFs
|
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
|
||||||
|
make build-blanko
|
||||||
|
```
|
||||||
|
|
||||||
|
Erzeugt Blanko-Karten ohne Teilnehmerdaten — keine `export_brevetcard.csv` erforderlich. Sinnvoll für Nachmeldungen oder als Reservekarten vor Ort. Die Veranstaltungsdaten aus `event.yml` werden übernommen, die Teilnehmerfelder bleiben leer.
|
||||||
|
|
||||||
|
Ausgabe: `brevetkarte-blanko.pdf` (Vorderseite) + `brevetkarte-rueckseite.pdf` (Rückseite)
|
||||||
|
|
||||||
### Einzelne Schritte
|
### Einzelne Schritte
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
+17
-5
@@ -59,7 +59,7 @@ def apply_event_placeholders(text, config):
|
|||||||
return text
|
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."""
|
"""Fill back side template with cell content from event config."""
|
||||||
cells = config.get('backside', {})
|
cells = config.get('backside', {})
|
||||||
result = template
|
result = template
|
||||||
@@ -71,7 +71,18 @@ def generate_backside(template, config):
|
|||||||
if content is None:
|
if content is None:
|
||||||
content = ""
|
content = ""
|
||||||
result = result.replace(placeholder, content.strip())
|
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):
|
def generate_card_from_template(template, data):
|
||||||
@@ -142,7 +153,7 @@ def main():
|
|||||||
blanko_output_file.write_text(blanko_output, encoding='utf-8')
|
blanko_output_file.write_text(blanko_output, encoding='utf-8')
|
||||||
print(f"Generated {blanko_output_file}")
|
print(f"Generated {blanko_output_file}")
|
||||||
backside_template = backside_template_file.read_text(encoding='utf-8')
|
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')
|
backside_output_file.write_text(backside_output, encoding='utf-8')
|
||||||
print(f"Generated {backside_output_file}")
|
print(f"Generated {backside_output_file}")
|
||||||
return
|
return
|
||||||
@@ -179,10 +190,11 @@ def main():
|
|||||||
output_file.write_text(''.join(document_parts), encoding='utf-8')
|
output_file.write_text(''.join(document_parts), encoding='utf-8')
|
||||||
print(f"Generated {output_file}")
|
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}...")
|
print(f"Reading back side template from {backside_template_file}...")
|
||||||
backside_template = backside_template_file.read_text(encoding='utf-8')
|
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')
|
backside_output_file.write_text(backside_output, encoding='utf-8')
|
||||||
print(f"Generated {backside_output_file}")
|
print(f"Generated {backside_output_file}")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user