---
obj: concept
website: https://typst.app
repo: https://github.com/typst/typst
rev: 2024-04-30
---

# Typst
Typst is a innovative tool that simplifies document writing by using familiar programming constructs instead of complex macros.

## Language
### Syntax
Typst is a markup language. This means that you can use simple syntax to accomplish common layout tasks. The lightweight markup syntax is complemented by set and show rules, which let you style your document easily and automatically. All this is backed by a tightly integrated scripting language with built-in and user-defined functions.

#### Modes
Typst has three syntactical modes: Markup, math, and code. Markup mode is the default in a Typst document, math mode lets you write mathematical formulas, and code mode lets you use Typst's scripting features.

You can switch to a specific mode at any point by referring to the following table:

| New Mode | Syntax                        | Example                       |
| -------- | ----------------------------- | ----------------------------- |
| Code     | Prefix the code with `#`      | `Number: #(1 + 2)`            |
| Math     | Surround equation with `$..$` | `$-x$ is the opposite of $x$` |
| Markup   | Surround markup with `[..]`   | `let name = [*Typst!*]`       |

Once you have entered code mode with `#`, you don't need to use further hashes unless you switched back to markup or math mode in between.

#### Markup
Typst provides built-in markup for the most common document elements. Most of the syntax elements are just shortcuts for a corresponding function. The table below lists all markup that is available and links to the best place to learn more about their syntax and usage.

| Name             | Example                |
| ---------------- | ---------------------- |
| Paragraph break  | Blank line             |
| Strong emphasis  | `*strong*`             |
| Emphasis         | `_emphasis_`           |
| Raw text         | `` `print(1)` ``       |
| Link             | `https://typst.app/`   |
| Label            | `<intro>`              |
| Reference        | `@intro`               |
| Heading          | `= Heading`            |
| Bullet list      | `- item`               |
| Numbered list    | `+ item`               |
| Term list        | `/ Term: description`  |
| Math             | `$x^2$`                |
| Line break       | `\`                    |
| Smart quote      | `'single' or "double"` |
| Symbol shorthand | `~, ---`               |
| Code expression  | `#rect(width: 1cm)`    |
| Character escape | `Tweet at us \#ad`     |
| Comment          | `/* block */, // line` |

#### Math mode
Math mode is a special markup mode that is used to typeset mathematical formulas. It is entered by wrapping an equation in `$` characters. The equation will be typeset into its own block if it starts and ends with at least one space (e.g. `$ x^2 $`). Inline math can be produced by omitting the whitespace (e.g. `$x^2$`). An overview over the syntax specific to math mode follows:

| Name                   | Example               |
| ---------------------- | --------------------- |
| Inline math            | `$x^2$`               |
| Block-level math       | `$ x^2 $`             |
| Bottom attachment      | `$x_1$`               |
| Top attachment         | `$x^2$`               |
| Fraction               | `$1 + (a+b)/5$`       |
| Line break             | `$x \ y$`             |
| Alignment point        | `$x &= 2 \ &= 3$`     |
| Variable access        | `$#x$, $pi$`          |
| Field access           | `$arrow.r.long$`      |
| Implied multiplication | `$x y$`               |
| Symbol shorthand       | `$->, !=$`            |
| Text/string in math    | `$a "is natural"$`    |
| Math function call     | `$floor(x)$`          |
| Code expression        | `$#rect(width: 1cm)$` |
| Character escape       | `$x\^2$`              |
| Comment                | `$/* comment */$`     |

#### Code mode

Within code blocks and expressions, new expressions can start without a leading `#` character. Many syntactic elements are specific to expressions. Below is a table listing all syntax that is available in code mode:

| Name                     | Example                     |
| ------------------------ | --------------------------- |
| Variable access          | `x`                         |
| Any literal              | `1pt, "hey"`                |
| Code block               | `{ let x = 1; x + 2 }`      |
| Content block            | `[*Hello*]`                 |
| Parenthesized expression | `(1 + 2)`                   |
| Array                    | `(1, 2, 3)`                 |
| Dictionary               | `(a: "hi", b: 2)`           |
| Unary operator           | `-x`                        |
| Binary operator          | `x + y`                     |
| Assignment               | `x = 1`                     |
| Field access             | `x.y`                       |
| Method call              | `x.flatten()`               |
| Function call            | `min(x, y)`                 |
| Argument spreading       | `min(..nums)`               |
| Unnamed function         | `(x, y) => x + y`           |
| Let binding              | `let x = 1`                 |
| Named function           | `let f(x) = 2 * x`          |
| Set rule                 | `set text(14pt)`            |
| Set-if rule              | `set text(..) if ..`        |
| Show-set rule            | `show par: set block(..)`   |
| Show rule with function  | `show raw: it => {..}`      |
| Show-everything rule     | `show: columns.with(2)`     |
| Context expression       | `context text.lang`         |
| Conditional              | `if x == 1 {..} else {..}`  |
| For loop                 | `for x in (1, 2, 3) {..}`   |
| While loop               | `while x < 10 {..}`         |
| Loop control flow        | `break, continue`           |
| Return from function     | `return x`                  |
| Include module           | `include "bar.typ"`         |
| Import module            | `import "bar.typ"`          |
| Import items from module | `import "bar.typ": a, b, c` |
| Comment                  | `/* block */, // line`      |

#### Comments
Comments are ignored by Typst and will not be included in the output. This is useful to exclude old versions or to add annotations. To comment out a single line, start it with `//`:

```
// our data barely supports
// this claim

We show with $p < 0.05$
that the difference is
significant.
```

Comments can also be wrapped between `/*` and `*/`. In this case, the comment can span over multiple lines:
```
Our study design is as follows:
/* Somebody write this up:
   - 1000 participants.
   - 2x2 data design. */
```

#### Escape sequences
Escape sequences are used to insert special characters that are hard to type or otherwise have special meaning in Typst. To escape a character, precede it with a backslash. To insert any [Unicode](../files/Unicode.md) codepoint, you can write a hexadecimal escape sequence: `\u{1f600}`. The same kind of escape sequences also work in strings.

### Styling
Typst includes a flexible styling system that automatically applies styling of your choice to your document. With _set rules,_ you can configure basic properties of elements. This way, you create most common styles. However, there might not be a built-in property for everything you wish to do. For this reason, Typst further supports _show rules_ that can completely redefine the appearance of elements.

