summaryrefslogtreecommitdiff
path: root/docs/reference
diff options
context:
space:
mode:
Diffstat (limited to 'docs/reference')
-rw-r--r--docs/reference/details.yml174
-rw-r--r--docs/reference/groups.yml76
-rw-r--r--docs/reference/scripting.md345
-rw-r--r--docs/reference/styling.md145
-rw-r--r--docs/reference/syntax.md138
-rw-r--r--docs/reference/types.md1190
-rw-r--r--docs/reference/welcome.md29
7 files changed, 2097 insertions, 0 deletions
diff --git a/docs/reference/details.yml b/docs/reference/details.yml
new file mode 100644
index 00000000..8e9af3a0
--- /dev/null
+++ b/docs/reference/details.yml
@@ -0,0 +1,174 @@
+types: |
+ To style your document, you need to work with values of different kinds: Lengths
+ specifying the size of your elements, colors for your text and shapes, and more.
+ Typst categorizes these into clearly defined _types_ and tells you where it
+ expects which type of value.
+
+ Apart from very basic types for numeric values and typical types known from
+ programming languages, Typst provides a special type for _content._ A value of
+ this type can hold anything that you can enter into your document: Text,
+ elements like headings and shapes, and style information.
+
+ In some places of Typst more specialized data types are used. Instead of listing
+ all of them here, they are explained where they are relevant.
+
+text: |
+ Text styling.
+
+ The [text function]($func/text) is of particular interest.
+
+math: |
+ Typst has special [syntax]($syntax/#math) and library functions
+ to typeset mathematical formulas. Math formulas can be displayed inline with
+ text or as separate blocks. They will be typeset into their own block if they
+ start and end with at least one space (e.g. `[$ x^2 $]`).
+
+ In math, single letters are always displayed as is. Multiple letters, however,
+ are interpreted as variables and functions. To display multiple letters
+ verbatim, you can place them into quotes and to access single letter
+ variables, you can use the
+ [hashtag syntax]($scripting/#expressions).
+
+ ```example
+ $ A = pi r^2 $
+ $ "area" = pi dot "radius"^2 $
+ $ cal(A) :=
+ { x in RR | x "is natural" } $
+ #let x = 5
+ $ #x < 17 $
+ ```
+
+ Math mode makes a wide selection of [symbols]($category/symbols/sym) like
+ `pi`, `dot`, or `RR` available. Many mathematical symbols are available in
+ different variants. You can select between different variants by applying
+ [modifiers]($type/symbol) to the symbol. Typst further recognizes a number of
+ shorthand sequences like `=>` that approximate a symbol. When such a shorthand
+ exists, the symbol's documentation lists it.
+
+ ```example
+ $ x < y => x gt.eq.not y $
+ ```
+
+ Formulas can also contain line breaks. Each line can contain one or multiple
+ _alignment points_ (`&`) which are then aligned.
+ ```example
+ $ sum_(k=0)^n k
+ &= 1 + ... + n \
+ &= (n(n+1)) / 2 $
+ ```
+
+ Math mode supports special function calls without the hashtag prefix. In these
+ "math calls", the argument list works a little differently than in code:
+
+ - Within them, Typst is still in "math mode". Thus, you can write math directly
+ into them, but need to use hashtag syntax to pass code expressions (except
+ for strings, which are available in the math syntax).
+ - They support positional and named arguments, but don't support
+ trailing content blocks and argument spreading.
+ - They provide additional syntax for 2-dimensional argument lists. The
+ semicolon (`;`) merges preceding arguments separated by commas into an array
+ argument.
+
+ ```example
+ $ frac(a^2, 2) $
+ $ vec(1, 2, delim: "[") $
+ $ mat(1, 2; 3, 4) $
+ $ lim_x =
+ op("lim", limits: #true)_x $
+ ```
+
+ To write a verbatim comma or semicolon in a math call, escape it with a
+ backslash. The colon on the other hand is only recognized in a special way if
+ directly preceded by an identifier, so to display it verbatim in those cases,
+ you can just insert a space before it.
+
+ Functions calls preceded by a hashtag are normal code function calls and not
+ affected by these rules.
+
+ All math functions are part of the `math` [module]($scripting/#modules), which
+ is available by default in equations. Outside of equations, they can be
+ accessed with the `math.` prefix. For example, to set the font used for
+ equations, write:
+
+ ```example
+ #show math.equation: set text(font: "Fira Math")
+ $ sum_(i in NN) 1 + i $
+ ```
+
+layout: |
+ Arranging elements on the page in different ways.
+
+ By combining layout functions, you can create complex and automatic layouts.
+
+visualize: |
+ Drawing and data visualization.
+
+ _Note:_ Functions for plotting and diagrams are not yet available. They will
+ be in the future.
+
+meta: |
+ Document structuring, introspection, and metadata configuration.
+
+ Here, you can find functions to structure your document and interact with that
+ structure. This includes section headings and figures, bibliography
+ management, cross-referencing and more.
+
+ Moreover, this category is home to Typst's introspection capabilities: With
+ the `counter` function, you can access and manipulate page, section, figure,
+ and equation counters or create custom ones. And the `query` function lets you
+ search for elements in the document to construct things like a list of
+ figures or headers which show the current chapter title.
+
+symbols: |
+ These two modules give names to symbols and emoji to make them easy to insert
+ with a normal keyboard. Alternatively, you can also always directly enter
+ Unicode symbols into your text and formulas. In addition to the symbols listed
+ below, math mode defines `dif` and `Dif`. These are not normal symbol values
+ because they also affect spacing and font style.
+
+sym: |
+ Named general symbols.
+
+ For example, `#sym.arrow` produces the → symbol. Within
+ [formulas]($category/math), these symbols can be used without the `#sym.`
+ prefix.
+
+ The `d` in an integral's `dx` can be written as `[$dif x$]`.
+ Outside math formulas, `dif` can be accessed as `math.dif`.
+
+emoji: |
+ Named emoji.
+
+ For example, `#emoji.face` produces the 😀 emoji. If you frequently use
+ certain emojis, you can also import them from the `emoji` module (`[#import
+ emoji: face]`) to use them without the `#emoji.` prefix.
+
+foundations: |
+ Foundational functions for computation.
+
+calculate: |
+ Calculations and processing of numeric values.
+
+ These functions are part of the `calc` module and not imported by default. In
+ addition to the functions listed below, the `calc` module also defines the
+ constants `pi`, `e`, `inf`, and `nan`.
+
+construct: |
+ Construction of and conversions between values of different types.
+
+data-loading: |
+ Data loading from external files.
+
+ These functions help you with embedding data from experiments in your
+ documents.
+
+utility: |
+ Useful utility functions.
+
+packages: |
+ Typst [packages]($scripting/#packages) encapsulate reusable building blocks
+ and make them reusable across projects. Below is a list of Typst packages
+ created by the community. Due to the early and experimental nature of Typst's
+ package management, they all live in a `preview` namespace. Click on a
+ package's name to view its documentation and use the copy button on the right
+ to get a full import statement for it.
diff --git a/docs/reference/groups.yml b/docs/reference/groups.yml
new file mode 100644
index 00000000..3bc80339
--- /dev/null
+++ b/docs/reference/groups.yml
@@ -0,0 +1,76 @@
+# This is responsible for the fact that certain math functions are grouped
+# together into one documentation page although they are not part of any scope.
+
+- name: variants
+ display: Variants
+ functions: ["serif", "sans", "frak", "mono", "bb", "cal"]
+ description: |
+ Alternate typefaces within formulas.
+
+ These functions are distinct from the [`text`]($func/text) function because
+ math fonts contain multiple variants of each letter.
+
+- name: styles
+ display: Styles
+ functions: ["upright", "italic", "bold"]
+ description: |
+ Alternate letterforms within formulas.
+
+ These functions are distinct from the [`text`]($func/text) function because
+ math fonts contain multiple variants of each letter.
+
+- name: sizes
+ display: Sizes
+ functions: ["display", "inline", "script", "sscript"]
+ description: |
+ Forced size styles for expressions within formulas.
+
+ These functions allow manual configuration of the size of equation elements
+ to make them look as in a display/inline equation or as if used in a root or
+ sub/superscripts.
+
+- name: underover
+ display: Under/Over
+ functions: [
+ "underline",
+ "overline",
+ "underbrace",
+ "overbrace",
+ "underbracket",
+ "overbracket",
+ ]
+ description: |
+ Delimiters above or below parts of an equation.
+
+ The braces and brackets further allow you to add an optional annotation
+ below or above themselves.
+
+- name: roots
+ display: Roots
+ functions: ["root", "sqrt"]
+ description: Square and non-square roots.
+
+- name: attach
+ display: Attach
+ functions: ["attach", "scripts", "limits"]
+ description: |
+ Subscript, superscripts, and limits.
+
+ The `attach` function backs the `[$a_b^c$]` syntax that adds top and bottom
+ attachments to a part of an equation. Attachments can be displayed either as
+ sub/superscripts, or limits. Typst automatically decides which is more
+ suitable depending on the base, but you can also control this manually with
+ the `scripts` and `limits` functions.
+
+- name: lr
+ display: Left/Right
+ functions: ["lr", "abs", "norm", "floor", "ceil", "round"]
+ description: |
+ Delimiter matching.
+
+ The `lr` function allows you to match two delimiters and scale them with the
+ content they contain. While this also happens automatically for delimiters
+ that match syntactically, `lr` allows you to match two arbitrary delimiters
+ and control their size exactly. Apart from the `lr` function, Typst provides
+ a few more functions that create delimiter pairings for absolute, ceiled,
+ and floored values as well as norms.
diff --git a/docs/reference/scripting.md b/docs/reference/scripting.md
new file mode 100644
index 00000000..c18bdc4b
--- /dev/null
+++ b/docs/reference/scripting.md
@@ -0,0 +1,345 @@
+---
+description: Automate your document with Typst's scripting capabilities.
+---
+
+# 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 { #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 hashtag (`#`) 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
+(`;`).
+
+```example
+#emph[Hello] \
+#emoji.face \
+#"hello".len()
+```
+
+The example above shows a few of the available expressions, including
+[function calls]($type/function),
+[field accesses]($scripting/#fields), and
+[method calls]($scripting/#methods). More kinds of expressions are
+discussed in the remainder of this chapter. A few kinds of expressions are not
+compatible with the hashtag syntax (e.g. binary operator expressions). To embed
+these into markup, you can use parentheses, as in `[#(1 + 2)]`.
+
+## Blocks { #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]($type/function). Content
+ blocks are delimited by square brackets and can contain arbitrary markup. A
+ content block results in a value of type [content]($type/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*]}`.
+
+```example
+#{
+ let a = [from]
+ let b = [*world*]
+ [hello ]
+ a + [ the ] + b
+}
+```
+
+## Bindings and Destructuring { #bindings }
+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]($type/function/#definitions). Let bindings can be
+accessed for the rest of the containing block or document.
+
+```example
+#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]($type/array) and
+[dictionaries]($type/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.
+
+```example
+#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:
+
+```example
+#let (_, y, _) = (1, 2, 3)
+The y coordinate is #y.
+```
+
+Destructuring also work in argument lists of functions ...
+
+```example
+#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.
+
+```example
+#{
+ let a = 1
+ let b = 2
+ (a, b) = (b, a)
+ [a = #a, b = #b]
+}
+```
+
+## Conditionals { #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.
+
+```example
+#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 { #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.
+
+```example
+#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 letter in "abc" {..}}` \
+ Iterates over the characters of the [string]($type/string).
+ (Technically, iterates over the grapheme clusters of the string. Most of the
+ time, a grapheme cluster is just a single character/codepoint. However, some
+ constructs like flag emojis that consist of multiple codepoints are still only
+ one cluster.)
+
+- `{for value in array {..}}` \
+ Iterates over the items in the [array]($type/array). The destructuring syntax
+ described in [Let binding]($scripting/#bindings) can also be used here.
+
+- `{for pair in dict {..}}` \
+ Iterates over the key-value pairs of the [dictionary]($type/dictionary).
+ The pairs can also be destructured by using `{for (key, value) in dict {..}}`.
+
+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.
+
+```example
+#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 { #fields }
+You can use _dot notation_ to access fields on a value. The value in question
+can be either:
+- a [dictionary]($type/dictionary) that has the specified key,
+- a [symbol]($type/symbol) that has the specified modifier,
+- a [module]($type/module) containing the specified definition,
+- [content]($type/content) consisting of an element that has the specified
+ field. The available fields match the arguments of the
+ [element function]($type/function/#element-functions) that were given when
+ the element was constructed.
+
+```example
+#let dict = (greet: "Hello")
+#dict.greet \
+#emoji.face
+
+#let it = [= Heading]
+#it.body \
+#it.level
+```
+
+## Methods { #methods }
+A method is a kind of a [function]($type/function) that is tightly coupled with
+a specific type. It is called on a value of its type using the same dot notation
+that is also used for fields: `{value.method(..)}`. The
+[type documentation]($type) lists the available methods for each of the built-in
+types. You cannot define your own methods.
+
+```example
+#let array = (1, 2, 3, 4)
+#array.pop() \
+#array.len() \
+
+#("a, b, c"
+ .split(", ")
+ .join[ --- ])
+```
+
+Methods are the only functions in Typst that can modify the value they are
+called on.
+
+## Modules { #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]($type/content).
+
+- **Import:** `{import "bar.typ"}` \
+ Evaluates the file at the path `bar.typ` and inserts the resulting
+ [module]($type/module) into the current scope as `bar` (filename without
+ extension).
+
+- **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.
+
+Instead of a path, you can also use a [module value]($type/module), as shown in
+the following example:
+
+```example
+#import emoji: face
+#face.grin
+```
+
+## Packages { #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.
+
+```example
+>>> #let add(x, y) = x + y
+<<< #import "@preview/example:0.1.0": add
+#add(2, 7)
+```
+
+The `preview` namespace contains packages shared by the community. You can find
+a searchable list of available community packages in the [packages]($packages)
+section.
+
+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 { #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 |
+
+[semver]: https://semver.org/
diff --git a/docs/reference/styling.md b/docs/reference/styling.md
new file mode 100644
index 00000000..85095e34
--- /dev/null
+++ b/docs/reference/styling.md
@@ -0,0 +1,145 @@
+---
+description: All concepts needed to style your document with Typst.
+---
+
+# 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 { #set-rules }
+With set rules, you can customize the appearance of elements. They are written
+as a [function call]($type/function) to an
+[element function]($type/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]($func/text.font) and
+[heading numbering]($func/heading.numbering).
+
+```example
+#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.
+
+```example
+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.
+
+```example
+#let task(body, critical: false) = {
+ set text(red) if critical
+ [- #body]
+}
+
+#task(critical: true)[Food today?]
+#task(critical: false)[Work deadline]
+```
+
+## Show rules { #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]($type/selector), a colon and then a set rule. The most basic form of selector is an
+[element function]($type/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.
+
+```example
+#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 behind the colon with an arbitrary
+[function]($type/function). This function receives the element in question and
+can return arbitrary content. Different
+[fields]($scripting/#fields) are available on the element passed
+to the function. Below, we define a show rule that formats headings for a
+fantasy encyclopedia.
+
+```example
+#set heading(numbering: "(I)")
+#show heading: it => block[
+ #set align(center)
+ #set text(font: "Inria Serif")
+ \~ #emph(it.body)
+ #counter(heading).display() \~
+]
+
+= 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 for even more flexibility.
+ See the documentation of the [`regex` function]($func/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` function]($func/label) for more details.
+
+```example
+#show "Project": smallcaps
+#show "badly": "great"
+
+We started Project in 2019
+and are still working on it.
+Project is progressing badly.
+```
diff --git a/docs/reference/syntax.md b/docs/reference/syntax.md
new file mode 100644
index 00000000..d0cd80d7
--- /dev/null
+++ b/docs/reference/syntax.md
@@ -0,0 +1,138 @@
+---
+description: |
+ A compact reference for Typst's syntax. Learn more about the language within
+ markup, math, and code mode.
+---
+
+# 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.
+
+## Markup { #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 | See |
+| ------------------ | ------------------------ | ---------------------------- |
+| Paragraph break | Blank line | [`parbreak`]($func/parbreak) |
+| Strong emphasis | `[*strong*]` | [`strong`]($func/strong) |
+| Emphasis | `[_emphasis_]` | [`emph`]($func/emph) |
+| Raw text | ``[`print(1)`]`` | [`raw`]($func/raw) |
+| Link | `[https://typst.app/]` | [`link`]($func/link) |
+| Label | `[<intro>]` | [`label`]($func/label) |
+| Reference | `[@intro]` | [`ref`]($func/ref) |
+| Heading | `[= Heading]` | [`heading`]($func/heading) |
+| Bullet list | `[- item]` | [`list`]($func/list) |
+| Numbered list | `[+ item]` | [`enum`]($func/enum) |
+| Term list | `[/ Term: description]` | [`terms`]($func/terms) |
+| Math | `[$x^2$]` | [Math]($category/math) |
+| Line break | `[\]` | [`linebreak`]($func/linebreak) |
+| Smart quote | `['single' or "double"]` | [`smartquote`]($func/smartquote) |
+| Symbol shorthand | `[~, ---]` | [Symbols]($category/symbols/sym) |
+| Code expression | `[#rect(width: 1cm)]` | [Scripting]($scripting/#expressions) |
+| Character escape | `[Tweet at us \#ad]` | [Below](#escapes) |
+| Comment | `[/* block */, // line]` | [Below](#comments) |
+
+## Math mode { #math }
+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 | See |
+| ---------------------- | ------------------------ | ------------------------ |
+| Inline math | `[$x^2$]` | [Math]($category/math) |
+| Block-level math | `[$ x^2 $]` | [Math]($category/math) |
+| Bottom attachment | `[$x_1$]` | [`attach`]($category/math/attach) |
+| Top attachment | `[$x^2$]` | [`attach`]($category/math/attach) |
+| Fraction | `[$1 + (a+b)/5$]` | [`frac`]($func/math.frac) |
+| Line break | `[$x \ y$]` | [`linebreak`]($func/linebreak) |
+| Alignment point | `[$x &= 2 \ &= 3$]` | [Math]($category/math) |
+| Variable access | `[$#x$, $pi$]` | [Math]($category/math) |
+| Field access | `[$arrow.r.long$]` | [Scripting]($scripting/#fields) |
+| Implied multiplication | `[$x y$]` | [Math]($category/math) |
+| Symbol shorthand | `[$->, !=$]` | [Symbols]($category/symbols/sym) |
+| Text/string in math | `[$a "is natural"$]` | [Math]($category/math) |
+| Math function call | `[$floor(x)$]` | [Math]($category/math) |
+| Code expression | `[$#rect(width: 1cm)$]` | [Scripting]($scripting/#expressions) |
+| Character escape | `[$x\^2$]` | [Below](#escapes) |
+| Comment | `[$/* comment */$]` | [Below](#comments) |
+
+## Code mode { #code }
+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 | See |
+| ------------------------ | ----------------------------- | ---------------------------------- |
+| Variable access | `{x}` | [Scripting]($scripting/#blocks) |
+| Any literal | `{1pt, "hey"}` | [Types]($types) |
+| Code block | `{{ let x = 1; x + 2 }}` | [Scripting]($scripting/#blocks) |
+| Content block | `{[*Hello*]}` | [Scripting]($scripting/#blocks) |
+| Parenthesized expression | `{(1 + 2)}` | [Scripting]($scripting/#blocks) |
+| Array | `{(1, 2, 3)}` | [Array]($type/array) |
+| Dictionary | `{(a: "hi", b: 2)}` | [Dictionary]($type/dictionary) |
+| Unary operator | `{-x}` | [Scripting]($scripting/#operators) |
+| Binary operator | `{x + y}` | [Scripting]($scripting/#operators) |
+| Assignment | `{x = 1}` | [Scripting]($scripting/#operators) |
+| Field access | `{x.y}` | [Scripting]($scripting/#fields) |
+| Method call | `{x.flatten()}` | [Scripting]($scripting/#methods) |
+| Function call | `{min(x, y)}` | [Function]($type/function) |
+| Unnamed function | `{(x, y) => x + y}` | [Function]($type/function) |
+| Let binding | `{let x = 1}` | [Scripting]($scripting/#bindings) |
+| Named function | `{let f(x) = 2 * x}` | [Function]($type/function) |
+| Set rule | `{set text(14pt)}` | [Styling]($styling/#set-rules) |
+| Set-if rule | `{set text(..) if .. }` | [Styling]($styling/#set-rules) |
+| Show-set rule | `{show par: set block(..)}` | [Styling]($styling/#show-rules) |
+| Show rule with function | `{show raw: it => {..}}` | [Styling]($styling/#show-rules) |
+| Show-everything rule | `{show: columns.with(2)}` | [Styling]($styling/#show-rules) |
+| Conditional | `{if x == 1 {..} else {..}}` | [Scripting]($scripting/#conditionals) |
+| For loop | `{for x in (1, 2, 3) {..}}` | [Scripting]($scripting/#loops) |
+| While loop | `{while x < 10 {..}}` | [Scripting]($scripting/#loops) |
+| Loop control flow | `{break, continue}` | [Scripting]($scripting/#loops) |
+| Return from function | `{return x}` | [Function]($type/function) |
+| Include module | `{include "bar.typ"}` | [Scripting]($scripting/#modules) |
+| Import module | `{import "bar.typ"}` | [Scripting]($scripting/#modules) |
+| Import items from module | `{import "bar.typ": a, b, c}` | [Scripting]($scripting/#modules) |
+| Comment | `[/* block */, // line]` | [Below](#comments) |
+
+## Comments { #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 `//`:
+```example
+// 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:
+```example
+Our study design is as follows:
+/* Somebody write this up:
+ - 1000 participants.
+ - 2x2 data design. */
+```
+
+## Escape sequences { #escapes }
+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 codepoint, you can write a hexadecimal
+escape sequence: `[\u{1f600}]`. The same kind of escape sequences also work in
+[strings]($type/string).
+
+```example
+I got an ice cream for
+\$1.50! \u{1f600}
+```
diff --git a/docs/reference/types.md b/docs/reference/types.md
new file mode 100644
index 00000000..3e08d670
--- /dev/null
+++ b/docs/reference/types.md
@@ -0,0 +1,1190 @@
+# None
+A value that indicates the absence of any other value.
+
+The none type has exactly one value: `{none}`.
+
+When inserted into the document, it is not visible.
+This is also the value that is produced by empty code blocks.
+It can be [joined]($scripting/#blocks) with any value, yielding
+the other value.
+
+## Example
+```example
+Not visible: #none
+```
+
+# Auto
+A value that indicates a smart default.
+
+The auto type has exactly one value: `{auto}`.
+
+Parameters that support the `{auto}` value have some smart default or contextual
+behaviour. A good example is the [text direction]($func/text.dir) parameter.
+Setting it to `{auto}` lets Typst automatically determine the direction from the
+[text language]($func/text.lang).
+
+# Boolean
+Either `{true}` or `{false}`.
+
+The boolean type has two values: `{true}` and `{false}`. It denotes whether
+something is active or enabled.
+
+## Example
+```example
+#false \
+#true \
+#(1 < 2)
+```
+
+# Integer
+A whole number.
+
+The number can be negative, zero, or positive. As Typst uses 64 bits to store
+integers, integers cannot be smaller than `{-9223372036854775808}` or larger than
+`{9223372036854775807}`.
+
+The number can also be specified as hexadecimal, octal, or binary by starting it
+with a zero followed by either `x`, `o`, or `b`.
+
+## Example
+```example
+#(1 + 2) \
+#(2 - 5) \
+#(3 + 4 < 8)
+
+#0xff \
+#0o10 \
+#0b1001
+```
+
+# Float
+A floating-pointer number.
+
+A limited-precision representation of a real number. Typst uses 64 bits to
+store floats. Wherever a float is expected, you can also pass an
+[integer]($type/integer).
+
+## Example
+```example
+#3.14 \
+#1e4 \
+#(10 / 4)
+```
+
+# Length
+A size or distance, possibly expressed with contextual units.
+Typst supports the following length units:
+
+- Points: `{72pt}`
+- Millimeters: `{254mm}`
+- Centimeters: `{2.54cm}`
+- Inches: `{1in}`
+- Relative to font size: `{2.5em}`
+
+## Example
+```example
+#rect(width: 20pt)
+#rect(width: 2em)
+#rect(width: 1in)
+```
+
+# Angle
+An angle describing a rotation.
+Typst supports the following angular units:
+
+- Degrees: `{180deg}`
+- Radians: `{3.14rad}`
+
+## Example
+```example
+#rotate(10deg)[Hello there!]
+```
+
+# Ratio
+A ratio of a whole.
+
+Written as a number, followed by a percent sign.
+
+## Example
+```example
+#set align(center)
+#scale(x: 150%)[
+ Scaled apart.
+]
+```
+
+# Relative Length
+A length in relation to some known length.
+
+This type is a combination of a [length]($type/length) with a
+[ratio]($type/ratio). It results from addition and subtraction
+of a length and a ratio. Wherever a relative length is expected, you can also
+use a bare length or ratio.
+
+## Example
+```example
+#rect(width: 100% - 50pt)
+```
+
+# Fraction
+Defines how the the remaining space in a layout is distributed.
+
+Each fractionally sized element gets space based on the ratio of its fraction to
+the sum of all fractions.
+
+For more details, also see the [h]($func/h) and [v]($func/v) functions and the
+[grid function]($func/grid).
+
+## Example
+```example
+Left #h(1fr) Left-ish #h(2fr) Right
+```
+
+# Color
+A color in a specific color space.
+
+Typst supports:
+- sRGB through the [`rgb` function]($func/rgb)
+- Device CMYK through [`cmyk` function]($func/cmyk)
+- D65 Gray through the [`luma` function]($func/luma)
+
+Furthermore, Typst provides the following built-in colors:
+
+`black`, `gray`, `silver`, `white`, `navy`, `blue`, `aqua`, `teal`, `eastern`,
+`purple`, `fuchsia`, `maroon`, `red`, `orange`, `yellow`, `olive`, `green`, and
+`lime`.
+
+## Methods
+### lighten()
+Lightens a color.
+
+- amount: ratio (positional, required)
+ The factor to lighten the color by.
+- returns: color
+
+### darken()
+Darkens a color.
+
+- amount: ratio (positional, required)
+ The factor to darken the color by.
+- returns: color
+
+### negate()
+Produces the negative of the color.
+
+- returns: color
+
+# Datetime
+Represents a date, a time, or a combination of both. Can be created by either
+specifying a custom datetime using the [`datetime`]($func/datetime) function or
+getting the current date with [`datetime.today`]($func/datetime.today).
+
+## Example
+```example
+#let date = datetime(
+ year: 2020,
+ month: 10,
+ day: 4,
+)
+
+#date.display() \
+#date.display(
+ "y:[year repr:last_two]"
+)
+
+#let time = datetime(
+ hour: 18,
+ minute: 2,
+ second: 23,
+)
+
+#time.display() \
+#time.display(
+ "h:[hour repr:12][period]"
+)
+```
+
+## Format
+You can specify a customized formatting using the
+[`display`]($type/datetime.display) method. The format of a datetime is
+specified by providing _components_ with a specified number of _modifiers_. A
+component represents a certain part of the datetime that you want to display,
+and with the help of modifiers you can define how you want to display that
+component. In order to display a component, you wrap the name of the component
+in square brackets (e.g. `[[year]]` will display the year). In order to add
+modifiers, you add a space after the component name followed by the name of the
+modifier, a colon and the value of the modifier (e.g. `[[month repr:short]]`
+will display the short representation of the month).
+
+The possible combination of components and their respective modifiers is as
+follows:
+
+* `year`: Displays the year of the datetime.
+ * `padding`: Can be either `zero`, `space` or `none`. Specifies how the year
+ is padded.
+ * `repr` Can be either `full` in which case the full year is displayed or
+ `last_two` in which case only the last two digits are displayed.
+ * `sign`: Can be either `automatic` or `mandatory`. Specifies when the sign
+ should be displayed.
+* `month`: Displays the month of the datetime.
+ * `padding`: Can be either `zero`, `space` or `none`. Specifies how the month
+ is padded.
+ * `repr`: Can be either `numerical`, `long` or `short`. Specifies if the month
+ should be displayed as a number or a word. Unfortunately, when choosing the
+ word representation, it can currently only display the English version. In
+ the future, it is planned to support localization.
+* `day`: Displays the day of the datetime.
+ * `padding`: Can be either `zero`, `space` or `none`. Specifies how the day
+ is padded.
+* `week_number`: Displays the week number of the datetime.
+ * `padding`: Can be either `zero`, `space` or `none`. Specifies how the week
+ number is padded.
+ * `repr`: Can be either `ISO`, `sunday` or `monday`. In the case of `ISO`,
+ week numbers are between 1 and 53, while the other ones are between 0
+ and 53.
+* `weekday`: Displays the weekday of the date.
+ * `repr` Can be either `long`, `short`, `sunday` or `monday`. In the case of
+ `long` and `short`, the corresponding English name will be displayed (same
+ as for the month, other languages are currently not supported). In the case
+ of `sunday` and `monday`, the numerical value will be displayed (assuming
+ Sunday and Monday as the first day of the week, respectively).
+ * `one_indexed`: Can be either `true` or `false`. Defines whether the
+ numerical representation of the week starts with 0 or 1.
+* `hour`: Displays the hour of the date.
+ * `padding`: Can be either `zero`, `space` or `none`. Specifies how the hour
+ is padded.
+ * `repr`: Can be either `24` or `12`. Changes whether the hour is displayed in
+ the 24-hour or 12-hour format.
+* `period`: The AM/PM part of the hour
+ * `case`: Can be `lower` to display it in lower case and `upper` to display it
+ in upper case.
+* `minute`: Displays the minute of the date.
+ * `padding`: Can be either `zero`, `space` or `none`. Specifies how the minute
+ is padded.
+* `second`: Displays the second of the date.
+ * `padding`: Can be either `zero`, `space` or `none`. Specifies how the second
+ is padded.
+
+Keep in mind that not always all components can be used. For example, if
+you create a new datetime with `{datetime(year: 2023, month: 10, day: 13)}`, it
+will be stored as a plain date internally, meaning that you cannot use
+components such as `hour` or `minute`, which would only work on datetimes
+that have a specified time.
+
+## Methods
+### display()
+Displays the datetime in a certain way. Depending on whether you have defined
+just a date, a time or both, the default format will be different.
+If you specified a date, it will be `[[year]-[month]-[day]]`. If you specified a
+time, it will be `[[hour]:[minute]:[second]]`. In the case of a datetime, it
+will be `[[year]-[month]-[day] [hour]:[minute]:[second]]`.
+
+- pattern: string (positional)
+ The format used to display the datetime.
+- returns: string
+
+### year()
+Returns the year of the datetime, if it exists. Otherwise, it returns `{none}`.
+
+- returns: integer or none
+
+### month()
+Returns the month of the datetime, if it exists. Otherwise, it returns `{none}`.
+
+- returns: integer or none
+
+### weekday()
+Returns the weekday of the datetime as a number starting with 1 from Monday, if
+it exists. Otherwise, it returns `{none}`.
+
+- returns: integer or none
+
+### day()
+Returns the day of the datetime, if it exists. Otherwise, it returns `{none}`.
+
+- returns: integer or none
+
+### hour()
+Returns the hour of the datetime, if it exists. Otherwise, it returns `{none}`.
+
+- returns: integer or none
+
+### minute()
+Returns the minute of the datetime, if it exists. Otherwise, it returns
+`{none}`.
+
+- returns: integer or none
+
+### second()
+Returns the second of the datetime, if it exists. Otherwise, it returns
+`{none}`.
+
+- returns: integer or none
+
+# Symbol
+A Unicode symbol.
+
+Typst defines common symbols so that they can easily be written with standard
+keyboards. The symbols are defined in modules, from which they can be accessed
+using [field access notation]($scripting/#fields):
+
+- General symbols are defined in the [`sym` module]($category/symbols/sym)
+- Emoji are defined in the [`emoji` module]($category/symbols/emoji)
+
+Moreover, you can define custom symbols with the [symbol]($func/symbol)
+function.
+
+```example
+#sym.arrow.r \
+#sym.gt.eq.not \
+$gt.eq.not$ \
+#emoji.face.halo
+```
+
+Many symbols have different variants, which can be selected by appending the
+modifiers with dot notation. The order of the modifiers is not relevant. Visit
+the documentation pages of the symbol modules and click on a symbol to see its
+available variants.
+
+```example
+$arrow.l$ \
+$arrow.r$ \
+$arrow.t.quad$
+```
+
+# String
+A sequence of Unicode codepoints.
+
+You can iterate over the grapheme clusters of the string using a
+[for loop]($scripting/#loops). Grapheme clusters are basically characters but
+keep together things that belong together, e.g. multiple codepoints that
+together form a flag emoji. Strings can be added with the `+` operator,
+[joined together]($scripting/#blocks) and multiplied with integers.
+
+Typst provides utility methods for string manipulation. Many of these methods
+(e.g., `split`, `trim` and `replace`) operate on _patterns:_ A pattern can be
+either a string or a [regular expression]($func/regex). This makes the methods
+quite versatile.
+
+All lengths and indices are expressed in terms of UTF-8 characters. Indices are
+zero-based and negative indices wrap around to the end of the string.
+
+### Example
+```example
+#"hello world!" \
+#"\"hello\n world\"!" \
+#"1 2 3".split() \
+#"1,2;3".split(regex("[,;]")) \
+#(regex("\d+") in "ten euros") \
+#(regex("\d+") in "10 euros")
+```
+
+### Escape sequences
+Just like in markup, you can escape a few symbols in strings:
+- `[\\]` for a backslash
+- `[\"]` for a quote
+- `[\n]` for a newline
+- `[\r]` for a carriage return
+- `[\t]` for a tab
+- `[\u{1f600}]` for a hexadecimal Unicode escape sequence
+
+## Methods
+### len()
+The length of the string in UTF-8 encoded bytes.
+
+- returns: integer
+
+### first()
+Extract the first grapheme cluster of the string.
+Fails with an error if the string is empty.
+
+- returns: any
+
+### last()
+Extract the last grapheme cluster of the string.
+Fails with an error if the string is empty.
+
+- returns: any
+
+### at()
+Extract the first grapheme cluster after the specified index. Returns the
+default value if the index is out of bounds or fails with an error if no default
+value was specified.
+
+- index: integer (positional, required)
+ The byte index.
+- default: any (named)
+ A default value to return if the index is out of bounds.
+- returns: string
+
+### slice()
+Extract a substring of the string.
+Fails with an error if the start or end index is out of bounds.
+
+- start: integer (positional, required)
+ The start byte index (inclusive).
+- end: integer (positional)
+ The end byte index (exclusive). If omitted, the whole slice until the end of the
+ string is extracted.
+- count: integer (named)
+ The number of bytes to extract. This is equivalent to passing `start + count`
+ as the `end` position. Mutually exclusive with `end`.
+- returns: string
+
+### clusters()
+Returns the grapheme clusters of the string as an array of substrings.
+
+- returns: array
+
+### codepoints()
+Returns the Unicode codepoints of the string as an array of substrings.
+
+- returns: array
+
+### contains()
+Whether the string contains the specified pattern.
+
+This method also has dedicated syntax: You can write `{"bc" in "abcd"}` instead
+of `{"abcd".contains("bc")}`.
+
+- pattern: string or regex (positional, required)
+ The pattern to search for.
+- returns: boolean
+
+### starts-with()
+Whether the string starts with the specified pattern.
+
+- pattern: string or regex (positional, required)
+ The pattern the string might start with.
+- returns: boolean
+
+### ends-with()
+Whether the string ends with the specified pattern.
+
+- pattern: string or regex (positional, required)
+ The pattern the string might end with.
+- returns: boolean
+
+### find()
+Searches for the specified pattern in the string and returns the first match
+as a string or `{none}` if there is no match.
+
+- pattern: string or regex (positional, required)
+ The pattern to search for.
+- returns: string or none
+
+### position()
+Searches for the specified pattern in the string and returns the index of the
+first match as an integer or `{none}` if there is no match.
+
+- pattern: string or regex (positional, required)
+ The pattern to search for.
+- returns: integer or none
+
+### match()
+Searches for the specified pattern in the string and returns a dictionary
+with details about the first match or `{none}` if there is no match.
+
+The returned dictionary has the following keys:
+* `start`: The start offset of the match
+* `end`: The end offset of the match
+* `text`: The text that matched.
+* `captures`: An array containing a string for each matched capturing group. The
+ first item of the array contains the first matched capturing, not the whole
+ match! This is empty unless the `pattern` was a regex with capturing groups.
+
+- pattern: string or regex (positional, required)
+ The pattern to search for.
+- returns: dictionary or none
+
+### matches()
+Searches for the specified pattern in the string and returns an array of
+dictionaries with details about all matches. For details about the returned
+dictionaries, see above.
+
+- pattern: string or regex (positional, required)
+ The pattern to search for.
+- returns: array
+
+### replace()
+Replaces all or a specified number of matches of a pattern with a replacement
+string and returns the resulting string.
+
+- pattern: string or regex (positional, required)
+ The pattern to search for.
+- replacement: string or function (positional, required)
+ The string to replace the matches with or a function that gets a dictionary for each match and can return individual replacement strings.
+- count: integer (named)
+ If given, only the first `count` matches of the pattern are placed.
+- returns: string
+
+### trim()
+Removes matches of a pattern from one or both sides of the string, once or
+repeatedly and returns the resulting string.
+
+- pattern: string or regex (positional, required)
+ The pattern to search for.
+- at: alignment (named)
+ Can be `start` or `end` to only trim the start or end of the string.
+ If omitted, both sides are trimmed.
+- repeat: boolean (named)
+ Whether to repeatedly removes matches of the pattern or just once.
+ Defaults to `{true}`.
+- returns: string
+
+### split()
+Splits a string at matches of a specified pattern and returns an array of
+the resulting parts.
+
+- pattern: string or regex (positional)
+ The pattern to split at. Defaults to whitespace.
+- returns: array
+
+# Content
+A piece of document content.
+
+This type is at the heart of Typst. All markup you write and most
+[functions]($type/function) you call produce content values. You can create a
+content value by enclosing markup in square brackets. This is also how you pass
+content to functions.
+
+```example
+Type of *Hello!* is
+#type([*Hello!*])
+```
+
+Content can be added with the `+` operator,
+[joined together]($scripting/#blocks) and multiplied with
+integers. Wherever content is expected, you can also pass a
+[string]($type/string) or `{none}`.
+
+## Representation
+Content consists of elements with fields. When constructing an element with
+its _element function,_ you provide these fields as arguments and when you have
+a content value, you can access its fields with
+[field access syntax]($scripting/#field-access).
+
+Some fields are required: These must be provided when constructing an element
+and as a consequence, they are always available through field access on content
+of that type. Required fields are marked as such in the documentation.
+
+Most fields are optional: Like required fields, they can be passed to the
+element function to configure them for a single element. However, these can also
+be configured with [set rules]($styling/#set-rules) to apply them to all
+elements within a scope. Optional fields are only available with field access
+syntax when they are were explicitly passed to the element function, not when
+they result from a set rule.
+
+Each element has a default appearance. However, you can also completely
+customize its appearance with a [show rule]($styling/#show-rules). The show rule
+is passed the element. It can access the element's field and produce arbitrary
+content from it.
+
+In the web app, you can hover over a content variable to see exactly which
+elements the content is composed of and what fields they have. Alternatively,
+you can inspect the output of the [`repr`]($func/repr) function.
+
+## Methods
+### func()
+The content's element function. This function can be used to create the element
+contained in this content. It can be used in set and show rules for the element.
+Can be compared with global functions to check whether you have a specific
+kind of element.
+
+- returns: function
+
+### has()
+Whether the content has the specified field.
+
+- field: string (positional, required)
+ The field to look for.
+- returns: boolean
+
+### at()
+Access the specified field on the content. Returns the default value if the
+field does not exist or fails with an error if no default value was specified.
+
+- field: string (positional, required)
+ The field to access.
+- default: any (named)
+ A default value to return if the field does not exist.
+- returns: any
+
+### fields()
+Return the fields of this content.
+
+```example
+#rect(
+ width: 10cm,
+ height: 10cm,
+).fields()
+```
+
+### location()
+The location of the content. This is only available on content returned by
+[query]($func/query), for other content it will fail with an error. The
+resulting location can be used with [counters]($func/counter),
+[state]($func/state) and [queries]($func/query).
+
+- returns: location
+
+# Array
+A sequence of values.
+
+You can construct an array by enclosing a comma-separated sequence of values
+in parentheses. The values do not have to be of the same type.
+
+You can access and update array items with the `.at()` method. Indices are
+zero-based and negative indices wrap around to the end of the array. You can
+iterate over an array using a [for loop]($scripting/#loops).
+Arrays can be added together with the `+` operator,
+[joined together]($scripting/#blocks) and multiplied with
+integers.
+
+**Note:** An array of length one needs a trailing comma, as in `{(1,)}`. This is
+to disambiguate from a simple parenthesized expressions like `{(1 + 2) * 3}`.
+An empty array is written as `{()}`.
+
+## Example
+```example
+#let values = (1, 7, 4, -3, 2)
+
+#values.at(0) \
+#(values.at(0) = 3)
+#values.at(-1) \
+#values.find(calc.even) \
+#values.filter(calc.odd) \
+#values.map(calc.abs) \
+#values.rev() \
+#(1, (2, 3)).flatten() \
+#(("A", "B", "C")
+ .join(", ", last: " and "))
+```
+
+## Methods
+### len()
+The number of values in the array.
+
+- returns: integer
+
+### first()
+Returns the first item in the array.
+May be used on the left-hand side of an assignment.
+Fails with an error if the array is empty.
+
+- returns: any
+
+### last()
+Returns the last item in the array.
+May be used on the left-hand side of an assignment.
+Fails with an error if the array is empty.
+
+- returns: any
+
+### at()
+Returns the item at the specified index in the array. May be used on the
+left-hand side of an assignment. Returns the default value if the index is out
+of bounds or fails with an error if no default value was specified.
+
+- index: integer (positional, required)
+ The index at which to retrieve the item.
+- default: any (named)
+ A default value to return if the index is out of bounds.
+- returns: any
+
+### push()
+Add a value to the end of the array.
+
+- value: any (positional, required)
+ The value to insert at the end of the array.
+
+### pop()
+Remove the last item from the array and return it.
+Fails with an error if the array is empty.
+
+- returns: any
+ The removed last value.
+
+### insert()
+Insert a value into the array at the specified index.
+Fails with an error if the index is out of bounds.
+
+- index: integer (positional, required)
+ The index at which to insert the item.
+- value: any (positional, required)
+ The value to insert into the array.
+
+### remove()
+Remove the value at the specified index from the array and return it.
+
+- index: integer (positional, required)
+ The index at which to remove the item.
+- returns: any
+
+### slice()
+Extract a subslice of the array.
+Fails with an error if the start or index is out of bounds.
+
+- start: integer (positional, required)
+ The start index (inclusive).
+- end: integer (positional)
+ The end index (exclusive). If omitted, the whole slice until the end of the
+ array is extracted.
+- count: integer (named)
+ The number of items to extract. This is equivalent to passing `start +
+ count` as the `end` position. Mutually exclusive with `end`.
+- returns: array
+
+### contains()
+Whether the array contains the specified value.
+
+This method also has dedicated syntax: You can write `{2 in (1, 2, 3)}` instead
+of `{(1, 2, 3).contains(2)}`.
+
+- value: any (positional, required)
+ The value to search for.
+- returns: boolean
+
+### find()
+Searches for an item for which the given function returns `{true}` and
+returns the first match or `{none}` if there is no match.
+
+- searcher: function (positional, required)
+ The function to apply to each item. Must return a boolean.
+- returns: any or none
+
+### position()
+Searches for an item for which the given function returns `{true}` and
+returns the index of the first match or `{none}` if there is no match.
+
+- searcher: function (positional, required)
+ The function to apply to each item. Must return a boolean.
+- returns: integer or none
+
+### filter()
+Produces a new array with only the items from the original one for which the
+given function returns true.
+
+- test: function (positional, required)
+ The function to apply to each item. Must return a boolean.
+- returns: array
+
+### map()
+Produces a new array in which all items from the original one were
+transformed with the given function.
+
+- mapper: function (positional, required)
+ The function to apply to each item.
+- returns: array
+
+### enumerate()
+Returns a new array with the values alongside their indices.
+
+The returned array consists of `(index, value)` pairs in the form of length-2
+arrays. These can be [destructured]($scripting/#bindings) with a let binding or
+for loop.
+
+- returns: array
+
+### zip()
+Zips the array with another array. If the two arrays are of unequal length, it
+will only zip up until the last element of the smaller array and the remaining
+elements will be ignored. The return value is an array where each element is yet
+another array of size 2.
+
+- other: array (positional, required)
+ The other array which should be zipped with the current one.
+- returns: array
+
+### fold()
+Folds all items into a single value using an accumulator function.
+
+- init: any (positional, required)
+ The initial value to start with.
+- folder: function (positional, required)
+ The folding function. Must have two parameters: One for the accumulated value
+ and one for an item.
+- returns: any
+
+### sum()
+Sums all items (works for any types that can be added).
+
+- default: any (named)
+ What to return if the array is empty. Must be set if the array can be empty.
+- returns: any
+
+### product()
+Calculates the product all items (works for any types that can be multiplied)
+
+- default: any (named)
+ What to return if the array is empty. Must be set if the array can be empty.
+- returns: any
+
+### any()
+Whether the given function returns `{true}` for any item in the array.
+
+- test: function (positional, required)
+ The function to apply to each item. Must return a boolean.
+- returns: boolean
+
+### all()
+Whether the given function returns `{true}` for all items in the array.
+
+- test: function (positional, required)
+ The function to apply to each item. Must return a boolean.
+- returns: boolean
+
+### flatten()
+Combine all nested arrays into a single flat one.
+
+- returns: array
+
+### rev()
+Return a new array with the same items, but in reverse order.
+
+- returns: array
+
+### join()
+Combine all items in the array into one.
+
+- separator: any (positional)
+ A value to insert between each item of the array.
+- last: any (named)
+ An alternative separator between the last two items
+- returns: any
+
+### sorted()
+Return a new array with the same items, but sorted.
+
+- key: function (named)
+ If given, applies this function to the elements in the array to determine the keys to sort by.
+- returns: array
+
+# Dictionary
+A map from string keys to values.
+
+You can construct a dictionary by enclosing comma-separated `key: value` pairs
+in parentheses. The values do not have to be of the same type. Since empty
+parentheses already yield an empty array, you have to use the special `(:)`
+syntax to create an empty dictionary.
+
+A dictionary is conceptually similar to an array, but it is indexed by strings
+instead of integers. You can access and create dictionary entries with the
+`.at()` method. If you know the key statically, you can alternatively use
+[field access notation]($scripting/#fields) (`.key`) to access
+the value. Dictionaries can be added with the `+` operator and
+[joined together]($scripting/#blocks).
+To check whether a key is present in the dictionary, use the `in` keyword.
+
+You can iterate over the pairs in a dictionary using a
+[for loop]($scripting/#loops). This will iterate in the order the pairs were
+inserted / declared.
+
+## Example
+```example
+#let dict = (
+ name: "Typst",
+ born: 2019,
+)
+
+#dict.name \
+#(dict.launch = 20)
+#dict.len() \
+#dict.keys() \
+#dict.values() \
+#dict.at("born") \
+#dict.insert("city", "Berlin ")
+#("name" in dict)
+```
+
+## Methods
+### len()
+The number of pairs in the dictionary.
+
+- returns: integer
+
+### at()
+Returns the value associated with the specified key in the dictionary. May be
+used on the left-hand side of an assignment if the key is already present in the
+dictionary. Returns the default value if the key is not part of the dictionary
+or fails with an error if no default value was specified.
+
+- key: string (positional, required)
+ The key at which to retrieve the item.
+- default: any (named)
+ A default value to return if the key is not part of the dictionary.
+- returns: any
+
+### insert()
+Insert a new pair into the dictionary and return the value.
+If the dictionary already contains this key, the value is updated.
+
+- key: string (positional, required)
+ The key of the pair that should be inserted.
+- value: any (positional, required)
+ The value of the pair that should be inserted.
+
+### keys()
+Returns the keys of the dictionary as an array in insertion order.
+
+- returns: array
+
+### values()
+Returns the values of the dictionary as an array in insertion order.
+
+- returns: array
+
+### pairs()
+Returns the keys and values of the dictionary as an array of pairs. Each pair is
+represented as an array of length two.
+
+- returns: array
+
+### remove()
+Remove a pair from the dictionary by key and return the value.
+
+- key: string (positional, required)
+ The key of the pair that should be removed.
+- returns: any
+
+# Function
+A mapping from argument values to a return value.
+
+You can call a function by writing a comma-separated list of function
+_arguments_ enclosed in parentheses directly after the function name.
+Additionally, you can pass any number of trailing content blocks arguments to a
+function _after_ the normal argument list. If the normal argument list would
+become empty, it can be omitted. Typst supports positional and named arguments.
+The former are identified by position and type, while the later are written as
+`name: value`.
+
+Within math mode, function calls have special behaviour. See the
+[math documentation]($category/math) for more details.
+
+### Example
+```example
+// Call a function.
+#list([A], [B])
+
+// Named arguments and trailing
+// content blocks.
+#enum(start: 2)[A][B]
+
+// Version without parentheses.
+#list[A][B]
+```
+
+Functions are a fundamental building block of Typst. Typst provides functions
+for a variety of typesetting tasks. Moreover, the markup you write is backed by
+functions and all styling happens through functions. This reference lists all
+available functions and how you can use them. Please also refer to the
+documentation about [set]($styling/#set-rules) and
+[show]($styling/#show-rules) rules to learn about additional ways
+you can work with functions in Typst.
+
+### Element functions { #element-functions }
+Some functions are associated with _elements_ like [headings]($func/heading) or
+[tables]($func/table). When called, these create an element of their respective
+kind. In contrast to normal functions, they can further be used in
+[set rules]($styling/#set-rules), [show rules]($styling/#show-rules), and
+[selectors]($type/selector).
+
+### Function scopes { #function-scopes }
+Functions can hold related definitions in their own scope, similar to a
+[module]($scripting/#modules). Examples of this are
+[`assert.eq`]($func/assert.eq) or [`list.item`]($func/list.item). However, this
+feature is currently only available for built-in functions.
+
+### Defining functions { #definitions }
+You can define your own function with a
+[let binding]($scripting/#bindings) that has a parameter list after
+the binding's name. The parameter list can contain positional parameters,
+named parameters with default values and
+[argument sinks]($type/arguments).
+The right-hand side of the binding can be a block or any other expression. It
+defines the function's return value and can depend on the parameters.
+
+```example
+#let alert(body, fill: red) = {
+ set text(white)
+ set align(center)
+ rect(
+ fill: fill,
+ inset: 8pt,
+ radius: 4pt,
+ [*Warning:\ #body*],
+ )
+}
+
+#alert[
+ Danger is imminent!
+]
+
+#alert(fill: blue)[
+ KEEP OFF TRACKS
+]
+```
+
+### Unnamed functions { #unnamed }
+You can also created an unnamed function without creating a binding by
+specifying a parameter list followed by `=>` and the function body. If your
+function has just one parameter, the parentheses around the parameter list are
+optional. Unnamed functions are mainly useful for show rules, but also for
+settable properties that take functions like the page function's
+[`footer`]($func/page.footer) property.
+
+```example
+#show "once?": it => [#it #it]
+once?
+```
+
+### Notable fact
+In Typst, all functions are _pure._ This means that for the same
+arguments, they always return the same result. They cannot "remember" things to
+produce another value when they are called a second time.
+
+The only exception are built-in methods like
+[`array.push(value)`]($type/array.push). These can modify the values they are
+called on.
+
+## Methods
+### with()
+Returns a new function that has the given arguments pre-applied.
+
+- arguments: any (variadic)
+ The named and positional arguments to apply.
+- returns: function
+
+### where()
+Returns a selector that filters for elements belonging to this function
+whose fields have the values of the given arguments.
+
+- fields: any (named, variadic)
+ The field values to filter by.
+- returns: selector
+
+# Arguments
+Captured arguments to a function.
+
+Like built-in functions, custom functions can also take a variable number of
+arguments. You can specify an _argument sink_ which collects all excess
+arguments as `..sink`. The resulting `sink` value is of the `arguments` type. It
+exposes methods to access the positional and named arguments and is iterable
+with a [for loop]($scripting/#loops). Inversely, you can spread
+arguments, arrays and dictionaries into a function call with the spread operator:
+`{func(..args)}`.
+
+## Example
+```example
+#let format(title, ..authors) = [
+ *#title* \
+ _Written by #(authors
+ .pos()
+ .join(", ", last: " and "));._
+]
+
+#format("ArtosFlow", "Jane", "Joe")
+```
+
+## Methods
+### pos()
+Returns the captured positional arguments as an array.
+
+- returns: array
+
+### named()
+Returns the captured named arguments as a dictionary.
+
+- returns: dictionary
+
+# Selector
+A filter for selecting elements within the document.
+
+You can construct a selector in the following ways:
+- you can use an element [function]($type/function)
+- you can filter for an element function with
+ [specific fields]($type/function.where)
+- you can use a [string]($type/string) or [regular expression]($func/regex)
+- you can use a [`{<label>}`]($func/label)
+- you can use a [`location`]($func/locate)
+- call the [`selector`]($func/selector) function to convert any of the above
+ types into a selector value and use the methods below to refine it
+
+Selectors are used to [apply styling rules]($styling/#show-rules) to elements.
+You can also use selectors to [query]($func/query) the document for certain
+types of elements.
+
+Furthermore, you can pass a selector to several of Typst's built-in functions to
+configure their behaviour. One such example is the [outline]($func/outline)
+where it can be used to change which elements are listed within the outline.
+
+Multiple selectors can be combined using the methods shown below. However, not
+all kinds of selectors are supported in all places, at the moment.
+
+## Example
+```example
+#locate(loc => query(
+ heading.where(level: 1)
+ .or(heading.where(level: 2)),
+ loc,
+))
+
+= This will be found
+== So will this
+=== But this will not.
+```
+
+## Methods
+### or()
+Allows combining any of a series of selectors. This is used to
+select multiple components or components with different properties
+all at once.
+
+- other: selector (variadic, required)
+ The list of selectors to match on.
+
+### and()
+Allows combining all of a series of selectors. This is used to check
+whether a component meets multiple selection rules simultaneously.
+
+- other: selector (variadic, required)
+ The list of selectors to match on.
+
+### before()
+Returns a modified selector that will only match elements that occur before the
+first match of the selector argument.
+
+- end: selector (positional, required)
+ The original selection will end at the first match of `end`.
+- inclusive: boolean (named)
+ Whether `end` itself should match or not. This is only relevant if both
+ selectors match the same type of element. Defaults to `{true}`.
+
+### after()
+Returns a modified selector that will only match elements that occur after the
+first match of the selector argument.
+
+- start: selector (positional, required)
+ The original selection will start at the first match of `start`.
+- inclusive: boolean (named)
+ Whether `start` itself should match or not. This is only relevant if both
+ selectors match the same type of element. Defaults to `{true}`.
+
+# Module
+An evaluated module, either built-in or resulting from a file.
+
+You can access definitions from the module using
+[field access notation]($scripting/#fields) and interact with it using the
+[import and include syntaxes]($scripting/#modules).
+
+## Example
+```example
+<<< #import "utils.typ"
+<<< #utils.add(2, 5)
+
+<<< #import utils: sub
+<<< #sub(1, 4)
+>>> #7
+>>>
+>>> #(-3)
+```
diff --git a/docs/reference/welcome.md b/docs/reference/welcome.md
new file mode 100644
index 00000000..fc526f52
--- /dev/null
+++ b/docs/reference/welcome.md
@@ -0,0 +1,29 @@
+---
+description: |
+ The Typst reference is a systematic and comprehensive guide to the Typst
+ typesetting language.
+---
+
+# Reference
+This reference documentation is a comprehensive guide to all of Typst's
+syntax, concepts, types, and functions. If you are completely new to Typst, we
+recommend starting with the [tutorial]($tutorial) and then coming back to
+the reference to learn more about Typst's features as you need them.
+
+## Language { #language }
+The reference starts with a language part that gives an overview over [Typst's
+syntax]($syntax) and contains information about concepts involved in
+[styling documents,]($styling) using
+[Typst's scripting capabilities,]($scripting) and a detailed documentation of
+all [data types]($types) in Typst.
+
+## Functions { #functions }
+The second part includes chapters on all functions used to insert, style, transform,
+and layout content in Typst documents. Each function is documented with a
+description of its purpose, a list of its parameters, and examples of how to use
+it.
+
+The final part of the reference explains all functions that are used within
+Typst's code mode to manipulate and transform data. Just as in the previous
+part, each function is documented with a description of its purpose, a list of
+its parameters, and examples of how to use it.