Showcase
Each example shows real output produced by typstgen itself, from files in the project repository. Input on the left, output on the right.
Seminar paper with citations
examples/thesis.typDetail: Seminar paper with citations →// The layout comes from the local package in packages/local/thesis/0.1.0.
// typstgen finds it through package_path in typstgen.toml.
#import "@local/thesis:0.1.0": thesis
#show: thesis.with(
kind: [Seminararbeit],
title: [Reproduzierbare Dokumente mit Typst],
subtitle: [Vom Quelltext zum archivierbaren PDF],
author: "Ada Example",
matriculation: "123456",
institution: [Example University],
department: [Fachbereich Informatik],
supervisors: ([Prof. Dr. Grace Example],),
date: datetime(year: 2026, month: 10, day: 1),
lang: "de",
chapter-pagebreak: false,
abstract: [
Diese Beispielarbeit zeigt die Vorlage `@local/thesis`: Titelblatt, Verzeichnisse,
nummerierte Formeln, Abbildungen und Tabellen, Zitate aus einer BibTeX-Datei und einen
Anhang. Inhaltlich skizziert sie, warum ein textbasierter Satz mit festem Zeitstempel zu
bitgleichen PDF-Dateien führt.
],
bibliography: bibliography("refs.bib", style: "apa"),
appendix: [
= Konfiguration
Die Arbeit wurde mit dieser `typstgen.toml` übersetzt:
#figure(
```toml
template_paths = ["templates"]
package_path = "packages"
download_packages = false
use_system_fonts = false
```,
caption: [Konfiguration des Beispielprojekts],
)
],
)
= Einleitung
Dokumente, die aus Quelltext entstehen, lassen sich wie Software behandeln: versionieren,
vergleichen und automatisch bauen. Knuth beschrieb mit dem Literate Programming bereits früh,
wie Programm und Erläuterung aus einer gemeinsamen Quelle hervorgehen @knuth1984. LaTeX hat
diesen Ansatz für wissenschaftliche Texte etabliert @lamport1994. Typst greift ihn mit einer
programmierbaren Auszeichnungssprache und inkrementeller Übersetzung neu auf @maedje2022.
Die vorliegende Arbeit fragt, unter welchen Bedingungen aus derselben Quelle stets dasselbe PDF
entsteht, und warum das für die Archivierung zählt.
= Grundlagen
== Reproduzierbarkeit
Ein Build gilt als reproduzierbar, wenn er aus derselben Quelle in jeder Umgebung bitgleiche
Ergebnisse liefert @lamb2022. Für eine Übersetzung $B$, eine Quelle $s$ und zwei Umgebungen
$e_1, e_2$ bedeutet das mit einer kryptografischen Hashfunktion $h$:
$ h(B(s, e_1)) = h(B(s, e_2)) $ <reproduzierbar>
Die Bedingung in @reproduzierbar scheitert in der Praxis an Werten, die nicht aus der Quelle stammen:
dem aktuellen Datum, zufälligen Kennungen oder Schriften, die nur auf einem Rechner installiert
sind.
== PDF/A
PDF/A ist die Norm für die Langzeitarchivierung von PDF-Dokumenten @iso19005-2. Sie verlangt
unter anderem eingebettete Schriften und Metadaten und verbietet Inhalte, die von außen
nachgeladen werden. Typst prüft diese Anforderungen bereits beim Übersetzen.
= Vorgehen
@ablauf zeigt den Weg vom Quelltext zum archivierten PDF. @einflussfaktoren ordnet jedem
Einflussfaktor die Einstellung zu, mit der typstgen ihn festlegt.
#figure(
image("figures/build-flow.svg", width: 72%),
caption: [Vom Quelltext zum archivierten PDF (erstellt mit Chartlet)],
) <ablauf>
#figure(
table(
columns: (auto, 1fr),
table.header([*Einflussfaktor*], [*Festgelegt durch*]),
[Datum und Uhrzeit], [`--creation-timestamp` bzw. `SOURCE_DATE_EPOCH`],
[Schriften], [mitgelieferte Schriften, `use_system_fonts = false`],
[Pakete], [Version im Import, `download_packages = false`],
[Vorlagen], [`template_paths` im Projekt],
),
caption: [Einflussfaktoren und ihre Festlegung],
) <einflussfaktoren>
Übersetzt wird mit einem Aufruf, der Norm und Zeitstempel festlegt:
#figure(
```sh
typstgen compile thesis.typ --config typstgen.toml \
--pdf-standard a-2b --creation-timestamp 1759276800
```,
caption: [Übersetzung als PDF/A-2b mit festem Zeitstempel],
)
= Fazit
Werden Datum, Schriften, Pakete und Vorlagen festgelegt, entsteht aus derselben Quelle dasselbe
PDF. Damit lässt sich jede archivierte Fassung später aus dem Quelltext prüfen.Open thesis.pdf · Download thesis.pdf (104.8 KiB)
Letter from a template
examples/letter.typDetail: Letter from a template →// The template is not next to this file: typstgen resolves the import
// against `template_paths` from typstgen.toml.
#import "letterhead.typ": letterhead
#show: letterhead.with(
sender: [Northwind Studio · 1 Harbour Road · Example Town],
recipient: [
Ada Example \
Example Ltd \
22 Market Street \
Example City
],
date: [14 September 2026],
subject: [Your quote request],
)
Dear Ms Example,
thank you for your enquiry. As discussed, we will set up the document
pipeline in two steps: first the templates, then the automated PDF build.
#table(
columns: (1fr, auto),
align: (left, right),
table.header([*Item*], [*Price*]),
[Letter and invoice templates], [€ 1,200],
[PDF build in CI], [€ 600],
[*Total*], [*€ 1,800*],
)
The offer is valid for 30 days. We look forward to hearing from you.
Kind regards \
Northwind StudioOpen letter.pdf · Download letter.pdf (19.2 KiB)
Bundled fonts
examples/fonts.typDetail: Bundled fonts →// Uses only the fonts that typstgen bundles, so it renders without any
// installed fonts (use_system_fonts = false in typstgen.toml).
#set page(paper: "a5", margin: 18mm)
#set text(size: 10.5pt)
= Bundled fonts
== Libertinus Serif
#text(font: "Libertinus Serif")[
The quick brown fox jumps over the lazy dog. *Bold*, _italic_, *_both_*.
]
== New Computer Modern
#text(font: "New Computer Modern")[
The quick brown fox jumps over the lazy dog. *Bold*, _italic_, *_both_*.
]
== New Computer Modern Math
$ integral_0^infinity e^(-x^2) dif x = sqrt(pi) / 2 $
== DejaVu Sans Mono
```rust
let pdf = typstgen::compile(input, &config)?;
```Open fonts.pdf · Download fonts.pdf (46.4 KiB)
Minimal document
examples/hello.typDetail: Minimal document →// The smallest input: plain Typst markup, no imports.
#set page(paper: "a5", margin: 20mm)
= Hello from typstgen
This page was compiled to PDF by the Typst engine embedded in typstgen.
No `typst` binary was installed or started.
- Headings, lists and paragraphs work as in any Typst document.
- Numbering, tables and math do too.Open hello.pdf · Download hello.pdf (18.7 KiB)
Missing import
examples/missing-import.typDetail: Missing import →// Imports a file that exists in no search root, so compilation fails.
#import "footer.typ": footer
#footererror: typst compilation failed: missing-import.typ:2:9: error: file not found (searched at /footer.typ)