Skip to main content

FAQ

Frequently asked questions about Touying.

Background and Colors

How do I change the slide background color?

Use config-page(fill: ...) inside your theme setup:

#import "@preview/touying:0.6.3": *
#import themes.simple: *

#show: simple-theme.with(
aspect-ratio: "16-9",
config-page(fill: rgb("#f0f4f8")),
)

= Title

== First Slide

Hello, Touying!
Touying example output

For single-page slides, use config-common(fill: ...):

#import "@preview/touying:0.6.3": *
#import themes.simple: *

#show: simple-theme.with(aspect-ratio: "16-9")

= Title

== First Slide

#slide(config: config-page(fill: gray))[
Hello, Touying!
]
Touying example output

How do I add a background image to my slides?

Pass an image(...) call to config-page(background: ...):

#import "@preview/touying:0.6.3": *
#import themes.simple: *

#show: simple-theme.with(
aspect-ratio: "16-9",
config-page(
background: rect(width: 100%, height: 100%, fill: gradient.linear(blue.lighten(80%), purple.lighten(80%))),
),
)

= Title

== Gradient Background Slide

Content appears over the background.
Touying example output

For single-page slides, use config-common(background: ...):

#import "@preview/touying:0.6.3": *
#import themes.simple: *
#show: simple-theme.with(aspect-ratio: "16-9")

= Title

== Gradient Background Slide

#slide(config: config-page(background: rect(width: 100%, height: 100%, fill: gradient.linear(blue.lighten(80%), purple.lighten(80%)))))[
Hello, Touying!
]
Touying example output

For a real image file you would write:

config-page(
background: image("bg.png", width: 100%, height: 100%),
)

How do I change the theme's primary color?

Use config-colors(primary: ...):

#import "@preview/touying:0.6.3": *
#import themes.metropolis: *

#show: metropolis-theme.with(
aspect-ratio: "16-9",
config-colors(primary: rgb("#d94f00")),
config-info(title: [Custom Color], author: [Author]),
)

= Section

== Slide

The header now uses the custom primary color.
Touying example output

Layout and Columns

How do I create a two-column layout?

Use slide with a composer argument to split content into columns:

#slide(composer: (1fr, 1fr))[
== Left Column

Some text on the left side.
][
== Right Column

Some text on the right side.
]
Touying example output

For unequal widths, adjust the fractions, e.g. (2fr, 1fr).

How do I use standard Typst columns inside a slide?

You can use Typst's built-in columns function directly inside slide content:

#slide[
== Two Columns with `columns`

#columns(2)[
Left side content with some text to fill the column.

#colbreak()

Right side content on the other column.
]
]
Touying example output

How do I place content at an absolute position?

Use Typst's place function for absolute positioning:

#slide[
Main slide content here.

#place(bottom + right, dx: -1em, dy: -1em)[
#rect(fill: blue.lighten(80%), inset: 0.5em)[Note]
]
]
Touying example output

How do I fit content to fill the remaining slide height or width?

Use utils.fit-to-height or utils.fit-to-width:

#slide[
#utils.fit-to-width(1fr)[
== This heading fills the slide width
]

Some content below.
]
Touying example output

Table of Contents

How do I display a table of contents?

Use components.adaptive-columns wrapping Typst's built-in outline:

#import "@preview/touying:0.6.3": *
#import themes.simple: *

#show: simple-theme.with(aspect-ratio: "16-9")

== Outline <touying:hidden>

#components.adaptive-columns(outline(title: none, indent: 1em))

= First Section

== Introduction

Hello, Touying!

= Second Section

== Details

More content here.
Touying example output

The <touying:hidden> label hides the outline slide from the outline itself.

How do I add numbering to sections in the outline?

Use the numbly package together with #set heading(numbering: ...):

#import "@preview/touying:0.6.3": *
#import themes.simple: *
#import "@preview/numbly:0.1.0": numbly

#set heading(numbering: numbly("{1}.", default: "1.1"))

#show: simple-theme.with(aspect-ratio: "16-9")

== Outline <touying:hidden>

#components.adaptive-columns(outline(title: none, indent: 1em))

= First Section

