Sign inSign up

idomi27/task-pdf-builder

By idomi27

•Updated 21 days ago

Image
0

317

idomi27/task-pdf-builder repository overview

⁠task-pdf-builder

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).

⁠Usage

⁠Locally
# 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.

⁠In GitLab CI
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).

⁠How a task repo is structured

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.

⁠Environment variables

  • FILES -- input markdown file(s) (default: task.md)
  • TITLE -- default: Feladat
  • SUBTITLE -- default: Frontend Programozás
  • AUTHOR -- 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 instead
  • TOC -- true/false, table of contents
  • TITLEPAGE, 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.

⁠What's in the image

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.

⁠Code block syntax highlighting

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.

⁠Versioning

The VERSION file's content is used for two Docker Hub tags on every push to main: <version> and latest.

Tag summary

Content type

Image

Digest

sha256:cbb19abab…

Size

2.6 GB

Last updated

21 days ago

docker pull idomi27/task-pdf-builder