Touying Author
Guide Typst presentation authoring with Touying, emphasizing clean structure, repeatable configuration, and slide-safe patterns.
Quick start
- Import Touying and a theme, then apply the theme with
#show: <theme>.with(...).
- Keep configuration centralized; include slide content from separate files.
- Use headings to create slides; use
#slide for custom layouts or animations.
- Start from
examples/simple.typ for a minimal deck, or examples/default.typ for the bare theme.
Snippet from examples/simple.typ:
#import "@preview/touying:0.6.1": *
#import themes.simple: *
#show: simple-theme.with(
aspect-ratio: "16-9",
footer: [Simple slides],
)
Best practices and code structure
- Use a single entry file (e.g.,
main.typ) that applies #show and all config-* calls.
- For multi-file decks, follow the
globals.typ + main.typ + content.typ pattern; use #include for content and #import for globals to avoid circular refs.
- Docs use both
config.typ (see docs/start.md) and globals.typ (see docs/multi-file.md) for the shared config file; pick one name and use it consistently in your project.
- For large decks, move
content.typ into sections/ and include sections/content.typ (and optional sections/another-section.typ) from main.typ.
- Prefer
config-page, config-common, config-info, config-colors, config-methods, and config-store over direct set page or ad-hoc global show.
- Use headings for most slides; use
config-common(slide-level: n) to choose which heading levels create slides.
- Use
#slide only for custom layout or animation; always wrap slide functions with touying-slide-wrapper.
- For callback-style animation (
#slide(repeat: n, self => [...])), set repeat explicitly and use utils.methods(self) to access uncover, only, and alternatives.
Single-file structure
.
├── globals.typ
├── main.typ
└── content.typ
Multi-file structure
.
├── globals.typ
├── main.typ
└── sections/
├── content.typ
└── another-section.typ
Core API map (exports)
- Slides:
touying-slides, slide, touying-slide, touying-slide-wrapper, empty-slide
- Dynamics:
pause, meanwhile, uncover, only, effect, alternatives, alternatives-match, alternatives-fn, alternatives-cases
- Config:
config-common, config-page, config-info, config-colors, config-methods, config-store, default-config, touying-set-config, appendix
- Utilities:
utils.* (fit-to-height, fit-to-width, cover helpers, progress, heading helpers)
- Components:
components.side-by-side, components.adaptive-columns, components.progressive-outline, components.custom-progressive-outline
- Integrations:
touying-reducer, touying-equation, touying-mitex, speaker-note, pdfpc.*
- Recall:
touying-recall, touying-fn-wrapper
Slide structure and headings
- Use heading labels to control numbering/outline/bookmarks: use
<touying:hidden> (see docs/code-styles.md), and see docs/changelog.md for <touying:unnumbered>, <touying:unoutlined>, <touying:unbookmarked>, and <touying:skip>.
- Use
components.adaptive-columns(outline(...)) for a table of contents slide; use components.progressive-outline for progress-aware outlines.
- Use
== <touying:hidden> to insert a blank title slide and clear the previous heading context.
- Use
#pagebreak() or --- to split slides without changing headings.
- Use
#empty-slide[...] for slides without header/footer.
- Use
config-common(handout: true) to keep only the last subslide per slide in handout output.
- Use
#show: appendix to freeze last-slide counts after the main deck.
Snippet from examples/default.typ:
= Outline <touying:hidden>
#components.adaptive-columns(outline(title: none, indent: 1em))
Animations and dynamic content
- Use
#pause and #meanwhile for simple reveals; avoid using them inside context where marks are not supported.
- Use
#uncover to reserve layout space; use #only to remove layout space when hidden.
- When marks cause warnings, use callback-style slides with
repeat and utils.methods(self).
- For math animations, use
pause/meanwhile inside $ ... $; use touying-equation when you need the helper for inline equation text (you can also use #pause or #pause;).
- See
examples/example.typ for simple/complex/callback animations and equation animations.
Snippet from examples/simple.typ:
== Dynamic slide
Did you know that...
#pause
...you can see the current section at the top of the slide?
Snippet from examples/example.typ:
#slide(
repeat: 3,
self => [
#let (uncover, only, alternatives) = utils.methods(self)
At subslide #self.subslide, we can
use #uncover("2-")[`#uncover` function] for reserving space,
use #only("2-")[`#only` function] for not reserving space,
#alternatives[call `#only` multiple times \u{2717}][use `#alternatives` function #sym.checkmark] for choosing one of the alternatives.
],
)
Layout and theming
- Preserve visual consistency: new layouts, figures, tables, and drawings must reuse the document's existing fonts, colors, and typographic hierarchy (unless instructed otherwise). Internal consistency should be maintained (same function → same size and color).
- Use
composer in #slide for columns; pass (1fr, 2fr) or a custom grid function.
- Use
config-page for margin, header, footer, and background; do not use set page directly.
- Use
config-methods(cover: utils.semi-transparent-cover.with(alpha: 85%)) only when layout changes are acceptable.
- Use
config-store to stash theme-specific values for headers/footers or navigation elements.
- Use
config-common(new-section-slide-fn: none) to disable automatic section slides, or provide a custom function to replace them.
- Apply global styles either around
#show: <theme>.with(...) or via config-methods(init: ...) in a theme.
- Use
config-info(...) for title/author/date and config-common(datetime-format: ...) to control date formatting.
Snippet from examples/default.typ:
#import "@preview/touying:0.6.1": *
#import themes.default: *
#import "@preview/numbly:0.1.0": numbly
#show: default-theme.with(
aspect-ratio: "16-9",
config-common(
slide-level: 3,
zero-margin-header: false,
),
config-colors(primary: blue),
config-methods(alert: utils.alert-with-primary-color),
config-page(
header: text(gray, utils.display-current-short-heading(level: 2)),
),
)
Speaker notes and presenter tools
- Add notes with
#speaker-note[...].
- Show notes on second screen with
config-common(show-notes-on-second-screen: right) or bottom.
- Export pdfpc metadata with
enable-pdfpc: true and typst query --field value --one "<pdfpc-file>".
Use bundled docs and examples
- Read only the specific docs needed for the task; avoid loading the full docs tree.
- Read
docs/start.md and docs/intro.md for basics and import patterns.
- Read
docs/multi-file.md for multi-file layout and include patterns.
- Read
docs/layout.md and docs/sections.md for slide-level and heading behavior.
- Read
docs/code-styles.md for simple vs block style and pagination tricks.
- Read
docs/global-settings.md for global styles and config-info usage.
- Read
docs/dynamic/*.md for pause, meanwhile, cover behavior, and equation animation.
- Read
docs/themes/*.md for theme-specific APIs and defaults.
- Read
docs/external/*.md for pdfpc and Pympress usage.
- Read
docs/integration/*.md for CeTZ/Fletcher/Theorion/MiTeX integrations.
- Use
examples/*.typ as working templates for each theme.
File tree (docs and examples)
docs/
├── build-your-own-theme.md
├── changelog.md
├── code-styles.md
├── dynamic
│ ├── complex.md
│ ├── cover.md
│ ├── equation.md
│ ├── handout.md
│ ├── other.md
│ └── simple.md
├── external
│ ├── pdfpc.md
│ ├── pympress.md
│ └── typst-preview.md
├── global-settings.md
├── integration
│ ├── cetz.md
│ ├── codly.md
│ ├── fletcher.md
│ ├── mitex.md
│ ├── pinit.md
│ └── theorion.md
├── intro.md
├── layout.md
├── multi-file.md
├── progress
│ ├── counters.md
│ └── sections.md
├── sections.md
├── start.md
├── themes
│ ├── aqua.md
│ ├── custom.md
│ ├── dewdrop.md
│ ├── metropolis.md
│ ├── simple.md
│ ├── stargazer.md
│ └── university.md
└── utilities
└── fit-to.md
examples/
├── aqua-zh.typ
├── aqua.typ
├── default.typ
├── dewdrop.typ
├── example.typ
├── metropolis.typ
├── simple.typ
├── stargazer.typ
└── university.typ
1---2name: touying-author3description: Author, refactor, and troubleshoot Typst slide decks built with Touying4---56# Touying Author78Guide Typst presentation authoring with Touying, emphasizing clean structure, repeatable configuration, and slide-safe patterns.910## Quick start11- Import Touying and a theme, then apply the theme with `#show: <theme>.with(...)`.12- Keep configuration centralized; include slide content from separate files.13- Use headings to create slides; use `#slide` for custom layouts or animations.14- Start from `examples/simple.typ` for a minimal deck, or `examples/default.typ` for the bare theme.1516Snippet from `examples/simple.typ`:1718```typst19#import "@preview/touying:0.6.1": *20#import themes.simple: *2122#show: simple-theme.with(23 aspect-ratio: "16-9",24 footer: [Simple slides],25)26```2728## Best practices and code structure2930- Use a single entry file (e.g., `main.typ`) that applies `#show` and all `config-*` calls.31- For multi-file decks, follow the `globals.typ` + `main.typ` + `content.typ` pattern; use `#include` for content and `#import` for globals to avoid circular refs.32- Docs use both `config.typ` (see `docs/start.md`) and `globals.typ` (see `docs/multi-file.md`) for the shared config file; pick one name and use it consistently in your project.33- For large decks, move `content.typ` into `sections/` and include `sections/content.typ` (and optional `sections/another-section.typ`) from `main.typ`.34- Prefer `config-page`, `config-common`, `config-info`, `config-colors`, `config-methods`, and `config-store` over direct `set page` or ad-hoc global `show`.35- Use headings for most slides; use `config-common(slide-level: n)` to choose which heading levels create slides.36- Use `#slide` only for custom layout or animation; always wrap slide functions with `touying-slide-wrapper`.37- For callback-style animation (`#slide(repeat: n, self => [...])`), set `repeat` explicitly and use `utils.methods(self)` to access `uncover`, `only`, and `alternatives`.3839### Single-file structure4041```42.43├── globals.typ44├── main.typ45└── content.typ46```4748### Multi-file structure4950```51.52├── globals.typ53├── main.typ54└── sections/55 ├── content.typ56 └── another-section.typ57```5859## Core API map (exports)6061- Slides: `touying-slides`, `slide`, `touying-slide`, `touying-slide-wrapper`, `empty-slide`62- Dynamics: `pause`, `meanwhile`, `uncover`, `only`, `effect`, `alternatives`, `alternatives-match`, `alternatives-fn`, `alternatives-cases`63- Config: `config-common`, `config-page`, `config-info`, `config-colors`, `config-methods`, `config-store`, `default-config`, `touying-set-config`, `appendix`64- Utilities: `utils.*` (fit-to-height, fit-to-width, cover helpers, progress, heading helpers)65- Components: `components.side-by-side`, `components.adaptive-columns`, `components.progressive-outline`, `components.custom-progressive-outline`66- Integrations: `touying-reducer`, `touying-equation`, `touying-mitex`, `speaker-note`, `pdfpc.*`67- Recall: `touying-recall`, `touying-fn-wrapper`6869## Slide structure and headings7071- Use heading labels to control numbering/outline/bookmarks: use `<touying:hidden>` (see `docs/code-styles.md`), and see `docs/changelog.md` for `<touying:unnumbered>`, `<touying:unoutlined>`, `<touying:unbookmarked>`, and `<touying:skip>`.72- Use `components.adaptive-columns(outline(...))` for a table of contents slide; use `components.progressive-outline` for progress-aware outlines.73- Use `== <touying:hidden>` to insert a blank title slide and clear the previous heading context.74- Use `#pagebreak()` or `---` to split slides without changing headings.75- Use `#empty-slide[...]` for slides without header/footer.76- Use `config-common(handout: true)` to keep only the last subslide per slide in handout output.77- Use `#show: appendix` to freeze last-slide counts after the main deck.7879Snippet from `examples/default.typ`:8081```typst82= Outline <touying:hidden>8384#components.adaptive-columns(outline(title: none, indent: 1em))85```8687## Animations and dynamic content8889- Use `#pause` and `#meanwhile` for simple reveals; avoid using them inside `context` where marks are not supported.90- Use `#uncover` to reserve layout space; use `#only` to remove layout space when hidden.91- When marks cause warnings, use callback-style slides with `repeat` and `utils.methods(self)`.92- For math animations, use `pause`/`meanwhile` inside `$ ... $`; use `touying-equation` when you need the helper for inline equation text (you can also use `#pause` or `#pause;`).93- See `examples/example.typ` for simple/complex/callback animations and equation animations.9495Snippet from `examples/simple.typ`:9697```typst98== Dynamic slide99100Did you know that...101102#pause103104...you can see the current section at the top of the slide?105```106107Snippet from `examples/example.typ`:108```typst109#slide(110 repeat: 3,111 self => [112 #let (uncover, only, alternatives) = utils.methods(self)113114 At subslide #self.subslide, we can115116 use #uncover("2-")[`#uncover` function] for reserving space,117118 use #only("2-")[`#only` function] for not reserving space,119120 #alternatives[call `#only` multiple times \u{2717}][use `#alternatives` function #sym.checkmark] for choosing one of the alternatives.121 ],122)123```124125## Layout and theming126- Preserve visual consistency: new layouts, figures, tables, and drawings must reuse the document's existing fonts, colors, and typographic hierarchy (unless instructed otherwise). Internal consistency should be maintained (same function → same size and color).127- Use `composer` in `#slide` for columns; pass `(1fr, 2fr)` or a custom `grid` function.128- Use `config-page` for margin, header, footer, and background; do not use `set page` directly.129- Use `config-methods(cover: utils.semi-transparent-cover.with(alpha: 85%))` only when layout changes are acceptable.130- Use `config-store` to stash theme-specific values for headers/footers or navigation elements.131- Use `config-common(new-section-slide-fn: none)` to disable automatic section slides, or provide a custom function to replace them.132- Apply global styles either around `#show: <theme>.with(...)` or via `config-methods(init: ...)` in a theme.133- Use `config-info(...)` for title/author/date and `config-common(datetime-format: ...)` to control date formatting.134135Snippet from `examples/default.typ`:136137```typst138#import "@preview/touying:0.6.1": *139#import themes.default: *140141#import "@preview/numbly:0.1.0": numbly142143#show: default-theme.with(144 aspect-ratio: "16-9",145 config-common(146 slide-level: 3,147 zero-margin-header: false,148 ),149 config-colors(primary: blue),150 config-methods(alert: utils.alert-with-primary-color),151 config-page(152 header: text(gray, utils.display-current-short-heading(level: 2)),153 ),154)155```156157## Speaker notes and presenter tools158159- Add notes with `#speaker-note[...]`.160- Show notes on second screen with `config-common(show-notes-on-second-screen: right)` or `bottom`.161- Export pdfpc metadata with `enable-pdfpc: true` and `typst query --field value --one "<pdfpc-file>"`.162163## Use bundled docs and examples164165- Read only the specific docs needed for the task; avoid loading the full docs tree.166- Read `docs/start.md` and `docs/intro.md` for basics and import patterns.167- Read `docs/multi-file.md` for multi-file layout and include patterns.168- Read `docs/layout.md` and `docs/sections.md` for slide-level and heading behavior.169- Read `docs/code-styles.md` for simple vs block style and pagination tricks.170- Read `docs/global-settings.md` for global styles and `config-info` usage.171- Read `docs/dynamic/*.md` for `pause`, `meanwhile`, cover behavior, and equation animation.172- Read `docs/themes/*.md` for theme-specific APIs and defaults.173- Read `docs/external/*.md` for pdfpc and Pympress usage.174- Read `docs/integration/*.md` for CeTZ/Fletcher/Theorion/MiTeX integrations.175- Use `examples/*.typ` as working templates for each theme.176177## File tree (docs and examples)178179```180docs/181├── build-your-own-theme.md182├── changelog.md183├── code-styles.md184├── dynamic185│ ├── complex.md186│ ├── cover.md187│ ├── equation.md188│ ├── handout.md189│ ├── other.md190│ └── simple.md191├── external192│ ├── pdfpc.md193│ ├── pympress.md194│ └── typst-preview.md195├── global-settings.md196├── integration197│ ├── cetz.md198│ ├── codly.md199│ ├── fletcher.md200│ ├── mitex.md201│ ├── pinit.md202│ └── theorion.md203├── intro.md204├── layout.md205├── multi-file.md206├── progress207│ ├── counters.md208│ └── sections.md209├── sections.md210├── start.md211├── themes212│ ├── aqua.md213│ ├── custom.md214│ ├── dewdrop.md215│ ├── metropolis.md216│ ├── simple.md217│ ├── stargazer.md218│ └── university.md219└── utilities220 └── fit-to.md221222examples/223├── aqua-zh.typ224├── aqua.typ225├── default.typ226├── dewdrop.typ227├── example.typ228├── metropolis.typ229├── simple.typ230├── stargazer.typ231└── university.typ232```