== First Slide

= Second Section

== Second Slide
Touying example output

How do I show a progressive/highlighted outline?

Use components.progressive-outline to highlight the current section:

#import "@preview/touying:0.6.3": *
#import themes.dewdrop: *

#show: dewdrop-theme.with(aspect-ratio: "16-9")

= First Section

== Outline

#components.progressive-outline()

= Second Section

== Slide
Touying example output

Bibliography and Citations

How do I show citations as footnotes?

Pass a bibliography(...) value to config-common(show-bibliography-as-footnote: ...):

#import "@preview/touying:0.6.3": *
#import themes.simple: *

#let bib = bytes(
"@book{knuth,
title={The Art of Computer Programming},
author={Donald E. Knuth},
year={1968},
publisher={Addison-Wesley},
}",
)

#show: simple-theme.with(
aspect-ratio: "16-9",
config-common(show-bibliography-as-footnote: bibliography(bib)),
)

= Citations

== Footnote Example

This is a famous book. @knuth
Touying example output

How do I add a bibliography slide at the end?

Use magic.bibliography(...) to display a references slide:

#import "@preview/touying:0.6.3": *
#import themes.simple: *

#let bib = bytes(
"@book{knuth,
title={The Art of Computer Programming},
author={Donald E. Knuth},
year={1968},
publisher={Addison-Wesley},
}",
)

#show: simple-theme.with(
aspect-ratio: "16-9",
config-common(show-bibliography-as-footnote: bibliography(bib)),
)

= Intro

== Slide

Some cited content. @knuth

== References

#magic.bibliography(title: none)
Touying example output

Speaker Notes

How do I add speaker notes to a slide?

Use the #speaker-note[...] function anywhere in a slide:

#slide[
== My Slide

Visible content here.

#speaker-note[
- Remind the audience of the previous topic.
- Emphasize the key takeaway.
- Time check: should be at 10 min mark.
]
]
Touying example output

Speaker notes do not appear in the slide output by default.

How do I show speaker notes on a second screen?

Use config-common(show-notes-on-second-screen: right) to show notes beside the slides:

#show: simple-theme.with(
aspect-ratio: "16-9",
config-common(show-notes-on-second-screen: right),
)

This is compatible with presenter tools like pdfpc and pympress.

How do I use Touying with pdfpc?

Export your slides to PDF with typst compile slides.typ and run:

pdfpc slides.pdf

pdfpc reads the notes metadata embedded by Touying automatically. For more details, see the pdfpc integration guide.

How do I use Touying with pympress?

Export to PDF and open with pympress:

pympress slides.pdf

pympress also reads embedded speaker notes. For more details, see the pympress integration guide.


Slide Numbering and Appendix

Use utils.slide-counter.display() for the current slide number and utils.last-slide-number for the total:

#import "@preview/touying:0.6.3": *
#import themes.simple: *

#show: simple-theme.with(
aspect-ratio: "16-9",
config-page(
footer: context [
#utils.slide-counter.display() / #utils.last-slide-number
],
),
)

= Section

== First Slide

The footer shows the slide number.

== Second Slide

Still counting.
Touying example output

How do I format slide numbers as "1 / 10"?

Combine utils.slide-counter.display() with utils.last-slide-number:

#import "@preview/touying:0.6.3": *
#import themes.default: *

#show: default-theme.with(
aspect-ratio: "16-9",
config-page(
footer: context align(right)[
Slide #utils.slide-counter.display() of #utils.last-slide-number
],
),
)

= Section

== First Slide

Custom numbering format in the footer.
Touying example output

How do I mark a slide as unnumbered?

Add the <touying:unnumbered> label to the heading:

= Title Slide <touying:unnumbered>

== Welcome

This slide is not counted.

== Normal Slide

This slide is counted.
Touying example output

How do I use an appendix so it doesn't affect the slide count?

Apply #show: appendix after your main content. Slides after this point do not increment the slide counter:

#import "@preview/touying:0.6.3": *
#import themes.simple: *

#show: simple-theme.with(aspect-ratio: "16-9")

= Main Content

== Introduction

This is slide 1.

== Results

This is slide 2.

