How to achieve fine-grained PDF page control (A4, margins, headers) with slipst.with(handout: true)?

Context

I am using Typst with the slipst package (v0.3.0) to generate two outputs from a single source:

  • Interactive HTML slides (handout: false)
  • Static PDF handout (handout: true)

Note: This use case is common in regions where educational practice deliberately relies on both physical media (specifically A4 paper handouts) and projector-based presentations. Both output formats must maintain visual correspondence—at minimum in terms of content width—even when portions of the source file are conditionally rendered for projection output. Additionally, the PDF version must support fine-grained layout control (headers, footers, footnotes, explicit page breaks), which motivated the selection of Typst as the authoring system.

Problem

When handout: true is enabled, slipst overrides Typst’s native page composition pipeline. Directives such as #set page(paper: “a4”, margin: …, header: […]) are ignored in the generated PDF. The output defaults to slipst’s internal pagination and viewport logic, which does not match the desired A4 format, physical margins, or repeating headers.

Attempting to bypass slipst conditionally for PDF (e.g., via #show: if mode == "html" { ... } else { content => content }) breaks the visual and typographic synchronization between the HTML and PDF outputs, causing divergent line breaks and grid layouts.

What I have tried

  1. Placing #set page(…) before or after #show: slipst.with(…). Result: ignored in PDF handout mode.
  2. Conditional engine switch: #show: if mode == "html" { slipst.with(...) } else { content => content }. Result: layout and line breaks diverge between formats.
  3. Simulating headers/margins via show-fn wrapper. Result: inconsistent spacing, degraded visual fidelity, and does not address paper size or native pagination.

Question

Is it possible to finely control PDF page properties (paper size, physical margins, repeating headers/footers) while keeping slipst.with(handout: true) active?

  • Does slipst expose a parameter, state mechanism, or override pattern to inject native #set page() rules into its handout pipeline?
  • Is there a recommended single-source workflow that forces A4 dimensions and custom margins without breaking typographic synchronization between HTML and PDF?
  • Or is precise PDF page control actually incompatible with slipst’s handout architecture?

Minimal reproducible example


#let mode = "pdf"

// Attempted page configuration
#set page(
  paper: "a4",
  flipped: false,
  margin: (top: 2.5cm, bottom: 2cm, left: 1.5cm, right: 1.5cm),
  header: [#align(right)[Header Text] #line(length: 100%)]
)

#show: slipst.with(
  handout: mode == "pdf",
  width: 21cm,
  margin: 1.5cm,
)
#set par(justify: true)

= Slide 1
#lorem(80)

#pause

= Slide 2
#grid(
  columns: (1fr, 1fr),
  column-gutter: 1em,
  figure(image("img-test.png", width: 100%)),
  [#lorem(50)]
)```


Here, we can see that the attempt to apply `#set page(paper: "a4")` fails in PDF mode.
![Capture d’écran du 2026-06-03 20-17-10|690x409](upload://7QMyHsyzJ0ZXsAKVRGDNo80UIqm.jpeg)

I am the creator of slipst. Thanks for your feedback! It’s really awesome to see someone using my project and pointing out its shortcomings.

Right now, slipst’s handout is definitely lacking a lot of features, and more fine-grained customization probably isn’t possible with the current version.

I’ll take the issues and needs you’ve raised into account and make them a priority for the next version update.