A Docker image that turns a teaching task/assignment's Markdown (task.md) into a branded PDF (pandoc + LaTeX/texlive), with the styling baked in. Built from Domi's pdfbuilder-docker tooling. Output uses a blue header/footer banner style -- there is currently no title page (the TITLEPAGE* variables are passed through to pandoc but not yet wired into the LaTeX template).
# From inside your task repo (containing task.md):
docker run --rm -v "$(pwd):/task" \
-e TITLE="Feladat címe" \
-e SUBTITLE="Tárgy neve" \
-e VERSION="1.0.0" \
-e AUTHOR="Szerző neve" \
idomi27/task-pdf-builder:latest
Output: build/<TITLE>.pdf inside your task repo.
variables:
TITLE: Feladat címe
SUBTITLE: Tárgy neve
AUTHOR: Szerző neve
stages:
- generate-assets
- package-release
- release
create_pdf:
stage: generate-assets
image:
name: idomi27/task-pdf-builder:latest
entrypoint: [""]
script:
- make -f /app/Makefile pdf FILES=task.md TITLE="$TITLE" SUBTITLE="$SUBTITLE" AUTHOR="$AUTHOR" VERSION="${CI_COMMIT_TAG:-dev}"
artifacts:
paths:
- build/
create_resources_zip:
stage: package-release
image: alpine:3.22
needs:
- job: create_pdf
before_script:
- apk add --no-cache zip
script:
- mv "build/$TITLE.pdf" resources/feladat.pdf
- cd resources
- zip -r "../$CI_PROJECT_NAME.zip" .
artifacts:
paths:
- "$CI_PROJECT_NAME.zip"
create_solutions_zip:
stage: package-release
image: alpine:3.22
needs:
- job: create_pdf
before_script:
- apk add --no-cache zip
script:
- cd solution
- zip -r "../solution-$CI_PROJECT_NAME.zip" .
artifacts:
paths:
- "solution-$CI_PROJECT_NAME.zip"
create_release:
stage: release
image: registry.gitlab.com/gitlab-org/release-cli:latest
needs:
- job: create_resources_zip
- job: create_solutions_zip
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
allow_failure: true
script:
- echo "Releasing pipeline $CI_PIPELINE_IID"
release:
tag_name: "v$CI_PIPELINE_IID"
description: "$TITLE (pipeline $CI_PIPELINE_IID)"
assets:
links:
- name: "$CI_PROJECT_NAME.zip"
url: "$CI_PROJECT_URL/-/jobs/artifacts/$CI_COMMIT_REF_NAME/raw/$CI_PROJECT_NAME.zip?job=create_resources_zip"
- name: "solution-$CI_PROJECT_NAME.zip"
url: "$CI_PROJECT_URL/-/jobs/artifacts/$CI_COMMIT_REF_NAME/raw/solution-$CI_PROJECT_NAME.zip?job=create_solutions_zip"
VERSION is sourced from $CI_COMMIT_TAG (GitLab's predefined variable, only set when the pipeline was triggered by a tag push), falling back to dev otherwise -- tag the task repo (e.g. git tag v1.0.0 && git push --tags) to produce a versioned PDF/release; untagged pushes still build fine, just labeled dev. AUTHOR has no baked-in default anymore (see Environment variables below) so it's listed in variables: explicitly, same as TITLE/SUBTITLE.
allow_failure: true on the release job because the release-cli image on this GitLab instance occasionally reports a false failure even though the release is created correctly -- check the Releases tab if the job shows red.
Compared to the old pattern (image: texlive/texlive:latest-full + apt install pandoc... + git clone .../pdfbuilder-docker.git on every run): no install step, no clone, no cross-instance CI_JOB_TOKEN clone needed -- the styling is already baked into this image and pulled once from Docker Hub. Two small fixes versus the old sample CI: the resources/solutions zips are now placed at the project root (cd resources / cd solution then zip -r ../..., matching how the artifact paths are declared) and the solutions zip artifact path includes $CI_PROJECT_NAME (the old version's artifacts.paths had a hardcoded solution/solution-.zip, missing the variable).
Based on the task-cafe sample:
task.md -- the assignment text, in Markdown (this is what gets turned into the PDF)
resources/ -- what the student receives: starter files (e.g. forras.html), assets, sample images
solution/ -- the reference solution (not given to students, kept in the repo for the instructor)
.gitlab-ci.yml -- builds task.md into a PDF, then zips resources/ (+ the PDF) and solution/ separately
The CI produces three deliverables per task: the PDF assignment sheet, a <repo-name>.zip (resources + PDF, for students), and a solution-<repo-name>.zip (reference solution), plus now a GitLab Release tying both zips together per pipeline run.
FILES -- input markdown file(s) (default: task.md)TITLE -- default: FeladatSUBTITLE -- default: Frontend ProgramozásAUTHOR -- no default, empty string -- must be set explicitly per task repo (previously defaulted to a specific person's name baked into the image; removed so the image itself carries no identity)VERSION -- default: 1.0.0 for local docker run; the CI example above overrides it with the pipeline's git tag insteadTOC -- true/false, table of contentsTITLEPAGE, TITLEPAGE_TEXT_COLOR, TITLEPAGE_RULE_COLOR, TITLEPAGE_COLOR, TITLEPAGE_BACKGROUND, TITLEPAGE_LOGO -- passed through to pandoc as metadata, but not currently wired into the LaTeX template -- the output has no title page regardless of these values. Ask if you want this actually implemented.texlive/texlive:latest-full + pandoc + make + zip/unzip + the baked pdf-elements/ (LaTeX template, Lua filters, style files) and Makefile. Mount your task repo at /task; the image's own tooling lives at /app and is referenced by absolute path (via PDF_ELEMENTS=/app/pdf-elements and TEXINPUTS), so it doesn't collide with your mounted content.
Handled entirely by pandoc's own built-in highlighter (Skylighting) via --highlight-style=haddock -- fenced code blocks ( ```bash, ```dockerfile, ```yaml for docker-compose, ```php, ```dart, ```cs for C#, ```html, ```css, ```javascript, and dozens more) are highlighted automatically with no extra setup. Verified with a real build covering all of the above -- all render correctly out of the box.
pdf-elements/pdf-languages.sty is a separate, hand-rolled listings-package language definition (currently just one merged HTML/CSS/JS block) that is not referenced anywhere in the template or filters -- it's dead code left over from before the switch to pandoc's own highlighter. Since Skylighting already covers every language above (and more) better than a hand-maintained listings definition would, it's not being extended -- say the word if you actually want it wired in for some other reason and it'll get built out properly.
The VERSION file's content is used for two Docker Hub tags on every push to main: <version> and latest.
Content type
Image
Digest
sha256:cbb19abab…
Size
2.6 GB
Last updated
21 days ago
docker pull idomi27/task-pdf-builder