typstgenv0.6.2

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.

This browser does not show PDFs inline. Use the links below.

Open thesis.pdf · Download thesis.pdf (104.8 KiB)

  • local package
  • BibTeX
  • PDF/A-2b

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 Studio

This browser does not show PDFs inline. Use the links below.

Open letter.pdf · Download letter.pdf (19.2 KiB)

  • template import
  • A4

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)?;
```

This browser does not show PDFs inline. Use the links below.

Open fonts.pdf · Download fonts.pdf (46.4 KiB)

  • fonts
  • math
  • A5

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.

This browser does not show PDFs inline. Use the links below.

Open hello.pdf · Download hello.pdf (18.7 KiB)

  • no imports
  • A5

Missing import

examples/missing-import.typDetail: Missing import →
// Imports a file that exists in no search root, so compilation fails.
#import "footer.typ": footer

#footer
error: typst compilation failed:
missing-import.typ:2:9: error: file not found (searched at /footer.typ)
  • error
  • exit code 1