#### Set rules
With set rules, you can customize the appearance of elements. They are written as a function call to an [element function](https://typst.app/docs/reference/foundations/function/#element-functions) preceded by the `set` keyword (or `#set` in markup). Only optional parameters of that function can be provided to the set rule. Refer to each function's documentation to see which parameters are optional. In the example below, we use two set rules to change the font family and heading numbering.

```
#set heading(numbering: "I.")
#set text(
  font: "New Computer Modern"
)

= Introduction
With set rules, you can style
your document.
```

A top level set rule stays in effect until the end of the file. When nested inside of a block, it is only in effect until the end of that block. With a block, you can thus restrict the effect of a rule to a particular segment of your document. Below, we use a content block to scope the list styling to one particular list.

```
This list is affected: #[
  #set list(marker: [--])
  - Dash
]

This one is not:
- Bullet
```

Sometimes, you'll want to apply a set rule conditionally. For this, you can use a _set-if_ rule.

```
#let task(body, critical: false) = {
  set text(red) if critical
  [- #body]
}

#task(critical: true)[Food today?]
#task(critical: false)[Work deadline]
```

#### Show rules
With show rules, you can deeply customize the look of a type of element. The most basic form of show rule is a _show-set rule._ Such a rule is written as the `show` keyword followed by a [selector](https://typst.app/docs/reference/foundations/selector/ "selector"), a colon and then a set rule. The most basic form of selector is an [element function](https://typst.app/docs/reference/foundations/function/#element-functions). This lets the set rule only apply to the selected element. In the example below, headings become dark blue while all other text stays black.

```
#show heading: set text(navy)

= This is navy-blue
But this stays black.
```

With show-set rules you can mix and match properties from different functions to achieve many different effects. But they still limit you to what is predefined in Typst. For maximum flexibility, you can instead write a show rule that defines how to format an element from scratch. To write such a show rule, replace the set rule after the colon with an arbitrary function. This function receives the element in question and can return arbitrary content. The available [fields](https://typst.app/docs/reference/scripting/#fields) on the element passed to the function again match the parameters of the respective element function. Below, we define a show rule that formats headings for a fantasy encyclopedia.

```
#set heading(numbering: "(I)")
#show heading: it => [
  #set align(center)
  #set text(font: "Inria Serif")
  \~ #emph(it.body)
     #counter(heading).display(
       it.numbering
     ) \~
]

= Dragon
With a base health of 15, the
dragon is the most powerful
creature.

= Manticore
While less powerful than the
dragon, the manticore gets
extra style points.
```

Like set rules, show rules are in effect until the end of the current block or file.

Instead of a function, the right-hand side of a show rule can also take a literal string or content block that should be directly substituted for the element. And apart from a function, the left-hand side of a show rule can also take a number of other _selectors_ that define what to apply the transformation to:

- **Everything:** `show: rest => ..`  
    Transform everything after the show rule. This is useful to apply a more complex layout to your whole document without wrapping everything in a giant function call.
    
- **Text:** `show "Text": ..`  
    Style, transform or replace text.
    
- **Regex:** `show regex("\w+"): ..`  
    Select and transform text with a [regular expression](Regex.md) for even more flexibility. See the documentation of the [`regex` type](https://typst.app/docs/reference/foundations/regex/) for details.
    
- **Function with fields:** `show heading.where(level: 1): ..`  
    Transform only elements that have the specified fields. For example, you might want to only change the style of level-1 headings.
    
- **Label:** `show <intro>: ..`  
    Select and transform elements that have the specified label. See the documentation of the [`label` type](https://typst.app/docs/reference/foundations/label/) for more details.
    

```
#show "Project": smallcaps
#show "badly": "great"

We started Project in 2019
and are still working on it.
Project is progressing badly.
```

### Scripting
Typst embeds a powerful scripting language. You can automate your documents and create more sophisticated styles with code. Below is an overview over the scripting concepts.

#### Expressions
In Typst, markup and code are fused into one. All but the most common elements are created with functions. To make this as convenient as possible, Typst provides compact syntax to embed a code expression into markup: An expression is introduced with a hash (#) and normal markup parsing resumes after the expression is finished. If a character would continue the expression but should be interpreted as text, the expression can forcibly be ended with a semicolon (`;`).

```
#emph[Hello] \
#emoji.face \
#"hello".len()
```

#### Blocks
To structure your code and embed markup into it, Typst provides two kinds of _blocks:_

- **Code block:** `{ let x = 1; x + 2 }`  
    When writing code, you'll probably want to split up your computation into multiple statements, create some intermediate variables and so on. Code blocks let you write multiple expressions where one is expected. The individual expressions in a code block should be separated by line breaks or semicolons. The output values of the individual expressions in a code block are joined to determine the block's value. Expressions without useful output, like `let` bindings yield `none`, which can be joined with any value without effect.
    
- **Content block:** `[*Hey* there!]`  
    With content blocks, you can handle markup/content as a programmatic value, store it in variables and pass it to functions. Content blocks are delimited by square brackets and can contain arbitrary markup. A content block results in a value of type [content](https://typst.app/docs/reference/foundations/content/ "content"). An arbitrary number of content blocks can be passed as trailing arguments to functions. That is, `list([A], [B])` is equivalent to `list[A][B]`.
    
Content and code blocks can be nested arbitrarily. In the example below, `[hello ]` is joined with the output of `a + [ the ] + b` yielding `[hello from the *world*]`.

```
#{
  let a = [from]
  let b = [*world*]
  [hello ]
  a + [ the ] + b
}
```

#### Bindings and Destructuring
As already demonstrated above, variables can be defined with `let` bindings. The variable is assigned the value of the expression that follows the `=` sign. The assignment of a value is optional, if no value is assigned, the variable will be initialized as `none`. The `let` keyword can also be used to create a [custom named function](https://typst.app/docs/reference/foundations/function/#defining-functions). Let bindings can be accessed for the rest of the containing block or document.

```
#let name = "Typst"
This is #name's documentation.
It explains #name.

#let add(x, y) = x + y
Sum is #add(2, 3).
```

Let bindings can also be used to destructure [arrays](https://typst.app/docs/reference/foundations/array/) and [dictionaries](https://typst.app/docs/reference/foundations/dictionary/). In this case, the left-hand side of the assignment should mirror an array or dictionary. The `..` operator can be used once in the pattern to collect the remainder of the array's or dictionary's items.

```
#let (x, y) = (1, 2)
The coordinates are #x, #y.

#let (a, .., b) = (1, 2, 3, 4)
The first element is #a.
The last element is #b.

#let books = (
  Shakespeare: "Hamlet",
  Homer: "The Odyssey",
  Austen: "Persuasion",
)

#let (Austen,) = books
Austen wrote #Austen.

#let (Homer: h) = books
Homer wrote #h.

#let (Homer, ..other) = books
#for (author, title) in other [
  #author wrote #title.
]
```

You can use the underscore to discard elements in a destructuring pattern:

```
#let (_, y, _) = (1, 2, 3)
The y coordinate is #y.
```

Destructuring also work in argument lists of functions ...

```
#let left = (2, 4, 5)
#let right = (3, 2, 6)
#left.zip(right).map(
  ((a,b)) => a + b
)
```

... and on the left-hand side of normal assignments. This can be useful to swap variables among other things.

```
#{
  let a = 1
  let b = 2
  (a, b) = (b, a)
  [a = #a, b = #b]
}
```

#### Conditionals
With a conditional, you can display or compute different things depending on whether some condition is fulfilled. Typst supports `if`, `else if` and `else` expression. When the condition evaluates to `true`, the conditional yields the value resulting from the if's body, otherwise yields the value resulting from the else's body.

```
#if 1 < 2 [
  This is shown
] else [
  This is not.
]
```

Each branch can have a code or content block as its body.

- `if condition {..}`
- `if condition [..]`
- `if condition [..] else {..}`
- `if condition [..] else if condition {..} else [..]`

#### Loops
With loops, you can repeat content or compute something iteratively. Typst supports two types of loops: `for` and `while` loops. The former iterate over a specified collection whereas the latter iterate as long as a condition stays fulfilled. Just like blocks, loops _join_ the results from each iteration into one value.

In the example below, the three sentences created by the for loop join together into a single content value and the length-1 arrays in the while loop join together into one larger array.

```
#for c in "ABC" [
  #c is a letter.
]

#let n = 2
#while n < 10 {
  n = (n * 2) - 1
  (n,)
}
```

For loops can iterate over a variety of collections:

- `for value in array {..}`  
    Iterates over the items in the [array](https://typst.app/docs/reference/foundations/array/ "array"). The destructuring syntax described in [Let binding](https://typst.app/docs/reference/scripting/#bindings) can also be used here.
    
- `for pair in dict {..}`  
    Iterates over the key-value pairs of the [dictionary](https://typst.app/docs/reference/foundations/dictionary/ "dictionary"). The pairs can also be destructured by using `for (key, value) in dict {..}`. It is more efficient than `for pair in dict.pairs() {..}` because it doesn't create a temporary array of all key-value pairs.
    
- `for letter in "abc" {..}`  
    Iterates over the characters of the [string](https://typst.app/docs/reference/foundations/str/). Technically, it iterates over the grapheme clusters of the string. Most of the time, a grapheme cluster is just a single codepoint. However, a grapheme cluster could contain multiple codepoints, like a flag emoji.
    
- `for byte in bytes("😀") {..}`  
    Iterates over the [bytes](https://typst.app/docs/reference/foundations/bytes/ "bytes"), which can be converted from a [string](https://typst.app/docs/reference/foundations/str/) or [read](https://typst.app/docs/reference/data-loading/read/ "read") from a file without encoding. Each byte value is an [integer](https://typst.app/docs/reference/foundations/int/) between `0` and `255`.
    

To control the execution of the loop, Typst provides the `break` and `continue` statements. The former performs an early exit from the loop while the latter skips ahead to the next iteration of the loop.

```
#for letter in "abc nope" {
  if letter == " " {
    break
  }

  letter
}
```

The body of a loop can be a code or content block:

- `for .. in collection {..}`
- `for .. in collection [..]`
- `while condition {..}`
- `while condition [..]`

#### Fields
You can use _dot notation_ to access fields on a value. The value in question can be either:

- a [dictionary](https://typst.app/docs/reference/foundations/dictionary/ "dictionary") that has the specified key,
- a [symbol](https://typst.app/docs/reference/symbols/symbol/ "symbol") that has the specified modifier,
- a [module](https://typst.app/docs/reference/foundations/module/ "module") containing the specified definition,
- [content](https://typst.app/docs/reference/foundations/content/ "content") consisting of an element that has the specified field. The available fields match the arguments of the [element function](https://typst.app/docs/reference/foundations/function/#element-functions) that were given when the element was constructed.

```
#let dict = (greet: "Hello")
#dict.greet \
#emoji.face

#let it = [= Heading]
#it.body \
#it.depth
```

#### Methods
A _method call_ is a convenient way to call a function that is scoped to a value's [type](https://typst.app/docs/reference/foundations/type/ "type"). For example, we can call the [`str.len`](https://typst.app/docs/reference/foundations/str/#definitions-len) function in the following two equivalent ways:

```
#str.len("abc") is the same as
#"abc".len()
```

The structure of a method call is `value.method(..args)` and its equivalent full function call is `type(value).method(value, ..args)`. The documentation of each type lists it's scoped functions. You cannot currently define your own methods.

```
#let array = (1, 2, 3, 4)
#array.pop() \
#array.len() \

#("a, b, c"
    .split(", ")
    .join[ --- ])

#"abc".len() is the same as
#str.len("abc")
```

There are a few special functions that modify the value they are called on (e.g. [`array.push`](https://typst.app/docs/reference/foundations/array/#definitions-push)). These functions _must_ be called in method form. In some cases, when the method is only called for its side effect, its return value should be ignored (and not participate in joining). The canonical way to discard a value is with a let binding: `let _ = array.remove(1)`.

#### Modules
You can split up your Typst projects into multiple files called _modules._ A module can refer to the content and definitions of another module in multiple ways:

- **Including:** `include "bar.typ"`  
    Evaluates the file at the path `bar.typ` and returns the resulting [content](https://typst.app/docs/reference/foundations/content/ "content").

- **Import:** `import "bar.typ"`  
    Evaluates the file at the path `bar.typ` and inserts the resulting [module](https://typst.app/docs/reference/foundations/module/ "module") into the current scope as `bar` (filename without extension). You can use the `as` keyword to rename the imported module: `import "bar.typ" as baz`
    
- **Import items:** `import "bar.typ": a, b`  
    Evaluates the file at the path `bar.typ`, extracts the values of the variables `a` and `b` (that need to be defined in `bar.typ`, e.g. through `let` bindings) and defines them in the current file. Replacing `a, b` with `*` loads all variables defined in a module. You can use the `as` keyword to rename the individual items: `import "bar.typ": a as one, b as two`
    
Instead of a path, you can also use a [module value](https://typst.app/docs/reference/foundations/module/), as shown in the following example:

```
#import emoji: face
#face.grin
```

#### Packages
To reuse building blocks across projects, you can also create and import Typst _packages._ A package import is specified as a triple of a namespace, a name, and a version.

```
#import "@preview/example:0.1.0": add
#add(2, 7)
```

The `preview` namespace contains packages shared by the community. You can find all available community packages on [Typst Universe](https://typst.app/universe/).

If you are using Typst locally, you can also create your own system-local packages. For more details on this, see the [package repository](https://github.com/typst/packages).

#### Operators
The following table lists all available unary and binary operators with effect, arity (unary, binary) and precedence level (higher binds stronger).

| Operator | Effect                          | Arity  | Precedence |
| -------- | ------------------------------- | ------ | ---------- |
| `-`      | Negation                        | Unary  | 7          |
| `+`      | No effect (exists for symmetry) | Unary  | 7          |
| `*`      | Multiplication                  | Binary | 6          |
| `/`      | Division                        | Binary | 6          |
| `+`      | Addition                        | Binary | 5          |
| `-`      | Subtraction                     | Binary | 5          |
| `==`     | Check equality                  | Binary | 4          |
| `!=`     | Check inequality                | Binary | 4          |
| `<`      | Check less-than                 | Binary | 4          |
| `<=`     | Check less-than or equal        | Binary | 4          |
| `>`      | Check greater-than              | Binary | 4          |
| `>=`     | Check greater-than or equal     | Binary | 4          |
| `in`     | Check if in collection          | Binary | 4          |
| `not in` | Check if not in collection      | Binary | 4          |
| `not`    | Logical "not"                   | Unary  | 3          |
| `and`    | Short-circuiting logical "and"  | Binary | 3          |
| `or`     | Short-circuiting logical "or    | Binary | 2          |
| `=`      | Assignment                      | Binary | 1          |
| `+=`     | Add-Assignment                  | Binary | 1          |
| `-=`     | Subtraction-Assignment          | Binary | 1          |
| `*=`     | Multiplication-Assignment       | Binary | 1          |
| `/=`     | Division-Assignment             | Binary | 1          |

### Context
Sometimes, we want to create content that reacts to its location in the document. This could be a localized phrase that depends on the configured text language or something as simple as a heading number which prints the right value based on how many headings came before it. However, Typst code isn't directly aware of its location in the document. Some code at the beginning of the source text could yield content that ends up at the back of the document.

To produce content that is reactive to its surroundings, we must thus specifically instruct Typst: We do this with the `context` keyword, which precedes an expression and ensures that it is computed with knowledge of its environment. In return, the context expression itself ends up opaque. We cannot directly access whatever results from it in our code, precisely because it is contextual: There is no one correct result, there may be multiple results in different places of the document. For this reason, everything that depends on the contextual data must happen inside of the context expression.

Aside from explicit context expressions, context is also established implicitly in some places that are also aware of their location in the document: [Show rules](https://typst.app/docs/reference/styling/#show-rules) provide context and numberings in the outline, for instance, also provide the proper context to resolve counters.

#### Style context
With set rules, we can adjust style properties for parts or the whole of our document. We cannot access these without a known context, as they may change throughout the course of the document. When context is available, we can retrieve them simply by accessing them as fields on the respective element function.

```
#set text(lang: "de")
#context text.lang
```

As explained above, a context expression is reactive to the different environments it is placed into. In the example below, we create a single context expression, store it in the `value` variable and use it multiple times. Each use properly reacts to the current surroundings.

```
#let value = context text.lang
#value

#set text(lang: "de")
#value

#set text(lang: "fr")
#value
```

Crucially, upon creation, `value` becomes opaque [content](https://typst.app/docs/reference/foundations/content/ "content") that we cannot peek into. It can only be resolved when placed somewhere because only then the context is known. The body of a context expression may be evaluated zero, one, or multiple times, depending on how many different places it is put into.

#### Location context
Context can not only give us access to set rule values. It can also let us know _where_ in the document we currently are, relative to other elements, and absolutely on the pages. We can use this information to create very flexible interactions between different document parts. This underpins features like heading numbering, the table of contents, or page headers dependant on section headings.

Some functions like [`counter.get`](https://typst.app/docs/reference/introspection/counter/#definitions-get) implicitly access the current location. In the example below, we want to retrieve the value of the heading counter. Since it changes throughout the document, we need to first enter a context expression. Then, we use `get` to retrieve the counter's current value. This function accesses the current location from the context to resolve the counter value. Counters have multiple levels and `get` returns an array with the resolved numbers. Thus, we get the following result:

```
#set heading(numbering: "1.")

= Introduction
#lorem(5)

#context counter(heading).get()

= Background
#lorem(5)

#context counter(heading).get()
```

For more flexibility, we can also use the [`here`](https://typst.app/docs/reference/introspection/here/ "`here`") function to directly extract the current [location](https://typst.app/docs/reference/introspection/location/ "location") from the context. The example below demonstrates this:

- We first have `counter(heading).get()`, which resolves to `(2,)` as before.
- We then use the more powerful [`counter.at`](https://typst.app/docs/reference/introspection/counter/#definitions-at "`counter.at`") with [`here`](https://typst.app/docs/reference/introspection/here/ "`here`"), which in combination is equivalent to `get`, and thus get `(2,)`.
- Finally, we use `at` with a [label](https://typst.app/docs/reference/foundations/label/ "label") to retrieve the value of the counter at a _different_ location in the document, in our case that of the introduction heading. This yields `(1,)`. Typst's context system gives us time travel abilities and lets us retrieve the values of any counters and states at _any_ location in the document.

```
#set heading(numbering: "1.")

= Introduction <intro>
#lorem(5)

= Background <back>
#lorem(5)

#context [
  #counter(heading).get() \
  #counter(heading).at(here()) \
  #counter(heading).at(<intro>)
]
```

As mentioned before, we can also use context to get the physical position of elements on the pages. We do this with the [`locate`](https://typst.app/docs/reference/introspection/locate/ "`locate`") function, which works similarly to `counter.at`: It takes a location or other [selector](https://typst.app/docs/reference/foundations/selector/ "selector") that resolves to a unique element (could also be a label) and returns the position on the pages for that element.

```
Background is at: \
#context locate(<back>).position()

= Introduction <intro>
#lorem(5)
#pagebreak()

= Background <back>
#lorem(5)
```

There are other functions that make use of the location context, most prominently [`query`](https://typst.app/docs/reference/introspection/query/ "`query`"). Take a look at the [introspection](https://typst.app/docs/reference/introspection/) category for more details on those.

#### Nested contexts
Context is also accessible from within function calls nested in context blocks. In the example below, `foo` itself becomes a contextual function, just like [`to-absolute`](https://typst.app/docs/reference/layout/length/#definitions-to-absolute) is.

```
#let foo() = 1em.to-absolute()
#context {
  foo() == text.size
}
```

Context blocks can be nested. Contextual code will then always access the innermost context. The example below demonstrates this: The first `text.lang` will access the outer context block's styles and as such, it will **not** see the effect of `set text(lang: "fr")`. The nested context block around the second `text.lang`, however, starts after the set rule and will thus show its effect.

```
#set text(lang: "de")
#context [
  #set text(lang: "fr")
  #text.lang \
  #context text.lang
]
```

You might wonder why Typst ignores the French set rule when computing the first `text.lang` in the example above. The reason is that, in the general case, Typst cannot know all the styles that will apply as set rules can be applied to content after it has been constructed. Below, `text.lang` is already computed when the template function is applied. As such, it cannot possibly be aware of the language change to French in the template.

```
#let template(body) = {
  set text(lang: "fr")
  upper(body)
}

#set text(lang: "de")
#context [
  #show: template
  #text.lang \
  #context text.lang
]
```

The second `text.lang`, however, _does_ react to the language change because evaluation of its surrounding context block is deferred until the styles for it are known. This illustrates the importance of picking the right insertion point for a context to get access to precisely the right styles.

The same also holds true for the location context. Below, the first `c.display()` call will access the outer context block and will thus not see the effect of `c.update(2)` while the second `c.display()` accesses the inner context and will thus see it.

```
#let c = counter("mycounter")
#c.update(1)
#context [
  #c.update(2)
  #c.display() \
  #context c.display()
]
```

#### Compiler iterations
To resolve contextual interactions, the Typst compiler processes your document multiple times. For instance, to resolve a `locate` call, Typst first provides a placeholder position, layouts your document and then recompiles with the known position from the finished layout. The same approach is taken to resolve counters, states, and queries. In certain cases, Typst may even need more than two iterations to resolve everything. While that's sometimes a necessity, it may also be a sign of misuse of contextual functions (e.g. of [state](https://typst.app/docs/reference/introspection/state/#caution)). If Typst cannot resolve everything within five attempts, it will stop and output the warning "layout did not converge within 5 attempts."

A very careful reader might have noticed that not all of the functions presented above actually make use of the current location. While `counter(heading).get()` definitely depends on it, `counter(heading).at(<intro>)`, for instance, does not. However, it still requires context. While its value is always the same _within_ one compilation iteration, it may change over the course of multiple compiler iterations. If one could call it directly at the top level of a module, the whole module and its exports could change over the course of multiple compiler iterations, which would not be desirable.

## Library
For library reference, see the excellent [documentation](https://typst.app/docs/reference)

## Universe
Typst can be extended with packages and templates available on [Typst Universe](https://typst.app/universe)

### Plugins
- [cades](https://typst.app/universe/package/cades) - Generate QR Codes
- [showybox](https://typst.app/universe/package/showybox) - Colorful and customizable boxes for Typst
- [cheq](https://typst.app/universe/package/cheq) - Markdown checklists

### Templates
- [appreciated-letter](https://typst.app/universe/package/appreciated-letter)
- [caidan](https://typst.app/universe/package/caidan) - Menu Card
- [modern-cv](https://typst.app/universe/package/modern-cv)
- [modern-technique-report](https://typst.app/universe/package/modern-technique-report)
- [letter-pro](https://typst.app/universe/package/letter-pro)
