PDF User Guide Generation
OWTS user documentation is also released as PDF. This page explains how we build and release those PDFs.
Overview
PDFs are generated locally by the developer using
./docs/scripts/generate_pdf.sh. They are not built in CI, because the
process relies on Playwright and a headless browser, which requires a display
environment and does not run reliably in GitLab CI.
The workflow is:
- Run
./docs/scripts/generate_pdf.shlocally before tagging a release. - Commit the generated PDFs to
docs/assets/pdf/. - Push the tag — CI uploads the PDFs and attaches them to the GitLab release.
Single-Language MkDocs Configs
We use two dedicated MkDocs configs for PDF generation:
| Config | Purpose |
|---|---|
docs/user/mkdocs.en-only.yml |
Builds only English — /print_page/ contains English content. |
docs/user/mkdocs.de-only.yml |
Builds only German — /print_page/ contains German content. |
Why not the main mkdocs.yml?
The main user docs config (docs/user/mkdocs.yml) uses mkdocs-static-i18n and
builds both languages. The mkdocs-print-site-plugin creates a single
/print_page/ that combines all pages. When building multiple languages, each
build overwrites the same path:
- First build (English) writes
/print_page/with English content. - Second build (German) writes
/print_page/again — overwriting the English version.
Because the German build runs last, /print_page/ ends up in German. There is
no way to force a specific language via URL parameter — the page is static HTML.
The single-language configs avoid this by building only one language per run.
Each run produces a correct /print_page/ for that language, which Playwright
then exports to PDF.
Why site_url: null?
The main mkdocs.yml sets:
site_url: https://docs.univ-exp.com/dev/user/
That base path is correct for the published GitLab Pages site. When MkDocs serves locally with this value, the site is rooted at that path. So the print page would be:
http://localhost:8000/
The generate_pdf.sh script (and pdf_export.py) expect the site at the root:
http://localhost:8000/print_page/
To make that work, we override site_url: null in both mkdocs.en-only.yml and
mkdocs.de-only.yml. With site_url unset, MkDocs serves at the root, so
http://localhost:8000/print_page/ is correct for PDF generation.
How to Generate PDFs
-
Ensure Playwright and its Chromium browser are installed (the script runs
uv run -m playwright install --with-deps chromium). -
Run the script:
./scripts/generate_pdf.sh -
The script will:
- Start a server with
mkdocs.en-only.yml, open/print_page/, export to PDF. - Restart the server with
mkdocs.de-only.yml, open/print_page/, export to PDF.
- Start a server with
-
Output files in
docs/assets/pdf/:OWTS_User_Guide_<version>.en.pdf— EnglishOWTS_User_Guide_<version>.de.pdf— German- Symlinks
OWTS_User_Guide.en.pdfandOWTS_Betriebsanleitung.de.pdfpointing to the versioned files.
-
Commit the PDFs before pushing a tag:
git add docs/assets/pdf/*.pdf git commit -m "Add PDF user guides for vX.Y.Z" git push origin main git tag X.Y.Z git push origin X.Y.Z
CI Release Flow
When you push a semver tag (e.g. 1.2.3), GitLab CI runs the release
stage:
| Job | What it does |
|---|---|
upload_pdfs |
Uploads OWTS_User_Guide_<tag>.en.pdf and OWTS_User_Guide_<tag>.de.pdf to the GitLab generic package registry. Fails if those files are not committed. |
release_docs |
Creates a GitLab release for the tag and adds two named download links (English and German) pointing to the uploaded PDFs. |
If the PDFs are missing, upload_pdfs will fail with:
ERROR: PDF not found: docs/assets/pdf/OWTS_User_Guide_X.Y.Z.en.pdf
Run ./scripts/generate_pdf.sh locally and commit the PDFs before tagging.
The pages job (which builds the HTML docs) runs on main and on tags, but it
does not generate PDFs. It uses the main docs/user/mkdocs.yml, which has
site_url set for the published site and does not run Playwright.
Summary
| Step | Action |
|---|---|
| 1 | Run ./scripts/generate_pdf.sh locally |
| 2 | Commit docs/assets/pdf/*.pdf |
| 3 | Push main, then create and push a semver tag |
| 4 | CI uploads PDFs and creates the release with download links |
Mermaid diagrams (dev docs)
Developer docs support Mermaid diagrams via a mermaid fenced code block. Use
this for architecture diagrams (state machines, flows, interfaces) close to the
code they describe.
Example:
stateDiagram-v2
[*] --> BootLanded
BootLanded --> Flying: "IAS >= v_en"
Flying --> LandingHoldArmed: "Burst_end"
LandingHoldArmed --> LandedConfirmed: "IAS < v_en for landing_hold_s"
LandedConfirmed --> Flying: "IAS >= v_en"
Reference:
Material for MkDocs diagrams.