Typst Example
This document showcases Typst features and how they look in the current web template. The rendered result is shown above, and the code blocks below are the corresponding source code.
Note
This is not a comprehensive Typst tutorial. The goal is to show how various Typst elements render in this template, and to demonstrate the syntax along the way.
If you have never used Typst or any markup language before, I recommend reading the Wiki page and the resources there first.
1. Fonts and Text Styling
Here we demonstrate bold, italic, underline, strikethrough, overline, superscript E=mc2, subscript H2O. Important content can be highlighted.
Here we demonstrate *bold*, _italic_, #underline[underline], #strike[strikethrough], #overline[overline], superscript E=mc#super[2], subscript H#sub[2]O. Important content can be #highlight[highlighted].
You can create paragraphs by leaving a blank line.
This is a new paragraph. You can add a line break by appending \ at the end of a line.
This is a new line.
You can create paragraphs by leaving a blank line.
This is a new paragraph. You can add a line break by appending `\\` at the end of a line.\\
This is a new line.
Currently, #line() does not support HTML export, but you can use #html.hr() to add a horizontal divider.
To display special characters, escape them: * _ # $ @
To display special characters, escape them: \* \_ \# \$ \@
The site’s visual appearance is controlled by CSS, so you currently cannot directly change text styles in Typst, such as color, size, or font. If you want to customize them, add your own CSS rules in assets/custom.css.
You currently cannot directly change text styles in Typst, such as #text(fill: blue)[color], #text(size: 14pt)[size], or #text(font: "Liu Jian Mao Cao")[font].
2. Headings
The “Typst Example” at the top is a level-1 heading, and “2. Headings” is a level-2 heading.
Level 3
Level 4
=== Level 3
==== Level 4
3. Links
You can use #link() to add links, for example:
- This is a link to an external webpage.
- This is also an external link.
-
You can also link to other pages or resources on this site, for example:
- This links to a PDF document. You can create Typst documents that compile to PDF, such as this PDF built from
sample-PDF.typ. You can link to the compiled PDF to showcase complex formatting (e.g. a PDF version of a resume). - And this links to the CV page of this site.
- This links to a PDF document. You can create Typst documents that compile to PDF, such as this PDF built from
- #link("https://github.com/Yousa-Mirage")[This is a link to an external webpage].
- #link("https://yousa-mirage.github.io/", "This is also an external link").
- You can also link to other pages or resources on this site, for example:
- #link("../typst-example/sample-PDF.pdf")[This links to a PDF document].
- #link("/CV/")[And this links to the CV page of this site.]
4. Lists
Here is an example of mixed lists:
- Unordered item 1
-
Unordered item 2
-
Indented levels are supported
- Indent further
-
You can insert an ordered list inside an unordered list
Add a paragraph at the current nesting level
-
- Ordered item 1
-
Ordered item 2 (auto-numbered)
-
Nested ordered item A
- You can insert an unordered list inside an ordered list
- Nested unordered item B
-
- Term list
- list items with names, useful for definitions.
- Typst
- A new markup-based typesetting system.
- Unordered item 1
- Unordered item 2
- Indented levels are supported
- Indent further
+ You can insert an ordered list inside an unordered list
Add a paragraph at the current nesting level
+ Ordered item 1
+ Ordered item 2 (auto-numbered)
+ Nested ordered item A
- You can insert an unordered list inside an ordered list
- Nested unordered item B
/ Term list: list items with names, useful for definitions.
/ Typst: A new markup-based typesetting system.
5. Margin Notes, Footnotes, and Bibliography
You can add margin content anywhere.
The most distinctive feature of the Tufte style is its wide margin layout: notes, references, and figures are displayed in the margin right next to the main text, replacing traditional footnotes or endnotes. This recreates a clear, immersive, side-by-side reading experience on screens. 11 This is what the homepage of this site says.
You can use footnote() to add footnotes. They will automatically appear in the margin aligned with the main text, so readers don’t have to scroll to the end of the page. 22 Footnotes really interrupt reading! That’s also why I built this blog template with the Tufte style.
You can use `footnote()` to add footnotes. #footnote[Footnotes really interrupt reading!]
You can use tufted.margin-note() to place arbitrary unbroken margin content anywhere, e.g. an image, inline code, or inline math. 33 box() can force content to stay in a single paragraph. ⬆️ This is a duck, this is
inline code, and this is inline math .
This is a line break
// Typst code that places an image and text in the right margin.
#tufted.margin-note[
#image("../../imgs/tufted-duck-male.webp")
]
#tufted.margin-note[
⬆️ This is a duck, this is `inline code`, and this is inline math $1 + 1 = 2$.\\
This is a line break
]
You can export references as a .bib file, then use bibliography() to load it into Typst. After that, you can cite entries with @, like this: (Tufte, 1973).
By default, the bibliography is displayed at the position where bibliography() is called. The template does not yet support automatically showing the bibliography in the margin, but you can cite it manually in a footnote. 44 Tufte, E. R. (1973). The Relationship between Seats and Votes in Two-Party Systems. American Political Science Review, 67(2), 540–554. https://doi.org/10.2307/1958782
- Tufte, E. R. (1973). The Relationship between Seats and Votes in Two-Party Systems. American Political Science Review, 67(2), 540–554. https://doi.org/10.2307/1958782
Then you can cite entries with `@`, like this: @tufte1973relationship.\\
You can also cite it manually in a footnote. #footnote[Tufte, E. R. (1973). The Relationship between Seats and Votes in Two-Party Systems. _American Political Science Review, 67_(2), 540–554. https://doi.org/10.2307/1958782]
#bibliography("../typst-example/papers.bib", title: none, style: "american-psychological-association")
You can even write a for loop to manually typeset items from a .bib file:
- Tufte, Edward R., “Determinants of the Outcomes of Midterm Congressional Elections,” American Political Science Review, 1975. DOI: 10.2307/1958391
- Tufte, Edward R., “The Relationship between Seats and Votes in Two-Party Systems,” American Political Science Review, 1973. DOI: 10.2307/1958782
#import "@preview/citegeist:0.2.0": load-bibliography
#{
let bib = load-bibliography(read("../typst-example/papers.bib"))
for item in bib.values().rev() [
#let data = item.fields
- #data.author, "#data.title," #emph(data.journal), #data.year. DOI: #link(data.url)[#data.doi]
]
}
You can use tufted.full-width() to display content in full width, for example, here is a super wide MIKU:
#tufted.full-width[#image("../typst-example/miku.png")]
6. Images
You can use figure() to add a caption for any content, especially images and tables. The caption will also appear in the margin.
Use image() to insert images. You can control size with width and height. For example, figure + image:
Figure 1: Another duck.
#figure(caption: "Another duck.")[
#image("../../imgs/tufted-duck-female-with-duckling.webp", width: 250pt)
]
#image("../../imgs/gorilla.webp", height: 250pt)
7. Tables
You can use table() to create a simple table:
Table 1: A table created with the table() function
| Name | Bio | Status |
| Alice | Frontend developer, likes Rust | Online |
| Bob | Backend engineer, likes Python | Offline |
#figure(caption: [A table created with the `table()` function])[
#table(
columns: (1fr, 2fr, auto),
[*Name*], [*Bio*], [*Status*],
[Alice], [Frontend developer, likes Rust], [Online],
[Bob], [Backend engineer, likes Python], [Offline],
)
]
A nicer option is the tablem package by @OrangeX4, which builds tables from a Markdown-like table syntax:
| Name | Location | Height | Score |
|---|---|---|---|
| John | Second St. | 180 cm | 5 |
| Wally | Third Av. | 160 cm | 10 |
#import "@preview/tablem:0.3.0": *
#tablem[
| *Name* | *Location* | *Height* | *Score* |
| :----: | :--------: | :------: | :-----: |
| John | Second St. | 180 cm | 5 |
| Wally | Third Av. | 160 cm | 10 |
]
Complex custom table designs are not supported yet. Of course, you can also link a PDF or use table images.
8. Code Blocks
Wrap code with ``` to insert a code block (with syntax highlighting). Like images and tables, you can also use figure() to add a caption. I customized the code block style and added line numbers and a copy button.
Listing 1: I can write Python.
# Fibonacci function in Python
def fib(n):
if n <= 1: return n
return fib(n-1) + fib(n-2)
Listing 2: I have been learning Rust recently.
fn main() {
println!("Typst is written in Rust.");
}
The Rust code block above corresponds to the following Typst source:
#figure(caption: "I have been learning Rust recently.")[
```rs
fn main() {
println!("Typst is written in Rust.");
}
```
]
9. Alignment, Columns, and Blocks
Currently, Typst’s HTML export does not support paragraph alignment or multi-column layouts, but you can do it in PDFs. This is very useful for resumes, multi-column papers, and slide decks.
You can use the theorem package theorion by @OrangeX4 to create special block styles, for example:
This is a quote block. You can place fairly long content here. You can place fairly long content here. You can place fairly long content here. You can place fairly long content here. It supports line breaks and paragraphs, and you can even nest another quote block inside.
- A list
This is a code block.
Tip
This is a tip box.
Note
This is a note box.
Important
This is an important box.
Warning
This is a warning box.
Caution
This is also a warning box.
#import "@preview/theorion:0.4.1": *
#quote-box[
This is a quote block. You can place fairly long content here. You can place fairly long content here. You can place fairly long content here. You can place fairly long content here.
It supports line breaks and paragraphs, and you can even nest another quote block inside.
#quote-box[This is a nested quote block.]
- A list
`This is a code block.`
]
#tip-box[This is a tip box.]
#note-box[This is a note box.]
#important-box[This is an important box.]
#warning-box[This is a warning box.]
#caution-box[This is also a warning box.]
10. Math
Typst uses $ $ to typeset math. Inline math is embedded in text, written with $ immediately followed by the formula, e.g. .
For example, $f(x) = x^2$.
Block math occupies its own line. In this case there is a space between $ and the formula, e.g.
$ A = pi r^2 $
Fractions, roots, sums, and integrals:
$ integral_0^infinity e^(-x^2) d x = sqrt(pi) / 2 $
$ sum_(k=0)^n k = 1 + ... + n = (n(n+1)) / 2 $
Matrices and determinants:
$
mat(
1, 2;
3, 4
) dot vec(x, y) = vec(5, 6)
$
Multi-line aligned equations:
Figure 2: Multi-line aligned equations
#figure(caption: "Multi-line aligned equations")[
$
f(x) & = (x + 1)^2 \\
& = x^2 + 2x + 1
$
]
Very long block equations (overflowing the screen width):
For more complex formulas and symbols, see the documentation.
11. Cross References
Typst supports cross references. You can label headings, figures, code blocks, etc., and reference them elsewhere.
Link to the “1. Fonts and Text Styling” section.
Link to the Listing 1 block.
Link to the Figure 1 figure.
Link to the “7. Tables” table.
Link to the @ch1 section.\\
Link to the @code1 block.\\
Link to the @duck figure.\\
Link to the @tbl1 table.
The corresponding label syntax looks like:
== 1. Fonts and Text Styling <ch1>
#figure(caption: "I can write Python.")[
... code block ...
]<code1>
#figure(caption: "Another duck.")[
... image ...
]<duck>
#figure(caption: [A table created with the `table()` function])[
... table ...
]<tbl1>
12. Programming Features
Typst is not only a markup typesetting language, but also a programmable typesetting language:
#let name = "Typst"
#if name == "Typst" [
#for i in range(3) [
This is Typst #i!
]
] else [
This is not Typst.
]
This is Typst 0! This is Typst 1! This is Typst 2!
#show "Latex": "Typst"
I love Latex!
I love Typst!
// Custom functions are supported
#let greet(name) = [Hello, #name!]
#greet("World")\\
#greet("Yousa Mirage")
Hello, World!
Hello, Yousa Mirage!
13. Embedding Markdown
You can use cmarker to embed Markdown content in Typst documents. This is especially useful when integrating existing Markdown files into a Typst-based website. To render math expressions, use mitex. For example, the following code:
#import "@preview/cmarker:0.1.8"
#import "@preview/mitex:0.2.6": *
// This scope is required
// See https://typst.app/universe/package/cmarker#resolving-paths-correctly
#let scope = (image: (source, alt: none, format: auto) => figure(image(source, alt: alt, format: format)))
#let md-content = read("tufted-titmouse-en.md")
#cmarker.render(md-content, math: mitex, scope: scope)
will render tufted-titmouse-en.md as the following content:
The Tufted Titmouse
The tufted titmouse (Baeolophus bicolor) is a small, lively songbird native to the deciduous forests of eastern North America. Its distinctive features include a gray crest, large dark eyes, and rusty flanks. These birds are agile foragers and frequent visitors to backyard feeders. In winter, they often join mixed flocks with chickadees and nuthatches. Their clear, whistle-like call sounds like they are repeatedly singing “peter-peter-peter”.
We can use the logistic growth equation to model their population dynamics:
Where denotes the population size, is the intrinsic growth rate, and is the carrying capacity of the habitat.
tufted-titmouse-en.md rendered.