Skip to content

Configuration ​

A project file is named stoetzms-pdf.yaml by default (see the command line). It has three top-level keys:

yaml
version: 1        # optional; the only supported version
document: {...}   # required; title is the only required option
sections: [...]   # required; at least one section with a document

Unknown options are errors (with a "did you mean" hint), so a typo never silently does nothing. All paths are relative to the project file.

Several options accept a shorthand: cover: false, toc: false, bookmarks: false, page_numbering: false and divider: false mean {enabled: false}, and a document or image can be given as just its path.

document ​

OptionDefault
title— (required)Document title: cover, PDF metadata, default output name.
subtitlenoneShown on the cover.
authornoneCover and PDF metadata.
subjectnonePDF metadata.
keywords[]PDF metadata.
languageenlang of generated pages and of the PDF. de and fr also switch the default wording ("Inhaltsverzeichnis", "Abschnitt").
outputoutput/<title-as-slug>.pdfOutput file. --output overrides it.
number_sectionsfalseNumber sections (1., 2., …) in the TOC, bookmarks and dividers.
timestampfalseEmbed the build time in the PDF metadata. Off by default for reproducible output.
coverSee below.
tocSee below.
bookmarksSee below.
page_numberingSee below.
dividersDefaults for every section divider. See below.
styleSee below.
templatesSee below.

document.cover ​

The cover shows the title and, when set, everything else below.

OptionDefault
enabledtrue
titledocument.title
subtitledocument.subtitle
authordocument.author
datenoneText, a date (2026-10-11), or today (uses the build date — this makes the output change daily).
date_formatISOstrftime pattern for dates, e.g. "%d %B %Y".
logononeImage file (PNG, JPEG, SVG, …).
details[]Extra lines on the cover: a list of {label: ..., value: ...}.
accent_barfalseA short rule above the title.
templatecover.htmlTemplate name.

document.toc ​

OptionDefault
enabledtrue
title"Table of Contents"Depends on language.
include_page_numberstrue
include_document_entriestruefalse lists sections only.
max_depth21 sections, 2 + documents, 3 + subsections.
indent1.6emIndentation per level (CSS length).
leaderdotteddotted, solid, space or none.
linkstrueMake entries clickable.
templatetoc.html

The TOC grows to as many pages as it needs; page numbers account for its final length.

document.bookmarks ​

OptionDefault
enabledtrue
include_subsectionstrueBookmark configured subsections.
include_source_bookmarksfalseNest each source PDF's own bookmarks under its document. Per document: source_bookmarks.
expand_sectionstrueShow sections expanded in the viewer's bookmark panel.

Section bookmarks point to the divider, or to the first page of the first document if the section has no divider. Document bookmarks point to the document's first page.

document.page_numbering ​

OptionDefault
enabledtruePrint numbers on pages. When false, the TOC and page labels still use the numbering below.
positionbottom-centerbottom-left, bottom-center, bottom-right, top-left, top-center, top-right.
start_at1First number of the main sequence.
stylearabicarabic, lower-roman or upper-roman.
count_fromdocumentdocument: physical page 1 is start_at. content: cover and TOC are numbered separately and the first section starts at start_at.
front_matter_stylelower-romanStyle of the cover/TOC sequence with count_from: content.
format"{page}"Text to print. {page} is the page's label, {total} the last label, e.g. "Page {page} of {total}".
coverfalsePrint the number on the cover.
toctrue… on TOC pages.
dividersfalse… on divider pages.
source_documentsfalse… on source PDF pages (as an overlay; the original content is untouched).
font_familystyle.font_family
font_size9pt
colorstyle.muted_color
margin12mmDistance from the page edge to the number (mm, cm, in, pt).
page_labelstrueStore the labels in the PDF so viewers show the printed numbers.

Pages that do not show a number are still counted.

document.dividers and sections[].divider ​

document.dividers sets defaults; divider in a section overrides them.

OptionDefault
enabledtruefalse: the section starts with its first document.
titlesection titleSection level only.
subtitlenoneSection level only.
descriptionnoneSection level only.
logononeImage file.
show_numberdocument.number_sectionsShow "Section 2" above the title.
list_documentsfalseList the section's document titles on the divider.
label"Section"Word before the number; depends on language.
templatedivider.html

document.style ​

Values used by the default stylesheet. Any CSS value is accepted.

OptionDefault
page_sizeA4 (Letter, A4 landscape, 210mm 297mm, …)
margin25mm
font_familyHelvetica Neue / Helvetica / Arial / Liberation Sans / DejaVu Sans
heading_font_familyfont_family
base_font_size10.5pt
text_color#000000
muted_color#000000
accent_color#000000
rule_color#000000
cover_alignleft (center, right)
divider_alignleft (center, right)

page_size applies to generated pages only; source documents keep their own sizes.

document.templates ​

OptionDefault
directorynoneFolder searched for templates before the built-in ones.
stylesheets[]CSS files applied after the default stylesheet.

See customization.md.

sections ​

OptionDefault
title— (required)
enabledtruefalse leaves the whole section out.
dividerdefaultsSee above.
documents— (required)At least one document.

A section with no documents is an error. A section whose documents are all disabled is left out with a warning.

sections[].documents[] ​

A document is either a PDF (file: x.pdf) or images (images: [...], or file: with an image).

OptionDefault
file—Source PDF, or a single image (.png, .jpg, .jpeg, .gif, .webp, .tif, .tiff, .bmp).
images—List of images, instead of file. See below.
titlefile nameapplication-form.pdf becomes "Application form".
enabledtruefalse leaves the document out (its files are not checked).
subsections[]Bookmarks/TOC entries inside the document: {title, page, subsections} with a 1-based page within the document. Shown in the TOC with max_depth: 3.

PDF documents only:

OptionDefault
source_bookmarksbookmarks.include_source_bookmarksNest the PDF's own bookmarks under this document.
password_envnoneName of an environment variable with the PDF's password.
allow_restrictedfalseAccept a PDF with an owner password (permission restrictions). The output is not encrypted.

Image documents only:

OptionDefault
per_page1Images per page.
columnsautomaticGrid columns. By default a portrait page is filled top to bottom (2 → 1×2, 4 → 2×2, 6 → 2×3, 9 → 3×3) and a landscape page left to right.
show_titletruePrint the document title above the images on each page.
page_sizestyle.page_sizePage size for these pages, e.g. A4 landscape.

Including the same file twice produces a warning.

Image documents ​

yaml
documents:
  - documents/scan.jpg              # one image, one page
  - title: "Identity Card"
    per_page: 2
    images:
      - file: documents/id-front.jpg
        title: "Front"              # caption under the image
      - documents/id-back.jpg       # no caption

Each item of images is a path or {file, title}; title is printed as a caption under the image. Images are laid out in a grid, in order, filling per_page cells per page; the last page may be partly empty. Each image is scaled to fit its cell with its proportions kept, and never enlarged beyond 96 dpi, so small images stay sharp. The camera orientation stored in a JPEG (EXIF) is applied, so phone photos appear upright.

Images are embedded as they are (JPEG data is not re-compressed), so a document with many full-resolution photos produces a large PDF; scale them down beforehand if size matters.

Image pages are generated pages: they use the document's margins and fonts, and show page numbers when page_numbering.source_documents is on. The layout comes from the images.html template (see customization). A missing, damaged or unsupported image is an error that names the image's line in the project file.