#show: appendix

= Appendix

== Extra Material

This slide is in the appendix and does not increment the main counter.
Touying example output

Animations and Dynamic Content

How do I use #pause to reveal content step by step?

Place #pause between content blocks within a #slide:

#slide[
First point.

#pause

Second point revealed on click.

#pause

Third point revealed on second click.
]
Touying example output

How do I show content only on specific subslides?

Use #only("...") to show content on particular subslides, or #uncover("...") to show it while reserving its space:

#slide[
#only("1")[Shown on subslide 1 only.]
#only("2-")[Shown from subslide 2 onward.]
#uncover("3-")[Revealed on subslide 3, space reserved before.]
]
Touying example output

Why doesn't #pause work inside a context expression?

#pause uses metadata injection that does not work inside context { ... } blocks. Use the callback-style slide instead to access self.subslide:

#slide(self => {
let (uncover, only) = utils.methods(self)
[First content.]
linebreak()
uncover("2-")[Revealed on subslide 2.]
linebreak()
only("3")[Only on subslide 3.]
})
Touying example output

How do I use #pause inside a CeTZ drawing?

Use touying-reducer to wrap CeTZ canvas so Touying can animate it:

#import "@preview/cetz:0.3.4"

#let cetz-canvas = touying-reducer.with(
reduce: cetz.canvas,
cover: cetz.draw.hide.with(bounds: true),
)

#slide[
#cetz-canvas({
import cetz.draw: *
rect((0, 0), (4, 3))
(pause,)
circle((2, 1.5), radius: 1)
})
]

How do I use #pause inside a Fletcher diagram?

Use touying-reducer to wrap Fletcher diagrams:

#import "@preview/fletcher:0.5.7" as fletcher: diagram, node, edge

#let fletcher-diagram = touying-reducer.with(
reduce: fletcher.diagram,
cover: fletcher.hide,
)

#slide[
#fletcher-diagram(
node((0, 0), [A]),
edge("->"),
(pause,),
node((1, 0), [B]),
)
]

How do I show alternative content across subslides?

Use #alternatives to swap between different content versions:

#slide[
The answer is: #alternatives[42][*forty-two*][_the ultimate answer_].
]
Touying example output

How do I enable handout mode (no animations)?

Set config-common(handout: true) in your theme setup:

#show: simple-theme.with(
aspect-ratio: "16-9",
config-common(handout: true),
)

In handout mode, only the final subslide of each slide is output.


Fonts and Text

How do I change the font for my presentation?

Use a #set text(...) rule before or after your theme setup:

#import "@preview/touying:0.6.3": *
#import themes.metropolis: *

#show: metropolis-theme.with(
aspect-ratio: "16-9",
config-info(title: [Custom Font]),
)

#set text(font: "New Computer Modern", size: 22pt)

= Section

== Slide

Text now uses the custom font.
Touying example output

For math, also set the math font:

#show math.equation: set text(font: "New Computer Modern Math")

How do I change the font size globally?

Set text(size: ...) globally:

#show: simple-theme.with(aspect-ratio: "16-9")

#set text(size: 22pt)

Most themes set their own default size; your set rule overrides it.

How do I justify paragraph text?

Use #set par(justify: true):

#set par(justify: true)

#slide[
== Justified Text

#lorem(40)
]
Touying example output

Headings and Sections

How do I disable automatic section slides?

Set config-common(new-section-slide-fn: none):

#import "@preview/touying:0.6.3": *
#import themes.metropolis: *

#show: metropolis-theme.with(
aspect-ratio: "16-9",
config-common(new-section-slide-fn: none),
config-info(title: [No Auto Sections]),
)

= Section

== Slide

No automatic section slide was created for the `= Section` heading.
Touying example output

How do I hide a slide from the presentation output entirely?

Add the <touying:hidden> label to the slide heading:

== Visible Slide

This slide appears in the output.

== Hidden Slide <touying:hidden>

This slide is hidden and does not appear in the output or outline.

== Another Visible Slide

Back to normal.
Touying example output

How do I exclude a slide from the outline but still show it?

Use the <touying:unoutlined> label:

== Outline <touying:hidden>

#components.adaptive-columns(outline(title: none, indent: 1em))

= Section

== Normal Slide

Appears in the outline.

== Interstitial Slide <touying:unoutlined>

This slide shows but is not listed in the outline.

== Another Normal Slide

Also appears in the outline.
Touying example output

How do I control which heading level creates a new slide?

Use config-common(slide-level: ...). The default varies by theme:

#import "@preview/touying:0.6.3": *
#import themes.simple: *

#show: simple-theme.with(
aspect-ratio: "16-9",
config-common(slide-level: 2),
)

= Section

This text is part of the section slide.

== Subsection Slide

Each `==` heading creates a new slide.

=== Sub-subheading

Sub-subheadings do not create new slides.
Touying example output

Use config-page(header: ..., footer: ...):

#import "@preview/touying:0.6.3": *
#import themes.default: *

#show: default-theme.with(
aspect-ratio: "16-9",
config-page(
header: text(gray)[My Custom Header],
footer: context align(right, text(gray)[
Slide #utils.slide-counter.display()
]),
),
)

= Section

== Slide

Slide with a custom header and footer.
Touying example output

Miscellaneous

How do I set the presentation title, author, and date?

Use config-info(...):

#import "@preview/touying:0.6.3": *
#import themes.metropolis: *

#show: metropolis-theme.with(
aspect-ratio: "16-9",
config-info(
title: [My Presentation],
subtitle: [A Subtitle],
author: [Jane Doe],
date: datetime.today(),
institution: [My University],
),
)

#title-slide()

= Introduction

== First Slide

Content here.
Touying example output

How do I override the config for a single slide?

Use touying-set-config around the content you want to change:

#slide[
Normal slide.
]

#touying-set-config(config-page(fill: rgb("#fff3cd")))[
#slide[
This slide has a yellow background.
]
]

#slide[
Back to normal.
]
Touying example output

How do I compile my Touying presentation?

Touying is a pure Typst package — there is no separate build step:

typst compile slides.typ

For live preview during editing:

typst watch slides.typ

Or use the Typst Preview VS Code extension for instant in-editor preview.

How do I create a multi-file presentation?

Import lib.typ from the main entry file and use include for sections:

// main.typ
#import "@preview/touying:0.6.3": *
#import themes.simple: *

#show: simple-theme.with(aspect-ratio: "16-9")

#include "intro.typ"
#include "methods.typ"
#include "results.typ"

Each included file uses headings normally — no extra imports needed in each file.

How do I use #show: simple-theme vs #show: simple-theme.with(...)?

  • #show: simple-theme uses all defaults.
  • #show: simple-theme.with(...) lets you pass configuration arguments:
// Minimal — uses defaults
#show: simple-theme

// With configuration
#show: simple-theme.with(
aspect-ratio: "16-9",
config-info(title: [My Talk]),
config-colors(primary: blue),
)

How do I change the aspect ratio?

Pass aspect-ratio: to your theme function. Valid values are "16-9" (default for most themes) and "4-3":

#show: simple-theme.with(aspect-ratio: "4-3")

Use utils.display-current-heading(...) or utils.display-current-short-heading(...):

#import "@preview/touying:0.6.3": *
#import themes.default: *

#show: default-theme.with(
aspect-ratio: "16-9",
config-page(
header: context text(gray)[
#utils.display-current-heading(level: 1)
],
),
)

= My Section

== Slide

The header shows the current section name.
Touying example output

How do I use Touying with the pinit package for pin annotations?

Import both packages and use #pin/#pinit-highlight inside slides as normal:

#import "@preview/touying:0.6.3": *
#import "@preview/pinit:0.2.2": *
#import themes.simple: *

#show: simple-theme.with(aspect-ratio: "16-9")

#slide[
A #pin(1)key term#pin(2) to highlight.

#pinit-highlight(1, 2)
]

For animated pin reveals, use the callback-style slide so #pause interacts correctly with pinit.

How do I freeze counters (figures, equations) across subslides?

Use config-common(frozen-counters: true) to prevent counters from advancing between subslides:

#show: simple-theme.with(
config-common(frozen-counters: true),
)