ecyht2 commited on
Commit
2d83f30
·
verified ·
1 Parent(s): 71d9c83

feat: Added typst docs

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. sources/CONTRIBUTING.md +73 -0
  2. sources/README.md +261 -0
  3. sources/crates/typst-syntax/README.md +40 -0
  4. sources/docs/changelog/0.1.0.md +73 -0
  5. sources/docs/changelog/0.10.0.md +130 -0
  6. sources/docs/changelog/0.11.0.md +270 -0
  7. sources/docs/changelog/0.11.1.md +62 -0
  8. sources/docs/changelog/0.12.0.md +402 -0
  9. sources/docs/changelog/0.13.0.md +344 -0
  10. sources/docs/changelog/0.13.1.md +29 -0
  11. sources/docs/changelog/0.2.0.md +47 -0
  12. sources/docs/changelog/0.3.0.md +77 -0
  13. sources/docs/changelog/0.4.0.md +106 -0
  14. sources/docs/changelog/0.5.0.md +68 -0
  15. sources/docs/changelog/0.6.0.md +66 -0
  16. sources/docs/changelog/0.7.0.md +142 -0
  17. sources/docs/changelog/0.8.0.md +124 -0
  18. sources/docs/changelog/0.9.0.md +189 -0
  19. sources/docs/changelog/earlier.md +309 -0
  20. sources/docs/changelog/welcome.md +28 -0
  21. sources/docs/dev/architecture.md +199 -0
  22. sources/docs/guides/guide-for-latex-users.md +676 -0
  23. sources/docs/guides/page-setup.md +487 -0
  24. sources/docs/guides/tables.md +1343 -0
  25. sources/docs/guides/welcome.md +14 -0
  26. sources/docs/overview.md +18 -0
  27. sources/docs/reference/export/html.md +61 -0
  28. sources/docs/reference/export/pdf.md +71 -0
  29. sources/docs/reference/export/png.md +61 -0
  30. sources/docs/reference/export/svg.md +48 -0
  31. sources/docs/reference/language/context.md +233 -0
  32. sources/docs/reference/language/scripting.md +373 -0
  33. sources/docs/reference/language/styling.md +145 -0
  34. sources/docs/reference/language/syntax.md +215 -0
  35. sources/docs/reference/library/data-loading.md +4 -0
  36. sources/docs/reference/library/foundations.md +4 -0
  37. sources/docs/reference/library/introspection.md +10 -0
  38. sources/docs/reference/library/layout.md +3 -0
  39. sources/docs/reference/library/math.md +101 -0
  40. sources/docs/reference/library/model.md +5 -0
  41. sources/docs/reference/library/symbols.md +5 -0
  42. sources/docs/reference/library/text.md +3 -0
  43. sources/docs/reference/library/visualize.md +5 -0
  44. sources/docs/reference/welcome.md +28 -0
  45. sources/docs/tutorial/1-writing.md +308 -0
  46. sources/docs/tutorial/2-formatting.md +280 -0
  47. sources/docs/tutorial/3-advanced.md +546 -0
  48. sources/docs/tutorial/4-template.md +406 -0
  49. sources/docs/tutorial/welcome.md +44 -0
  50. sources/tests/README.md +150 -0
sources/CONTRIBUTING.md ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Contributing to Typst
2
+ Thank you for considering to contribute to Typst. We want to foster a welcoming
3
+ and productive atmosphere for contributors. Therefore, we outline a few steps to
4
+ land your contribution below.
5
+
6
+ 1. Before starting significant work on a feature or refactoring, please
7
+ find/open an [issue] or start a thread in the [#contributors] channel on
8
+ Discord to discuss the design. Feel also free to ping a maintainer/team
9
+ member to get some input on your idea. Don't be shy! Typst is a complex
10
+ project with a long-term vision and it's frustrating to find out that your
11
+ idea does not align with that vision _after_ you have already implemented
12
+ something.
13
+ 2. Fork the Typst repository and start with your contribution. If you, at any
14
+ point in this process, are unsure about how to do something in the Typst
15
+ codebase, reach out to a maintainer or a more experienced contributor. Also
16
+ have a look at the [`architecture.md`][architecture] file. It explains how
17
+ the compiler works.
18
+ 3. Create a pull request (PR) in the Typst repository, outlining your
19
+ contribution, the technical rationale behind it, and, if it includes a new
20
+ feature, how users will use it. Best to link to an existing issue with this
21
+ information here.
22
+ 4. When you send a PR, automated CI checks will run. Your PR can only be merged
23
+ if CI passes and will often also only get its first review round once it has
24
+ the green checkmark. You can ping a maintainer if you need guidance with
25
+ failing CI (or anything else).
26
+ 5. A maintainer will review your PR. In this review, we check code quality,
27
+ bugs, and whether the contribution aligns with what was previously discussed.
28
+ If you think that a review comment misses something or is not quite right,
29
+ please challenge it!
30
+ 6. If the review passes, your PR will be merged and ship in the next version of
31
+ Typst. You will appear as one of the contributors in the [changelog].
32
+ Thank you!
33
+
34
+ Below are some signs of a good PR:
35
+ - Implements a single, self-contained feature or bugfix that has been discussed
36
+ previously.
37
+ - Adds/changes as little code and as few interfaces as possible. Should changes
38
+ to larger-scale abstractions be necessary, these should be discussed
39
+ throughout the implementation process.
40
+ - Adds tests if appropriate (with reference output for visual/HTML tests). See
41
+ the [testing] readme for more details.
42
+ - Contains documentation comments on all new Rust types.
43
+ - Comes with brief documentation for all new Typst definitions
44
+ (elements/functions), ideally with a concise example that fits into ~5-10
45
+ lines with <38 columns (check out existing examples for inspiration). This
46
+ part is not too critical, as we will touch up the documentation before making
47
+ a release.
48
+
49
+ Sometimes, a contributor can become unresponsive during a review process. This
50
+ is okay! We will, however, close PRs on which we are waiting for a contributor
51
+ response after an extended period of time to avoid filling up the PR tracker
52
+ with many stale PRs. In the same way, it may take a while for us to find time to
53
+ review your PR. If there is no response after a longer while (1-2 weeks), feel
54
+ free to ping us, as we may have missed it.
55
+
56
+ While Typst is an open-source project, it is also the product of a startup. We
57
+ always judge technical contributions to the project based on their technical
58
+ merits. However, as a company, our immediate priorities can and do change often
59
+ and sometimes without prior notice. This affects the design and decision making
60
+ process as well as the development and review velocity. Some proposals may also
61
+ have direct impact on our viability as a company, in which case we carefully
62
+ consider them from the business perspective.
63
+
64
+ If you are unsure whether your idea is a good fit for this project, please
65
+ discuss it with us! The core question is "Does this help to make Typst the prime
66
+ technical typesetting app?". If the answer is yes, your idea is likely right for
67
+ Typst!
68
+
69
+ [issue]: https://github.com/typst/typst/issues
70
+ [testing]: https://github.com/typst/typst/blob/main/tests/README.md
71
+ [#contributors]: https://discord.com/channels/1054443721975922748/1088371867913572452
72
+ [architecture]: https://github.com/typst/typst/blob/main/docs/dev/architecture.md
73
+ [changelog]: https://typst.app/docs/changelog/
sources/README.md ADDED
@@ -0,0 +1,261 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <h1 align="center">
2
+ <img alt="Typst" src="https://user-images.githubusercontent.com/17899797/226108480-722b770e-6313-40d7-84f2-26bebb55a281.png">
3
+ </h1>
4
+
5
+ <p align="center">
6
+ <a href="https://typst.app/docs/">
7
+ <img alt="Documentation" src="https://img.shields.io/website?down_message=offline&label=docs&up_color=007aff&up_message=online&url=https%3A%2F%2Ftypst.app%2Fdocs"
8
+ ></a>
9
+ <a href="https://typst.app/">
10
+ <img alt="Typst App" src="https://img.shields.io/website?down_message=offline&label=typst.app&up_color=239dad&up_message=online&url=https%3A%2F%2Ftypst.app"
11
+ ></a>
12
+ <a href="https://discord.gg/2uDybryKPe">
13
+ <img alt="Discord Server" src="https://img.shields.io/discord/1054443721975922748?color=5865F2&label=discord&labelColor=555"
14
+ ></a>
15
+ <a href="https://github.com/typst/typst/blob/main/LICENSE">
16
+ <img alt="Apache-2 License" src="https://img.shields.io/badge/license-Apache%202-brightgreen"
17
+ ></a>
18
+ <a href="https://typst.app/jobs/">
19
+ <img alt="Jobs at Typst" src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Ftypst.app%2Fassets%2Fdata%2Fshields.json&query=%24.jobs.text&label=jobs&color=%23A561FF&cacheSeconds=1800"
20
+ ></a>
21
+ </p>
22
+
23
+ Typst is a new markup-based typesetting system that is designed to be as powerful
24
+ as LaTeX while being much easier to learn and use. Typst has:
25
+
26
+ - Built-in markup for the most common formatting tasks
27
+ - Flexible functions for everything else
28
+ - A tightly integrated scripting system
29
+ - Math typesetting, bibliography management, and more
30
+ - Fast compile times thanks to incremental compilation
31
+ - Friendly error messages in case something goes wrong
32
+
33
+ This repository contains the Typst compiler and its CLI, which is everything you
34
+ need to compile Typst documents locally. For the best writing experience,
35
+ consider signing up to our [collaborative online editor][app] for free.
36
+
37
+ ## Example
38
+ A [gentle introduction][tutorial] to Typst is available in our documentation.
39
+ However, if you want to see the power of Typst encapsulated in one image, here
40
+ it is:
41
+ <p align="center">
42
+ <img alt="Example" width="900" src="https://user-images.githubusercontent.com/17899797/228031796-ced0e452-fcee-4ae9-92da-b9287764ff25.png">
43
+ </p>
44
+
45
+
46
+ Let's dissect what's going on:
47
+
48
+ - We use _set rules_ to configure element properties like the size of pages or
49
+ the numbering of headings. By setting the page height to `auto`, it scales to
50
+ fit the content. Set rules accommodate the most common configurations. If you
51
+ need full control, you can also use [show rules][show] to completely redefine
52
+ the appearance of an element.
53
+
54
+ - We insert a heading with the `= Heading` syntax. One equals sign creates a top
55
+ level heading, two create a subheading and so on. Typst has more lightweight
56
+ markup like this, see the [syntax] reference for a full list.
57
+
58
+ - [Mathematical equations][math] are enclosed in dollar signs. By adding extra
59
+ spaces around the contents of an equation, we can put it into a separate block.
60
+ Multi-letter identifiers are interpreted as Typst definitions and functions
61
+ unless put into quotes. This way, we don't need backslashes for things like
62
+ `floor` and `sqrt`. And `phi.alt` applies the `alt` modifier to the `phi` to
63
+ select a particular symbol variant.
64
+
65
+ - Now, we get to some [scripting]. To input code into a Typst document, we can
66
+ write a hash followed by an expression. We define two variables and a
67
+ recursive function to compute the n-th fibonacci number. Then, we display the
68
+ results in a center-aligned table. The table function takes its cells
69
+ row-by-row. Therefore, we first pass the formulas `$F_1$` to `$F_8$` and then
70
+ the computed fibonacci numbers. We apply the spreading operator (`..`) to both
71
+ because they are arrays and we want to pass the arrays' items as individual
72
+ arguments.
73
+
74
+ <details>
75
+ <summary>Text version of the code example.</summary>
76
+
77
+ ```typst
78
+ #set page(width: 10cm, height: auto)
79
+ #set heading(numbering: "1.")
80
+
81
+ = Fibonacci sequence
82
+ The Fibonacci sequence is defined through the
83
+ recurrence relation $F_n = F_(n-1) + F_(n-2)$.
84
+ It can also be expressed in _closed form:_
85
+
86
+ $ F_n = round(1 / sqrt(5) phi.alt^n), quad
87
+ phi.alt = (1 + sqrt(5)) / 2 $
88
+
89
+ #let count = 8
90
+ #let nums = range(1, count + 1)
91
+ #let fib(n) = (
92
+ if n <= 2 { 1 }
93
+ else { fib(n - 1) + fib(n - 2) }
94
+ )
95
+
96
+ The first #count numbers of the sequence are:
97
+
98
+ #align(center, table(
99
+ columns: count,
100
+ ..nums.map(n => $F_#n$),
101
+ ..nums.map(n => str(fib(n))),
102
+ ))
103
+ ```
104
+ </details>
105
+
106
+ ## Installation
107
+ Typst's CLI is available from different sources:
108
+
109
+ - You can get sources and pre-built binaries for the latest release of Typst
110
+ from the [releases page][releases]. Download the archive for your platform and
111
+ place it in a directory that is in your `PATH`. To stay up to date with future
112
+ releases, you can simply run `typst update`.
113
+
114
+ - You can install Typst through different package managers. Note that the
115
+ versions in the package managers might lag behind the latest release.
116
+ - Linux:
117
+ - View [Typst on Repology][repology]
118
+ - View [Typst's Snap][snap]
119
+ - macOS: `brew install typst`
120
+ - Windows: `winget install --id Typst.Typst`
121
+
122
+ - If you have a [Rust][rust] toolchain installed, you can install
123
+ - the latest released Typst version with
124
+ `cargo install --locked typst-cli`
125
+ - a development version with
126
+ `cargo install --git https://github.com/typst/typst --locked typst-cli`
127
+
128
+ - Nix users can
129
+ - use the `typst` package with `nix-shell -p typst`
130
+ - build and run a development version with
131
+ `nix run github:typst/typst -- --version`.
132
+
133
+ - Docker users can run a prebuilt image with
134
+ `docker run ghcr.io/typst/typst:latest --help`.
135
+
136
+ ## Usage
137
+ Once you have installed Typst, you can use it like this:
138
+ ```sh
139
+ # Creates `file.pdf` in working directory.
140
+ typst compile file.typ
141
+
142
+ # Creates PDF file at the desired path.
143
+ typst compile path/to/source.typ path/to/output.pdf
144
+ ```
145
+
146
+ You can also watch source files and automatically recompile on changes. This is
147
+ faster than compiling from scratch each time because Typst has incremental
148
+ compilation.
149
+ ```sh
150
+ # Watches source files and recompiles on changes.
151
+ typst watch file.typ
152
+ ```
153
+
154
+ Typst further allows you to add custom font paths for your project and list all
155
+ of the fonts it discovered:
156
+ ```sh
157
+ # Adds additional directories to search for fonts.
158
+ typst compile --font-path path/to/fonts file.typ
159
+
160
+ # Lists all of the discovered fonts in the system and the given directory.
161
+ typst fonts --font-path path/to/fonts
162
+
163
+ # Or via environment variable (Linux syntax).
164
+ TYPST_FONT_PATHS=path/to/fonts typst fonts
165
+ ```
166
+
167
+ For other CLI subcommands and options, see below:
168
+ ```sh
169
+ # Prints available subcommands and options.
170
+ typst help
171
+
172
+ # Prints detailed usage of a subcommand.
173
+ typst help watch
174
+ ```
175
+
176
+ If you prefer an integrated IDE-like experience with autocompletion and instant
177
+ preview, you can also check out [Typst's free web app][app].
178
+
179
+ ## Community
180
+ The main places where the community gathers are our [Forum][forum] and our
181
+ [Discord server][discord]. The Forum is a great place to ask questions, help
182
+ others, and share cool things you created with Typst. The Discord server is more
183
+ suitable for quicker questions, discussions about contributing, or just to chat.
184
+ We'd be happy to see you there!
185
+
186
+ [Typst Universe][universe] is where the community shares templates and packages.
187
+ If you want to share your own creations, you can submit them to our
188
+ [package repository][packages].
189
+
190
+ If you had a bad experience in our community, please [reach out to us][contact].
191
+
192
+ ## Contributing
193
+ We love to see contributions from the community. If you experience bugs, feel
194
+ free to open an issue. If you would like to implement a new feature or bug fix,
195
+ please follow the steps outlined in the [contribution guide][contributing].
196
+
197
+ To build Typst yourself, first ensure that you have the
198
+ [latest stable Rust][rust] installed. Then, clone this repository and build the
199
+ CLI with the following commands:
200
+
201
+ ```sh
202
+ git clone https://github.com/typst/typst
203
+ cd typst
204
+ cargo build --release
205
+ ```
206
+
207
+ The optimized binary will be stored in `target/release/`.
208
+
209
+ Another good way to contribute is by [sharing packages][packages] with the
210
+ community.
211
+
212
+ ## Pronunciation and Spelling
213
+ IPA: /taɪpst/. "Ty" like in **Ty**pesetting and "pst" like in Hi**pst**er. When
214
+ writing about Typst, capitalize its name as a proper noun, with a capital "T".
215
+
216
+ ## Design Principles
217
+ All of Typst has been designed with three key goals in mind: Power,
218
+ simplicity, and performance. We think it's time for a system that matches the
219
+ power of LaTeX, is easy to learn and use, all while being fast enough to realize
220
+ instant preview. To achieve these goals, we follow three core design principles:
221
+
222
+ - **Simplicity through Consistency:**
223
+ If you know how to do one thing in Typst, you should be able to transfer that
224
+ knowledge to other things. If there are multiple ways to do the same thing,
225
+ one of them should be at a different level of abstraction than the other. E.g.
226
+ it's okay that `= Introduction` and `#heading[Introduction]` do the same thing
227
+ because the former is just syntax sugar for the latter.
228
+
229
+ - **Power through Composability:**
230
+ There are two ways to make something flexible: Have a knob for everything or
231
+ have a few knobs that you can combine in many ways. Typst is designed with the
232
+ second way in mind. We provide systems that you can compose in ways we've
233
+ never even thought of. TeX is also in the second category, but it's a bit
234
+ low-level and therefore people use LaTeX instead. But there, we don't really
235
+ have that much composability. Instead, there's a package for everything
236
+ (`\usepackage{knob}`).
237
+
238
+ - **Performance through Incrementality:**
239
+ All Typst language features must accommodate for incremental compilation.
240
+ Luckily we have [`comemo`], a system for incremental compilation which does
241
+ most of the hard work in the background.
242
+
243
+ [docs]: https://typst.app/docs/
244
+ [app]: https://typst.app/
245
+ [discord]: https://discord.gg/2uDybryKPe
246
+ [forum]: https://forum.typst.app/
247
+ [universe]: https://typst.app/universe/
248
+ [tutorial]: https://typst.app/docs/tutorial/
249
+ [show]: https://typst.app/docs/reference/styling/#show-rules
250
+ [math]: https://typst.app/docs/reference/math/
251
+ [syntax]: https://typst.app/docs/reference/syntax/
252
+ [scripting]: https://typst.app/docs/reference/scripting/
253
+ [rust]: https://rustup.rs/
254
+ [releases]: https://github.com/typst/typst/releases/
255
+ [repology]: https://repology.org/project/typst/versions
256
+ [contact]: https://typst.app/contact
257
+ [architecture]: https://github.com/typst/typst/blob/main/docs/dev/architecture.md
258
+ [contributing]: https://github.com/typst/typst/blob/main/CONTRIBUTING.md
259
+ [packages]: https://github.com/typst/packages/
260
+ [`comemo`]: https://github.com/typst/comemo/
261
+ [snap]: https://snapcraft.io/typst
sources/crates/typst-syntax/README.md ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # typst-syntax
2
+
3
+ Welcome to the Typst Syntax crate! This crate manages the syntactical structure
4
+ of Typst by holding some core abstractions like assigning source file ids,
5
+ parsing Typst syntax, creating an Abstract Syntax Tree (AST), initializing
6
+ source "spans" (for linking AST elements to their outputs in a document), and
7
+ syntax highlighting.
8
+
9
+ Below are quick descriptions of the files you might be editing if you find
10
+ yourself here :)
11
+
12
+ - `lexer.rs`: The lexical foundation of the parser, which converts a string of
13
+ characters into tokens.
14
+ - `parser.rs`: The main parser definition, preparing a Concrete Syntax Tree made
15
+ of nested vectors of `SyntaxNode`s.
16
+ - `reparser.rs`: The algorithm for reparsing the minimal required amount of
17
+ source text for efficient incremental compilation.
18
+ - `ast.rs`: The conversion layer between the Concrete Syntax Tree of the parser
19
+ and the Abstract Syntax Tree used for code evaluation.
20
+ - `node.rs` & `span.rs`: The underlying data structure for the Concrete Syntax
21
+ Tree and the definitions of source spans used for efficiently pointing to a
22
+ syntax node in things like diagnostics.
23
+ - `kind.rs` & `set.rs`: An enum with all syntactical tokens and nodes and
24
+ bit-set data structure for sets of `SyntaxKind`s.
25
+ - `highlight.rs`: Extracting of syntax highlighting information out of the
26
+ Concrete Syntax Tree (and outputting as HTML).
27
+ - `path.rs`, `file.rs`, `package.rs`: The system for interning project and
28
+ package paths as unique file IDs and resolving them in a virtual filesystem
29
+ (not actually for _opening_ files).
30
+
31
+ The structure of the parser is largely adapted from Rust Analyzer. Their
32
+ [documentation][ra] is a good reference for a number of the design decisions
33
+ around the parser and AST.
34
+
35
+ The reparsing algorithm is explained in Section 4 of [Martin's thesis][thesis]
36
+ (though it changed a bit since).
37
+
38
+ [ra]: https://github.com/rust-lang/rust-analyzer/blob/master/docs/dev/syntax.md
39
+ [thesis]:
40
+ https://www.researchgate.net/publication/364622490_Fast_Typesetting_with_Incremental_Compilation
sources/docs/changelog/0.1.0.md ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: 0.1.0
3
+ description: Changes in Typst 0.1.0
4
+ ---
5
+
6
+ # Version 0.1.0 (April 04, 2023)
7
+
8
+ ## Breaking changes
9
+ - When using the CLI, you now have to use subcommands:
10
+ - `typst compile file.typ` or `typst c file.typ` to create a PDF
11
+ - `typst watch file.typ` or `typst w file.typ` to compile and watch
12
+ - `typst fonts` to list all fonts
13
+ - Manual counters now start at zero. Read the "How to step" section
14
+ [here]($counter) for more details
15
+ - The [bibliography styles]($bibliography.style) `{"author-date"}` and
16
+ `{"author-title"}` were renamed to `{"chicago-author-date"}` and
17
+ `{"chicago-author-title"}`
18
+
19
+ ## Figure improvements
20
+ - Figures now automatically detect their content and adapt their behavior.
21
+ Figures containing tables, for instance, are automatically prefixed with
22
+ "Table X" and have a separate counter
23
+ - The figure's supplement (e.g. "Figure" or "Table") can now be customized
24
+ - In addition, figures can now be completely customized because the show rule
25
+ gives access to the automatically resolved kind, supplement, and counter
26
+
27
+ ## Bibliography improvements
28
+ - The [`bibliography`] now also accepts multiple bibliography paths (as an
29
+ array)
30
+ - Parsing of BibLaTeX files is now more permissive (accepts non-numeric edition,
31
+ pages, volumes, dates, and Jabref-style comments; fixed abbreviation parsing)
32
+ - Labels and references can now include `:` and `.` except at the end
33
+ - Fixed APA bibliography ordering
34
+
35
+ ## Drawing additions
36
+ - Added [`polygon`] function for drawing polygons
37
+ - Added support for clipping in [boxes]($box.clip) and [blocks]($block.clip)
38
+
39
+ ## Command line interface
40
+ - Now returns with non-zero status code if there is an error
41
+ - Now watches the root directory instead of the current one
42
+ - Now puts the PDF file next to input file by default
43
+ - Now accepts more kinds of input files (e.g. `/dev/stdin`)
44
+ - Added `--open` flag to directly open the PDF
45
+
46
+ ## Miscellaneous improvements
47
+ - Added [`yaml`] function to load data from YAML files
48
+ - Added basic i18n for a few more languages (IT, RU, ZH, FR, PT)
49
+ - Added numbering support for Hebrew
50
+ - Added support for [integers]($int) with base 2, 8, and 16
51
+ - Added symbols for double bracket and laplace operator
52
+ - The [`link`] function now accepts [labels]($label)
53
+ - The link syntax now allows more characters
54
+ - Improved justification of Japanese and Chinese text
55
+ - Calculation functions behave more consistently w.r.t to non-real results
56
+ - Replaced deprecated angle brackets
57
+ - Reduced maximum function call depth from 256 to 64
58
+ - Fixed [`first-line-indent`]($par.first-line-indent) being not applied when a
59
+ paragraph starts with styled text
60
+ - Fixed extraneous spacing in unary operators in equations
61
+ - Fixed block spacing, e.g. in `{block(above: 1cm, below: 1cm, ..)}`
62
+ - Fixed styling of text operators in math
63
+ - Fixed invalid parsing of language tag in raw block with a single backtick
64
+ - Fixed bugs with displaying counters and state
65
+ - Fixed crash related to page counter
66
+ - Fixed crash when [`symbol`] function was called without arguments
67
+ - Fixed crash in bibliography generation
68
+ - Fixed access to label of certain content elements
69
+ - Fixed line number in error message for CSV parsing
70
+ - Fixed invalid autocompletion after certain markup elements
71
+
72
+ ## Contributors
73
+ <contributors from="v23-03-28" to="v0.1.0" />
sources/docs/changelog/0.10.0.md ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: 0.10.0
3
+ description: Changes in Typst 0.10.0
4
+ ---
5
+
6
+ # Version 0.10.0 (December 4, 2023)
7
+
8
+ ## Bibliography management
9
+ - Added support for citation collapsing (e.g. `[[1]-[3]]` instead of
10
+ `[[1], [2], [3]]`) if requested by a CSL style
11
+ - Fixed bug where an additional space would appear after a group of citations
12
+ - Fixed link show rules for links in the bibliography
13
+ - Fixed show-set rules on citations
14
+ - Fixed bibliography-related crashes that happened on some systems
15
+ - Corrected name of the GB/T 7714 family of styles from 7114 to 7714
16
+ - Fixed missing title in some bibliography styles
17
+ - Fixed printing of volumes in some styles
18
+ - Fixed delimiter order for contributors in some styles (e.g. APA)
19
+ - Fixed behavior of alphanumeric style
20
+ - Fixed multiple bugs with GB/T 7714 style
21
+ - Fixed escaping in Hayagriva values
22
+ - Fixed crashes with empty dates in Hayagriva files
23
+ - Fixed bug with spacing around math blocks
24
+ - Fixed title case formatting after verbatim text and apostrophes
25
+ - Page ranges in `.bib` files can now be arbitrary strings
26
+ - Multi-line values in `.bib` files are now parsed correctly
27
+ - Entry keys in `.bib` files now allow more characters
28
+ - Fixed error message for empty dates in `.bib` files
29
+ - Added support for years of lengths other than 4 without leading zeros in
30
+ `.bib` files
31
+ - More LaTeX commands (e.g. for quotes) are now respected in `.bib` files
32
+
33
+ ## Visualization
34
+ - Added support for [patterns]($tiling) as fills and strokes
35
+ - The `alpha` parameter of the [`components`]($color.components) function on
36
+ colors is now a named parameter **(Breaking change)**
37
+ - Added support for the [Oklch]($color.oklch) color space
38
+ - Improved conversions between colors in different color spaces
39
+ - Removed restrictions on [Oklab]($color.oklab) chroma component
40
+ - Fixed [clipping]($block.clip) on blocks and boxes without a stroke
41
+ - Fixed bug with [gradients]($gradient) on math
42
+ - Fixed bug with gradient rotation on text
43
+ - Fixed bug with gradient colors in PDF
44
+ - Fixed relative base of Oklab chroma ratios
45
+ - Fixed Oklab color negation
46
+
47
+ ## Text and Layout
48
+ - CJK text can now be emphasized with the `*` and `_` syntax even when there are
49
+ no spaces
50
+ - Added basic i18n for Greek and Estonian
51
+ - Improved default [figure caption separator]($figure.caption.separator) for
52
+ Chinese, French, and Russian
53
+ - Changed default [figure supplement]($figure.supplement) for Russian to short
54
+ form
55
+ - Fixed [CJK-Latin-spacing]($text.cjk-latin-spacing) before line breaks and in
56
+ [`locate`] calls
57
+ - Fixed line breaking at the end of links
58
+
59
+ ## Math
60
+ - Added [`mid`]($math.mid) function for scaling a delimiter up to the height of
61
+ the surrounding [`lr`]($math.lr) group
62
+ - The [`op`]($math.op) function can now take any content, not just strings
63
+ - Improved documentation for [math alignment]($category/math/#alignment)
64
+ - Fixed swallowing of trailing comma when a symbol is used in a function-like
65
+ way (e.g. `pi(a,b,)`)
66
+
67
+ ## Scripting
68
+ - Any non-identifier dictionary key is now interpreted as an expression: For
69
+ instance, `{((key): value)}` will create a dictionary with a dynamic key
70
+ - The [`stroke`] type now has a constructor that converts a value to a stroke or
71
+ creates one from its parts
72
+ - Added constructor for [`arguments`] type
73
+ - Added [`calc.div-euclid`]($calc.div-euclid) and
74
+ [`calc.rem-euclid`]($calc.rem-euclid) functions
75
+ - Fixed equality of [`arguments`]
76
+ - Fixed [`repr`]of [`cmyk`]($color.cmyk) colors
77
+ - Fixed crashes with provided elements like figure captions, outline entries,
78
+ and footnote entries
79
+
80
+ ## Tooling and Diagnostics
81
+ - Show rules that match on their own output now produce an appropriate error
82
+ message instead of a crash (this is a first step, in the future they will just
83
+ work)
84
+ - Too highly or infinitely nested layouts now produce error messages instead of
85
+ crashes
86
+ - Added hints for invalid identifiers
87
+ - Added hint when trying to use a manually constructed footnote or outline entry
88
+ - Added missing details to autocompletions for types
89
+ - Improved error message when passing a named argument where a positional one is
90
+ expected
91
+ - Jump from click now works on raw blocks
92
+
93
+ ## Export
94
+ - PDF compilation output is now again fully byte-by-byte reproducible if the
95
+ document's [`date`]($document.date) is set manually
96
+ - Fixed color export in SVG
97
+ - Fixed PDF metadata encoding of multiple [authors]($document.author)
98
+
99
+ ## Command line interface
100
+ - Fixed a major bug where `typst watch` would confuse files and fail to pick up
101
+ updates
102
+ - Fetching of the release metadata in `typst update` now respects proxies
103
+ - Fixed bug with `--open` flag on Windows when the path contains a space
104
+ - The `TYPST_FONT_PATHS` environment variable can now contain multiple paths
105
+ (separated by `;` on Windows and `:` elsewhere)
106
+ - Updated embedded New Computer Modern fonts to version 4.7
107
+ - The watching process doesn't stop anymore when the main file contains invalid
108
+ UTF-8
109
+
110
+ ## Miscellaneous Improvements
111
+ - Parallelized image encoding in PDF export
112
+ - Improved the internal representation of content for improved performance
113
+ - Optimized introspection (query, counter, etc.) performance
114
+ - The [document title]($document.title) can now be arbitrary content instead of
115
+ just a string
116
+ - The [`number-align`]($enum.number-align) parameter on numbered lists now also
117
+ accepts vertical alignments
118
+ - Fixed selectors on [quote] elements
119
+ - Fixed parsing of `[#return]` expression in markup
120
+ - Fixed bug where inline equations were displayed in equation outlines
121
+ - Fixed potential CRLF issue in [`raw`] blocks
122
+ - Fixed a bug where Chinese numbering couldn't exceed the number 255
123
+
124
+ ## Development
125
+ - Merged `typst` and `typst-library` and extracted `typst-pdf`, `typst-svg`, and
126
+ `typst-render` into separate crates
127
+ - The Nix flake now includes the git revision when running `typst --version`
128
+
129
+ ## Contributors
130
+ <contributors from="v0.9.0" to="v0.10.0" />
sources/docs/changelog/0.11.0.md ADDED
@@ -0,0 +1,270 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: 0.11.0
3
+ description: Changes in Typst 0.11.0
4
+ ---
5
+
6
+ # Version 0.11.0 (March 15, 2024)
7
+
8
+ ## Tables
9
+ - Tables are now _much_ more flexible, read the new
10
+ [table guide]($guides/table-guide) to get started
11
+ - Added [`table.cell`] element for per-cell configuration
12
+ - Cells can now span multiple [columns]($table.cell.colspan) or
13
+ [rows]($table.cell.rowspan)
14
+ - The [stroke]($table.cell.stroke) of individual cells can now be customized
15
+ - The [`align`]($table.align) and [`inset`]($table.inset) arguments of the table
16
+ function now also take `{(x, y) => ..}` functions
17
+ - Added [`table.hline`] and [`table.vline`] for convenient line customization
18
+ - Added [`table.header`] element for table headers that repeat on every page
19
+ - Added [`table.footer`] element for table footers that repeat on every page
20
+ - All the new table functionality is also available for [grids]($grid)
21
+ - Fixed gutter-related bugs
22
+
23
+ _Thanks to [@PgBiel](https://github.com/PgBiel) for his work on tables!_
24
+
25
+ ## Templates
26
+ - You can now use template packages to get started with new projects. Click
27
+ _Start from template_ on the web app's dashboard and choose your preferred
28
+ template or run the `typst init <template>` command in the CLI. You can
29
+ [browse the available templates here]($universe/search/?kind=templates).
30
+ - Switching templates after the fact has become easier. You can just import a
31
+ styling function from a different template package.
32
+ - Package authors can now submit their own templates to the
33
+ [package repository](https://github.com/typst/packages). Share a template
34
+ for a paper, your institution, or an original work to help the community get
35
+ a head start on their projects.
36
+ - Templates and packages are now organized by category and discipline. Filter
37
+ packages by either taxonomy in the _Start from template_ wizard. If you are a
38
+ package author, take a look at the new documentation for
39
+ [categories](https://github.com/typst/packages/blob/main/CATEGORIES.md) and
40
+ [disciplines](https://github.com/typst/packages/blob/main/DISCIPLINES.md).
41
+
42
+ ## Context
43
+ - Added _context expressions:_ Read the chapter on [context] to get started
44
+ - With context, you can access settable properties, e.g. `{context text.lang}`
45
+ to access the language set via `{set text(lang: "..")}`
46
+ - The following existing functions have been made contextual: [`query`],
47
+ [`locate`], [`measure`], [`counter.display`], [`counter.at`],
48
+ [`counter.final`], [`state.at`], and [`state.final`]
49
+ - Added contextual methods [`counter.get`] and [`state.get`] to retrieve the
50
+ value of a counter or state in the current context
51
+ - Added contextual function [`here`] to retrieve the [location] of the current
52
+ context
53
+ - The [`locate`] function now returns the location of a selector's unique match.
54
+ Its old behavior has been replaced by context expressions and only remains
55
+ temporarily available for compatibility.
56
+ - The [`counter.at`] and [`state.at`] methods are now more flexible: They
57
+ directly accept any kind of [locatable]($location/#locatable) selector with a
58
+ unique match (e.g. a label) instead of just locations
59
+ - When context is available, [`counter.display`] now directly returns the result
60
+ of applying the numbering instead of yielding opaque content. It should not be
61
+ used anymore without context. (Deprecation planned)
62
+ - The `state.display` function should not be used anymore, use [`state.get`]
63
+ instead (Deprecation planned)
64
+ - The `location` argument of [`query`], [`counter.final`], and [`state.final`]
65
+ should not be used anymore (Deprecation planned)
66
+ - The `styles` argument of the `measure` function should not be used anymore
67
+ (Deprecation planned)
68
+ - The `style` function should not be used anymore, use context instead
69
+ (Deprecation planned)
70
+ - The correct context is now also provided in various other places where it is
71
+ available, e.g. in show rules, layout callbacks, and numbering functions in
72
+ the outline
73
+
74
+ ## Styling
75
+ - Fixed priority of multiple [show-set rules]($styling/#show-rules): They now
76
+ apply in the same order as normal set rules would
77
+ - Show-set rules on the same element (e.g. `{show heading.where(level: 1): set
78
+ heading(numbering: "1.")}`) now work properly
79
+ - Setting properties on an element within a transformational show rule (e.g.
80
+ `{show heading: it => { set heading(..); it }}`) is **not** supported anymore
81
+ (previously it also only worked sometimes); use show-set rules instead
82
+ **(Breaking change)**
83
+ - Text show rules that match their own output now work properly (e.g.
84
+ `` {show "cmd": `cmd`} ``)
85
+ - The elements passed to show rules and returned by queries now contain all
86
+ fields of their respective element functions rather than just specific ones
87
+ - All settable properties can now be used in [where]($function.where) selectors
88
+ - [And]($selector.and) and [or]($selector.or) selectors can now be used with
89
+ show rules
90
+ - Errors within show rules and context expressions are now ignored in all but
91
+ the last introspection iteration, in line with the behavior of the old
92
+ [`locate`]
93
+ - Fixed a bug where document set rules were allowed after content
94
+
95
+ ## Layout
96
+ - Added `reflow` argument to [`rotate`]($rotate) and [`scale`]($scale) which
97
+ lets them affect the layout
98
+ - Fixed a bug where [floating placement]($place.float) or
99
+ [floating figures]($figure.placement) could end up out of order
100
+ - Fixed overlap of text and figure for full-page floating figures
101
+ - Fixed various cases where the [`hide`] function didn't hide its contents
102
+ properly
103
+ - Fixed usage of [`h`] and [`v`] in [stacks]($stack)
104
+ - Invisible content like a counter update will no longer force a visible block
105
+ for just itself
106
+ - Fixed a bug with horizontal spacing followed by invisible content (like a
107
+ counter update) directly at the start of a paragraph
108
+
109
+ ## Text
110
+ - Added [`stroke`]($text.stroke) property for text
111
+ - Added basic i18n for Serbian and Catalan
112
+ - Added support for contemporary Japanese [numbering] method
113
+ - Added patches for various wrong metadata in specific fonts
114
+ - The [text direction]($text.dir) can now be overridden within a paragraph
115
+ - Fixed Danish [smart quotes]($smartquote)
116
+ - Fixed font fallback next to a line break
117
+ - Fixed width adjustment of JIS-style Japanese punctuation
118
+ - Fixed Finnish translation of "Listing"
119
+ - Fixed Z-ordering of multiple text decorations (underlines, etc.)
120
+ - Fixed a bug due to which text [features]($text.features) could not be
121
+ overridden in consecutive set rules
122
+
123
+ ## Model
124
+ - Added [`depth`]($heading.depth) and [`offset`]($heading.offset) arguments to
125
+ heading to increase or decrease the heading level for a bunch of content; the
126
+ heading syntax now sets `depth` rather than `level` **(Breaking change)**
127
+ - List [markers]($list.marker) now cycle by default
128
+ - The [`quote`] function now more robustly selects the correct quotes based on
129
+ language and nesting
130
+ - Fixed indent bugs related to the default show rule of [terms]
131
+
132
+ ## Math
133
+ - Inline equations now automatically linebreak at appropriate places
134
+ - Added [`number-align`]($math.equation.number-align) argument to equations
135
+ - Added support for adjusting the [`size`]($math.accent.size) of accents
136
+ relative to their base
137
+ - Improved positioning of accents
138
+ - [Primes]($math.primes) are now always attached as [scripts]($math.scripts) by
139
+ default
140
+ - Exposed [`math.primes`] element which backs the `[$f'$]` syntax in math
141
+ - Math mode is not affected by [`strong`] and [`emph`] anymore
142
+ - Fixed [`attach`]($math.attach) under [fractions]($math.frac)
143
+ - Fixed that [`math.class`] did not affect smart limit placement
144
+ - Fixed weak spacing in [`lr`]($math.lr) groups
145
+ - Fixed layout of large operators for Cambria Math font
146
+ - Fixed math styling of Hebrew symbol codepoints
147
+
148
+ ## Symbols
149
+ - Added `gradient` as an alias for `nabla`
150
+ - Added `partial` as an alias for `diff`, `diff` will be deprecated in the
151
+ future
152
+ - Added `colon.double`, `gt.approx`, `gt.napprox`, `lt.approx`, and `lt.napprox`
153
+ - Added `arrow.r.tilde` and `arrow.l.tilde`
154
+ - Added `tilde.dot`
155
+ - Added `forces` and `forces.not`
156
+ - Added `space.nobreak.narrow`
157
+ - Added `lrm` (Left-to-Right Mark) and `rlm` (Right-to-Left Mark)
158
+ - Fixed `star.stroked` symbol (which previously had the wrong codepoint)
159
+
160
+ ## Scripting
161
+ - Arrays can now be compared lexicographically
162
+ - Added contextual method [`to-absolute`]($length.to-absolute) to lengths
163
+ - Added [`calc.root`]($calc.root)
164
+ - Added [`int.signum`] and [`float.signum`] methods
165
+ - Added [`float.is-nan`] and [`float.is-infinite`] methods
166
+ - Added [`int.bit-not`], [`int.bit-and`], [`int.bit-or`], [`int.bit-xor`],
167
+ [`int.bit-lshift`], and [`int.bit-rshift`] methods
168
+ - Added [`array.chunks`] method
169
+ - A module can now be converted to a dictionary with the
170
+ [dictionary constructor]($dictionary/#constructor) to access its contents
171
+ dynamically
172
+ - Added [`row-type`]($csv.row-type) argument to `csv` function to configure
173
+ how rows will be represented
174
+ - [XML parsing]($xml) now allows DTDs (document type definitions)
175
+ - Improved formatting of negative numbers with [`str`]($str) and [`repr`]($repr)
176
+ - For loops can now iterate over [bytes]
177
+ - Fixed a bug with pattern matching in for loops
178
+ - Fixed a bug with labels not being part of [`{.fields()}`]($content.fields)
179
+ dictionaries
180
+ - Fixed a bug where unnamed argument sinks wouldn't capture excess arguments
181
+ - Fixed typo in `repr` output of strokes
182
+
183
+ ## Syntax
184
+ - Added support for nested [destructuring patterns]($scripting/#bindings)
185
+ - Special spaces (like thin or non-breaking spaces) are now parsed literally
186
+ instead of being collapsed into normal spaces **(Breaking change)**
187
+ - Korean text can now use emphasis syntax without adding spaces
188
+ **(Breaking change)**
189
+ - The token [`context`] is now a keyword and cannot be used as an identifier
190
+ anymore **(Breaking change)**
191
+ - Nested line comments aren't allowed anymore in block comments
192
+ **(Breaking change)**
193
+ - Fixed a bug where `x.)` would be treated as a field access
194
+ - Text elements can now span across curly braces in markup
195
+ - Fixed silently wrong parsing when function name is parenthesized
196
+ - Fixed various bugs with parsing of destructuring patterns, arrays, and
197
+ dictionaries
198
+
199
+ ## Tooling & Diagnostics
200
+ - Click-to-jump now works properly within [`raw`] text
201
+ - Added suggestion for accessing a field if a method doesn't exist
202
+ - Improved hint for calling a function stored in a dictionary
203
+ - Improved errors for mutable accessor functions on arrays and dictionaries
204
+ - Fixed error message when calling constructor of type that doesn't have one
205
+ - Fixed confusing error message with nested dictionaries for strokes on
206
+ different sides
207
+ - Fixed autocompletion for multiple packages with the same name from different
208
+ namespaces
209
+
210
+ ## Visualization
211
+ - The [`image`] function doesn't upscale images beyond their natural size
212
+ anymore
213
+ - The [`image`] function now respects rotation stored in EXIF metadata
214
+ - Added support for SVG filters
215
+ - Added alpha component to [`luma`]($color.luma) colors
216
+ - Added [`color.transparentize`] and [`color.opacify`] methods
217
+ - Improved [`color.negate`] function
218
+ - Added [`stroke`]($highlight.stroke) and [`radius`]($highlight.radius)
219
+ arguments to `highlight` function
220
+ - Changed default [`highlight`] color to be transparent
221
+ - CMYK to RGB conversion is now color-managed
222
+ - Fixed crash with gradients in Oklch color space
223
+ - Fixed color-mixing for hue-based spaces
224
+ - Fixed bugs with color conversion
225
+ - SVG sizes are not rounded anymore, preventing slightly wrong aspect ratios
226
+ - Fixed a few other SVG-related bugs
227
+ - [`color.components`] doesn't round anything anymore
228
+
229
+ ## Export
230
+ - PDFs now contain named destinations for headings derived from their labels
231
+ - The internal PDF structure was changed to make it easier for external tools to
232
+ extract or modify individual pages, avoiding a bug with Typst PDFs in Apple
233
+ Preview
234
+ - PDFs produced by Typst should now be byte-by-byte reproducible when
235
+ `{set document(date: none)}` is set
236
+ - Added missing flag to PDF annotation
237
+ - Fixed multiple bugs with gradients in PDF export
238
+ - Fixed a bug with patterns in PDF export
239
+ - Fixed a bug with embedding of grayscale images in PDF export
240
+ - Fixed a bug with To-Unicode mapping of CFF fonts in PDF export
241
+ - Fixed a bug with the generation of the PDF outline
242
+ - Fixed a sorting bug in PDF export leading to non-reproducible output
243
+ - Fixed a bug with transparent text in PNG export
244
+ - Exported SVG files now include units in their top-level `width` and `height`
245
+
246
+ ## Command line interface
247
+ - Added support for passing [inputs]($category/foundations/sys) via a CLI flag
248
+ - When passing the filename `-`, Typst will now read input from stdin
249
+ - Now uses the system-native TLS implementation for network fetching which
250
+ should be generally more robust
251
+ - Watch mode will now properly detect when a previously missing file is created
252
+ - Added `--color` flag to configure whether to print colored output
253
+ - Fixed user agent with which packages are downloaded
254
+ - Updated bundled fonts to the newest versions
255
+
256
+ ## Development
257
+ - Added `--vendor-openssl` to CLI to configure whether to link OpenSSL
258
+ statically instead of dynamically (not applicable to Windows and Apple
259
+ platforms)
260
+ - Removed old tracing (and its verbosity) flag from the CLI
261
+ - Added new `--timings` flag which supersedes the old flamegraph profiling in
262
+ the CLI
263
+ - Added minimal CLI to `typst-docs` crate for extracting the language and
264
+ standard library documentation as JSON
265
+ - The `typst_pdf::export` function's `ident` argument switched from `Option` to
266
+ `Smart`. It should only be set to `Smart::Custom` if you can provide a stable
267
+ identifier (like the web app can). The CLI sets `Smart::Auto`.
268
+
269
+ ## Contributors
270
+ <contributors from="v0.10.0" to="v0.11.0" />
sources/docs/changelog/0.11.1.md ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: 0.11.1
3
+ description: Changes in Typst 0.11.1
4
+ ---
5
+
6
+ # Version 0.11.1 (May 17, 2024)
7
+
8
+ ## Security
9
+ - Fixed a vulnerability where image files at known paths could be embedded into
10
+ the PDF even if they were outside of the project directory
11
+
12
+ ## Bibliography
13
+ - Fixed et-al handling in subsequent citations
14
+ - Fixed suppression of title for citations and bibliography references with no
15
+ author
16
+ - Fixed handling of initials in citation styles without a delimiter
17
+ - Fixed bug with citations in footnotes
18
+
19
+ ## Text and Layout
20
+ - Fixed interaction of [`first-line-indent`]($par.first-line-indent) and
21
+ [`outline`]
22
+ - Fixed compression of CJK punctuation marks at line start and end
23
+ - Fixed handling of [rectangles]($rect) with negative dimensions
24
+ - Fixed layout of [`path`] in explicitly sized container
25
+ - Fixed broken [`raw`] text in right-to-left paragraphs
26
+ - Fixed tab rendering in `raw` text with language `typ` or `typc`
27
+ - Fixed highlighting of multi-line `raw` text enclosed by single backticks
28
+ - Fixed indentation of overflowing lines in `raw` blocks
29
+ - Fixed extra space when `raw` text ends with a backtick
30
+
31
+ ## Math
32
+ - Fixed broken [equations]($math.equation) in right-to-left paragraphs
33
+ - Fixed missing [blackboard bold]($math.bb) letters
34
+ - Fixed error on empty arguments in 2D math argument list
35
+ - Fixed stretching via [`mid`]($math.mid) for various characters
36
+ - Fixed that alignment points in equations were affected by `{set align(..)}`
37
+
38
+ ## Export
39
+ - Fixed [smart quotes]($smartquote) in PDF outline
40
+ - Fixed [patterns]($tiling) with spacing in PDF
41
+ - Fixed wrong PDF page labels when [page numbering]($page.numbering) was
42
+ disabled after being previously enabled
43
+
44
+ ## Scripting
45
+ - Fixed overflow for large numbers in external data files (by converting to
46
+ floats instead)
47
+ - Fixed [`{str.trim(regex, at: end)}`]($str.trim) when the whole string is
48
+ matched
49
+
50
+ ## Miscellaneous
51
+ - Fixed deformed strokes for specific shapes and thicknesses
52
+ - Fixed newline handling in code mode: There can now be comments within chained
53
+ method calls and between an `if` branch and the `else` keyword
54
+ - Fixed inefficiency with incremental reparsing
55
+ - Fixed autocompletions for relative file imports
56
+ - Fixed crash in autocompletion handler
57
+ - Fixed a bug where the path and entrypoint printed by `typst init` were not
58
+ properly escaped
59
+ - Fixed various documentation errors
60
+
61
+ ## Contributors
62
+ <contributors from="v0.11.0" to="v0.11.1" />
sources/docs/changelog/0.12.0.md ADDED
@@ -0,0 +1,402 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: 0.12.0
3
+ description: Changes in Typst 0.12.0
4
+ ---
5
+
6
+ # Version 0.12.0 (October 18, 2024)
7
+
8
+ ## Highlights
9
+ - Added support for multi-column floating [placement]($place.scope) and
10
+ [figures]($figure.scope)
11
+ - Added support for automatic [line numbering]($par.line) (often used in
12
+ academic papers)
13
+ - Typst's layout engine is now multithreaded. Typical speedups are 2-3x for
14
+ larger documents. The multithreading operates on page break boundaries, so
15
+ explicit page breaks are necessary for it to kick in.
16
+ - Paragraph justification was optimized with a new two-pass algorithm. Speedups
17
+ are larger for shorter paragraphs and go up to 6x.
18
+ - Highly reduced PDF file sizes due to better font subsetting (thanks to
19
+ [@LaurenzV](https://github.com/LaurenzV))
20
+ - Emoji are now exported properly in PDF
21
+ - Added initial support for PDF/A. For now, only the PDF/A-2b profile is
22
+ supported, but more is planned for the future.
23
+ - Added various options for configuring the CLI's environment (fonts, package
24
+ paths, etc.)
25
+ - Text show rules now match across multiple text elements
26
+ - Block-level equations can now optionally break over multiple pages
27
+ - Fixed a bug where some fonts would not print correctly on professional
28
+ printers
29
+ - Fixed a long-standing bug which could cause headings to be orphaned at the
30
+ bottom of the page
31
+
32
+ ## Layout
33
+ - Added support for multi-column floating placement and figures via
34
+ [`place.scope`] and [`figure.scope`]. Two-column documents should now prefer
35
+ `{set page(columns: 2)}` over `{show: column.with(2)}` (see the
36
+ [page setup guide]($guides/page-setup-guide/#columns)).
37
+ - Added support for automatic [line numbering]($par.line) (often used in
38
+ academic papers)
39
+ - Added [`par.spacing`] property for configuring paragraph spacing. This should
40
+ now be used instead of `{show par: set block(spacing: ..)}`
41
+ **(Breaking change)**
42
+ - Block-level elements like lists, grids, and stacks now show themselves as
43
+ blocks and are thus affected by all block properties (e.g. `stroke`) rather
44
+ than just `spacing` **(Breaking change)**
45
+ - Added [`block.sticky`] property which prevents a page break after a block
46
+ - Added [`place.flush`] function which forces all floating figures to be placed
47
+ before any further content
48
+ - Added [`skew`] function
49
+ - Added `{auto}` option for [`page.header`] and [`page.footer`] which results in
50
+ an automatic header/footer based on the numbering (which was previously
51
+ inaccessible after a change)
52
+ - Added `gap` and `justify` parameters to [`repeat`] function
53
+ - Added `width` and `height` parameters to the [`measure`] function to define
54
+ the space in which the content should be measured. Especially useful in
55
+ combination with [`layout`].
56
+ - The height of a `block`, `image`, `rect`, `square`, `ellipse`, or `circle` can
57
+ now be specified in [fractional units]($fraction)
58
+ - The [`scale`] function now supports absolute lengths for `x`, `y`, `factor`.
59
+ This way an element of unknown size can be scaled to a fixed size.
60
+ - The values of `block.above` and `block.below` can now be retrieved in context
61
+ expressions.
62
+ - Increased accuracy of conversions between absolute units (pt, mm, cm, in)
63
+ - Fixed a bug which could cause headings to be orphaned at the bottom of the
64
+ page
65
+ - Fixed footnotes within breakable blocks appearing on the page where the
66
+ breakable block ends instead of at the page where the footnote marker is
67
+ - Fixed numbering of nested footnotes and footnotes in floats
68
+ - Fixed empty pages appearing when a [context] expression wraps whole pages
69
+ - Fixed `{set block(spacing: x)}` behaving differently from
70
+ `{set block(above: x, below: x)}`
71
+ - Fixed behavior of [`rotate`] and [`scale`] with `{reflow: true}`
72
+ - Fixed interaction of `{align(horizon)}` and `{v(1fr)}`
73
+ - Fixed various bugs where floating placement would yield overlapping results
74
+ - Fixed a bug where widow/orphan prevention would unnecessarily move text into
75
+ the next column
76
+ - Fixed [weak spacing]($h.weak) not being trimmed at the start and end of lines
77
+ in a paragraph (only at the start and end of paragraphs)
78
+ - Fixed interaction of weak page break and [`pagebreak.to`]
79
+ - Fixed compilation output of a single weak page break
80
+ - Fixed crash when [padding]($pad) by `{100%}`
81
+
82
+ ## Text
83
+ - Tuned hyphenation: It is less eager by default and hyphenations close to the
84
+ edges of words are now discouraged more strongly
85
+ **(May lead to larger layout reflows)**
86
+ - New default font: Libertinus Serif. This is the maintained successor to the
87
+ old default font Linux Libertine. **(May lead to smaller reflows)**
88
+ - Setting the font to an unavailable family will now result in a warning
89
+ - Implemented a new smart quote algorithm, fixing various bugs where smart
90
+ quotes weren't all that smart
91
+ - Added [`text.costs`] parameter for tweaking various parameters that affect the
92
+ choices of the layout engine during text layout
93
+ - Added `typm` highlighting mode for math in [raw blocks]($raw.lang)
94
+ - Added basic i18n for Galician, Catalan, Latin, Icelandic, Hebrew
95
+ - Implemented hyphenation duplication for Czech, Croatian, Lower Sorbian,
96
+ Polish, Portuguese, Slovak, and Spanish.
97
+ - The [`smallcaps`] function is now an element function and can thereby be used
98
+ in show(-set) rules.
99
+ - The [`raw.theme`] parameter can now be set to `{none}` to disable highlighting
100
+ even in the presence of a language tag, and to `{auto}` to reset to the
101
+ default
102
+ - Multiple [stylistic sets]($text.stylistic-set) can now be enabled at once
103
+ - Fixed the Chinese translation for "Equation"
104
+ - Fixed that hyphenation could occur outside of words
105
+ - Fixed incorrect layout of bidirectional text in edge cases
106
+ - Fixed layout of paragraphs with explicit trailing whitespace
107
+ - Fixed bugs related to empty paragraphs created via `#""`
108
+ - Fixed accidental trailing spaces for line breaks immediately preceding an
109
+ inline equation
110
+ - Fixed [`text.historical-ligatures`] not working correctly
111
+ - Fixed accidental repetition of Thai characters around line breaks in some
112
+ circumstances
113
+ - Fixed [smart quotes]($smartquote) for Swiss French
114
+ - New font metadata exceptions for Archivo, Kaiti SC, and Kaiti TC
115
+ - Updated bundled New Computer Modern fonts to version 6.0
116
+
117
+ ## Math
118
+ - Block-level equations can now break over multiple pages if enabled via
119
+ `{show math.equation: set block(breakable: true)}`.
120
+ - Matrix and vector sizing is now more consistent across different cell contents
121
+ - Added [`stretch`]($math.stretch) function for manually or automatically
122
+ stretching characters like arrows or parentheses horizontally or vertically
123
+ - Improved layout of attachments on parenthesized as well as under- or overlined
124
+ expressions
125
+ - Improved layout of nested attachments resulting from code like
126
+ `[#let a0 = $a_0$; $a0^1$]`
127
+ - Improved layout of primes close to superscripts
128
+ - Improved layout of fractions
129
+ - Typst now makes use of math-specific height-dependent kerning information in
130
+ some fonts for better attachment layout
131
+ - The `floor` and `ceil` functions in math are now callable symbols, such that
132
+ `[$ floor(x) = lr(floor.l x floor.r) $]`
133
+ - The [`mat.delim`]($math.mat.delim), [`vec.delim`]($math.vec.delim), and
134
+ [`cases.delim`]($math.cases.delim) parameters now allow any character that is
135
+ considered a delimiter or "fence" (e.g. |) by Unicode. The `{delim: "||"}`
136
+ notation is _not_ supported anymore and should be replaced by
137
+ `{delim: bar.double}` **(Minor breaking change)**
138
+ - Added [`vec.align`]($math.vec.align) and [`mat.align`]($math.mat.align)
139
+ parameters
140
+ - Added [`underparen`]($math.underparen), [`overparen`]($math.overparen),
141
+ [`undershell`]($math.undershell), and [`overshell`]($math.overshell)
142
+ - Added `~` shorthand for `tilde.op` in math mode **(Minor breaking change)**
143
+ - Fixed baseline alignment of equation numbers
144
+ - Fixed positioning of corner brackets (⌜, ⌝, ⌞, ⌟)
145
+ - Fixed baseline of large roots
146
+ - Fixed multiple minor layout bugs with attachments
147
+ - Fixed that alignment points could affect line height in math
148
+ - Fixed that spaces could show up between text and invisible elements like
149
+ [`metadata`] in math
150
+ - Fixed a crash with recursive show rules in math
151
+ - Fixed [`lr.size`]($math.lr.size) not affecting characters enclosed in
152
+ [`mid`]($math.mid) in some cases
153
+ - Fixed resolving of em units in sub- and superscripts
154
+ - Fixed bounding box of inline equations when a [text edge]($text.top-edge) is
155
+ set to `{"bounds"}`
156
+
157
+ ## Introspection
158
+ - Implemented a new system by which Typst tracks where elements end up on the
159
+ pages. This may lead to subtly different behavior in introspections.
160
+ **(Breaking change)**
161
+ - Fixed various bugs with wrong counter behavior in complex layout situations,
162
+ through a new, more principled implementation
163
+ - Counter updates can now be before the first, in between, and after the last
164
+ page when isolated by weak page breaks. This allows, for instance, updating a
165
+ counter before the first page header and background.
166
+ - Fixed logical ordering of introspections within footnotes and figures
167
+ - Fixed incorrect [`here().position()`]($here) when [`place`] was used in a
168
+ context expression
169
+ - Fixed resolved positions of elements (in particular, headings) whose show rule
170
+ emits an invisible element (like a state update) before a page break
171
+ - Fixed behavior of stepping a counter at a deeper level than its current state
172
+ has
173
+ - Fixed citation formatting not working in table headers and a few other places
174
+ - Displaying the footnote counter will now respect the footnote numbering style
175
+
176
+ ## Model
177
+ - Document set rules do not need to be at the very start of the document
178
+ anymore. The only restriction is that they must not occur inside of layout
179
+ containers.
180
+ - The `spacing` property of [lists]($list.spacing),
181
+ [enumerations]($enum.spacing), and [term lists]($terms.spacing) is now also
182
+ respected for tight lists
183
+ - Tight lists now only attach (with tighter spacing) to preceding paragraphs,
184
+ not arbitrary blocks
185
+ - The [`quote`] element is now locatable (can be used in queries)
186
+ - The bibliography heading now uses `depth` instead of `level` so that its level
187
+ can still be configured via a show-set rule
188
+ - Added support for more [numbering] formats: Devanagari, Eastern Arabic,
189
+ Bengali, and circled numbers
190
+ - Added [`hanging-indent`]($heading.hanging-indent) parameter to heading
191
+ function to tweak the appearance of multi-line headings and improved default
192
+ appearance of multi-line headings
193
+ - Improved handling of bidirectional text in outline entry
194
+ - Fixed document set rules being ignored in an otherwise empty document
195
+ - Fixed document set rules not being usable in context expressions
196
+ - Fixed bad interaction between `{set document}` and `{set page}`
197
+ - Fixed `{show figure: set align(..)}`. Since the default figure alignment is
198
+ now a show-set rule, it is not revoked by `{show figure: it => it.body}`
199
+ anymore. **(Minor breaking change)**
200
+ - Fixed numbering of footnote references
201
+ - Fixed spacing after bibliography heading
202
+
203
+ ## Bibliography
204
+ - The Hayagriva YAML `publisher` field can now accept a dictionary with a
205
+ `location` key. The top-level `location` key is now primarily intended for
206
+ event and item locations.
207
+ - Multiple page ranges with prefixes and suffixes are now allowed
208
+ - Added `director` and catch-all editor types to BibLaTeX parsing
209
+ - Added support for disambiguation to alphanumeric citation style
210
+ - The year 0 will now render as 1BC
211
+ - Fixes for sorting of bibliography entries
212
+ - Fixed pluralization of page range labels
213
+ - Fixed sorting of citations by their number
214
+ - Fixed how citation number ranges collapse
215
+ - Fixed when the short form of a title is used
216
+ - Fixed parsing of unbalanced dollars in BibLaTeX `url` field
217
+ - Updated built-in citation styles
218
+
219
+ ## Visualization
220
+ - Added `fill-rule` parameter to [`path`]($path.fill-rule) and
221
+ [`polygon`]($polygon.fill-rule) functions
222
+ - Fixed color mixing and gradients for [Luma colors]($color.luma)
223
+ - Fixed conversion from Luma to CMYK colors
224
+ - Fixed offset gradient strokes in PNG export
225
+ - Fixed unintended cropping of some SVGs
226
+ - SVGs with foreign objects now produce a warning as they will likely not render
227
+ correctly in Typst
228
+
229
+ ## Syntax
230
+ - Added support for nested imports like `{import "file.typ": module.item}`
231
+ - Added support for parenthesized imports like `{import "file.typ": (a, b, c)}`.
232
+ With those, the import list can break over multiple lines.
233
+ - Fixed edge case in parsing of reference syntax
234
+ - Fixed edge case in parsing of heading, list, enum, and term markers
235
+ immediately followed by comments
236
+ - Fixed rare crash in parsing of parenthesized expressions
237
+
238
+ ## Scripting
239
+ - Added new fixed-point [`decimal`] number type for highly precise arithmetic on
240
+ numbers in base 10, as needed for finance
241
+ - Added `std` module for accessing standard library definitions even when a
242
+ variable with the same name shadows/overwrites it
243
+ - Added [`array.to-dict`], [`array.reduce`], [`array.windows`] methods
244
+ - Added `exact` argument to [`array.zip`]
245
+ - Added [`arguments.at`] method
246
+ - Added [`int.from-bytes`], [`int.to-bytes`], [`float.from-bytes`], and
247
+ [`float.to-bytes`]
248
+ - Added proper support for negative values of the `digits` parameter of
249
+ [`calc.round`] (the behaviour existed before but was subtly broken)
250
+ - Conversions from [`int`] to [`float`] will now error instead of saturating if
251
+ the float is too large **(Minor breaking change)**
252
+ - Added `float.nan` and `float.inf`, removed `calc.nan`
253
+ **(Minor breaking change)**
254
+ - Certain symbols are now generally callable like functions and not only
255
+ specifically in math. Examples are accents or [`floor`]($math.floor) and
256
+ [`ceil`]($math.ceil).
257
+ - Improved [`repr`] of relative values, sequences, infinities, NaN,
258
+ `{type(none)}` and `{type(auto)}`
259
+ - Fixed crash on whole packages (rather than just files) cyclically importing
260
+ each other
261
+ - Fixed return type of [`calc.round`] on integers when a non-zero value is
262
+ provided for `digits`
263
+
264
+ ## Styling
265
+ - Text show rules now match across multiple text elements
266
+ - The string `{"}` in a text show rule now matches smart quotes
267
+ - Fixed a long-standing styling bug where the header and footer would
268
+ incorrectly inherit styles from a lone element on the page (e.g. a heading)
269
+ - Fixed `{set page}` not working directly after a counter/state update
270
+ - Page fields configured via an explicit `{page(..)[..]}` call can now be
271
+ properly retrieved in context expressions
272
+
273
+ ## Export
274
+ - Highly reduced PDF file sizes due to better font subsetting
275
+ - Emoji are now exported properly in PDF
276
+ - Added initial support for PDF/A. For now, only the standard PDF/A-2b is
277
+ supported, but more is planned for the future. Enabled via `--pdf-standard
278
+ a-2b` in the CLI and via the UI in File > Export as > PDF in the web app.
279
+ - Setting [`page.fill`] to `{none}` will now lead to transparent pages instead
280
+ of white ones in PNG and SVG. The new default of `{auto}` means transparent
281
+ for PDF and white for PNG and SVG.
282
+ - Improved text copy-paste from PDF in complex scenarios
283
+ - Exported SVGs now contain the `data-typst-label` attribute on groups resulting
284
+ from labelled [boxes]($box) and [blocks]($block)
285
+ - Fixed a bug where some fonts would not print correctly on professional
286
+ printers
287
+ - Fixed a bug where transparency could leak from one PDF object to another
288
+ - Fixed a bug with CMYK gradients in PDF
289
+ - Fixed various bugs with export of Oklab gradients in PDF
290
+ - Fixed crashes related to rendering of non-outline glyphs
291
+ - Two small fixes for PDF standard conformance
292
+
293
+ ## Performance
294
+ - Typst's layout engine is now multithreaded. Typical speedups are 2-3x for
295
+ larger documents. The multithreading operates on page break boundaries, so
296
+ explicit page breaks are necessary for it to kick in.
297
+ - Paragraph justification was optimized with a new two-pass algorithm. Speedups
298
+ are larger for shorter paragraphs and range from 1-6x.
299
+
300
+ ## Command Line Interface
301
+ - Added `--pages` option to select specific page ranges to export
302
+ - Added `--package-path` and `--package-cache-path` as well as
303
+ `TYPST_PACKAGE_PATH` and `TYPST_PACKAGE_CACHE_PATH` environment variables for
304
+ configuring where packages are loaded from and cached in, respectively
305
+ - Added `--ignore-system-fonts` flag to disable system fonts fully for better
306
+ reproducibility
307
+ - Added `--make-deps` argument for outputting the dependencies of the current
308
+ compilation as a Makefile
309
+ - Added `--pretty` option to `typst query`, with the default now being to minify
310
+ (only applies to JSON format)
311
+ - Added `--backup-path` to `typst update` to configure where the previous
312
+ version is backed up
313
+ - Added useful links to help output
314
+ - The CLI will now greet users who invoke just `typst` for the first time
315
+ - The document can now be written to stdout by passing `-` as the output
316
+ filename (for PDF or single-page image export)
317
+ - Typst will now emit a proper error message instead of failing silently when
318
+ the certificate specified by `--cert` or `TYPST_CERT` could not be loaded
319
+ - The CLI now respects the `SOURCE_DATE_EPOCH` environment variable for better
320
+ reproducibility
321
+ - When exporting multiple images, you can now use `{t}` (total pages), `{p}`
322
+ (current page), and `{0p}` (zero-padded current page, same as current `{n}`)
323
+ in the output path
324
+ - The input and output paths now allow non-UTF-8 values
325
+ - Times are now formatted more consistently across the CLI
326
+ - Fixed a bug related to the `--open` flag
327
+ - Fixed path completions for `typst` not working in zsh
328
+
329
+ ## Tooling and Diagnostics
330
+ - The "compiler" field for specifying the minimum Typst version required by a
331
+ package now supports imprecise bounds like 0.11 instead of 0.11.0
332
+ - Added warning when a label is ignored by Typst because no preceding labellable
333
+ element exists
334
+ - Added hint when trying to apply labels in code mode
335
+ - Added hint when trying to call a standard library function that has been
336
+ shadowed/overwritten by a local definition
337
+ - Added hint when trying to set both the language and the region in the `lang`
338
+ parameter
339
+ - Added hints when trying to compile non-Typst files (e.g. after having typed
340
+ `typst c file.pdf` by accident)
341
+ - Added hint when a string is used where a label is expected
342
+ - Added hint when a stray end of a block comment (`*/`) is encountered
343
+ - Added hints when destructuring arrays with the wrong number of elements
344
+ - Improved error message when trying to use a keyword as an identifier in a let
345
+ binding
346
+ - Improved error messages when accessing nonexistent fields
347
+ - Improved error message when a package exists, but not the specified version
348
+ - Improved hints for unknown variables
349
+ - Improved hint when trying to convert a length with non-zero em component to an
350
+ absolute unit
351
+ - Fixed a crash that could be triggered by certain hover tooltips
352
+ - Fixed an off-by-one error in to-source jumps when first-line-indent is enabled
353
+ - Fixed suggestions for `.` after the end of an inline code expressions
354
+ - Fixed autocompletions being duplicated in a specific case
355
+
356
+ ## Symbols
357
+ - New: `parallelogram`, `original`, `image`, `crossmark`, `rest`, `natural`,
358
+ `flat`, `sharp`, `tiny`, `miny`, `copyleft`, `trademark`, `emoji.beet`,
359
+ `emoji.fingerprint`, `emoji.harp`, `emoji.shovel`, `emoji.splatter`,
360
+ `emoji.tree.leafless`,
361
+ - New variants: `club.stroked`, `diamond.stroked`, `heart.stroked`,
362
+ `spade.stroked`, `gt.neq`, `lt.neq`, `checkmark.heavy`, `paren.double`,
363
+ `brace.double`, `shell.double`, `arrow.turn`, `plus.double`, `plus.triple`,
364
+ `infinity.bar`, `infinity.incomplete`, `infinity.tie`, `multimap.double`,
365
+ `ballot.check`, `ballot.check.heavy`, `emptyset.bar`, `emptyset.circle`,
366
+ `emptyset.arrow.l`, `emptyset.arrow.r`, `parallel.struck`, `parallel.eq`,
367
+ `parallel.equiv`, `parallel.slanted`, `parallel.tilde`, `angle.l.curly`,
368
+ `angle.l.dot`, `angle.r.curly`, `angle.r.dot`, `angle.oblique`, `angle.s`,
369
+ `em.two`, `em.three`
370
+ - Renamed: `turtle` to `shell`, `notes` to `note`, `ballot.x` to `ballot.cross`,
371
+ `succ.eq` to `succ.curly.eq`, `prec.eq` to `prec.curly.eq`, `servicemark` to
372
+ `trademark.service`, `emoji.face.tired` to `emoji.face.distress`
373
+ **(Breaking change)**
374
+ - Changed codepoint: `prec.eq`, `prec.neq`, `succ.eq`, `succ.neq`, `triangle`
375
+ from ▷ to △, `emoji.face.tired` **(Breaking change)**
376
+ - Removed: `lt.curly` in favor of `prec`, `gt.curly` in favor of `succ`
377
+ **(Breaking change)**
378
+
379
+ ## Deprecations
380
+ - [`counter.display`] without an established context
381
+ - [`counter.final`] with a location
382
+ - [`state.final`] with a location
383
+ - `state.display`
384
+ - [`query`] with a location as the second argument
385
+ - [`locate`] with a callback function
386
+ - [`measure`] with styles
387
+ - `style`
388
+
389
+ ## Development
390
+ - Added `typst-kit` crate which provides useful APIs for `World` implementors
391
+ - Added go-to-definition API in `typst-ide`
392
+ - Added package manifest parsing APIs to `typst-syntax`
393
+ - As the compiler is now capable of multithreading, `World` implementations must
394
+ satisfy `Send` and `Sync`
395
+ - Changed signature of `World::main` to allow for the scenario where the main
396
+ file could not be loaded
397
+ - Removed `Tracer` in favor of `Warned<T>` and `typst::trace` function
398
+ - The `xz2` dependency used by the self-updater is now statically linked
399
+ - The Dockerfile now has an `ENTRYPOINT` directive
400
+
401
+ ## Contributors
402
+ <contributors from="v0.11.0" to="v0.12.0" />
sources/docs/changelog/0.13.0.md ADDED
@@ -0,0 +1,344 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: 0.13.0
3
+ description: Changes in Typst 0.13.0
4
+ ---
5
+
6
+ # Version 0.13.0 (February 19, 2025)
7
+
8
+ ## Highlights
9
+ - There is now a distinction between [proper paragraphs]($par) and just
10
+ inline-level content. This is important for future work on accessibility and
11
+ means that [first line indent]($par.first-line-indent) can now be enabled for
12
+ all paragraphs instead of just consecutive ones.
13
+ - The [`outline`] has a better out-of-the-box look and is more customizable
14
+ - The new [`curve`] function (that supersedes the `path` function) provides a
15
+ simpler and more flexible interface for creating Bézier curves
16
+ - The `image` function now supports raw [pixel raster formats]($image.format)
17
+ for generating images from within Typst
18
+ - Functions that accept [file paths]($syntax/#paths) now also accept raw
19
+ [bytes], for full flexibility
20
+ - WebAssembly [plugins]($plugin) are more flexible and automatically run
21
+ multi-threaded
22
+ - Fixed a long-standing bug where single-letter strings in math (`[$"a"$]`)
23
+ would be displayed in italics
24
+ - You can now specify which charset should be [covered]($text.font) by which
25
+ font family
26
+ - The [`pdf.embed`] function lets you embed arbitrary files in the exported
27
+ PDF
28
+ - HTML export is currently under active development. The feature is still _very_
29
+ incomplete, but already available for experimentation behind a feature flag.
30
+
31
+ ## Model
32
+ - There is now a distinction between [proper paragraphs]($par) and just
33
+ inline-level content **(Breaking change)**
34
+ - All text at the root of a document is wrapped in paragraphs. Meanwhile, text
35
+ in a container (like a block) is only wrapped in a paragraph if the
36
+ container holds any block-level content. If all of the content is
37
+ inline-level, no paragraph is created.
38
+ - In the laid-out document, it's not immediately visible whether text became
39
+ part of a paragraph. However, it is still important for accessibility, HTML
40
+ export, and for properties like `first-line-indent`.
41
+ - Show rules on `par` now only affect proper paragraphs
42
+ - The `first-line-indent` and `hanging-indent` properties also only affect
43
+ proper paragraphs
44
+ - Creating a `{par[..]}` with body content that is not fully inline-level will
45
+ result in a warning
46
+ - The default show rules of various built-in elements like lists, quotes, etc.
47
+ were adjusted to ensure they produce/don't produce paragraphs as appropriate
48
+ - Removed support for booleans and content in [`outline.indent`]
49
+ - The [`outline`] function was fully reworked to improve its out-of-the-box
50
+ behavior **(Breaking change)**
51
+ - [Outline entries]($outline.entry) are now [blocks]($block) and are thus
52
+ affected by block spacing
53
+ - The `{auto}` indentation mode now aligns numberings and titles outline-wide
54
+ for a grid-like look
55
+ - Automatic indentation now also indents entries without a numbering
56
+ - Titles wrapping over multiple lines now have hanging indent
57
+ - The page number won't appear alone on its own line anymore
58
+ - The link now spans the full entry instead of just the title and page number
59
+ - The default spacing between outline leader dots was increased
60
+ - The [`fill`]($outline.entry.fill) parameter was moved from `outline` to
61
+ `outline.entry` and can thus be configured through show-set rules
62
+ - Removed `body` and `page` fields from outline entry
63
+ - Added `indented`, `prefix`, `inner`, `body`, and `page` methods on outline
64
+ entries to simplify writing of show rules
65
+ - Added configuration to [`par.first-line-indent`] for indenting all paragraphs
66
+ instead of just consecutive ones
67
+ - Added [`form`]($ref.form) parameter to `ref` function. Setting the form to
68
+ `{"page"}` will produce a page reference instead of a textual one.
69
+ - Added [`document.description`] field, which results in corresponding PDF and
70
+ HTML metadata
71
+ - Added [`enum.reversed`] parameter
72
+ - Added support for Greek [numbering]
73
+ - When the [`link`] function wraps around a container like a [block], it will
74
+ now generate only one link for the whole block instead of individual links for
75
+ all the visible leaf elements. This significantly reduces PDF file sizes when
76
+ combining `link` and [`repeat`].
77
+ - The [`link`] function will now only strip one prefix (like `mailto:` or
78
+ `tel:`) instead of multiple
79
+ - The link function now suppresses hyphenation via a built-in show-set rule
80
+ rather than through its default show rule
81
+ - Displaying the page counter without a specified numbering will now take the
82
+ page numbering into account
83
+
84
+ ## Visualization
85
+ - Added new [`curve`] function that supersedes the [`path`] function and
86
+ provides a simpler and more flexible interface. The `path` function is now
87
+ deprecated.
88
+ - The `image` function now supports raw [pixel raster formats]($image.format).
89
+ This can be used to generate images from within Typst without the need for
90
+ encoding in an image exchange format.
91
+ - Added [`image.scaling`] parameter for configuring how an image is scaled by
92
+ PNG export and PDF viewers (smooth or pixelated)
93
+ - Added [`image.icc`] parameter for providing or overriding the ICC profile of
94
+ an image
95
+ - Renamed `pattern` to [`tiling`]. The name `pattern` remains as a deprecated
96
+ alias.
97
+ - Added [`gradient.center`], [`gradient.radius`], [`gradient.focal-center`], and
98
+ [`gradient.focal-radius`] methods
99
+ - Fixed interaction of clipping and outset on [`box`] and [`block`]
100
+ - Fixed panic with [`path`] of infinite length
101
+ - Fixed non-solid (e.g. tiling) text fills in clipped blocks
102
+ - Fixed a crash for images with a DPI value of zero
103
+ - Fixed floating-point error in [`gradient.repeat`]
104
+ - Auto-detection of image formats from a raw buffer now has support for SVGs
105
+
106
+ ## Scripting
107
+ - Functions that accept [file paths]($syntax/#paths) now also accept raw
108
+ [bytes]
109
+ - [`image`], [`cbor`], [`csv`], [`json`], [`toml`], [`xml`], and [`yaml`] now
110
+ support a path string or bytes and their `.decode` variants are deprecated
111
+ - [`plugin`], [`bibliography`], [`bibliography.style`], [`cite.style`],
112
+ [`raw.theme`], and [`raw.syntaxes`] now accept bytes in addition to path
113
+ strings. These did not have `.decode` variants, so this adds new
114
+ flexibility.
115
+ - The `path` argument/field of [`image`] and [`bibliography`] was renamed to
116
+ `source` and `sources`, respectively **(Minor breaking change)**
117
+ - Improved WebAssembly [plugins]($plugin)
118
+ - The `plugin` type is replaced by a [`plugin` function]($plugin) that returns
119
+ a [module] containing normal Typst functions. This module can be used with
120
+ import syntax. **(Breaking change)**
121
+ - Plugins now automatically run in multiple threads without any changes by
122
+ plugin authors
123
+ - A new [`plugin.transition`] API is introduced which allows plugins to run
124
+ impure initialization in a way that doesn't break Typst's purity guarantees
125
+ - The variable name bound by a bare import (no renaming, no import list) is now
126
+ determined statically and dynamic imports without `{as}` renaming (e.g.
127
+ `{import "ot" + "her.typ"}`) are a hard error **(Breaking change)**
128
+ - Values of the [`arguments`] type can now be added with `+` and
129
+ [joined]($scripting/#blocks) in curly-braced code blocks
130
+ - Functions in an element function's scope can now be called with method syntax,
131
+ bringing elements and types closer (in anticipation of a future full
132
+ unification of the two). Currently, this is only useful for [`outline.entry`]
133
+ as no other element function defines methods.
134
+ - Added [`calc.norm`] function
135
+ - Added support for 32-bit floats in [`float.from-bytes`] and [`float.to-bytes`]
136
+ - The [`decimal`] constructor now also accepts decimal values
137
+ - Improved `repr` of [symbols]($symbol), [arguments], and [types]($type)
138
+ - Duplicate [symbol] variants and modifiers are now a hard error
139
+ **(Breaking change)**
140
+
141
+ ## Math
142
+ - Fixed a bug where single letter strings in math (`[$"a"$]`) would be displayed
143
+ in italics
144
+ - Math function calls can now have hyphenated named arguments and support
145
+ [argument spreading]($arguments/#spreading)
146
+ - Better looking accents thanks to support for the `flac` (Flattened Accent
147
+ Forms) and `dtls` (Dotless Forms) OpenType features
148
+ - Added `lcm` [text operator]($math.op)
149
+ - The [`bold`]($math.bold) function now works with ϝ and Ϝ
150
+ - The [`italic`]($math.italic) function now works with ħ
151
+ - Fixed a bug where the extent of a math equation was wrongly affected by
152
+ internal metadata
153
+ - Fixed interaction of [`lr`]($math.lr) and [context] expressions
154
+ - Fixed weak spacing being unconditionally ignored in [`lr`]($math.lr)
155
+ - Fixed sub/superscripts sometimes being in the wrong position with
156
+ [`lr`]($math.lr)
157
+ - Fixed multi-line annotations (e.g. overbrace) changing the math baseline
158
+ - Fixed merging of attachments when the base is a nested equation
159
+ - Fixed resolving of contextual (em-based) text sizes within math
160
+ - Fixed spacing around up tacks (⊥)
161
+
162
+ ## Bibliography
163
+ - Prose and author-only citations now use editor names if the author names are
164
+ unavailable
165
+ - Some non-standard but widely used BibLaTeX `editortype`s like `producer`,
166
+ `writer`, `scriptwriter`, and `none` (defined by widespread style
167
+ `biblatex-chicago` to mean performers within `music` and `video` entries) are
168
+ now recognized
169
+ - CSL styles can now render affixes around the bibliography
170
+ - For BibTeX entries with `eprinttype = {pubmed}`, the PubMed ID will now be
171
+ correctly processed
172
+ - Whitespace handling for strings delimiting initialized names has been improved
173
+ - Uppercase spelling after apostrophes used as quotation marks is now possible
174
+ - Fixed bugs around the handling of CSL delimiting characters
175
+ - Fixed a problem with parsing multibyte characters in page ranges that could
176
+ prevent Hayagriva from parsing some BibTeX page ranges
177
+ - Updated CSL APA style
178
+ - Updated CSL locales for Finnish, Swiss German, Austrian German, German, and
179
+ Arabic
180
+
181
+ ## Text
182
+ - Added support for specifying which charset should be [covered]($text.font) by
183
+ which font family
184
+ - Added [`all`]($smallcaps.all) parameter to `smallcaps` function that also
185
+ enables small capitals on uppercase letters
186
+ - Added basic i18n for Basque and Bulgarian
187
+ - [Justification]($par.justify) does not affect [raw] blocks anymore
188
+ - [CJK-Latin-spacing]($text.cjk-latin-spacing) does not affect [raw] text
189
+ anymore
190
+ - Fixed wrong language codes being used for Greek and Ukrainian
191
+ - Fixed default quotes for Croatian and Bulgarian
192
+ - Fixed crash in RTL text handling
193
+ - Added support for [`raw`] syntax highlighting for a few new languages: CFML,
194
+ NSIS, and WGSL
195
+ - New font metadata exception for New Computer Modern Sans Math
196
+ - Updated bundled New Computer Modern fonts to version 7.0.1
197
+
198
+ ## Layout
199
+ - Fixed various bugs with footnotes
200
+ - Fixed footnotes getting lost when multiple footnotes were nested within
201
+ another footnote
202
+ - Fixed endless loops with empty and overlarge footnotes
203
+ - Fixed crash with overlarge footnotes within a floating placement
204
+ - Fixed sizing of quadratic shapes ([`square`] and [`circle`])
205
+ - Fixed [`block.sticky`] not working properly at the top of a container
206
+ - Fixed crash due to consecutive weak spacing
207
+ - Fixed crash when a [block] or text have negative sizes
208
+ - Fixed unnecessary hyphenations occurring in rare scenarios due to a bad
209
+ interaction between padding and paragraph optimization
210
+ - Fixed lone [citations]($cite) in [`align`] not becoming their own paragraph
211
+
212
+ ## Syntax
213
+ - Top-level closing square brackets that do not have a matching opening square
214
+ bracket are now a hard error **(Minor breaking change)**
215
+ - Adding a space between the identifier and the parentheses in a set rule is not
216
+ allowed anymore **(Minor breaking change)**
217
+ - Numbers with a unit cannot have a base prefix anymore, e.g. `0b100000pt` is
218
+ not allowed anymore. Previously, it was syntactically allowed but always
219
+ resolved to a value of zero. **(Minor breaking change)**
220
+ - Using `is` as an identifier will now warn as it might become a keyword in the
221
+ future
222
+ - Fixed minor whitespace handling bugs
223
+ - in math mode argument lists
224
+ - at the end of headings
225
+ - between a term list's term and description
226
+ - Fixed parsing of empty single line raw blocks with 3+ backticks and a language
227
+ tag
228
+ - Fixed minor bug with parentheses parsing in math
229
+ - Markup that can only appear at the start of the line (headings, lists) can now
230
+ also appear at the start of a list item
231
+ - A shebang `#!` at the very start of a file is now ignored
232
+
233
+ ## PDF export
234
+ - Added [`pdf.embed`] function for embedding arbitrary files in the exported PDF
235
+ - Added support for PDF/A-3b export
236
+ - The PDF timestamp will now contain the timezone by default
237
+
238
+ ## HTML export
239
+ **Note:** HTML export is currently under active development. The feature is
240
+ still _very_ incomplete, but already available for experimentation behind a
241
+ feature flag.
242
+
243
+ - Added HTML output support for some (but not all) of the built-in elements
244
+ - Added [`html.elem`] function for outputting an arbitrary HTML element
245
+ - Added [`html.frame`] function for integrating content that requires layout
246
+ into HTML (by embedding an SVG)
247
+ - Added [`target`] function which returns either `{"paged"}` or `{"html"}`
248
+ depending on the export target
249
+
250
+ ## Tooling and Diagnostics
251
+ - Autocompletion improvements
252
+ - Added autocompletion for file paths
253
+ - Smarter autocompletion of variables: Completing `{rect(fill: |)}` will now
254
+ only show variables which contain a valid fill (either directly or nested,
255
+ e.g. a dictionary containing a valid fill)
256
+ - Different functions will now autocomplete with different brackets (round vs
257
+ square) depending on which kind is more useful
258
+ - Positional parameters which are already provided aren't autocompleted again
259
+ anymore
260
+ - Fixed variable autocompletion not considering parameters
261
+ - Added autocompletion snippets for common figure usages
262
+ - Fixed autocompletion after half-completed import item
263
+ - Fixed autocompletion for `cite` function
264
+ - Added warning when an unconditional return in a code block discards joined
265
+ content
266
+ - Fixed error message when accessing non-existent label
267
+ - Fixed handling of nested imports in IDE functionality
268
+
269
+ ## Command Line Interface
270
+ - Added `--features` argument and `TYPST_FEATURES` environment variable for
271
+ opting into experimental features. The only feature so far is `html`.
272
+ - Added a live reloading HTTP server to `typst watch` when targeting HTML
273
+ - Fixed self-update not being aware about certain target architectures
274
+ - Fixed crash when piping `typst fonts` output to another command
275
+ - Fixed handling of relative paths in `--make-deps` output
276
+ - Fixed handling of multipage SVG and PNG export in `--make-deps` output
277
+ - Colons in filenames are now correctly escaped in `--make-deps` output
278
+
279
+ ## Symbols
280
+ - New
281
+ - `inter`, `inter.and`, `inter.big`, `inter.dot`, `inter.double`, `inter.sq`,
282
+ `inter.sq.big`, `inter.sq.double`, `integral.inter`
283
+ - `asymp`, `asymp.not`
284
+ - `mapsto`, `mapsto.long`
285
+ - `divides.not.rev`, `divides.struck`
286
+ - `interleave`, `interleave.big`, `interleave.struck`
287
+ - `eq.triple.not`, `eq.dots`, `eq.dots.down`, `eq.dots.up`
288
+ - `smt`, `smt.eq`, `lat`, `lat.eq`
289
+ - `colon.tri`, `colon.tri.op`
290
+ - `dagger.triple`, `dagger.l`, `dagger.r`, `dagger.inv`
291
+ - `hourglass.stroked`, `hourglass.filled`
292
+ - `die.six`, `die.five`, `die.four`, `die.three`, `die.two`, `die.one`
293
+ - `errorbar.square.stroked`, `errorbar.square.filled`,
294
+ `errorbar.diamond.stroked`, `errorbar.diamond.filled`,
295
+ `errorbar.circle.stroked`, `errorbar.circle.filled`
296
+ - `numero`
297
+ - Renamed **(Breaking change)**
298
+ - `ohm.inv` to `Omega.inv`
299
+ - Changed codepoint **(Breaking change)**
300
+ - `angle.l.double` from `《` to `⟪`
301
+ - `angle.r.double` from `》` to `⟫`
302
+ - `angstrom` from U+212B (`Å`) to U+00C5 (`Å`)
303
+ - Deprecated
304
+ - `sect` and all its variants in favor of `inter`
305
+ - `integral.sect` in favor of `integral.inter`
306
+ - Removed **(Breaking change)**
307
+ - `degree.c` in favor of `°C` (`[$upright(°C)$]` or `[$upright(degree C)$]` in math)
308
+ - `degree.f` in favor of `°F` (`[$upright(°F)$]` or `[$upright(degree F)$]` in math)
309
+ - `kelvin` in favor of just K (`[$upright(K)$]` in math)
310
+ - `ohm` in favor of `Omega`
311
+
312
+ ## Deprecations
313
+ - The [`path`] function in favor of the [`curve`] function
314
+ - The name `pattern` for tiling patterns in favor of the new name [`tiling`]
315
+ - [`image.decode`], [`cbor.decode`], [`csv.decode`], [`json.decode`],
316
+ [`toml.decode`], [`xml.decode`], [`yaml.decode`] in favor of the top-level
317
+ functions directly accepting both paths and bytes
318
+ - The `sect` and its variants in favor of `inter`, and `integral.sect` in favor
319
+ of `integral.inter`
320
+ - The compatibility behavior of type/str comparisons (e.g. `{int == "integer"}`)
321
+ which was temporarily introduced in Typst 0.8 now emits warnings. It will be
322
+ removed in Typst 0.14.
323
+
324
+ ## Removals
325
+ - Removed `style` function and `styles` argument of [`measure`], use a [context]
326
+ expression instead **(Breaking change)**
327
+ - Removed `state.display` function, use [`state.get`] instead
328
+ **(Breaking change)**
329
+ - Removed `location` argument of [`state.at`], [`counter.at`], and [`query`]
330
+ **(Breaking change)**
331
+ - Removed compatibility behavior where [`counter.display`] worked without
332
+ [context] **(Breaking change)**
333
+ - Removed compatibility behavior of [`locate`] **(Breaking change)**
334
+
335
+ ## Development
336
+ - The `typst::compile` function is now generic and can return either a
337
+ `PagedDocument` or an `HtmlDocument`
338
+ - `typst-timing` now supports WebAssembly targets via `web-sys` when the `wasm`
339
+ feature is enabled
340
+ - Increased minimum supported Rust version to 1.80
341
+ - Fixed linux/arm64 Docker image
342
+
343
+ ## Contributors
344
+ <contributors from="v0.12.0" to="v0.13.0" />
sources/docs/changelog/0.13.1.md ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: 0.13.1
3
+ description: Changes in Typst 0.13.1
4
+ ---
5
+
6
+ # Version 0.13.1 (March 7, 2025)
7
+
8
+ ## Command Line Interface
9
+ - Fixed high CPU usage for `typst watch` on Linux. Depending on the project
10
+ size, CPU usage would spike for varying amounts of time. This bug appeared
11
+ with 0.13.0 due to a behavioral change in the inotify file watching backend.
12
+
13
+ ## HTML export
14
+ - Fixed export of tables with [gutters]($table.gutter)
15
+ - Fixed usage of `<html>` and `<body>` element within [context]
16
+ - Fixed querying of [metadata] next to `<html>` and `<body>` element
17
+
18
+ ## Visualization
19
+ - Fixed [curves]($curve) with multiple non-closed components
20
+
21
+ ## Introspection
22
+ - Fixed a regression where labelled [symbols]($symbol) could not be
23
+ [queried]($query) by label
24
+
25
+ ## Deprecations
26
+ - Fixed false positives in deprecation warnings for type/str comparisons
27
+
28
+ ## Contributors
29
+ <contributors from="v0.13.0" to="v0.13.1" />
sources/docs/changelog/0.2.0.md ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: 0.2.0
3
+ description: Changes in Typst 0.2.0
4
+ ---
5
+
6
+ # Version 0.2.0 (April 11, 2023)
7
+
8
+ ## Breaking changes
9
+ - Removed support for iterating over index and value in
10
+ [for loops]($scripting/#loops). This is now handled via unpacking and
11
+ enumerating. Same goes for the [`map`]($array.map) method.
12
+ - [Dictionaries]($dictionary) now iterate in insertion order instead of
13
+ alphabetical order.
14
+
15
+ ## New features
16
+ - Added [unpacking syntax]($scripting/#bindings) for let bindings, which allows
17
+ things like `{let (1, 2) = array}`
18
+ - Added [`enumerate`]($array.enumerate) method
19
+ - Added [`path`] function for drawing Bézier paths
20
+ - Added [`layout`] function to access the size of the surrounding page or
21
+ container
22
+ - Added `key` parameter to [`sorted`]($array.sorted) method
23
+
24
+ ## Command line interface
25
+ - Fixed `--open` flag blocking the program
26
+ - New Computer Modern font is now embedded into the binary
27
+ - Shell completions and man pages can now be generated by setting the
28
+ `GEN_ARTIFACTS` environment variable to a target directory and then building
29
+ Typst
30
+
31
+ ## Miscellaneous improvements
32
+ - Fixed page numbering in outline
33
+ - Added basic i18n for a few more languages (AR, NB, CS, NN, PL, SL, ES, UA, VI)
34
+ - Added a few numbering patterns (Ihora, Chinese)
35
+ - Added `sinc` [operator]($math.op)
36
+ - Fixed bug where math could not be hidden with [`hide`]
37
+ - Fixed sizing issues with box, block, and shapes
38
+ - Fixed some translations
39
+ - Fixed inversion of "R" in [`cal`]($math.cal) and [`frak`]($math.frak) styles
40
+ - Fixed some styling issues in math
41
+ - Fixed supplements of references to headings
42
+ - Fixed syntax highlighting of identifiers in certain scenarios
43
+ - [Ratios]($ratio) can now be multiplied with more types and be converted to
44
+ [floats]($float) with the [`float`] function
45
+
46
+ ## Contributors
47
+ <contributors from="v0.1.0" to="v0.2.0" />
sources/docs/changelog/0.3.0.md ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: 0.3.0
3
+ description: Changes in Typst 0.3.0
4
+ ---
5
+
6
+ # Version 0.3.0 (April 26, 2023)
7
+
8
+ ## Breaking changes
9
+ - Renamed a few symbols: What was previous `dot.op` is now just `dot` and the
10
+ basic dot is `dot.basic`. The same applies to `ast` and `tilde`.
11
+ - Renamed `mod` to [`rem`]($calc.rem) to more accurately reflect the behavior.
12
+ It will remain available as `mod` until the next update as a grace period.
13
+ - A lone underscore is not a valid identifier anymore, it can now only be used
14
+ in patterns
15
+ - Removed `before` and `after` arguments from [`query`]. This is now handled
16
+ through flexible [selectors]($selector) combinator methods
17
+ - Added support for [attachments]($math.attach) (sub-, superscripts) that
18
+ precede the base symbol. The `top` and `bottom` arguments have been renamed to
19
+ `t` and `b`.
20
+
21
+ ## New features
22
+ - Added support for more complex [strokes]($stroke) (configurable caps, joins,
23
+ and dash patterns)
24
+ - Added [`cancel`]($math.cancel) function for equations
25
+ - Added support for [destructuring]($scripting/#bindings) in argument lists and
26
+ assignments
27
+ - Added [`alt`]($image.alt) text argument to image function
28
+ - Added [`toml`] function for loading data from a TOML file
29
+ - Added [`zip`]($array.zip), [`sum`]($array.sum), and
30
+ [`product`]($array.product) methods for arrays
31
+ - Added `fact`, `perm`, `binom`, `gcd`, `lcm`, `atan2`, `quo`, `trunc`, and
32
+ `fract` [calculation]($category/foundations/calc) functions
33
+
34
+ ## Improvements
35
+ - Text in SVGs now displays properly
36
+ - Typst now generates a PDF heading outline
37
+ - [References]($ref) now provides the referenced element as a field in show
38
+ rules
39
+ - Refined linebreak algorithm for better Chinese justification
40
+ - Locations are now a valid kind of selector
41
+ - Added a few symbols for algebra
42
+ - Added Spanish smart quote support
43
+ - Added [`selector`] function to turn a selector-like value into a selector on
44
+ which combinator methods can be called
45
+ - Improved some error messages
46
+ - The outline and bibliography headings can now be styled with show-set rules
47
+ - Operations on numbers now produce an error instead of overflowing
48
+
49
+ ## Bug fixes
50
+ - Fixed wrong linebreak before punctuation that follows inline equations,
51
+ citations, and other elements
52
+ - Fixed a bug with [argument sinks]($arguments)
53
+ - Fixed strokes with thickness zero
54
+ - Fixed hiding and show rules in math
55
+ - Fixed alignment in matrices
56
+ - Fixed some alignment bugs in equations
57
+ - Fixed grid cell alignment
58
+ - Fixed alignment of list marker and enum markers in presence of global
59
+ alignment settings
60
+ - Fixed [path]($path) closing
61
+ - Fixed compiler crash with figure references
62
+ - A single trailing line breaks is now ignored in math, just like in text
63
+
64
+ ## Command line interface
65
+ - Font path and compilation root can now be set with the environment variables
66
+ `TYPST_FONT_PATHS` and `TYPST_ROOT`
67
+ - The output of `typst fonts` now includes the embedded fonts
68
+
69
+ ## Development
70
+ - Added instrumentation for debugging and optimization
71
+ - Added `--update` flag and `UPDATE_EXPECT` environment variable to update
72
+ reference images for tests
73
+ - You can now run a specific subtest with `--subtest`
74
+ - Tests now run on multiple threads
75
+
76
+ ## Contributors
77
+ <contributors from="v0.2.0" to="v0.3.0" />
sources/docs/changelog/0.4.0.md ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: 0.4.0
3
+ description: Changes in Typst 0.4.0
4
+ ---
5
+
6
+ # Version 0.4.0 (May 20, 2023)
7
+
8
+ ## Footnotes
9
+ - Implemented support for footnotes
10
+ - The [`footnote`] function inserts a footnote
11
+ - The [`footnote.entry`]($footnote.entry) function can be used to customize the
12
+ footnote listing
13
+ - The `{"chicago-notes"}` [citation style]($cite.style) is now available
14
+
15
+ ## Documentation
16
+ - Added a [Guide for LaTeX users]($guides/guide-for-latex-users)
17
+ - Now shows default values for optional arguments
18
+ - Added richer outlines in "On this Page"
19
+ - Added initial support for search keywords: "Table of Contents" will now find
20
+ the [outline] function. Suggestions for more keywords are welcome!
21
+ - Fixed issue with search result ranking
22
+ - Fixed many more small issues
23
+
24
+ ## Math
25
+ - **Breaking change**: Alignment points (`&`) in equations now alternate between
26
+ left and right alignment
27
+ - Added support for writing roots with Unicode: For example, `[$root(x+y)$]` can
28
+ now also be written as `[$√(x+y)$]`
29
+ - Fixed uneven vertical [`attachment`]($math.attach) alignment
30
+ - Fixed spacing on decorated elements (e.g., spacing around a
31
+ [canceled]($math.cancel) operator)
32
+ - Fixed styling for stretchable symbols
33
+ - Added `tack.r.double`, `tack.l.double`, `dotless.i` and `dotless.j`
34
+ [symbols]($category/symbols/sym)
35
+ - Fixed show rules on symbols (e.g. `{show sym.tack: set text(blue)}`)
36
+ - Fixed missing rename from `ast.op` to `ast` that should have been in the
37
+ previous release
38
+
39
+ ## Scripting
40
+ - Added function scopes: A function can now hold related definitions in its own
41
+ scope, similar to a module. The new [`assert.eq`]($assert.eq) function, for
42
+ instance, is part of the [`assert`] function's scope. Note that function
43
+ scopes are currently only available for built-in functions.
44
+ - Added [`assert.eq`]($assert.eq) and [`assert.ne`]($assert.ne) functions for
45
+ simpler equality and inequality assertions with more helpful error messages
46
+ - Exposed [list]($list.item), [enum]($enum.item), and [term list]($terms.item)
47
+ items in their respective functions' scope
48
+ - The `at` methods on [strings]($str.at), [arrays]($array.at),
49
+ [dictionaries]($dictionary.at), and [content]($content.at) now support
50
+ specifying a default value
51
+ - Added support for passing a function to [`replace`]($str.replace) that is
52
+ called with each match.
53
+ - Fixed [replacement]($str.replace) strings: They are now inserted completely
54
+ verbatim instead of supporting the previous (unintended) magic dollar syntax
55
+ for capture groups
56
+ - Fixed bug with trailing placeholders in destructuring patterns
57
+ - Fixed bug with underscore in parameter destructuring
58
+ - Fixed crash with nested patterns and when hovering over an invalid pattern
59
+ - Better error messages when casting to an [integer]($int) or [float]($float)
60
+ fails
61
+
62
+ ## Text and Layout
63
+ - Implemented sophisticated CJK punctuation adjustment
64
+ - Disabled [overhang]($text.overhang) for CJK punctuation
65
+ - Added basic translations for Traditional Chinese
66
+ - Fixed [alignment]($raw.align) of text inside raw blocks (centering a raw
67
+ block, e.g. through a figure, will now keep the text itself left-aligned)
68
+ - Added support for passing a array instead of a function to configure table
69
+ cell [alignment]($table.align) and [fill]($table.fill) per column
70
+ - Fixed automatic figure [`kind`]($figure.kind) detection
71
+ - Made alignment of [enum numbers]($enum.number-align) configurable, defaulting
72
+ to `end`
73
+ - Figures can now be made breakable with a show-set rule for blocks in figure
74
+ - Initial fix for smart quotes in RTL languages
75
+
76
+ ## Export
77
+ - Fixed ligatures in PDF export: They are now copyable and searchable
78
+ - Exported PDFs now embed ICC profiles for images that have them
79
+ - Fixed export of strokes with zero thickness
80
+
81
+ ## Web app
82
+ - Projects can now contain folders
83
+ - Added upload by drag-and-drop into the file panel
84
+ - Files from the file panel can now be dragged into the editor to insert them
85
+ into a Typst file
86
+ - You can now copy-paste images and other files from your computer directly into
87
+ the editor
88
+ - Added a button to resend confirmation email
89
+ - Added an option to invert preview colors in dark mode
90
+ - Added tips to the loading screen and the Help menu. Feel free to propose more!
91
+ - Added syntax highlighting for YAML files
92
+ - Allowed middle mouse button click on many buttons to navigate into a new tab
93
+ - Allowed more project names
94
+ - Fixed overridden Vim mode keybindings
95
+ - Fixed many bugs regarding file upload and more
96
+
97
+ ## Miscellaneous Improvements
98
+ - Improved performance of counters, state, and queries
99
+ - Improved incremental parsing for more efficient recompilations
100
+ - Added support for `.yaml` extension in addition to `.yml` for bibliographies
101
+ - The CLI now emits escape codes only if the output is a TTY
102
+ - For users of the `typst` crate: The `Document` is now `Sync` again and the
103
+ `World` doesn't have to be `'static` anymore
104
+
105
+ ## Contributors
106
+ <contributors from="v0.3.0" to="v0.4.0" />
sources/docs/changelog/0.5.0.md ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: 0.5.0
3
+ description: Changes in Typst 0.5.0
4
+ ---
5
+
6
+ # Version 0.5.0 (June 9, 2023)
7
+
8
+ ## Text and Layout
9
+ - Added [`raw`] syntax highlighting for many more languages
10
+ - Added support for Korean [numbering]
11
+ - Added basic i18n for a few more languages (NL, SV, DA)
12
+ - Improved line breaking for East Asian languages
13
+ - Expanded functionality of outline [`indent`]($outline.indent) property
14
+ - Fixed footnotes in columns
15
+ - Fixed page breaking bugs with [footnotes]($footnote)
16
+ - Fixed bug with handling of footnotes in lists, tables, and figures
17
+ - Fixed a bug with CJK punctuation adjustment
18
+ - Fixed a crash with rounded rectangles
19
+ - Fixed alignment of [`line`] elements
20
+
21
+ ## Math
22
+ - **Breaking change:** The syntax rules for mathematical
23
+ [attachments]($math.attach) were improved: `[$f^abs(3)$]` now parses as
24
+ `[$f^(abs(3))$]` instead of `[$(f^abs)(3)$]`. To disambiguate, add a space:
25
+ `[$f^zeta (3)$]`.
26
+ - Added [forced size]($category/math/sizes) commands for math (e.g.,
27
+ [`display`]($math.display))
28
+ - Added [`supplement`]($math.equation.supplement) parameter to
29
+ [`equation`]($math.equation), used by [references]($ref)
30
+ - New [symbols]($category/symbols/sym): `bullet`, `xor`, `slash.big`,
31
+ `sigma.alt`, `tack.r.not`, `tack.r.short`, `tack.r.double.not`
32
+ - Fixed a bug with symbols in matrices
33
+ - Fixed a crash in the [`attach`]($math.attach) function
34
+
35
+ ## Scripting
36
+ - Added new [`datetime`] type and [`datetime.today`]($datetime.today) to
37
+ retrieve the current date
38
+ - Added [`str.from-unicode`]($str.from-unicode) and
39
+ [`str.to-unicode`]($str.to-unicode) functions
40
+ - Added [`fields`]($content.fields) method on content
41
+ - Added `base` parameter to [`str`] function
42
+ - Added [`calc.exp`]($calc.exp) and [`calc.ln`]($calc.ln)
43
+ - Improved accuracy of [`calc.pow`]($calc.pow) and [`calc.log`]($calc.log) for
44
+ specific bases
45
+ - Fixed [removal]($dictionary.remove) order for dictionary
46
+ - Fixed `.at(default: ..)` for [strings]($str.at) and [content]($content.at)
47
+ - Fixed field access on styled elements
48
+ - Removed deprecated `calc.mod` function
49
+
50
+ ## Command line interface
51
+ - Added PNG export via `typst compile source.typ output-{n}.png`. The output
52
+ path must contain `[{n}]` if the document has multiple pages.
53
+ - Added `--diagnostic-format=short` for Unix-style short diagnostics
54
+ - Doesn't emit color codes anymore if stderr isn't a TTY
55
+ - Now sets the correct exit when invoked with a nonexistent file
56
+ - Now ignores UTF-8 BOM in Typst files
57
+
58
+ ## Miscellaneous Improvements
59
+ - Improved errors for mismatched delimiters
60
+ - Improved error message for failed length comparisons
61
+ - Fixed a bug with images not showing up in Apple Preview
62
+ - Fixed multiple bugs with the PDF outline
63
+ - Fixed citations and other searchable elements in [`hide`]
64
+ - Fixed bugs with [reference supplements]($ref.supplement)
65
+ - Fixed Nix flake
66
+
67
+ ## Contributors
68
+ <contributors from="v0.4.0" to="v0.5.0" />
sources/docs/changelog/0.6.0.md ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: 0.6.0
3
+ description: Changes in Typst 0.6.0
4
+ ---
5
+
6
+ # Version 0.6.0 (June 30, 2023)
7
+
8
+ ## Package Management
9
+ - Typst now has built-in [package management]($scripting/#packages)
10
+ - You can import [published]($universe) community packages or create and use
11
+ [system-local](https://github.com/typst/packages#local-packages) ones
12
+ - Published packages are also supported in the web app
13
+
14
+ ## Math
15
+ - Added support for optical size variants of glyphs in math mode
16
+ - Added argument to enable [`limits`]($math.limits) conditionally depending on
17
+ whether the equation is set in [`display`]($math.display) or
18
+ [`inline`]($math.inline) style
19
+ - Added `gt.eq.slant` and `lt.eq.slant` symbols
20
+ - Increased precedence of factorials in math mode (`[$1/n!$]` works correctly
21
+ now)
22
+ - Improved [underlines]($math.underline) and [overlines]($math.overline) in math
23
+ mode
24
+ - Fixed usage of [`limits`]($math.limits) function in show rules
25
+ - Fixed bugs with line breaks in equations
26
+
27
+ ## Text and Layout
28
+ - Added support for alternating page [margins]($page.margin) with the `inside`
29
+ and `outside` keys
30
+ - Added support for specifying the page [`binding`]($page.binding)
31
+ - Added [`to`]($pagebreak.to) argument to pagebreak function to skip to the next
32
+ even or odd page
33
+ - Added basic i18n for a few more languages (TR, SQ, TL)
34
+ - Fixed bug with missing table row at page break
35
+ - Fixed bug with [underlines]($underline)
36
+ - Fixed bug superfluous table lines
37
+ - Fixed smart quotes after line breaks
38
+ - Fixed a crash related to text layout
39
+
40
+ ## Command line interface
41
+ - **Breaking change:** Added requirement for `--root`/`TYPST_ROOT` directory to
42
+ contain the input file because it designates the _project_ root. Existing
43
+ setups that use `TYPST_ROOT` to emulate package management should switch to
44
+ [local packages](https://github.com/typst/packages#local-packages)
45
+ - **Breaking change:** Now denies file access outside of the project root
46
+ - Added support for local packages and on-demand package download
47
+ - Now watches all relevant files, within the root and all packages
48
+ - Now displays compilation time
49
+
50
+ ## Miscellaneous Improvements
51
+ - Added [`outline.entry`]($outline.entry) to customize outline entries with show
52
+ rules
53
+ - Added some hints for error messages
54
+ - Added some missing syntaxes for [`raw`] highlighting
55
+ - Improved rendering of rotated images in PNG export and web app
56
+ - Made [footnotes]($footnote) reusable and referenceable
57
+ - Fixed bug with citations and bibliographies in [`locate`]
58
+ - Fixed inconsistent tense in documentation
59
+
60
+ ## Development
61
+ - Added [contribution guide](https://github.com/typst/typst/blob/main/CONTRIBUTING.md)
62
+ - Reworked `World` interface to accommodate for package management and make it a
63
+ bit simpler to implement _(Breaking change for implementors)_
64
+
65
+ ## Contributors
66
+ <contributors from="v0.5.0" to="v0.6.0" />
sources/docs/changelog/0.7.0.md ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: 0.7.0
3
+ description: Changes in Typst 0.7.0
4
+ ---
5
+
6
+ # Version 0.7.0 (August 7, 2023)
7
+
8
+ ## Text and Layout
9
+ - Added support for floating figures through the
10
+ [`placement`]($figure.placement) argument on the figure function
11
+ - Added support for arbitrary floating content through the
12
+ [`float`]($place.float) argument on the place function
13
+ - Added support for loading `.sublime-syntax` files as highlighting
14
+ [syntaxes]($raw.syntaxes) for raw blocks
15
+ - Added support for loading `.tmTheme` files as highlighting
16
+ [themes]($raw.theme) for raw blocks
17
+ - Added _bounds_ option to [`top-edge`]($text.top-edge) and
18
+ [`bottom-edge`]($text.bottom-edge) arguments of text function for tight
19
+ bounding boxes
20
+ - Removed nonsensical top- and bottom-edge options, e.g. _ascender_ for the
21
+ bottom edge **(Breaking change)**
22
+ - Added [`script`]($text.script) argument to text function
23
+ - Added [`alternative`]($smartquote.alternative) argument to smart quote
24
+ function
25
+ - Added basic i18n for Japanese
26
+ - Added hyphenation support for `nb` and `nn` language codes in addition to `no`
27
+ - Fixed positioning of [placed elements]($place) in containers
28
+ - Fixed overflowing containers due to optimized line breaks
29
+
30
+ ## Export
31
+ - Greatly improved export of SVG images to PDF. Many thanks to
32
+ [@LaurenzV](https://github.com/LaurenzV) for their work on this.
33
+ - Added support for the alpha channel of RGBA colors in PDF export
34
+ - Fixed a bug with PPI (pixels per inch) for PNG export
35
+
36
+ ## Math
37
+ - Improved layout of primes (e.g. in `[$a'_1$]`)
38
+ - Improved display of multi-primes (e.g. in `[$a''$]`)
39
+ - Improved layout of [roots]($math.root)
40
+ - Changed relations to show attachments as [limits]($math.limits) by default
41
+ (e.g. in `[$a ->^x b$]`)
42
+ - Large operators and delimiters are now always vertically centered
43
+ - [Boxes]($box) in equations now sit on the baseline instead of being vertically
44
+ centered by default. Notably, this does not affect [blocks]($block) because
45
+ they are not inline elements.
46
+ - Added support for [weak spacing]($h.weak)
47
+ - Added support for OpenType character variants
48
+ - Added support for customizing the [math class]($math.class) of content
49
+ - Fixed spacing around `.`, `\/`, and `...`
50
+ - Fixed spacing between closing delimiters and large operators
51
+ - Fixed a bug with math font weight selection
52
+ - Symbols and Operators **(Breaking changes)**
53
+ - Added `id`, `im`, and `tr` text [operators]($math.op)
54
+ - Renamed `ident` to `equiv` with alias `eq.triple` and removed `ident.strict`
55
+ in favor of `eq.quad`
56
+ - Renamed `ast.sq` to `ast.square` and `integral.sq` to `integral.square`
57
+ - Renamed `.eqq` modifier to `.equiv` (and `.neqq` to `.nequiv`) for `tilde`,
58
+ `gt`, `lt`, `prec`, and `succ`
59
+ - Added `emptyset` as alias for `nothing`
60
+ - Added `lt.curly` and `gt.curly` as aliases for `prec` and `succ`
61
+ - Added `aleph`, `beth`, and `gimmel` as alias for `alef`, `bet`, and `gimel`
62
+
63
+ ## Scripting
64
+ - Fields
65
+ - Added `abs` and `em` field to [lengths]($length)
66
+ - Added `ratio` and `length` field to [relative lengths]($relative)
67
+ - Added `x` and `y` field to [2d alignments]($align.alignment)
68
+ - Added `paint`, `thickness`, `cap`, `join`, `dash`, and `miter-limit` field
69
+ to [strokes]($stroke)
70
+ - Accessor and utility methods
71
+ - Added [`dedup`]($array.dedup) method to arrays
72
+ - Added `pt`, `mm`, `cm`, and `inches` method to [lengths]($length)
73
+ - Added `deg` and `rad` method to [angles]($angle)
74
+ - Added `kind`, `hex`, `rgba`, `cmyk`, and `luma` method to [colors]($color)
75
+ - Added `axis`, `start`, `end`, and `inv` method to [directions]($stack.dir)
76
+ - Added `axis` and `inv` method to [alignments]($align.alignment)
77
+ - Added `inv` method to [2d alignments]($align.alignment)
78
+ - Added `start` argument to [`enumerate`]($array.enumerate) method on arrays
79
+ - Added [`color.mix`]($color.mix) function
80
+ - Added `mode` and `scope` arguments to [`eval`] function
81
+ - Added [`bytes`] type for holding large byte buffers
82
+ - Added [`encoding`]($read.encoding) argument to read function to read a file
83
+ as bytes instead of a string
84
+ - Added [`image.decode`]($image.decode) function for decoding an image
85
+ directly from a string or bytes
86
+ - Added [`bytes`] function for converting a string or an array of integers to
87
+ bytes
88
+ - Added [`array`] function for converting bytes to an array of integers
89
+ - Added support for converting bytes to a string with the [`str`] function
90
+
91
+ ## Tooling and Diagnostics
92
+ - Added support for compiler warnings
93
+ - Added warning when compilation does not converge within five attempts due to
94
+ intense use of introspection features
95
+ - Added warnings for empty emphasis (`__` and `**`)
96
+ - Improved error message for invalid field assignments
97
+ - Improved error message after single `#`
98
+ - Improved error message when a keyword is used where an identifier is expected
99
+ - Fixed parameter autocompletion for functions that are in modules
100
+ - Import autocompletion now only shows the latest package version until a colon
101
+ is typed
102
+ - Fixed autocompletion for dictionary key containing a space
103
+ - Fixed autocompletion for `for` loops
104
+
105
+ ## Command line interface
106
+ - Added `typst query` subcommand to execute a
107
+ [query]($reference/introspection/query/#command-line-queries) on the command
108
+ line
109
+ - The `--root` and `--font-paths` arguments cannot appear in front of the
110
+ command anymore **(Breaking change)**
111
+ - Local and cached packages are now stored in directories of the form
112
+ `[{namespace}/{name}/{version}]` instead of `[{namespace}/{name}-{version}]`
113
+ **(Breaking change)**
114
+ - Now prioritizes explicitly given fonts (via `--font-paths`) over system and
115
+ embedded fonts when both exist
116
+ - Fixed `typst watch` not working with some text editors
117
+ - Fixed displayed compilation time (now includes export)
118
+
119
+ ## Miscellaneous Improvements
120
+ - Added [`bookmarked`]($heading.bookmarked) argument to heading to control
121
+ whether a heading becomes part of the PDF outline
122
+ - Added [`caption-pos`]($figure.caption.position) argument to control the
123
+ position of a figure's caption
124
+ - Added [`metadata`] function for exposing an arbitrary value to the
125
+ introspection system
126
+ - Fixed that a [`state`] was identified by the pair `(key, init)` instead of
127
+ just its `key`
128
+ - Improved indent logic of [enumerations]($enum). Instead of requiring at least
129
+ as much indent as the end of the marker, they now require only one more space
130
+ indent than the start of the marker. As a result, even long markers like `12.`
131
+ work with just 2 spaces of indent.
132
+ - Fixed bug with indent logic of [`raw`] blocks
133
+ - Fixed a parsing bug with dictionaries
134
+
135
+ ## Development
136
+ - Extracted parser and syntax tree into `typst-syntax` crate
137
+ - The `World::today` implementation of Typst dependents may need fixing if they
138
+ have the same [bug](https://github.com/typst/typst/issues/1842) that the CLI
139
+ world had
140
+
141
+ ## Contributors
142
+ <contributors from="v0.6.0" to="v0.7.0" />
sources/docs/changelog/0.8.0.md ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: 0.8.0
3
+ description: Changes in Typst 0.8.0
4
+ ---
5
+
6
+ # Version 0.8.0 (September 13, 2023)
7
+
8
+ ## Scripting
9
+ - Plugins (thanks to [@astrale-sharp](https://github.com/astrale-sharp) and
10
+ [@arnaudgolfouse](https://github.com/arnaudgolfouse))
11
+ - Typst can now load [plugins]($plugin) that are compiled to WebAssembly
12
+ - Anything that can be compiled to WebAssembly can thus be loaded as a plugin
13
+ - These plugins are fully encapsulated (no access to file system or network)
14
+ - Plugins can be shipped as part of [packages]($scripting/#packages)
15
+ - Plugins work just the same in the web app
16
+ - Types are now first-class values **(Breaking change)**
17
+ - A [type] is now itself a value
18
+ - Some types can be called like functions (those that have a constructor),
19
+ e.g. [`int`] and [`str`]
20
+ - Type checks are now of the form `{type(10) == int}` instead of the old
21
+ `{type(10) == "integer"}`. [Compatibility]($type/#compatibility) with the
22
+ old way will remain for a while to give package authors time to upgrade, but
23
+ it will be removed at some point.
24
+ - Methods are now syntax sugar for calling a function scoped to a type,
25
+ meaning that `{"hello".len()}` is equivalent to `{str.len("hello")}`
26
+ - Added support for [`import`]($scripting/#modules) renaming with `as`
27
+ - Added a [`duration`] type
28
+ - Added support for [CBOR]($cbor) encoding and decoding
29
+ - Added encoding and decoding functions from and to bytes for data formats:
30
+ [`json.decode`]($json.decode), [`json.encode`]($json.encode), and similar
31
+ functions for other formats
32
+ - Added [`array.intersperse`]($array.intersperse) function
33
+ - Added [`str.rev`]($str.rev) function
34
+ - Added `calc.tau` constant
35
+ - Made [bytes] joinable and addable
36
+ - Made [`array.zip`]($array.zip) function variadic
37
+ - Fixed bug with [`eval`] when the `mode` was set to `{"math"}`
38
+ - Fixed bug with [`ends-with`]($str.ends-with) function on strings
39
+ - Fixed bug with destructuring in combination with break, continue, and return
40
+ - Fixed argument types of [hyperbolic functions]($calc.cosh), they don't allow
41
+ angles anymore **(Breaking change)**
42
+ - Renamed some color methods: `rgba` becomes `to-rgba`, `cmyk` becomes
43
+ `to-cmyk`, and `luma` becomes `to-luma` **(Breaking change)**
44
+
45
+ ## Export
46
+ - Added SVG export (thanks to [@Enter-tainer](https://github.com/Enter-tainer))
47
+ - Fixed bugs with PDF font embedding
48
+ - Added support for page labels that reflect the
49
+ [page numbering]($page.numbering) style in the PDF
50
+
51
+ ## Text and Layout
52
+ - Added [`highlight`] function for highlighting text with a background color
53
+ - Added [`polygon.regular`]($polygon.regular) function for drawing a regular
54
+ polygon
55
+ - Added support for tabs in [`raw`] elements alongside
56
+ [`tab-width`]($raw.tab-size) parameter
57
+ - The layout engine now tries to prevent "runts" (final lines consisting of just
58
+ a single word)
59
+ - Added Finnish translations
60
+ - Added hyphenation support for Polish
61
+ - Improved handling of consecutive smart quotes of different kinds
62
+ - Fixed vertical alignments for [`number-align`]($page.number-align) argument on
63
+ page function **(Breaking change)**
64
+ - Fixed weak pagebreaks after counter updates
65
+ - Fixed missing text in SVG when the text font is set to "New Computer Modern"
66
+ - Fixed translations for Chinese
67
+ - Fixed crash for empty text in show rule
68
+ - Fixed leading spaces when there's a linebreak after a number and a comma
69
+ - Fixed placement of floating elements in columns and other containers
70
+ - Fixed sizing of block containing just a single box
71
+
72
+ ## Math
73
+ - Added support for [augmented matrices]($math.mat.augment)
74
+ - Removed support for automatic matching of fences like `|` and `||` as
75
+ there were too many false positives. You can use functions like
76
+ [`abs`]($math.abs) or [`norm`]($math.norm) or an explicit [`lr`]($math.lr)
77
+ call instead. **(Breaking change)**
78
+ - Fixed spacing after number with decimal point in math
79
+ - Fixed bug with primes in subscript
80
+ - Fixed weak spacing
81
+ - Fixed crash when text within math contains a newline
82
+
83
+ ## Tooling and Diagnostics
84
+ - Added hints when trying to call a function stored in a dictionary without
85
+ extra parentheses
86
+ - Fixed hint when referencing an equation without numbering
87
+ - Added more details to some diagnostics (e.g. when SVG decoding fails)
88
+
89
+ ## Command line interface
90
+ - Added `typst update` command for self-updating the CLI
91
+ (thanks to [@jimvdl](https://github.com/jimvdl))
92
+ - Added download progress indicator for packages and updates
93
+ - Added `--format` argument to explicitly specify the output format
94
+ - The CLI now respects proxy configuration through environment variables and has
95
+ a new `--cert` option for setting a custom CA certificate
96
+ - Fixed crash when field wasn't present and `--one` is passed to `typst query`
97
+
98
+ ## Miscellaneous Improvements
99
+ - Added [page setup guide]($guides/page-setup-guide)
100
+ - Added [`figure.caption`]($figure.caption) function that can be used for
101
+ simpler figure customization (**Breaking change** because `it.caption` now
102
+ renders the full caption with supplement in figure show rules and manual
103
+ outlines)
104
+ - Moved `caption-pos` argument to `figure.caption` function and renamed it to
105
+ `position` **(Breaking change)**
106
+ - Added [`separator`]($figure.caption.separator) argument to `figure.caption`
107
+ function
108
+ - Added support for combination of and/or and before/after
109
+ [selectors]($selector)
110
+ - Packages can now specify a
111
+ [minimum compiler version](https://github.com/typst/packages#package-format)
112
+ they require to work
113
+ - Fixed parser bug where method calls could be moved onto their own line for
114
+ `[#let]` expressions in markup **(Breaking change)**
115
+ - Fixed bugs in sentence and title case conversion for bibliographies
116
+ - Fixed supplements for alphanumeric and author-title bibliography styles
117
+ - Fixed off-by-one error in APA bibliography style
118
+
119
+ ## Development
120
+ - Made `Span` and `FileId` more type-safe so that all error conditions must be
121
+ handled by `World` implementors
122
+
123
+ ## Contributors
124
+ <contributors from="v0.7.0" to="v0.8.0" />
sources/docs/changelog/0.9.0.md ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: 0.9.0
3
+ description: Changes in Typst 0.9.0
4
+ ---
5
+
6
+ # Version 0.9.0 (October 31, 2023)
7
+
8
+ ## Bibliography management
9
+ - New bibliography engine based on [CSL](https://citationstyles.org/) (Citation
10
+ Style Language). Ships with about 100 commonly used citation styles and can
11
+ load custom `.csl` files.
12
+ - Added new [`form`]($cite.form) argument to the `cite` function to produce
13
+ different forms of citations (e.g. for producing a citation suitable for
14
+ inclusion in prose)
15
+ - The [`cite`] function now takes only a single label/key instead of allowing
16
+ multiple. Adjacent citations are merged and formatted according to the
17
+ citation style's rules automatically. This works both with the reference
18
+ syntax and explicit calls to the `cite` function. **(Breaking change)**
19
+ - The `cite` function now takes a [label] instead of a string
20
+ **(Breaking change)**
21
+ - Added [`full`]($bibliography.full) argument to bibliography function to print
22
+ the full bibliography even if not all works were cited
23
+ - Bibliography entries can now contain Typst equations (wrapped in `[$..$]` just
24
+ like in markup), this works both for `.yml` and `.bib` bibliographies
25
+ - The hayagriva YAML format was improved. See its
26
+ [changelog](https://github.com/typst/hayagriva/blob/main/CHANGELOG.md) for
27
+ more details. **(Breaking change)**
28
+ - A few bugs with `.bib` file parsing were fixed
29
+ - Removed `brackets` argument of `cite` function in favor of `form`
30
+
31
+ ## Visualization
32
+ - Gradients and colors (thanks to [@Dherse](https://github.com/Dherse))
33
+ - Added support for [gradients]($gradient) on shapes and text
34
+ - Supports linear, radial, and conic gradients
35
+ - Added support for defining colors in more color spaces, including
36
+ [Oklab]($color.oklab), [Linear RGB(A)]($color.linear-rgb),
37
+ [HSL]($color.hsl), and [HSV]($color.hsv)
38
+ - Added [`saturate`]($color.saturate), [`desaturate`]($color.desaturate), and
39
+ [`rotate`]($color.rotate) functions on colors
40
+ - Added [`color.map`]($color/#predefined-color-maps) module with predefined
41
+ color maps that can be used with gradients
42
+ - Rename `kind` function on colors to [`space`]($color.space)
43
+ - Removed `to-rgba`, `to-cmyk`, and `to-luma` functions in favor of a new
44
+ [`components`]($color.components) function
45
+ - Improved rendering of [rectangles]($rect) with corner radius and varying
46
+ stroke widths
47
+ - Added support for properly clipping [boxes]($box.clip) and
48
+ [blocks]($block.clip) with a border radius
49
+ - Added `background` parameter to [`overline`], [`underline`], and [`strike`]
50
+ functions
51
+ - Fixed inaccurate color embedding in PDFs
52
+ - Fixed ICC profile handling for images embedded in PDFs
53
+
54
+ ## Text and Layout
55
+ - Added support for automatically adding proper
56
+ [spacing]($text.cjk-latin-spacing) between CJK and Latin text (enabled by
57
+ default)
58
+ - Added support for automatic adjustment of more CJK punctuation
59
+ - Added [`quote`] element for inserting inline and block quotes with optional
60
+ attributions
61
+ - Added [`raw.line`]($raw.line) element for customizing the display of
62
+ individual lines of raw text, e.g. to add line numbers while keeping proper
63
+ syntax highlighting
64
+ - Added support for per-side [inset]($table.inset) customization to table
65
+ function
66
+ - Added Hungarian and Romanian translations
67
+ - Added support for Czech hyphenation
68
+ - Added support for setting custom [smart quotes]($smartquote)
69
+ - The default [figure separator]($figure.caption.separator) now reacts to the
70
+ currently set language and region
71
+ - Improved line breaking of links / URLs (especially helpful for bibliographies
72
+ with many URLs)
73
+ - Improved handling of consecutive hyphens in justification algorithm
74
+ - Fixed interaction of justification and hanging indent
75
+ - Fixed a bug with line breaking of short lines without spaces when
76
+ justification is enabled
77
+ - Fixed font fallback for hyphen generated by hyphenation
78
+ - Fixed handling of word joiner and other no-break characters during hyphenation
79
+ - Fixed crash when hyphenating after an empty line
80
+ - Fixed line breaking of composite emoji like 🏳️‍🌈
81
+ - Fixed missing text in some SVGs
82
+ - Fixed font fallback in SVGs
83
+ - Fixed behavior of [`to`]($pagebreak.to) argument on `pagebreak` function
84
+ - Fixed `{set align(..)}` for equations
85
+ - Fixed spacing around [placed]($place) elements
86
+ - Fixed coalescing of [`above`]($block.above) and [`below`]($block.below)
87
+ spacing if given in em units and the font sizes differ
88
+ - Fixed handling of `extent` parameter of [`underline`], [`overline`], and
89
+ [`strike`] functions
90
+ - Fixed crash for [floating placed elements]($place.float) with no specified
91
+ vertical alignment
92
+ - Partially fixed a bug with citations in footnotes
93
+
94
+ ## Math
95
+ - Added `gap` argument for [`vec`]($math.vec.gap), [`mat`]($math.mat.gap), and
96
+ [`cases`]($math.cases.gap) function
97
+ - Added `size` argument for [`abs`]($math.abs), [`norm`]($math.norm),
98
+ [`floor`]($math.floor), [`ceil`]($math.ceil), and [`round`]($math.round)
99
+ functions
100
+ - Added [`reverse`]($math.cases.reverse) parameter to cases function
101
+ - Added support for multinomial coefficients to [`binom`]($math.binom) function
102
+ - Removed `rotation` argument on [`cancel`]($math.cancel) function in favor of a
103
+ new and more flexible `angle` argument **(Breaking change)**
104
+ - Added `wide` constant, which inserts twice the spacing of `quad`
105
+ - Added `csch` and `sech` [operators]($math.op)
106
+ - `↼`, `⇀`, `↔`, and `⟷` can now be used as [accents]($math.accent)
107
+ - Added `integral.dash`, `integral.dash.double`, and `integral.slash`
108
+ [symbols]($category/symbols/sym)
109
+ - Added support for specifying negative indices for
110
+ [augmentation]($math.mat.augment) lines to position the line from the back
111
+ - Fixed default color of matrix [augmentation]($math.mat.augment) lines
112
+ - Fixed attachment of primes to inline expressions
113
+ - Math content now respects the text [baseline]($text.baseline) setting
114
+
115
+ ## Performance
116
+ - Fixed a bug related to show rules in templates which would effectively disable
117
+ incremental compilation in affected documents
118
+ - Micro-optimized code in several hot paths, which brings substantial
119
+ performance gains, in particular in incremental compilations
120
+ - Improved incremental parsing, which affects the whole incremental compilation
121
+ pipeline
122
+ - Added support for incremental parsing in the CLI
123
+ - Added support for incremental SVG encoding during PDF export, which greatly
124
+ improves export performance for documents with many SVG
125
+
126
+ ## Tooling and Diagnostics
127
+ - Improved autocompletion for variables that are in-scope
128
+ - Added autocompletion for package imports
129
+ - Added autocompletion for [labels]($label)
130
+ - Added tooltip that shows which variables a function captures (when hovering
131
+ over the equals sign or arrow of the function)
132
+ - Diagnostics are now deduplicated
133
+ - Improved diagnostics when trying to apply unary `+` or `-` to types that only
134
+ support binary `+` and `-`
135
+ - Error messages now state which label or citation key isn't present in the
136
+ document or its bibliography
137
+ - Fixed a bug where function argument parsing errors were shadowed by function
138
+ execution errors (e.g. when trying to call [`array.sorted`]($array.sorted) and
139
+ passing the key function as a positional argument instead of a named one).
140
+
141
+ ## Export
142
+ - Added support for configuring the document's creation
143
+ [`date`]($document.date). If the `date` is set to `{auto}` (the default), the
144
+ PDF's creation date will be set to the current date and time.
145
+ - Added support for configuring document [`keywords`]($document.keywords)
146
+ - Generated PDFs now contain PDF document IDs
147
+ - The PDF creator tool metadata now includes the Typst version
148
+
149
+ ## Web app
150
+ - Added version picker to pin a project to an older compiler version
151
+ (with support for Typst 0.6.0+)
152
+ - Fixed desyncs between editor and compiler and improved overall stability
153
+ - The app now continues to highlight the document when typing while the document
154
+ is being compiled
155
+
156
+ ## Command line interface
157
+ - Added support for discovering fonts through fontconfig
158
+ - Now clears the screen instead of resetting the terminal
159
+ - Now automatically picks correct file extension for selected output format
160
+ - Now only regenerates images for changed pages when using `typst watch` with
161
+ PNG or SVG export
162
+
163
+ ## Miscellaneous Improvements
164
+ - Added [`version`] type and `sys.version` constant specifying the current
165
+ compiler version. Can be used to gracefully support multiple versions.
166
+ - The U+2212 MINUS SIGN is now used when displaying a numeric value, in the
167
+ [`repr`] of any numeric value and to replace a normal hyphen in text mode when
168
+ before a digit. This improves, in particular, how negative integer values are
169
+ displayed in math mode.
170
+ - Added support for specifying a default value instead of failing for `remove`
171
+ function in [array]($array.remove) and [dictionary]($dictionary.remove)
172
+ - Simplified page setup guide examples
173
+ - Switched the documentation from using the word "hashtag" to the word "hash"
174
+ where appropriate
175
+ - Added support for [`array.zip`]($array.zip) without any further arguments
176
+ - Fixed crash when a plugin tried to read out of bounds memory
177
+ - Fixed crashes when handling infinite [lengths]($length)
178
+ - Fixed introspection (mostly bibliography) bugs due to weak page break close to
179
+ the end of the document
180
+
181
+ ## Development
182
+ - Extracted `typst::ide` into separate `typst_ide` crate
183
+ - Removed a few remaining `'static` bounds on `&dyn World`
184
+ - Removed unnecessary dependency, which reduces the binary size
185
+ - Fixed compilation of `typst` by itself (without `typst-library`)
186
+ - Fixed warnings with Nix flake when using `lib.getExe`
187
+
188
+ ## Contributors
189
+ <contributors from="v0.8.0" to="v0.9.0" />
sources/docs/changelog/earlier.md ADDED
@@ -0,0 +1,309 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Earlier
3
+ description: Changes in early, unversioned Typst
4
+ ---
5
+
6
+ # Changes in early, unversioned Typst
7
+
8
+ ## March 28, 2023
9
+ - **Breaking changes:**
10
+ - Enumerations now require a space after their marker, that is, `[1.ok]` must
11
+ now be written as `[1. ok]`
12
+ - Changed default style for [term lists]($terms): Does not include a colon
13
+ anymore and has a bit more indent
14
+
15
+ - Command line interface
16
+ - Added `--font-path` argument for CLI
17
+ - Embedded default fonts in CLI binary
18
+ - Fixed build of CLI if `git` is not installed
19
+
20
+ - Miscellaneous improvements
21
+ - Added support for disabling [matrix]($math.mat) and [vector]($math.vec)
22
+ delimiters. Generally with `[#set math.mat(delim: none)]` or one-off with
23
+ `[$mat(delim: #none, 1, 2; 3, 4)$]`.
24
+ - Added [`separator`]($terms.separator) argument to term lists
25
+ - Added [`round`]($math.round) function for equations
26
+ - Numberings now allow zeros. To reset a counter, you can write
27
+ `[#counter(..).update(0)]`
28
+ - Added documentation for `{page()}` and `{position()}` methods on
29
+ [`location`] type
30
+ - Added symbols for double, triple, and quadruple dot accent
31
+ - Added smart quotes for Norwegian Bokmål
32
+ - Added Nix flake
33
+ - Fixed bibliography ordering in IEEE style
34
+ - Fixed parsing of decimals in math: `[$1.2/3.4$]`
35
+ - Fixed parsing of unbalanced delimiters in fractions: `[$1/(2 (x)$]`
36
+ - Fixed unexpected parsing of numbers as enumerations, e.g. in `[1.2]`
37
+ - Fixed combination of page fill and header
38
+ - Fixed compiler crash if [`repeat`] is used in page with automatic width
39
+ - Fixed [matrices]($math.mat) with explicit delimiter
40
+ - Fixed [`indent`]($terms.indent) property of term lists
41
+ - Numerous documentation fixes
42
+ - Links in bibliographies are now affected by link styling
43
+ - Fixed hovering over comments in web app
44
+
45
+ <contributors from="v23-03-21" to="v23-03-28" />
46
+
47
+ ## March 21, 2023
48
+ - Reference and bibliography management
49
+ - [Bibliographies]($bibliography) and [citations]($cite) (currently supported
50
+ styles are APA, Chicago Author Date, IEEE, and MLA)
51
+ - You can now [reference]($ref) sections, figures, formulas, and works from
52
+ the bibliography with `[@label]`
53
+ - You can make an element referenceable with a label:
54
+ - `[= Introduction <intro>]`
55
+ - `[$ A = pi r^2 $ <area>]`
56
+
57
+ - Introspection system for interactions between different parts of the document
58
+ - [`counter`] function
59
+ - Access and modify counters for pages, headings, figures, and equations
60
+ - Define and use your own custom counters
61
+ - Time travel: Find out what the counter value was or will be at some other
62
+ point in the document (e.g. when you're building a list of figures, you
63
+ can determine the value of the figure counter at any given figure).
64
+ - Counters count in layout order and not in code order
65
+ - [`state`] function
66
+ - Manage arbitrary state across your document
67
+ - Time travel: Find out the value of your state at any position in the
68
+ document
69
+ - State is modified in layout order and not in code order
70
+ - [`query`] function
71
+ - Find all occurrences of an element or a label, either in the whole
72
+ document or before/after some location
73
+ - Link to elements, find out their position on the pages and access their
74
+ fields
75
+ - Example use cases: Custom list of figures or page header with current
76
+ chapter title
77
+ - [`locate`] function
78
+ - Determines the location of itself in the final layout
79
+ - Can be accessed to get the `page` and `x`, `y` coordinates
80
+ - Can be used with counters and state to find out their values at that
81
+ location
82
+ - Can be used with queries to find elements before or after its location
83
+
84
+ - New [`measure`] function
85
+ - Measure the layouted size of elements
86
+ - To be used in combination with the new `style` function that lets you
87
+ generate different content based on the style context something is inserted
88
+ into (because that affects the measured size of content)
89
+
90
+ - Exposed content representation
91
+ - Content is not opaque anymore
92
+ - Content can be compared for equality
93
+ - The tree of content elements can be traversed with code
94
+ - Can be observed in hover tooltips or with [`repr`]
95
+ - New [methods]($content) on content: `func`, `has`, `at`, and `location`
96
+ - All optional fields on elements are now settable
97
+ - More uniform field names (`heading.title` becomes `heading.body`,
98
+ `list.items` becomes `list.children`, and a few more changes)
99
+
100
+ - Further improvements
101
+ - Added [`figure`] function
102
+ - Added [`numbering`]($math.equation.numbering) parameter on equation function
103
+ - Added [`numbering`]($page.numbering) and
104
+ [`number-align`]($page.number-align) parameters on page function
105
+ - The page function's [`header`]($page.header) and [`footer`]($page.footer)
106
+ parameters do not take functions anymore. If you want to customize them
107
+ based on the page number, use the new [`numbering`]($page.numbering)
108
+ parameter or [`counter`] function instead.
109
+ - Added [`footer-descent`]($page.footer-descent) and
110
+ [`header-ascent`]($page.header-ascent) parameters
111
+ - Better default alignment in header and footer
112
+ - Fixed Arabic vowel placement
113
+ - Fixed PDF font embedding issues
114
+ - Renamed `math.formula` to [`math.equation`]($math.equation)
115
+ - Font family must be a named argument now: `[#set text(font: "..")]`
116
+ - Added support for [hanging indent]($par.hanging-indent)
117
+ - Renamed paragraph `indent` to [`first-line-indent`]($par.first-line-indent)
118
+ - More accurate [logarithm]($calc.log) when base is `2` or `10`
119
+ - Improved some error messages
120
+ - Fixed layout of [`terms`] list
121
+
122
+ - Web app improvements
123
+ - Added template gallery
124
+ - Added buttons to insert headings, equations, raw blocks, and references
125
+ - Jump to the source of something by clicking on it in the preview panel
126
+ (works for text, equations, images, and more)
127
+ - You can now upload your own fonts and use them in your project
128
+ - Hover debugging and autocompletion now takes multiple files into account and
129
+ works in show rules
130
+ - Hover tooltips now automatically collapse multiple consecutive equal values
131
+ - The preview now automatically scrolls to the right place when you type
132
+ - Links are now clickable in the preview area
133
+ - Toolbar, preview, and editor can now all be hidden
134
+ - Added autocompletion for raw block language tags
135
+ - Added autocompletion in SVG files
136
+ - New back button instead of four-dots button
137
+ - Lots of bug fixes
138
+
139
+ ## February 25, 2023
140
+ - Font changes
141
+ - New default font: Linux Libertine
142
+ - New default font for raw blocks: DejaVu Sans Mono
143
+ - New default font for math: Book weight of New Computer Modern Math
144
+ - Lots of new math fonts available
145
+ - Removed Latin Modern fonts in favor of New Computer Modern family
146
+ - Removed unnecessary smallcaps fonts which are already accessible through the
147
+ corresponding main font and the [`smallcaps`] function
148
+ - Improved default spacing for headings
149
+ - Added [`panic`] function
150
+ - Added [`clusters`]($str.clusters) and [`codepoints`]($str.codepoints) methods
151
+ for strings
152
+ - Support for multiple authors in [`set document`]($document.author)
153
+ - Fixed crash when string is accessed at a position that is not a char boundary
154
+ - Fixed semicolon parsing in `[#var ;]`
155
+ - Fixed incremental parsing when inserting backslash at end of `[#"abc"]`
156
+ - Fixed names of a few font families (including Noto Sans Symbols and New
157
+ Computer Modern families)
158
+ - Fixed autocompletion for font families
159
+ - Improved incremental compilation for user-defined functions
160
+
161
+ ## February 15, 2023
162
+ - [Box]($box) and [block] have gained `fill`, `stroke`, `radius`, and `inset`
163
+ properties
164
+ - Blocks may now be explicitly sized, fixed-height blocks can still break across
165
+ pages
166
+ - Blocks can now be configured to be [`breakable`]($block.breakable) or not
167
+ - [Numbering style]($enum.numbering) can now be configured for nested enums
168
+ - [Markers]($list.marker) can now be configured for nested lists
169
+ - The [`eval`] function now expects code instead of markup and returns an
170
+ arbitrary value. Markup can still be evaluated by surrounding the string with
171
+ brackets.
172
+ - PDFs generated by Typst now contain XMP metadata
173
+ - Link boxes are now disabled in PDF output
174
+ - Tables don't produce small empty cells before a pagebreak anymore
175
+ - Fixed raw block highlighting bug
176
+
177
+ ## February 12, 2023
178
+ - Shapes, images, and transformations (move/rotate/scale/repeat) are now
179
+ block-level. To integrate them into a paragraph, use a [`box`] as with other
180
+ elements.
181
+ - A colon is now required in an "everything" show rule: Write `{show: it => ..}`
182
+ instead of `{show it => ..}`. This prevents intermediate states that ruin your
183
+ whole document.
184
+ - Non-math content like a shape or table in a math formula is now centered
185
+ vertically
186
+ - Support for widow and orphan prevention within containers
187
+ - Support for [RTL]($text.dir) in lists, grids, and tables
188
+ - Support for explicit `{auto}` sizing for boxes and shapes
189
+ - Support for fractional (i.e. `{1fr}`) widths for boxes
190
+ - Fixed bug where columns jump to next page
191
+ - Fixed bug where list items have no leading
192
+ - Fixed relative sizing in lists, squares and grid auto columns
193
+ - Fixed relative displacement in [`place`] function
194
+ - Fixed that lines don't have a size
195
+ - Fixed bug where `{set document(..)}` complains about being after content
196
+ - Fixed parsing of `{not in}` operation
197
+ - Fixed hover tooltips in math
198
+ - Fixed bug where a heading show rule may not contain a pagebreak when an
199
+ outline is present
200
+ - Added [`baseline`]($box.baseline) property on [`box`]
201
+ - Added [`tg`]($math.op) and [`ctg`]($math.op) operators in math
202
+ - Added delimiter setting for [`cases`]($math.cases) function
203
+ - Parentheses are now included when accepting a function autocompletion
204
+
205
+ ## February 2, 2023
206
+ - Merged text and math symbols, renamed a few symbols (including `infty` to
207
+ `infinity` with the alias `oo`)
208
+ - Fixed missing italic mappings
209
+ - Math italics correction is now applied properly
210
+ - Parentheses now scale in `[$zeta(x/2)$]`
211
+ - Fixed placement of large root index
212
+ - Fixed spacing in `[$abs(-x)$]`
213
+ - Fixed inconsistency between text and identifiers in math
214
+ - Accents are now ignored when positioning superscripts
215
+ - Fixed vertical alignment in matrices
216
+ - Fixed `text` set rule in `raw` show rule
217
+ - Heading and list markers now parse consistently
218
+ - Allow arbitrary math directly in content
219
+
220
+ ## January 30, 2023
221
+ [Go to the announcement blog post.](https://typst.app/blog/2023/january-update)
222
+ - New expression syntax in markup/math
223
+ - Blocks cannot be directly embedded in markup anymore
224
+ - Like other expressions, they now require a leading hash
225
+ - More expressions available with hash, including literals (`[#"string"]`) as
226
+ well as field access and method call without space: `[#emoji.face]`
227
+ - New import syntax
228
+ - `[#import "module.typ"]` creates binding named `module`
229
+ - `[#import "module.typ": a, b]` or `[#import "module.typ": *]` to import
230
+ items
231
+ - `[#import emoji: face, turtle]` to import from already bound module
232
+ - New symbol handling
233
+ - Removed symbol notation
234
+ - Symbols are now in modules: `{sym}`, `{emoji}`, and `{math}`
235
+ - Math module also reexports all of `{sym}`
236
+ - Modified through field access, still order-independent
237
+ - Unknown modifiers are not allowed anymore
238
+ - Support for custom symbol definitions with `symbol` function
239
+ - Symbols now listed in documentation
240
+ - New `{math}` module
241
+ - Contains all math-related functions
242
+ - Variables and function calls directly in math (without hash) access this
243
+ module instead of the global scope, but can also access local variables
244
+ - Can be explicitly used in code, e.g. `[#set math.vec(delim: "[")]`
245
+ - Delimiter matching in math
246
+ - Any opening delimiters matches any closing one
247
+ - When matched, they automatically scale
248
+ - To prevent scaling, escape them
249
+ - To forcibly match two delimiters, use `lr` function
250
+ - Line breaks may occur between matched delimiters
251
+ - Delimiters may also be unbalanced
252
+ - You can also use the `lr` function to scale the brackets (or just one
253
+ bracket) to a specific size manually
254
+ - Multi-line math with alignment
255
+ - The `\` character inserts a line break
256
+ - The `&` character defines an alignment point
257
+ - Alignment points also work for underbraces, vectors, cases, and matrices
258
+ - Multiple alignment points are supported
259
+ - More capable math function calls
260
+ - Function calls directly in math can now take code expressions with hash
261
+ - They can now also take named arguments
262
+ - Within math function calls, semicolons turn preceding arguments to arrays to
263
+ support matrices: `[$mat(1, 2; 3, 4)$]`
264
+ - Arbitrary content in math
265
+ - Text, images, and other arbitrary content can now be embedded in math
266
+ - Math now also supports font fallback to support e.g. CJK and emoji
267
+ - More math features
268
+ - New text operators: `op` function, `lim`, `max`, etc.
269
+ - New matrix function: `mat`
270
+ - New n-ary roots with `root` function: `[$root(3, x)$]`
271
+ - New under- and overbraces, -brackets, and -lines
272
+ - New `abs` and `norm` functions
273
+ - New shorthands: `[|`, `|]`, and `||`
274
+ - New `attach` function, overridable attachments with `script` and `limit`
275
+ - Manual spacing in math, with `h`, `thin`, `med`, `thick` and `quad`
276
+ - Symbols and other content may now be used like a function, e.g.
277
+ `[$zeta(x)$]`
278
+ - Added Fira Math font, removed Noto Sans Math font
279
+ - Support for alternative math fonts through `[#show math.formula: set
280
+ text("Fira Math")]`
281
+ - More library improvements
282
+ - New `calc` module, `abs`, `min`, `max`, `even`, `odd` and `mod` moved there
283
+ - New `message` argument on `{assert}` function
284
+ - The `pairs` method on dictionaries now returns an array of length-2 arrays
285
+ instead of taking a closure
286
+ - The method call `{dict.at("key")}` now always fails if `"key"` doesn't exist
287
+ Previously, it was allowed in assignments. Alternatives are `{dict.key = x}`
288
+ and `{dict.insert("key", x)}`.
289
+ - Smarter editor functionality
290
+ - Autocompletion for local variables
291
+ - Autocompletion for methods available on a value
292
+ - Autocompletion for symbols and modules
293
+ - Autocompletion for imports
294
+ - Hover over an identifier to see its value(s)
295
+ - Further editor improvements
296
+ - New Font menu with previews
297
+ - Single projects may now be shared with share links
298
+ - New dashboard experience if projects are shared with you
299
+ - Keyboard Shortcuts are now listed in the menus and there are more of them
300
+ - New Offline indicator
301
+ - Tooltips for all buttons
302
+ - Improved account protection
303
+ - Moved Status indicator into the error list button
304
+ - Further fixes
305
+ - Multiple bug fixes for incremental parser
306
+ - Fixed closure parameter capturing
307
+ - Fixed tons of math bugs
308
+ - Bugfixes for performance, file management, editing reliability
309
+ - Added redirection to the page originally navigated to after signin
sources/docs/changelog/welcome.md ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ description: |
3
+ Learn what has changed in the latest Typst releases and move your documents
4
+ forward.
5
+ ---
6
+
7
+ # Changelog
8
+ Learn what has changed in the latest Typst releases and move your documents
9
+ forward. This section documents all changes to Typst since its initial public
10
+ release.
11
+
12
+ ## Versions
13
+ - [Typst 0.13.1]($changelog/0.13.1)
14
+ - [Typst 0.13.0]($changelog/0.13.0)
15
+ - [Typst 0.12.0]($changelog/0.12.0)
16
+ - [Typst 0.11.1]($changelog/0.11.1)
17
+ - [Typst 0.11.0]($changelog/0.11.0)
18
+ - [Typst 0.10.0]($changelog/0.10.0)
19
+ - [Typst 0.9.0]($changelog/0.9.0)
20
+ - [Typst 0.8.0]($changelog/0.8.0)
21
+ - [Typst 0.7.0]($changelog/0.7.0)
22
+ - [Typst 0.6.0]($changelog/0.6.0)
23
+ - [Typst 0.5.0]($changelog/0.5.0)
24
+ - [Typst 0.4.0]($changelog/0.4.0)
25
+ - [Typst 0.3.0]($changelog/0.3.0)
26
+ - [Typst 0.2.0]($changelog/0.2.0)
27
+ - [Typst 0.1.0]($changelog/0.1.0)
28
+ - [Earlier]($changelog/earlier)
sources/docs/dev/architecture.md ADDED
@@ -0,0 +1,199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Typst Compiler Architecture
2
+ Wondering how to contribute or just curious how Typst works? This document
3
+ covers the general structure and architecture of Typst's compiler, so you get an
4
+ understanding of what's where and how everything fits together.
5
+
6
+
7
+ ## Directories
8
+ Let's start with a broad overview of the directories in this repository:
9
+
10
+ - `crates/typst`: The main compiler crate which defines the complete language
11
+ and library.
12
+ - `crates/typst-cli`: Typst's command line interface. This is a relatively small
13
+ layer on top of the compiler and the exporters.
14
+ - `crates/typst-eval`: The interpreter for the Typst language.
15
+ - `crates/typst-ide`: Exposes IDE functionality.
16
+ - `crates/typst-kit`: Contains various default implementation of
17
+ functionality used in `typst-cli`.
18
+ - `crates/typst-layout`: Typst's layout engine.
19
+ - `crates/typst-library`: Typst's standard library.
20
+ - `crates/typst-macros`: Procedural macros for the compiler.
21
+ - `crates/typst-pdf`: The PDF exporter.
22
+ - `crates/typst-realize`: Typst's realization subsystem.
23
+ - `crates/typst-render`: A renderer for Typst frames.
24
+ - `crates/typst-svg`: The SVG exporter.
25
+ - `crates/typst-syntax`: Home to the parser and syntax tree definition.
26
+ - `crates/typst-timing`: Performance timing for Typst.
27
+ - `crates/typst-utils`: Utilities for Typst.
28
+ - `docs`: Generates the content of the official
29
+ [documentation][docs] from markdown files and the inline
30
+ Rust documentation. Only generates the content and structure, not the concrete
31
+ HTML (that part is currently closed source).
32
+ - `tests`: Integration tests for Typst compilation.
33
+ - `tools`: Tooling for development.
34
+
35
+
36
+ ## Compilation
37
+ The source-to-PDF compilation process of a Typst file proceeds in four phases.
38
+
39
+ 1. **Parsing:** Turns a source string into a syntax tree.
40
+ 2. **Evaluation:** Turns a syntax tree and its dependencies into content.
41
+ 3. **Layout:** Layouts content into frames.
42
+ 4. **Export:** Turns frames into an output format like PDF or a raster graphic.
43
+
44
+ The Typst compiler is _incremental:_ Recompiling a document that was compiled
45
+ previously is much faster than compiling from scratch. Most of the hard work is
46
+ done by [`comemo`], an incremental compilation framework we have written for
47
+ Typst. However, the compiler is still carefully written with incrementality in
48
+ mind. Below we discuss the four phases and how incrementality affects each of
49
+ them.
50
+
51
+
52
+ ## Parsing
53
+ The syntax tree and parser are located in `crates/typst-syntax`. Parsing is
54
+ a pure function `&str -> SyntaxNode` without any further dependencies. The
55
+ result is a concrete syntax tree reflecting the whole file structure, including
56
+ whitespace and comments. Parsing cannot fail. If there are syntactic errors, the
57
+ returned syntax tree contains error nodes instead. It's important that the
58
+ parser deals well with broken code because it is also used for syntax
59
+ highlighting and IDE functionality.
60
+
61
+ **Typedness:**
62
+ The syntax tree is untyped, any node can have any `SyntaxKind`. This makes it
63
+ very easy to (a) attach spans to each node (see below), (b) traverse the tree
64
+ when doing highlighting or IDE analyses (no extra complications like a visitor
65
+ pattern). The `typst::syntax::ast` module provides a typed API on top of
66
+ the raw tree. This API resembles a more classical AST and is used by the
67
+ interpreter.
68
+
69
+ **Spans:**
70
+ After parsing, the syntax tree is numbered with _span numbers._ These numbers
71
+ are unique identifiers for syntax nodes that are used to trace back errors in
72
+ later compilation phases to a piece of syntax. The span numbers are ordered so
73
+ that the node corresponding to a number can be found quickly.
74
+
75
+ **Incremental:**
76
+ Typst has an incremental parser that can reparse a segment of markup or a
77
+ code/content block. After incremental parsing, span numbers are reassigned
78
+ locally. This way, span numbers further away from an edit stay mostly stable.
79
+ This is important because they are used pervasively throughout the compiler,
80
+ also as input to memoized functions. The less they change, the better for
81
+ incremental compilation.
82
+
83
+
84
+ ## Evaluation
85
+ The evaluation phase lives in `crates/typst/src/eval`. It takes a parsed
86
+ `Source` file and evaluates it to a `Module`. A module consists of the `Content`
87
+ that was written in it and a `Scope` with the bindings that were defined within
88
+ it.
89
+
90
+ A source file may depend on other files (imported sources, images, data files),
91
+ which need to be resolved. Since Typst is deployed in different environments
92
+ (CLI, web app, etc.) these system dependencies are resolved through a general
93
+ interface called a `World`. Apart from files, the world also provides
94
+ configuration and fonts.
95
+
96
+ **Interpreter:**
97
+ Typst implements a tree-walking interpreter. To evaluate a piece of source, you
98
+ first create a `Vm` with a scope stack. Then, the AST is recursively evaluated
99
+ through trait impls of the form `fn eval(&self, vm: &mut Vm) -> Result<Value>`.
100
+ An interesting detail is how closures are dealt with: When the interpreter sees
101
+ a closure / function definition, it walks the body of the closure and finds all
102
+ accesses to variables that aren't defined within the closure. It then clones the
103
+ values of all these variables (it _captures_ them) and stores them alongside the
104
+ closure's syntactical definition in a closure value. When the closure is called,
105
+ a fresh `Vm` is created and its scope stack is initialized with the captured
106
+ variables.
107
+
108
+ **Incremental:**
109
+ In this phase, incremental compilation happens at the granularity of the module
110
+ and the closure. Typst memoizes the result of evaluating a source file across
111
+ compilations. Furthermore, it memoizes the result of calling a closure with a
112
+ certain set of parameters. This is possible because Typst ensures that all
113
+ functions are pure. The result of a closure call can be recycled if the closure
114
+ has the same syntax and captures, even if the closure values stems from a
115
+ different module evaluation (i.e. if a module is reevaluated, previous calls to
116
+ closures defined in the module can still be reused).
117
+
118
+
119
+ ## Layout
120
+ The layout phase takes `Content` and produces one `Frame` per page for it. To
121
+ layout `Content`, we first have to _realize_ it by applying all relevant show
122
+ rules to the content. Since show rules may be defined as Typst closures,
123
+ realization can trigger closure evaluation, which in turn produces content that
124
+ is recursively realized. Realization is a shallow process: While collecting list
125
+ items into a list that we want to layout, we don't realize the content within
126
+ the list items just yet. This only happens lazily once the list items are
127
+ layouted.
128
+
129
+ When we a have realized the content into a layoutable element, we can then
130
+ layout it into _regions,_ which describe the space into which the content shall
131
+ be layouted. Within these, an element is free to layout itself as it sees fit,
132
+ returning one `Frame` per region it wants to occupy.
133
+
134
+ **Introspection:**
135
+ How content layouts (and realizes) may depend on how _it itself_ is layouted
136
+ (e.g., through page numbers in the table of contents, counters, state, etc.).
137
+ Typst resolves these inherently cyclical dependencies through the _introspection
138
+ loop:_ The layout phase runs in a loop until the results stabilize. Most
139
+ introspections stabilize after one or two iterations. However, some may never
140
+ stabilize, so we give up after five attempts.
141
+
142
+ **Incremental:**
143
+ Layout caching happens at the granularity of the element. This is important
144
+ because overall layout is the most expensive compilation phase, so we want to
145
+ reuse as much as possible.
146
+
147
+
148
+ ## Export
149
+ Exporters live in separate crates. They turn layouted frames into an output file
150
+ format.
151
+
152
+ - The PDF exporter takes layouted frames and turns them into a PDF file.
153
+ - The SVG exporter takes a frame and turns it into an SVG.
154
+ - The built-in renderer takes a frame and turns it into a pixel buffer.
155
+ - HTML export does not exist yet, but will in the future. However, this requires
156
+ some complex compiler work because the export will start with `Content`
157
+ instead of `Frames` (layout is the browser's job).
158
+
159
+
160
+ ## IDE
161
+ The `crates/typst-ide` crate implements IDE functionality for Typst. It
162
+ builds heavily on the other modules (most importantly, `syntax` and `eval`).
163
+
164
+ **Syntactic:**
165
+ Basic IDE functionality is based on a file's syntax. However, the standard
166
+ syntax node is a bit too limited for writing IDE tooling. It doesn't provide
167
+ access to its parents or neighbours. This is fine for an evaluation-like
168
+ recursive traversal, but impractical for IDE use cases. For this reason, there
169
+ is an additional abstraction on top of a syntax node called a `LinkedNode`,
170
+ which is used pervasively across the `ide` module.
171
+
172
+ **Semantic:**
173
+ More advanced functionality like autocompletion requires semantic analysis of
174
+ the source. To gain semantic information for things like hover tooltips, we
175
+ directly use other parts of the compiler. For instance, to find out the type of
176
+ a variable, we evaluate and realize the full document equipped with a `Tracer`
177
+ that emits the variable's value whenever it is visited. From the set of
178
+ resulting values, we can then compute the set of types a value takes on. Thanks
179
+ to incremental compilation, we can recycle large parts of the compilation that
180
+ we had to do anyway to typeset the document.
181
+
182
+ **Incremental:**
183
+ Syntactic IDE stuff is relatively cheap for now, so there are no special
184
+ incrementality concerns. Semantic analysis with a tracer is relatively
185
+ expensive. However, large parts of a traced analysis compilation can reuse
186
+ memoized results from a previous normal compilation. Only the module evaluation
187
+ of the active file and layout code that somewhere within evaluates source code
188
+ in the active file needs to re-run. This is all handled automatically by
189
+ `comemo` because the tracer is wrapped in a `comemo::TrackedMut` container.
190
+
191
+
192
+ ## Tests
193
+ Typst has an extensive suite of integration tests. These tests cover parsing,
194
+ evaluation, realization, layout, and rendering. PDF output is sadly untested so
195
+ far, but most bugs are in earlier phases of the compiler. For more details about
196
+ testing, see the [tests directory](/tests) and its README.
197
+
198
+ [docs]: https://typst.app/docs/
199
+ [`comemo`]: https://github.com/typst/comemo/
sources/docs/guides/guide-for-latex-users.md ADDED
@@ -0,0 +1,676 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ description: |
3
+ Are you a LaTeX user? This guide explains the differences and
4
+ similarities between Typst and LaTeX so you can get started quickly.
5
+ ---
6
+
7
+ # Guide for LaTeX users { # }
8
+ This page is a good starting point if you have used LaTeX before and want to try
9
+ out Typst. We will explore the main differences between these two systems from a
10
+ user perspective. Although Typst is not built upon LaTeX and has a different
11
+ syntax, you will learn how to use your LaTeX skills to get a head start.
12
+
13
+ Just like LaTeX, Typst is a markup-based typesetting system: You compose your
14
+ document in a text file and mark it up with commands and other syntax. Then, you
15
+ use a compiler to typeset the source file into a PDF. However, Typst also
16
+ differs from LaTeX in several aspects: For one, Typst uses more dedicated syntax
17
+ (like you may know from Markdown) for common tasks. Typst's commands are also
18
+ more principled: They all work the same, so unlike in LaTeX, you just need to
19
+ understand a few general concepts instead of learning different conventions for
20
+ each package. Moreover Typst compiles faster than LaTeX: Compilation usually
21
+ takes milliseconds, not seconds, so the web app and the compiler can both
22
+ provide instant previews.
23
+
24
+ In the following, we will cover some of the most common questions a user
25
+ switching from LaTeX will have when composing a document in Typst. If you prefer
26
+ a step-by-step introduction to Typst, check out our [tutorial].
27
+
28
+ ## Installation
29
+ You have two ways to use Typst: In [our web app](https://typst.app/signup/) or
30
+ by [installing the compiler](https://github.com/typst/typst/releases) on your
31
+ computer. When you use the web app, we provide a batteries-included
32
+ collaborative editor and run Typst in your browser, no installation required.
33
+
34
+ If you choose to use Typst on your computer instead, you can download the
35
+ compiler as a single, small binary which any user can run, no root privileges
36
+ required. Unlike LaTeX, packages are downloaded when you first use them and
37
+ then cached locally, keeping your Typst installation lean. You can use your own
38
+ editor and decide where to store your files with the local compiler.
39
+
40
+ ## How do I create a new, empty document? { #getting-started }
41
+ That's easy. You just create a new, empty text file (the file extension is
42
+ `.typ`). No boilerplate is needed to get started. Simply start by writing your
43
+ text. It will be set on an empty A4-sized page. If you are using the web app,
44
+ click "+ Empty document" to create a new project with a file and enter the
45
+ editor. [Paragraph breaks]($parbreak) work just as they do in LaTeX, just use a
46
+ blank line.
47
+
48
+ ```example
49
+ Hey there!
50
+
51
+ Here are two paragraphs. The
52
+ output is shown to the right.
53
+ ```
54
+
55
+ If you want to start from an preexisting LaTeX document instead, you can use
56
+ [Pandoc](https://pandoc.org) to convert your source code to Typst markup. This
57
+ conversion is also built into our web app, so you can upload your `.tex` file to
58
+ start your project in Typst.
59
+
60
+ ## How do I create section headings, emphasis, ...? { #elements }
61
+ LaTeX uses the command `\section` to create a section heading. Nested headings
62
+ are indicated with `\subsection`, `\subsubsection`, etc. Depending on your
63
+ document class, there is also `\part` or `\chapter`.
64
+
65
+ In Typst, [headings]($heading) are less verbose: You prefix the line with the
66
+ heading on it with an equals sign and a space to get a first-order heading:
67
+ `[= Introduction]`. If you need a second-order heading, you use two equals
68
+ signs: `[== In this paper]`. You can nest headings as deeply as you'd like by
69
+ adding more equals signs.
70
+
71
+ Emphasis (usually rendered as italic text) is expressed by enclosing text in
72
+ `[_underscores_]` and strong emphasis (usually rendered in boldface) by using
73
+ `[*stars*]` instead.
74
+
75
+ Here is a list of common markup commands used in LaTeX and their Typst
76
+ equivalents. You can also check out the [full syntax cheat sheet]($syntax).
77
+
78
+ | Element | LaTeX | Typst | See |
79
+ |:-----------------|:--------------------------|:-----------------------|:-----------|
80
+ | Strong emphasis | `\textbf{strong}` | `[*strong*]` | [`strong`] |
81
+ | Emphasis | `\emph{emphasis}` | `[_emphasis_]` | [`emph`] |
82
+ | Monospace / code | `\texttt{print(1)}` | ``[`print(1)`]`` | [`raw`] |
83
+ | Link | `\url{https://typst.app}` | `[https://typst.app/]` | [`link`] |
84
+ | Label | `\label{intro}` | `[<intro>]` | [`label`] |
85
+ | Reference | `\ref{intro}` | `[@intro]` | [`ref`] |
86
+ | Citation | `\cite{humphrey97}` | `[@humphrey97]` | [`cite`] |
87
+ | Bullet list | `itemize` environment | `[- List]` | [`list`] |
88
+ | Numbered list | `enumerate` environment | `[+ List]` | [`enum`] |
89
+ | Term list | `description` environment | `[/ Term: List]` | [`terms`] |
90
+ | Figure | `figure` environment | `figure` function | [`figure`] |
91
+ | Table | `table` environment | `table` function | [`table`] |
92
+ | Equation | `$x$`, `align` / `equation` environments | `[$x$]`, `[$ x = y $]` | [`equation`]($math.equation) |
93
+
94
+ [Lists]($list) do not rely on environments in Typst. Instead, they have
95
+ lightweight syntax like headings. To create an unordered list (`itemize`),
96
+ prefix each line of an item with a hyphen:
97
+
98
+ ````example
99
+ To write this list in Typst...
100
+
101
+ ```latex
102
+ \begin{itemize}
103
+ \item Fast
104
+ \item Flexible
105
+ \item Intuitive
106
+ \end{itemize}
107
+ ```
108
+
109
+ ...just type this:
110
+
111
+ - Fast
112
+ - Flexible
113
+ - Intuitive
114
+
115
+ ````
116
+
117
+ Nesting lists works just by using proper indentation. Adding a blank line in
118
+ between items results in a more [widely]($list.tight) spaced list.
119
+
120
+ To get a [numbered list]($enum) (`enumerate`) instead, use a `+` instead of the
121
+ hyphen. For a [term list]($terms) (`description`), write `[/ Term: Description]`
122
+ instead.
123
+
124
+ ## How do I use a command? { #commands }
125
+ LaTeX heavily relies on commands (prefixed by backslashes). It uses these
126
+ _macros_ to affect the typesetting process and to insert and manipulate content.
127
+ Some commands accept arguments, which are most frequently enclosed in curly
128
+ braces: `\cite{rasmus}`.
129
+
130
+ Typst differentiates between [markup mode and code mode]($scripting/#blocks).
131
+ The default is markup mode, where you compose text and apply syntactic
132
+ constructs such as `[*stars for bold text*]`. Code mode, on the other hand,
133
+ parallels programming languages like Python, providing the option to input and
134
+ execute segments of code.
135
+
136
+ Within Typst's markup, you can switch to code mode for a single command (or
137
+ rather, _expression_) using a hash (`#`). This is how you call functions to, for
138
+ example, split your project into different [files]($scripting/#modules) or
139
+ render text based on some [condition]($scripting/#conditionals). Within code
140
+ mode, it is possible to include normal markup [_content_]($content) by using
141
+ square brackets. Within code mode, this content is treated just as any other
142
+ normal value for a variable.
143
+
144
+ ```example
145
+ First, a rectangle:
146
+ #rect()
147
+
148
+ Let me show how to do
149
+ #underline([_underlined_ text])
150
+
151
+ We can also do some maths:
152
+ #calc.max(3, 2 * 4)
153
+
154
+ And finally a little loop:
155
+ #for x in range(3) [
156
+ Hi #x.
157
+ ]
158
+ ```
159
+
160
+ A function call always involves the name of the function ([`rect`],
161
+ [`underline`], [`calc.max`]($calc.max), [`range`]($array.range)) followed by
162
+ parentheses (as opposed to LaTeX where the square brackets and curly braces are
163
+ optional if the macro requires no arguments). The expected list of arguments
164
+ passed within those parentheses depends on the concrete function and is
165
+ specified in the [reference].
166
+
167
+ ### Arguments
168
+ A function can have multiple arguments. Some arguments are positional, i.e., you
169
+ just provide the value: The function `[#lower("SCREAM")]` returns its argument
170
+ in all-lowercase. Many functions use named arguments instead of positional
171
+ arguments to increase legibility. For example, the dimensions and stroke of a
172
+ rectangle are defined with named arguments:
173
+
174
+ ```example
175
+ #rect(
176
+ width: 2cm,
177
+ height: 1cm,
178
+ stroke: red,
179
+ )
180
+ ```
181
+
182
+ You specify a named argument by first entering its name (above, it's `width`,
183
+ `height`, and `stroke`), then a colon, followed by the value (`2cm`, `1cm`,
184
+ `red`). You can find the available named arguments in the [reference
185
+ page]($reference) for each function or in the autocomplete panel when typing.
186
+ Named arguments are similar to how some LaTeX environments are configured, for
187
+ example, you would type `\begin{enumerate}[label={\alph*)}]` to start a list
188
+ with the labels `a)`, `b)`, and so on.
189
+
190
+ Often, you want to provide some [content] to a function. For example, the LaTeX
191
+ command `\underline{Alternative A}` would translate to
192
+ `[#underline([Alternative A])]` in Typst. The square brackets indicate that a
193
+ value is [content]. Within these brackets, you can use normal markup.
194
+ However, that's a lot of parentheses for a pretty simple construct. This is why
195
+ you can also move trailing content arguments after the parentheses (and omit the
196
+ parentheses if they would end up empty).
197
+
198
+ ```example
199
+ Typst is an #underline[alternative]
200
+ to LaTeX.
201
+
202
+ #rect(fill: aqua)[Get started here!]
203
+ ```
204
+
205
+ ### Data types
206
+ You likely already noticed that the arguments have distinctive data types. Typst
207
+ supports many [data types]($type). Below, there is a table with some of the most
208
+ important ones and how to write them. In order to specify values of any of these
209
+ types, you have to be in code mode!
210
+
211
+ | Data type | Example |
212
+ |:--------------------------------|:----------------------------------|
213
+ | [Content]($content) | `{[*fast* typesetting]}` |
214
+ | [String]($str) | `{"Pietro S. Author"}` |
215
+ | [Integer]($int) | `{23}` |
216
+ | [Floating point number]($float) | `{1.459}` |
217
+ | [Absolute length]($length) | `{12pt}`, `{5in}`, `{0.3cm}`, ... |
218
+ | [Relative length]($ratio) | `{65%}` |
219
+
220
+ The difference between content and string is that content can contain markup,
221
+ including function calls, while a string really is just a plain sequence of
222
+ characters.
223
+
224
+ Typst provides [control flow constructs]($scripting/#conditionals) and
225
+ [operators]($scripting/#operators) such as `+` for adding things or `==` for
226
+ checking equality between two variables.
227
+
228
+ You can also store values, including functions, in your own
229
+ [variables]($scripting/#bindings). This can be useful to perform computations on
230
+ them, create reusable automations, or reference a value multiple times. The
231
+ variable binding is accomplished with the let keyword, which works similar to
232
+ `\newcommand`:
233
+
234
+ ```example
235
+ // Store the integer `5`.
236
+ #let five = 5
237
+
238
+ // Define a function that
239
+ // increments a value.
240
+ #let inc(i) = i + 1
241
+
242
+ // Reference the variables.
243
+ I have #five fingers.
244
+
245
+ If I had one more, I'd have
246
+ #inc(five) fingers. Whoa!
247
+ ```
248
+
249
+ ### Commands to affect the remaining document { #rules }
250
+ In LaTeX, some commands like `\textbf{bold text}` receive an argument in curly
251
+ braces and only affect that argument. Other commands such as `\bfseries bold
252
+ text` act as switches (LaTeX calls this a declaration), altering the appearance
253
+ of all subsequent content within the document or current scope.
254
+
255
+ In Typst, the same function can be used both to affect the appearance for the
256
+ remainder of the document, a block (or scope), or just its arguments. For
257
+ example, `[#text(weight: "bold")[bold text]]` will only embolden its argument,
258
+ while `[#set text(weight: "bold")]` will embolden any text until the end of the
259
+ current block, or, if there is none, document. The effects of a function are
260
+ immediately obvious based on whether it is used in a call or a
261
+ [set rule.]($styling/#set-rules)
262
+
263
+ ```example
264
+ I am starting out with small text.
265
+
266
+ #set text(14pt)
267
+
268
+ This is a bit #text(18pt)[larger,]
269
+ don't you think?
270
+ ```
271
+
272
+ Set rules may appear anywhere in the document. They can be thought of as
273
+ default argument values of their respective function:
274
+
275
+ ```example
276
+ #set enum(numbering: "I.")
277
+
278
+ Good results can only be obtained by
279
+ + following best practices
280
+ + being aware of current results
281
+ of other researchers
282
+ + checking the data for biases
283
+ ```
284
+
285
+ The `+` is syntactic sugar (think of it as an abbreviation) for a call to the
286
+ [`{enum}`]($enum) function, to which we apply a set rule above.
287
+ [Most syntax is linked to a function in this way.]($syntax) If you need to style
288
+ an element beyond what its arguments enable, you can completely redefine its
289
+ appearance with a [show rule]($styling/#show-rules) (somewhat comparable to
290
+ `\renewcommand`).
291
+
292
+ You can achieve the effects of LaTeX commands like `\textbf`, `\textsf`,
293
+ `\rmfamily`, `\mdseries`, and `\itshape` with the [`font`]($text.font),
294
+ [`style`]($text.style), and [`weight`]($text.weight) arguments of the `text`
295
+ function. The text function can be used in a set rule (declaration style) or
296
+ with a content argument. To replace `\textsc`, you can use the [`smallcaps`]
297
+ function, which renders its content argument as smallcaps. Should you want to
298
+ use it declaration style (like `\scshape`), you can use an
299
+ [_everything_ show rule]($styling/#show-rules) that applies the function to the
300
+ rest of the scope:
301
+
302
+ ```example
303
+ #show: smallcaps
304
+
305
+ Boisterous Accusations
306
+ ```
307
+
308
+ ## How do I load a document class? { #templates }
309
+ In LaTeX, you start your main `.tex` file with the `\documentclass{article}`
310
+ command to define how your document is supposed to look. In that command, you
311
+ may have replaced `article` with another value such as `report` and `amsart` to
312
+ select a different look.
313
+
314
+ When using Typst, you style your documents with [functions]($function).
315
+ Typically, you use a template that provides a function that styles your whole
316
+ document. First, you import the function from a template file. Then, you apply
317
+ it to your whole document. This is accomplished with a
318
+ [show rule]($styling/#show-rules) that wraps the following document in a given
319
+ function. The following example illustrates how it works:
320
+
321
+ ```example:single
322
+ >>> #let conf(
323
+ >>> title: none,
324
+ >>> authors: (),
325
+ >>> abstract: [],
326
+ >>> doc,
327
+ >>> ) = {
328
+ >>> set text(font: "Libertinus Serif", 11pt)
329
+ >>> set par(justify: true)
330
+ >>> set page(
331
+ >>> "us-letter",
332
+ >>> margin: auto,
333
+ >>> header: align(
334
+ >>> right + horizon,
335
+ >>> title
336
+ >>> ),
337
+ >>> numbering: "1",
338
+ >>> columns: 2
339
+ >>> )
340
+ >>>
341
+ >>> show heading.where(
342
+ >>> level: 1
343
+ >>> ): it => block(
344
+ >>> align(center,
345
+ >>> text(
346
+ >>> 13pt,
347
+ >>> weight: "regular",
348
+ >>> smallcaps(it.body),
349
+ >>> )
350
+ >>> ),
351
+ >>> )
352
+ >>> show heading.where(
353
+ >>> level: 2
354
+ >>> ): it => box(
355
+ >>> text(
356
+ >>> 11pt,
357
+ >>> weight: "regular",
358
+ >>> style: "italic",
359
+ >>> it.body + [.],
360
+ >>> )
361
+ >>> )
362
+ >>>
363
+ >>> place(top, float: true, scope: "parent", {
364
+ >>> set align(center)
365
+ >>> text(17pt, title)
366
+ >>>
367
+ >>> let count = calc.min(authors.len(), 3)
368
+ >>> grid(
369
+ >>> columns: (1fr,) * count,
370
+ >>> row-gutter: 24pt,
371
+ >>> ..authors.map(author => [
372
+ >>> #author.name \
373
+ >>> #author.affiliation \
374
+ >>> #link("mailto:" + author.email)
375
+ >>> ]),
376
+ >>> )
377
+ >>>
378
+ >>> par(justify: false)[
379
+ >>> *Abstract* \
380
+ >>> #abstract
381
+ >>> ]
382
+ >>> })
383
+ >>>
384
+ >>> set align(left)
385
+ >>> doc
386
+ >>> }
387
+ <<< #import "conf.typ": conf
388
+ #show: conf.with(
389
+ title: [
390
+ Towards Improved Modelling
391
+ ],
392
+ authors: (
393
+ (
394
+ name: "Theresa Tungsten",
395
+ affiliation: "Artos Institute",
396
+ email: "[email protected]",
397
+ ),
398
+ (
399
+ name: "Eugene Deklan",
400
+ affiliation: "Honduras State",
401
+ email: "[email protected]",
402
+ ),
403
+ ),
404
+ abstract: lorem(80),
405
+ )
406
+
407
+ Let's get started writing this
408
+ article by putting insightful
409
+ paragraphs right here!
410
+ >>> #lorem(500)
411
+ ```
412
+
413
+ The [`{import}`]($scripting/#modules) statement makes [functions]($function)
414
+ (and other definitions) from another file available. In this example, it imports
415
+ the `conf` function from the `conf.typ` file. This function formats a document
416
+ as a conference article. We use a show rule to apply it to the document and also
417
+ configure some metadata of the article. After applying the show rule, we can
418
+ start writing our article right away!
419
+
420
+ You can also use templates from Typst Universe (which is Typst's equivalent of
421
+ CTAN) using an import statement like this: `[#import
422
+ "@preview/elsearticle:0.2.1": elsearticle]`. Check the documentation of an
423
+ individual template to learn the name of its template function. Templates and
424
+ packages from Typst Universe are automatically downloaded when you first use
425
+ them.
426
+
427
+ In the web app, you can choose to create a project from a template on Typst
428
+ Universe or even create your own using the template wizard. Locally, you can use
429
+ the `typst init` CLI to create a new project from a template. Check out [the
430
+ list of templates]($universe/search/?kind=templates) published on Typst
431
+ Universe. You can also take a look at the [`awesome-typst`
432
+ repository](https://github.com/qjcg/awesome-typst) to find community templates
433
+ that aren't available through Universe.
434
+
435
+ You can also [create your own, custom templates.]($tutorial/making-a-template)
436
+ They are shorter and more readable than the corresponding LaTeX `.sty` files by
437
+ orders of magnitude, so give it a try!
438
+
439
+ <div class="info-box">
440
+
441
+ Functions are Typst's "commands" and can transform their arguments to an output
442
+ value, including document _content._ Functions are "pure", which means that they
443
+ cannot have any effects beyond creating an output value / output content. This
444
+ is in stark contrast to LaTeX macros that can have arbitrary effects on your
445
+ document.
446
+
447
+ To let a function style your whole document, the show rule processes everything
448
+ that comes after it and calls the function specified after the colon with the
449
+ result as an argument. The `.with` part is a _method_ that takes the `conf`
450
+ function and pre-configures some of its arguments before passing it on to the
451
+ show rule.
452
+ </div>
453
+
454
+ ## How do I load packages? { #packages }
455
+ Typst is "batteries included," so the equivalent of many popular LaTeX packages
456
+ is built right-in. Below, we compiled a table with frequently loaded packages
457
+ and their corresponding Typst functions.
458
+
459
+ | LaTeX Package | Typst Alternative |
460
+ |:--------------------------------|:-------------------------------------------|
461
+ | graphicx, svg | [`image`] function |
462
+ | tabularx | [`table`], [`grid`] functions |
463
+ | fontenc, inputenc, unicode-math | Just start writing! |
464
+ | babel, polyglossia | [`text`]($text.lang) function: `[#set text(lang: "zh")]` |
465
+ | amsmath | [Math mode]($category/math) |
466
+ | amsfonts, amssymb | [`sym`]($category/symbols) module and [syntax]($syntax/#math) |
467
+ | geometry, fancyhdr | [`page`] function |
468
+ | xcolor | [`text`]($text.fill) function: `[#set text(fill: rgb("#0178A4"))]` |
469
+ | hyperref | [`link`] function |
470
+ | bibtex, biblatex, natbib | [`cite`], [`bibliography`] functions |
471
+ | lstlisting, minted | [`raw`] function and syntax |
472
+ | parskip | [`block`]($block.spacing) and [`par`]($par.first-line-indent) functions |
473
+ | csquotes | Set the [`text`]($text.lang) language and type `["]` or `[']` |
474
+ | caption | [`figure`] function |
475
+ | enumitem | [`list`], [`enum`], [`terms`] functions |
476
+
477
+ Although _many_ things are built-in, not everything can be. That's why Typst has
478
+ its own [package ecosystem]($universe) where the community share its creations
479
+ and automations. Let's take, for instance, the _cetz_ package: This package
480
+ allows you to create complex drawings and plots. To use cetz in your document,
481
+ you can just write:
482
+
483
+ ```typ
484
+ #import "@preview/cetz:0.2.1"
485
+ ```
486
+
487
+ (The `@preview` is a _namespace_ that is used while the package manager is still
488
+ in its early and experimental state. It will be replaced in the future.)
489
+
490
+ Aside from the official package hub, you might also want to check out the
491
+ [awesome-typst repository](https://github.com/qjcg/awesome-typst), which
492
+ compiles a curated list of resources created for Typst.
493
+
494
+ If you need to load functions and variables from another file within your
495
+ project, for example to use a template, you can use the same
496
+ [`import`]($scripting/#modules) statement with a file name rather than a
497
+ package specification. To instead include the textual content of another file,
498
+ you can use an [`include`]($scripting/#modules) statement. It will retrieve
499
+ the content of the specified file and put it in your document.
500
+
501
+ ## How do I input maths? { #maths }
502
+ To enter math mode in Typst, just enclose your equation in dollar signs. You can
503
+ enter display mode by adding spaces or newlines between the equation's contents
504
+ and its enclosing dollar signs.
505
+
506
+ ```example
507
+ The sum of the numbers from
508
+ $1$ to $n$ is:
509
+
510
+ $ sum_(k=1)^n k = (n(n+1))/2 $
511
+ ```
512
+
513
+ [Math mode]($category/math) works differently than regular markup or code mode.
514
+ Numbers and single characters are displayed verbatim, while multiple consecutive
515
+ (non-number) characters will be interpreted as Typst variables.
516
+
517
+ Typst pre-defines a lot of useful variables in math mode. All Greek (`alpha`,
518
+ `beta`, ...) and some Hebrew letters (`alef`, `bet`, ...) are available through
519
+ their name. Some symbols are additionally available through shorthands, such as
520
+ `<=`, `>=`, and `->`.
521
+
522
+ Refer to the [symbol pages]($reference/symbols) for a full list of the symbols.
523
+ If a symbol is missing, you can also access it through a
524
+ [Unicode escape sequence]($syntax/#escapes).
525
+
526
+ Alternate and related forms of symbols can often be selected by
527
+ [appending a modifier]($symbol) after a period. For example,
528
+ `arrow.l.squiggly` inserts a squiggly left-pointing arrow. If you want to insert
529
+ multiletter text in your expression instead, enclose it in double quotes:
530
+
531
+ ```example
532
+ $ delta "if" x <= 5 $
533
+ ```
534
+
535
+ In Typst, delimiters will scale automatically for their expressions, just as if
536
+ `\left` and `\right` commands were implicitly inserted in LaTeX. You can
537
+ customize delimiter behaviour using the [`lr` function]($math.lr). To
538
+ prevent a pair of delimiters from scaling, you can escape them with backslashes.
539
+
540
+ Typst will automatically set terms around a slash `/` as a fraction while
541
+ honoring operator precedence. All round parentheses not made redundant by the
542
+ fraction will appear in the output.
543
+
544
+ ```example
545
+ $ f(x) = (x + 1) / x $
546
+ ```
547
+
548
+ [Sub- and superscripts]($math.attach) work similarly in Typst and LaTeX.
549
+ `{$x^2$}` will produce a superscript, `{$x_2$}` yields a subscript. If you want
550
+ to include more than one value in a sub- or superscript, enclose their contents
551
+ in parentheses: `{$x_(a -> epsilon)$}`.
552
+
553
+ Since variables in math mode do not need to be prepended with a `#` or a `/`,
554
+ you can also call functions without these special characters:
555
+
556
+ ```example
557
+ $ f(x, y) := cases(
558
+ 1 "if" (x dot y)/2 <= 0,
559
+ 2 "if" x "is even",
560
+ 3 "if" x in NN,
561
+ 4 "else",
562
+ ) $
563
+ ```
564
+
565
+ The above example uses the [`cases` function]($math.cases) to describe f. Within
566
+ the cases function, arguments are delimited using commas and the arguments are
567
+ also interpreted as math. If you need to interpret arguments as Typst
568
+ values instead, prefix them with a `#`:
569
+
570
+ ```example
571
+ $ (a + b)^2
572
+ = a^2
573
+ + text(fill: #maroon, 2 a b)
574
+ + b^2 $
575
+ ```
576
+
577
+ You can use all Typst functions within math mode and insert any content. If you
578
+ want them to work normally, with code mode in the argument list, you can prefix
579
+ their call with a `#`. Nobody can stop you from using rectangles or emoji as
580
+ your variables anymore:
581
+
582
+ ```example
583
+ $ sum^10_(🥸=1)
584
+ #rect(width: 4mm, height: 2mm)/🥸
585
+ = 🧠 maltese $
586
+ ```
587
+
588
+ If you'd like to enter your mathematical symbols directly as Unicode, that is
589
+ possible, too!
590
+
591
+ Math calls can have two-dimensional argument lists using `;` as a delimiter. The
592
+ most common use for this is the [`mat` function]($math.mat) that creates
593
+ matrices:
594
+
595
+ ```example
596
+ $ mat(
597
+ 1, 2, ..., 10;
598
+ 2, 2, ..., 10;
599
+ dots.v, dots.v, dots.down, dots.v;
600
+ 10, 10, ..., 10;
601
+ ) $
602
+ ```
603
+
604
+ ## How do I get the "LaTeX look?" { #latex-look }
605
+ Papers set in LaTeX have an unmistakeable look. This is mostly due to their
606
+ font, Computer Modern, justification, narrow line spacing, and wide margins.
607
+
608
+ The example below
609
+ - sets wide [margins]($page.margin)
610
+ - enables [justification]($par.justify), [tighter lines]($par.leading) and
611
+ [first-line-indent]($par.first-line-indent)
612
+ - [sets the font]($text.font) to "New Computer Modern", an OpenType derivative of
613
+ Computer Modern for both text and [code blocks]($raw)
614
+ - disables paragraph [spacing]($block.spacing)
615
+ - increases [spacing]($block.spacing) around [headings]($heading)
616
+
617
+ ```typ
618
+ #set page(margin: 1.75in)
619
+ #set par(leading: 0.55em, spacing: 0.55em, first-line-indent: 1.8em, justify: true)
620
+ #set text(font: "New Computer Modern")
621
+ #show raw: set text(font: "New Computer Modern Mono")
622
+ #show heading: set block(above: 1.4em, below: 1em)
623
+ ```
624
+
625
+ This should be a good starting point! If you want to go further, why not create
626
+ a reusable template?
627
+
628
+ ## Bibliographies
629
+ Typst includes a fully-featured bibliography system that is compatible with
630
+ BibTeX files. You can continue to use your `.bib` literature libraries by
631
+ loading them with the [`bibliography`] function. Another possibility is to use
632
+ [Typst's YAML-based native format](https://github.com/typst/hayagriva/blob/main/docs/file-format.md).
633
+
634
+ Typst uses the Citation Style Language to define and process citation and
635
+ bibliography styles. You can compare CSL files to BibLaTeX's `.bbx` files.
636
+ The compiler already includes [over 80 citation styles]($bibliography.style),
637
+ but you can use any CSL-compliant style from the
638
+ [CSL repository](https://github.com/citation-style-language/styles) or write
639
+ your own.
640
+
641
+ You can cite an entry in your bibliography or reference a label in your document
642
+ with the same syntax: `[@key]` (this would reference an entry called `key`).
643
+ Alternatively, you can use the [`cite`] function.
644
+
645
+ Alternative forms for your citation, such as year only and citations for natural
646
+ use in prose (cf. `\citet` and `\textcite`) are available with
647
+ [`[#cite(<key>, form: "prose")]`]($cite.form).
648
+
649
+ You can find more information on the documentation page of the [`bibliography`]
650
+ function.
651
+
652
+ ## What limitations does Typst currently have compared to LaTeX? { #limitations }
653
+ Although Typst can be a LaTeX replacement for many today, there are still
654
+ features that Typst does not (yet) support. Here is a list of them which, where
655
+ applicable, contains possible workarounds.
656
+
657
+ - **Well-established plotting ecosystem.** LaTeX users often create elaborate
658
+ charts along with their documents in PGF/TikZ. The Typst ecosystem does not
659
+ yet offer the same breadth of available options, but the ecosystem around the
660
+ [`cetz` package](https://typst.app/universe/package/cetz) is catching up
661
+ quickly.
662
+
663
+ - **Change page margins without a pagebreak.** In LaTeX, margins can always be
664
+ adjusted, even without a pagebreak. To change margins in Typst, you use the
665
+ [`page` function]($page) which will force a page break. If you just want a few
666
+ paragraphs to stretch into the margins, then reverting to the old margins, you
667
+ can use the [`pad` function]($pad) with negative padding.
668
+
669
+ - **Include PDFs as images.** In LaTeX, it has become customary to insert vector
670
+ graphics as PDF or EPS files. Typst supports neither format as an image
671
+ format, but you can easily convert both into SVG files with [online
672
+ tools](https://cloudconvert.com/pdf-to-svg) or
673
+ [Inkscape](https://inkscape.org/). The web app will automatically convert PDF
674
+ files to SVG files upon uploading them. You can also use the
675
+ community-provided [`muchpdf` package](https://typst.app/universe/package/muchpdf)
676
+ to embed PDFs. It internally converts PDFs to SVGs on-the-fly.
sources/docs/guides/page-setup.md ADDED
@@ -0,0 +1,487 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ description: |
3
+ An in-depth guide to setting page dimensions, margins, and page numbers in
4
+ Typst. Learn how to create appealing and clear layouts and get there quickly.
5
+ ---
6
+
7
+ # Page setup guide
8
+ Your page setup is a big part of the first impression your document gives. Line
9
+ lengths, margins, and columns influence
10
+ [appearance](https://practicaltypography.com/page-margins.html) and
11
+ [legibility](https://designregression.com/article/line-length-revisited-following-the-research)
12
+ while the right headers and footers will help your reader easily navigate your
13
+ document. This guide will help you to customize pages, margins, headers,
14
+ footers, and page numbers so that they are the right fit for your content and
15
+ you can get started with writing.
16
+
17
+ In Typst, each page has a width, a height, and margins on all four sides. The
18
+ top and bottom margins may contain a header and footer. The set rule of the
19
+ [`{page}`]($page) element is where you control all of the page setup. If you
20
+ make changes with this set rule, Typst will ensure that there is a new and
21
+ conforming empty page afterward, so it may insert a page break. Therefore, it is
22
+ best to specify your [`{page}`]($page) set rule at the start of your document or
23
+ in your template.
24
+
25
+ ```example
26
+ #set rect(
27
+ width: 100%,
28
+ height: 100%,
29
+ inset: 4pt,
30
+ )
31
+ >>> #set text(6pt)
32
+ >>> #set page(margin: auto)
33
+
34
+ #set page(
35
+ paper: "iso-b7",
36
+ header: rect(fill: aqua)[Header],
37
+ footer: rect(fill: aqua)[Footer],
38
+ number-align: center,
39
+ )
40
+
41
+ #rect(fill: aqua.lighten(40%))
42
+ ```
43
+
44
+ This example visualizes the dimensions for page content, headers, and footers.
45
+ The page content is the page size (ISO B7) minus each side's default margin. In
46
+ the top and the bottom margin, there are stroked rectangles visualizing the
47
+ header and footer. They do not touch the main content, instead, they are offset
48
+ by 30% of the respective margin. You can control this offset by specifying the
49
+ [`header-ascent`]($page.header-ascent) and
50
+ [`footer-descent`]($page.footer-descent) arguments.
51
+
52
+ Below, the guide will go more into detail on how to accomplish common page setup
53
+ requirements with examples.
54
+
55
+ ## Customize page size and margins { #customize-margins }
56
+ Typst's default page size is A4 paper. Depending on your region and your use
57
+ case, you will want to change this. You can do this by using the
58
+ [`{page}`]($page) set rule and passing it a string argument to use a common page
59
+ size. Options include the complete ISO 216 series (e.g. `"a4"` and `"iso-c2"`),
60
+ customary US formats like `"us-legal"` or `"us-letter"`, and more. Check out the
61
+ reference for the [page's paper argument]($page.paper) to learn about all
62
+ available options.
63
+
64
+ ```example
65
+ >>> #set page(margin: auto)
66
+ #set page("us-letter")
67
+
68
+ This page likes freedom.
69
+ ```
70
+
71
+ If you need to customize your page size to some dimensions, you can specify the
72
+ named arguments [`width`]($page.width) and [`height`]($page.height) instead.
73
+
74
+ ```example
75
+ >>> #set page(margin: auto)
76
+ #set page(width: 12cm, height: 12cm)
77
+
78
+ This page is a square.
79
+ ```
80
+
81
+ ### Change the page's margins { #change-margins }
82
+ Margins are a vital ingredient for good typography:
83
+ [Typographers consider lines that fit between 45 and 75 characters best length
84
+ for legibility](http://webtypography.net/2.1.2) and your margins and
85
+ [columns](#columns) help define line widths. By default, Typst will create
86
+ margins proportional to the page size of your document. To set custom margins,
87
+ you will use the [`margin`]($page.margin) argument in the [`{page}`]($page) set
88
+ rule.
89
+
90
+ The `margin` argument will accept a length if you want to set all margins to the
91
+ same width. However, you often want to set different margins on each side. To do
92
+ this, you can pass a dictionary:
93
+
94
+ ```example
95
+ #set page(margin: (
96
+ top: 3cm,
97
+ bottom: 2cm,
98
+ x: 1.5cm,
99
+ ))
100
+
101
+ #lorem(100)
102
+ ```
103
+
104
+ The page margin dictionary can have keys for each side (`top`, `bottom`, `left`,
105
+ `right`), but you can also control left and right together by setting the `x`
106
+ key of the margin dictionary, like in the example. Likewise, the top and bottom
107
+ margins can be adjusted together by setting the `y` key.
108
+
109
+ If you do not specify margins for all sides in the margin dictionary, the old
110
+ margins will remain in effect for the unset sides. To prevent this and set all
111
+ remaining margins to a common size, you can use the `rest` key. For example,
112
+ `[#set page(margin: (left: 1.5in, rest: 1in))]` will set the left margin to 1.5
113
+ inches and the remaining margins to one inch.
114
+
115
+ ### Different margins on alternating pages { #alternating-margins }
116
+ Sometimes, you'll need to alternate horizontal margins for even and odd pages,
117
+ for example, to have more room towards the spine of a book than on the outsides
118
+ of its pages. Typst keeps track of whether a page is to the left or right of the
119
+ binding. You can use this information and set the `inside` or `outside` keys of
120
+ the margin dictionary. The `inside` margin points towards the spine, and the
121
+ `outside` margin points towards the edge of the bound book.
122
+
123
+ ```typ
124
+ #set page(margin: (inside: 2.5cm, outside: 2cm, y: 1.75cm))
125
+ ```
126
+
127
+ Typst will assume that documents written in Left-to-Right scripts are bound on
128
+ the left while books written in Right-to-Left scripts are bound on the right.
129
+ However, you will need to change this in some cases: If your first page is
130
+ output by a different app, the binding is reversed from Typst's perspective.
131
+ Also, some books, like English-language Mangas are customarily bound on the
132
+ right, despite English using Left-to-Right script. To change the binding side
133
+ and explicitly set where the `inside` and `outside` are, set the
134
+ [`binding`]($page.binding) argument in the [`{page}`]($page) set rule.
135
+
136
+ ```typ
137
+ // Produce a book bound on the right,
138
+ // even though it is set in Spanish.
139
+ #set text(lang: "es")
140
+ #set page(binding: right)
141
+ ```
142
+
143
+ If `binding` is `left`, `inside` margins will be on the left on odd pages, and
144
+ vice versa.
145
+
146
+ ## Add headers and footers { #headers-and-footers }
147
+ Headers and footers are inserted in the top and bottom margins of every page.
148
+ You can add custom headers and footers or just insert a page number.
149
+
150
+ In case you need more than just a page number, the best way to insert a header
151
+ and a footer are the [`header`]($page.header) and [`footer`]($page.footer)
152
+ arguments of the [`{page}`]($page) set rule. You can pass any content as their
153
+ values:
154
+
155
+ ```example
156
+ >>> #set page("a5", margin: (x: 2.5cm, y: 3cm))
157
+ #set page(header: [
158
+ _Lisa Strassner's Thesis_
159
+ #h(1fr)
160
+ National Academy of Sciences
161
+ ])
162
+
163
+ #lorem(150)
164
+ ```
165
+
166
+ Headers are bottom-aligned by default so that they do not collide with the top
167
+ edge of the page. You can change this by wrapping your header in the
168
+ [`{align}`]($align) function.
169
+
170
+ ### Different header and footer on specific pages { #specific-pages }
171
+ You'll need different headers and footers on some pages. For example, you may
172
+ not want a header and footer on the title page. The example below shows how to
173
+ conditionally remove the header on the first page:
174
+
175
+ ```typ
176
+ >>> #set page("a5", margin: (x: 2.5cm, y: 3cm))
177
+ #set page(header: context {
178
+ if counter(page).get().first() > 1 [
179
+ _Lisa Strassner's Thesis_
180
+ #h(1fr)
181
+ National Academy of Sciences
182
+ ]
183
+ })
184
+
185
+ #lorem(150)
186
+ ```
187
+
188
+ This example may look intimidating, but let's break it down: By using the
189
+ `{context}` keyword, we are telling Typst that the header depends on where we
190
+ are in the document. We then ask Typst if the page [counter] is larger than one
191
+ at our (context-dependent) current position. The page counter starts at one, so
192
+ we are skipping the header on a single page. Counters may have multiple levels.
193
+ This feature is used for items like headings, but the page counter will always
194
+ have a single level, so we can just look at the first one.
195
+
196
+ You can, of course, add an `else` to this example to add a different header to
197
+ the first page instead.
198
+
199
+ ### Adapt headers and footers on pages with specific elements { #specific-elements }
200
+ The technique described in the previous section can be adapted to perform more
201
+ advanced tasks using Typst's labels. For example, pages with big tables could
202
+ omit their headers to help keep clutter down. We will mark our tables with a
203
+ `<big-table>` [label] and use the [query system]($query) to find out if such a
204
+ label exists on the current page:
205
+
206
+ ```typ
207
+ >>> #set page("a5", margin: (x: 2.5cm, y: 3cm))
208
+ #set page(header: context {
209
+ let page-counter =
210
+ let matches = query(<big-table>)
211
+ let current = counter(page).get()
212
+ let has-table = matches.any(m =>
213
+ counter(page).at(m.location()) == current
214
+ )
215
+
216
+ if not has-table [
217
+ _Lisa Strassner's Thesis_
218
+ #h(1fr)
219
+ National Academy of Sciences
220
+ ]
221
+ }))
222
+
223
+ #lorem(100)
224
+ #pagebreak()
225
+
226
+ #table(
227
+ columns: 2 * (1fr,),
228
+ [A], [B],
229
+ [C], [D],
230
+ ) <big-table>
231
+ ```
232
+
233
+ Here, we query for all instances of the `<big-table>` label. We then check that
234
+ none of the tables are on the page at our current position. If so, we print the
235
+ header. This example also uses variables to be more concise. Just as above, you
236
+ could add an `else` to add another header instead of deleting it.
237
+
238
+ ## Add and customize page numbers { #page-numbers }
239
+ Page numbers help readers keep track of and reference your document more easily.
240
+ The simplest way to insert page numbers is the [`numbering`]($page.numbering)
241
+ argument of the [`{page}`]($page) set rule. You can pass a
242
+ [_numbering pattern_]($numbering.numbering) string that shows how you want your
243
+ pages to be numbered.
244
+
245
+ ```example
246
+ >>> #set page("iso-b6", margin: 1.75cm)
247
+ #set page(numbering: "1")
248
+
249
+ This is a numbered page.
250
+ ```
251
+
252
+ Above, you can check out the simplest conceivable example. It adds a single
253
+ Arabic page number at the center of the footer. You can specify other characters
254
+ than `"1"` to get other numerals. For example, `"i"` will yield lowercase Roman
255
+ numerals. Any character that is not interpreted as a number will be output
256
+ as-is. For example, put dashes around your page number by typing this:
257
+
258
+ ```example
259
+ >>> #set page("iso-b6", margin: 1.75cm)
260
+ #set page(numbering: "— 1 —")
261
+
262
+ This is a — numbered — page.
263
+ ```
264
+
265
+ You can add the total number of pages by entering a second number character in
266
+ the string.
267
+
268
+ ```example
269
+ >>> #set page("iso-b6", margin: 1.75cm)
270
+ #set page(numbering: "1 of 1")
271
+
272
+ This is one of many numbered pages.
273
+ ```
274
+
275
+ Go to the [`{numbering}` function reference]($numbering.numbering) to learn more
276
+ about the arguments you can pass here.
277
+
278
+ In case you need to right- or left-align the page number, use the
279
+ [`number-align`]($page.number-align) argument of the [`{page}`]($page) set rule.
280
+ Alternating alignment between even and odd pages is not currently supported
281
+ using this property. To do this, you'll need to specify a custom footer with
282
+ your footnote and query the page counter as described in the section on
283
+ conditionally omitting headers and footers.
284
+
285
+ ### Custom footer with page numbers
286
+ Sometimes, you need to add other content than a page number to your footer.
287
+ However, once a footer is specified, the [`numbering`]($page.numbering) argument
288
+ of the [`{page}`]($page) set rule is ignored. This section shows you how to add
289
+ a custom footer with page numbers and more.
290
+
291
+ ```example
292
+ >>> #set page("iso-b6", margin: 1.75cm)
293
+ #set page(footer: context [
294
+ *American Society of Proceedings*
295
+ #h(1fr)
296
+ #counter(page).display(
297
+ "1/1",
298
+ both: true,
299
+ )
300
+ ])
301
+
302
+ This page has a custom footer.
303
+ ```
304
+
305
+ First, we add some strongly emphasized text on the left and add free space to
306
+ fill the line. Then, we call `counter(page)` to retrieve the page counter and
307
+ use its `display` function to show its current value. We also set `both` to
308
+ `{true}` so that our numbering pattern applies to the current _and_ final page
309
+ number.
310
+
311
+ We can also get more creative with the page number. For example, let's insert a
312
+ circle for each page.
313
+
314
+ ```example
315
+ >>> #set page("iso-b6", margin: 1.75cm)
316
+ #set page(footer: context [
317
+ *Fun Typography Club*
318
+ #h(1fr)
319
+ #let (num,) = counter(page).get()
320
+ #let circles = num * (
321
+ box(circle(
322
+ radius: 2pt,
323
+ fill: navy,
324
+ )),
325
+ )
326
+ #box(
327
+ inset: (bottom: 1pt),
328
+ circles.join(h(1pt))
329
+ )
330
+ ])
331
+
332
+ This page has a custom footer.
333
+ ```
334
+
335
+ In this example, we use the number of pages to create an array of
336
+ [circles]($circle). The circles are wrapped in a [box] so they can all appear on
337
+ the same line because they are blocks and would otherwise create paragraph
338
+ breaks. The length of this [array] depends on the current page number.
339
+
340
+ We then insert the circles at the right side of the footer, with 1pt of space
341
+ between them. The join method of an array will attempt to
342
+ [_join_]($scripting/#blocks) the different values of an array into a single
343
+ value, interspersed with its argument. In our case, we get a single content
344
+ value with circles and spaces between them that we can use with the align
345
+ function. Finally, we use another box to ensure that the text and the circles
346
+ can share a line and use the [`inset` argument]($box.inset) to raise the circles
347
+ a bit so they line up nicely with the text.
348
+
349
+ ### Reset the page number and skip pages { #skip-pages }
350
+ Do you, at some point in your document, need to reset the page number? Maybe you
351
+ want to start with the first page only after the title page. Or maybe you need
352
+ to skip a few page numbers because you will insert pages into the final printed
353
+ product.
354
+
355
+ The right way to modify the page number is to manipulate the page [counter]. The
356
+ simplest manipulation is to set the counter back to 1.
357
+
358
+ ```typ
359
+ #counter(page).update(1)
360
+ ```
361
+
362
+ This line will reset the page counter back to one. It should be placed at the
363
+ start of a page because it will otherwise create a page break. You can also
364
+ update the counter given its previous value by passing a function:
365
+
366
+ ```typ
367
+ #counter(page).update(n => n + 5)
368
+ ```
369
+
370
+ In this example, we skip five pages. `n` is the current value of the page
371
+ counter and `n + 5` is the return value of our function.
372
+
373
+ In case you need to retrieve the actual page number instead of the value of the
374
+ page counter, you can use the [`page`]($location.page) method on the return
375
+ value of the [`here`] function:
376
+
377
+ ```example
378
+ #counter(page).update(n => n + 5)
379
+
380
+ // This returns one even though the
381
+ // page counter was incremented by 5.
382
+ #context here().page()
383
+ ```
384
+
385
+ You can also obtain the page numbering pattern from the location returned by
386
+ `here` with the [`page-numbering`]($location.page-numbering) method.
387
+
388
+ ## Add columns { #columns }
389
+ Add columns to your document to fit more on a page while maintaining legible
390
+ line lengths. Columns are vertical blocks of text which are separated by some
391
+ whitespace. This space is called the gutter.
392
+
393
+ To lay out your content in columns, just specify the desired number of columns
394
+ in a [`{page}`]($page.columns) set rule. To adjust the amount of space between
395
+ the columns, add a set rule on the [`columns` function]($columns), specifying
396
+ the `gutter` parameter.
397
+
398
+ ```example
399
+ >>> #set page(height: 120pt)
400
+ #set page(columns: 2)
401
+ #set columns(gutter: 12pt)
402
+
403
+ #lorem(30)
404
+ ```
405
+
406
+ Very commonly, scientific papers have a single-column title and abstract, while
407
+ the main body is set in two-columns. To achieve this effect, Typst's [`place`
408
+ function]($place) can temporarily escape the two-column layout by specifying
409
+ `{float: true}` and `{scope: "parent"}`:
410
+
411
+ ```example:single
412
+ >>> #set page(height: 180pt)
413
+ #set page(columns: 2)
414
+ #set par(justify: true)
415
+
416
+ #place(
417
+ top + center,
418
+ float: true,
419
+ scope: "parent",
420
+ text(1.4em, weight: "bold")[
421
+ Impacts of Odobenidae
422
+ ],
423
+ )
424
+
425
+ == About seals in the wild
426
+ #lorem(80)
427
+ ```
428
+
429
+ _Floating placement_ refers to elements being pushed to the top or bottom of the
430
+ column or page, with the remaining content flowing in between. It is also
431
+ frequently used for [figures]($figure.placement).
432
+
433
+ ### Use columns anywhere in your document { #columns-anywhere }
434
+ To create columns within a nested layout, e.g. within a rectangle, you can use
435
+ the [`columns` function]($columns) directly. However, it really should only be
436
+ used within nested layouts. At the page-level, the page set rule is preferable
437
+ because it has better interactions with things like page-level floats,
438
+ footnotes, and line numbers.
439
+
440
+ ```example
441
+ #rect(
442
+ width: 6cm,
443
+ height: 3.5cm,
444
+ columns(2, gutter: 12pt)[
445
+ In the dimly lit gas station,
446
+ a solitary taxi stood silently,
447
+ its yellow paint fading with
448
+ time. Its windows were dark,
449
+ its engine idle, and its tires
450
+ rested on the cold concrete.
451
+ ]
452
+ )
453
+ ```
454
+
455
+ ### Balanced columns
456
+ If the columns on the last page of a document differ greatly in length, they may
457
+ create a lopsided and unappealing layout. That's why typographers will often
458
+ equalize the length of columns on the last page. This effect is called balancing
459
+ columns. Typst cannot yet balance columns automatically. However, you can
460
+ balance columns manually by placing [`[#colbreak()]`]($colbreak) at an
461
+ appropriate spot in your markup, creating the desired column break manually.
462
+
463
+
464
+ ## One-off modifications
465
+ You do not need to override your page settings if you need to insert a single
466
+ page with a different setup. For example, you may want to insert a page that's
467
+ flipped to landscape to insert a big table or change the margin and columns for
468
+ your title page. In this case, you can call [`{page}`]($page) as a function with
469
+ your content as an argument and the overrides as the other arguments. This will
470
+ insert enough new pages with your overridden settings to place your content on
471
+ them. Typst will revert to the page settings from the set rule after the call.
472
+
473
+ ```example
474
+ >>> #set page("a6")
475
+ #page(flipped: true)[
476
+ = Multiplication table
477
+
478
+ #table(
479
+ columns: 5 * (1fr,),
480
+ ..for x in range(1, 10) {
481
+ for y in range(1, 6) {
482
+ (str(x*y),)
483
+ }
484
+ }
485
+ )
486
+ ]
487
+ ```
sources/docs/guides/tables.md ADDED
@@ -0,0 +1,1343 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ description: |
3
+ Not sure how to change table strokes? Need to rotate a table? This guide
4
+ explains all you need to know about tables in Typst.
5
+ ---
6
+
7
+ # Table guide
8
+ Tables are a great way to present data to your readers in an easily readable,
9
+ compact, and organized manner. They are not only used for numerical values, but
10
+ also survey responses, task planning, schedules, and more. Because of this wide
11
+ set of possible applications, there is no single best way to lay out a table.
12
+ Instead, think about the data you want to highlight, your document's overarching
13
+ design, and ultimately how your table can best serve your readers.
14
+
15
+ Typst can help you with your tables by automating styling, importing data from
16
+ other applications, and more! This guide takes you through a few of the most
17
+ common questions you may have when adding a table to your document with Typst.
18
+ Feel free to skip to the section most relevant to you – we designed this guide
19
+ to be read out of order.
20
+
21
+ If you want to look up a detail of how tables work, you should also [check out
22
+ their reference page]($table). And if you are looking for a table of contents
23
+ rather than a normal table, the reference page of the [`outline`
24
+ function]($outline) is the right place to learn more.
25
+
26
+ ## How to create a basic table? { #basic-tables }
27
+ In order to create a table in Typst, use the [`table` function]($table). For a
28
+ basic table, you need to tell the table function two things:
29
+
30
+ - The number of columns
31
+ - The content for each of the table cells
32
+
33
+ So, let's say you want to create a table with two columns describing the
34
+ ingredients for a cookie recipe:
35
+
36
+ ```example
37
+ #table(
38
+ columns: 2,
39
+ [*Amount*], [*Ingredient*],
40
+ [360g], [Baking flour],
41
+ [250g], [Butter (room temp.)],
42
+ [150g], [Brown sugar],
43
+ [100g], [Cane sugar],
44
+ [100g], [70% cocoa chocolate],
45
+ [100g], [35-40% cocoa chocolate],
46
+ [2], [Eggs],
47
+ [Pinch], [Salt],
48
+ [Drizzle], [Vanilla extract],
49
+ )
50
+ ```
51
+
52
+ This example shows how to call, configure, and populate a table. Both the column
53
+ count and cell contents are passed to the table as arguments. The [argument
54
+ list]($function) is surrounded by round parentheses. In it, we first pass the
55
+ column count as a named argument. Then, we pass multiple [content
56
+ blocks]($content) as positional arguments. Each content block contains the
57
+ contents for a single cell.
58
+
59
+ To make the example more legible, we have placed two content block arguments on
60
+ each line, mimicking how they would appear in the table. You could also write
61
+ each cell on its own line. Typst does not care on which line you place the
62
+ arguments. Instead, Typst will place the content cells from left to right (or
63
+ right to left, if that is the writing direction of your language) and then from
64
+ top to bottom. It will automatically add enough rows to your table so that it
65
+ fits all of your content.
66
+
67
+ It is best to wrap the header row of your table in the [`table.header`
68
+ function]($table.header). This clarifies your intent and will also allow future
69
+ versions of Typst to make the output more accessible to users with a screen
70
+ reader:
71
+
72
+ ```example
73
+ #table(
74
+ columns: 2,
75
+ table.header[*Amount*][*Ingredient*],
76
+ [360g], [Baking flour],
77
+ <<< // ... the remaining cells
78
+ >>> [250g], [Butter (room temp.)],
79
+ >>> [150g], [Brown sugar],
80
+ >>> [100g], [Cane sugar],
81
+ >>> [100g], [70% cocoa chocolate],
82
+ >>> [100g], [35-40% cocoa chocolate],
83
+ >>> [2], [Eggs],
84
+ >>> [Pinch], [Salt],
85
+ >>> [Drizzle], [Vanilla extract],
86
+ )
87
+ ```
88
+
89
+ You could also write a show rule that automatically [strongly
90
+ emphasizes]($strong) the contents of the first cells for all tables. This
91
+ quickly becomes useful if your document contains multiple tables!
92
+
93
+ ```example
94
+ #show table.cell.where(y: 0): strong
95
+
96
+ #table(
97
+ columns: 2,
98
+ table.header[Amount][Ingredient],
99
+ [360g], [Baking flour],
100
+ <<< // ... the remaining cells
101
+ >>> [250g], [Butter (room temp.)],
102
+ >>> [150g], [Brown sugar],
103
+ >>> [100g], [Cane sugar],
104
+ >>> [100g], [70% cocoa chocolate],
105
+ >>> [100g], [35-40% cocoa chocolate],
106
+ >>> [2], [Eggs],
107
+ >>> [Pinch], [Salt],
108
+ >>> [Drizzle], [Vanilla extract],
109
+ )
110
+ ```
111
+
112
+ We are using a show rule with a selector for cell coordinates here instead of
113
+ applying our styles directly to `table.header`. This is due to a current
114
+ limitation of Typst that will be fixed in a future release.
115
+
116
+ Congratulations, you have created your first table! Now you can proceed to
117
+ [change column sizes](#column-sizes), [adjust the strokes](#strokes), [add
118
+ striped rows](#fills), and more!
119
+
120
+ ## How to change the column sizes? { #column-sizes }
121
+ If you create a table and specify the number of columns, Typst will make each
122
+ column large enough to fit its largest cell. Often, you want something
123
+ different, for example, to make a table span the whole width of the page. You
124
+ can provide a list, specifying how wide you want each column to be, through the
125
+ `columns` argument. There are a few different ways to specify column widths:
126
+
127
+ - First, there is `{auto}`. This is the default behavior and tells Typst to grow
128
+ the column to fit its contents. If there is not enough space, Typst will try
129
+ its best to distribute the space among the `{auto}`-sized columns.
130
+ - [Lengths]($length) like `{6cm}`, `{0.7in}`, or `{120pt}`. As usual, you can
131
+ also use the font-dependent `em` unit. This is a multiple of your current font
132
+ size. It's useful if you want to size your table so that it always fits
133
+ about the same amount of text, independent of font size.
134
+ - A [ratio in percent]($ratio) such as `{40%}`. This will make the column take
135
+ up 40% of the total horizontal space available to the table, so either the
136
+ inner width of the page or the table's container. You can also mix ratios and
137
+ lengths into [relative lengths]($relative). Be mindful that even if you
138
+ specify a list of column widths that sum up to 100%, your table could still
139
+ become larger than its container. This is because there can be
140
+ [gutter]($table.gutter) between columns that is not included in the column
141
+ widths. If you want to make a table fill the page, the next option is often
142
+ very useful.
143
+ - A [fractional part of the free space]($fraction) using the `fr` unit, such as
144
+ `1fr`. This unit allows you to distribute the available space to columns. It
145
+ works as follows: First, Typst sums up the lengths of all columns that do not
146
+ use `fr`s. Then, it determines how much horizontal space is left. This
147
+ horizontal space then gets distributed to all columns denominated in `fr`s.
148
+ During this process, a `2fr` column will become twice as wide as a `1fr`
149
+ column. This is where the name comes from: The width of the column is its
150
+ fraction of the total fractionally sized columns.
151
+
152
+ Let's put this to use with a table that contains the dates, numbers, and
153
+ descriptions of some routine checks. The first two columns are `auto`-sized and
154
+ the last column is `1fr` wide as to fill the whole page.
155
+
156
+ ```example
157
+ #table(
158
+ columns: (auto, auto, 1fr),
159
+ table.header[Date][°No][Description],
160
+ [24/01/03], [813], [Filtered participant pool],
161
+ [24/01/03], [477], [Transitioned to sec. regimen],
162
+ [24/01/11], [051], [Cycled treatment substrate],
163
+ )
164
+ ```
165
+
166
+ Here, we have passed our list of column lengths as an [array], enclosed in round
167
+ parentheses, with its elements separated by commas. The first two columns are
168
+ automatically sized, so that they take on the size of their content and the
169
+ third column is sized as `{1fr}` so that it fills up the remainder of the space
170
+ on the page. If you wanted to instead change the second column to be a bit more
171
+ spacious, you could replace its entry in the `columns` array with a value like
172
+ `{6em}`.
173
+
174
+ ## How to caption and reference my table? { #captions-and-references }
175
+ A table is just as valuable as the information your readers draw from it. You
176
+ can enhance the effectiveness of both your prose and your table by making a
177
+ clear connection between the two with a cross-reference. Typst can help you with
178
+ automatic [references]($ref) and the [`figure` function]($figure).
179
+
180
+ Just like with images, wrapping a table in the `figure` function allows you to
181
+ add a caption and a label, so you can reference the figure elsewhere. Wrapping
182
+ your table in a figure also lets you use the figure's `placement` parameter to
183
+ float it to the top or bottom of a page.
184
+
185
+ Let's take a look at a captioned table and how to reference it in prose:
186
+
187
+ ```example
188
+ >>> #set page(width: 14cm)
189
+ #show table.cell.where(y: 0): set text(weight: "bold")
190
+
191
+ #figure(
192
+ table(
193
+ columns: 4,
194
+ stroke: none,
195
+
196
+ table.header[Test Item][Specification][Test Result][Compliance],
197
+ [Voltage], [220V ± 5%], [218V], [Pass],
198
+ [Current], [5A ± 0.5A], [4.2A], [Fail],
199
+ ),
200
+ caption: [Probe results for design A],
201
+ ) <probe-a>
202
+
203
+ The results from @probe-a show that the design is not yet optimal.
204
+ We will show how its performance can be improved in this section.
205
+ ```
206
+
207
+ The example shows how to wrap a table in a figure, set a caption and a label,
208
+ and how to reference that label. We start by using the `figure` function. It
209
+ expects the contents of the figure as a positional argument. We just put the
210
+ table function call in its argument list, omitting the `#` character because it
211
+ is only needed when calling a function in markup mode. We also add the caption
212
+ as a named argument (above or below) the table.
213
+
214
+ After the figure call, we put a label in angle brackets (`[<probe-a>]`). This
215
+ tells Typst to remember this element and make it referenceable under this name
216
+ throughout your document. We can then reference it in prose by using the at sign
217
+ and the label name `[@probe-a]`. Typst will print a nicely formatted reference
218
+ and automatically update the label if the table's number changes.
219
+
220
+ ## How to get a striped table? { #fills }
221
+ Many tables use striped rows or columns instead of strokes to differentiate
222
+ between rows and columns. This effect is often called _zebra stripes._ Tables
223
+ with zebra stripes are popular in Business and commercial Data Analytics
224
+ applications, while academic applications tend to use strokes instead.
225
+
226
+ To add zebra stripes to a table, we use the `table` function's `fill` argument.
227
+ It can take three kinds of arguments:
228
+
229
+ - A single color (this can also be a gradient or a tiling) to fill all cells
230
+ with. Because we want some cells to have another color, this is not useful if
231
+ we want to build zebra tables.
232
+ - An array with colors which Typst cycles through for each column. We can use an
233
+ array with two elements to get striped columns.
234
+ - A function that takes the horizontal coordinate `x` and the vertical
235
+ coordinate `y` of a cell and returns its fill. We can use this to create
236
+ horizontal stripes or [checkerboard patterns]($grid.cell).
237
+
238
+ Let's start with an example of a horizontally striped table:
239
+
240
+ ```example
241
+ >>> #set page(width: 16cm)
242
+ #set text(font: "IBM Plex Sans")
243
+
244
+ // Medium bold table header.
245
+ #show table.cell.where(y: 0): set text(weight: "medium")
246
+
247
+ // Bold titles.
248
+ #show table.cell.where(x: 1): set text(weight: "bold")
249
+
250
+ // See the strokes section for details on this!
251
+ #let frame(stroke) = (x, y) => (
252
+ left: if x > 0 { 0pt } else { stroke },
253
+ right: stroke,
254
+ top: if y < 2 { stroke } else { 0pt },
255
+ bottom: stroke,
256
+ )
257
+
258
+ #set table(
259
+ fill: (rgb("EAF2F5"), none),
260
+ stroke: frame(rgb("21222C")),
261
+ )
262
+
263
+ #table(
264
+ columns: (0.4fr, 1fr, 1fr, 1fr),
265
+
266
+ table.header[Month][Title][Author][Genre],
267
+ [January], [The Great Gatsby], [F. Scott Fitzgerald], [Classic],
268
+ [February], [To Kill a Mockingbird], [Harper Lee], [Drama],
269
+ [March], [1984], [George Orwell], [Dystopian],
270
+ [April], [The Catcher in the Rye], [J.D. Salinger], [Coming-of-Age],
271
+ )
272
+ ```
273
+
274
+ This example shows a book club reading list. The line `{fill: (rgb("EAF2F5"),
275
+ none)}` in `table`'s set rule is all that is needed to add striped columns. It
276
+ tells Typst to alternate between coloring columns with a light blue (in the
277
+ [`rgb`]($color.rgb) function call) and nothing (`{none}`). Note that we
278
+ extracted all of our styling from the `table` function call itself into set and
279
+ show rules, so that we can automatically reuse it for multiple tables.
280
+
281
+ Because setting the stripes itself is easy we also added some other styles to
282
+ make it look nice. The other code in the example provides a dark blue
283
+ [stroke](#stroke-functions) around the table and below the first line and
284
+ emboldens the first row and the column with the book title. See the
285
+ [strokes](#strokes) section for details on how we achieved this stroke
286
+ configuration.
287
+
288
+ Let's next take a look at how we can change only the set rule to achieve
289
+ horizontal stripes instead:
290
+
291
+ ```example
292
+ >>> #set page(width: 16cm)
293
+ >>> #set text(font: "IBM Plex Sans")
294
+ >>> #show table.cell.where(x: 1): set text(weight: "medium")
295
+ >>> #show table.cell.where(y: 0): set text(weight: "bold")
296
+ >>>
297
+ >>> #let frame(stroke) = (x, y) => (
298
+ >>> left: if x > 0 { 0pt } else { stroke },
299
+ >>> right: stroke,
300
+ >>> top: if y < 2 { stroke } else { 0pt },
301
+ >>> bottom: stroke,
302
+ >>> )
303
+ >>>
304
+ #set table(
305
+ fill: (_, y) => if calc.odd(y) { rgb("EAF2F5") },
306
+ stroke: frame(rgb("21222C")),
307
+ )
308
+ >>>
309
+ >>> #table(
310
+ >>> columns: (0.4fr, 1fr, 1fr, 1fr),
311
+ >>>
312
+ >>> table.header[Month][Title][Author][Genre],
313
+ >>> [January], [The Great Gatsby],
314
+ >>> [F. Scott Fitzgerald], [Classic],
315
+ >>> [February], [To Kill a Mockingbird],
316
+ >>> [Harper Lee], [Drama],
317
+ >>> [March], [1984],
318
+ >>> [George Orwell], [Dystopian],
319
+ >>> [April], [The Catcher in the Rye],
320
+ >>> [J.D. Salinger], [Coming-of-Age],
321
+ >>> )
322
+ ```
323
+
324
+ We just need to replace the set rule from the previous example with this one and
325
+ get horizontal stripes instead. Here, we are passing a function to `fill`. It
326
+ discards the horizontal coordinate with an underscore and then checks if the
327
+ vertical coordinate `y` of the cell is odd. If so, the cell gets a light blue
328
+ fill, otherwise, no fill is returned.
329
+
330
+ Of course, you can make this function arbitrarily complex. For example, if you
331
+ want to stripe the rows with a light and darker shade of blue, you could do
332
+ something like this:
333
+
334
+ ```example
335
+ >>> #set page(width: 16cm)
336
+ >>> #set text(font: "IBM Plex Sans")
337
+ >>> #show table.cell.where(x: 1): set text(weight: "medium")
338
+ >>> #show table.cell.where(y: 0): set text(weight: "bold")
339
+ >>>
340
+ >>> #let frame(stroke) = (x, y) => (
341
+ >>> left: if x > 0 { 0pt } else { stroke },
342
+ >>> right: stroke,
343
+ >>> top: if y < 2 { stroke } else { 0pt },
344
+ >>> bottom: stroke,
345
+ >>> )
346
+ >>>
347
+ #set table(
348
+ fill: (_, y) => (none, rgb("EAF2F5"), rgb("DDEAEF")).at(calc.rem(y, 3)),
349
+ stroke: frame(rgb("21222C")),
350
+ )
351
+ >>>
352
+ >>> #table(
353
+ >>> columns: (0.4fr, 1fr, 1fr, 1fr),
354
+ >>>
355
+ >>> table.header[Month][Title][Author][Genre],
356
+ >>> [January], [The Great Gatsby],
357
+ >>> [F. Scott Fitzgerald], [Classic],
358
+ >>> [February], [To Kill a Mockingbird],
359
+ >>> [Harper Lee], [Drama],
360
+ >>> [March], [1984],
361
+ >>> [George Orwell], [Dystopian],
362
+ >>> [April], [The Catcher in the Rye],
363
+ >>> [J.D. Salinger], [Coming-of-Age],
364
+ >>> )
365
+ ```
366
+
367
+ This example shows an alternative approach to write our fill function. The
368
+ function uses an array with three colors and then cycles between its values for
369
+ each row by indexing the array with the remainder of `y` divided by 3.
370
+
371
+ Finally, here is a bonus example that uses the _stroke_ to achieve striped rows:
372
+
373
+ ```example
374
+ >>> #set page(width: 16cm)
375
+ >>> #set text(font: "IBM Plex Sans")
376
+ >>> #show table.cell.where(x: 1): set text(weight: "medium")
377
+ >>> #show table.cell.where(y: 0): set text(weight: "bold")
378
+ >>>
379
+ >>> #let frame(stroke) = (x, y) => (
380
+ >>> left: if x > 0 { 0pt } else { stroke },
381
+ >>> right: stroke,
382
+ >>> top: if y < 2 { stroke } else { 0pt },
383
+ >>> bottom: stroke,
384
+ >>> )
385
+ >>>
386
+ #set table(
387
+ stroke: (x, y) => (
388
+ y: 1pt,
389
+ left: if x > 0 { 0pt } else if calc.even(y) { 1pt },
390
+ right: if calc.even(y) { 1pt },
391
+ ),
392
+ )
393
+ >>>
394
+ >>> #table(
395
+ >>> columns: (0.4fr, 1fr, 1fr, 1fr),
396
+ >>>
397
+ >>> table.header[Month][Title][Author][Genre],
398
+ >>> [January], [The Great Gatsby],
399
+ >>> [F. Scott Fitzgerald], [Classic],
400
+ >>> [February], [To Kill a Mockingbird],
401
+ >>> [Harper Lee], [Drama],
402
+ >>> [March], [1984],
403
+ >>> [George Orwell], [Dystopian],
404
+ >>> [April], [The Catcher in the Rye],
405
+ >>> [J.D. Salinger], [Coming-of-Age],
406
+ >>> )
407
+ ```
408
+
409
+ ### Manually overriding a cell's fill color { #fill-override }
410
+ Sometimes, the fill of a cell needs not to vary based on its position in the
411
+ table, but rather based on its contents. We can use the [`table.cell`
412
+ element]($table.cell) in the `table`'s parameter list to wrap a cell's content
413
+ and override its fill.
414
+
415
+ For example, here is a list of all German presidents, with the cell borders
416
+ colored in the color of their party.
417
+
418
+ ```example
419
+ >>> #set page(width: 10cm)
420
+ #set text(font: "Roboto")
421
+
422
+ #let cdu(name) = ([CDU], table.cell(fill: black, text(fill: white, name)))
423
+ #let spd(name) = ([SPD], table.cell(fill: red, text(fill: white, name)))
424
+ #let fdp(name) = ([FDP], table.cell(fill: yellow, name))
425
+
426
+ #table(
427
+ columns: (auto, auto, 1fr),
428
+ stroke: (x: none),
429
+
430
+ table.header[Tenure][Party][President],
431
+ [1949-1959], ..fdp[Theodor Heuss],
432
+ [1959-1969], ..cdu[Heinrich Lübke],
433
+ [1969-1974], ..spd[Gustav Heinemann],
434
+ [1974-1979], ..fdp[Walter Scheel],
435
+ [1979-1984], ..cdu[Karl Carstens],
436
+ [1984-1994], ..cdu[Richard von Weizsäcker],
437
+ [1994-1999], ..cdu[Roman Herzog],
438
+ [1999-2004], ..spd[Johannes Rau],
439
+ [2004-2010], ..cdu[Horst Köhler],
440
+ [2010-2012], ..cdu[Christian Wulff],
441
+ [2012-2017], [n/a], [Joachim Gauck],
442
+ [2017-], ..spd[Frank-Walter-Steinmeier],
443
+ )
444
+ ```
445
+
446
+ In this example, we make use of variables because there only have been a total
447
+ of three parties whose members have become president (and one unaffiliated
448
+ president). Their colors will repeat multiple times, so we store a function that
449
+ produces an array with their party's name and a table cell with that party's
450
+ color and the president's name (`cdu`, `spd`, and `fdp`). We then use these
451
+ functions in the `table` argument list instead of directly adding the name. We
452
+ use the [spread operator]($arguments/#spreading) `..` to turn the items of the
453
+ arrays into single cells. We could also write something like
454
+ `{[FDP], table.cell(fill: yellow)[Theodor Heuss]}` for each cell directly in the
455
+ `table`'s argument list, but that becomes unreadable, especially for the parties
456
+ whose colors are dark so that they require white text. We also delete vertical
457
+ strokes and set the font to Roboto.
458
+
459
+ The party column and the cell color in this example communicate redundant
460
+ information on purpose: Communicating important data using color only is a bad
461
+ accessibility practice. It disadvantages users with vision impairment and is in
462
+ violation of universal access standards, such as the
463
+ [WCAG 2.1 Success Criterion 1.4.1](https://www.w3.org/WAI/WCAG21/Understanding/use-of-color.html).
464
+ To improve this table, we added a column printing the party name. Alternatively,
465
+ you could have made sure to choose a color-blindness friendly palette and mark
466
+ up your cells with an additional label that screen readers can read out loud.
467
+ The latter feature is not currently supported by Typst, but will be added in a
468
+ future release. You can check how colors look for color-blind readers with
469
+ [this Chrome extension](https://chromewebstore.google.com/detail/colorblindly/floniaahmccleoclneebhhmnjgdfijgg),
470
+ [Photoshop](https://helpx.adobe.com/photoshop/using/proofing-colors.html), or
471
+ [GIMP](https://docs.gimp.org/2.10/en/gimp-display-filter-dialog.html).
472
+
473
+ ## How to adjust the lines in a table? { #strokes }
474
+ By default, Typst adds strokes between each row and column of a table. You can
475
+ adjust these strokes in a variety of ways. Which one is the most practical,
476
+ depends on the modification you want to make and your intent:
477
+
478
+ - Do you want to style all tables in your document, irrespective of their size
479
+ and content? Use the `table` function's [stroke]($table.stroke) argument in a
480
+ set rule.
481
+ - Do you want to customize all lines in a single table? Use the `table`
482
+ function's [stroke]($table.stroke) argument when calling the table function.
483
+ - Do you want to change, add, or remove the stroke around a single cell? Use the
484
+ `table.cell` element in the argument list of your table call.
485
+ - Do you want to change, add, or remove a single horizontal or vertical stroke
486
+ in a single table? Use the [`table.hline`] and [`table.vline`] elements in the
487
+ argument list of your table call.
488
+
489
+ We will go over all of these options with examples next! First, we will tackle
490
+ the `table` function's [stroke]($table.stroke) argument. Here, you can adjust
491
+ both how the table's lines get drawn and configure which lines are drawn at all.
492
+
493
+ Let's start by modifying the color and thickness of the stroke:
494
+
495
+ ```example
496
+ #table(
497
+ columns: 4,
498
+ stroke: 0.5pt + rgb("666675"),
499
+ [*Monday*], [11.5], [13.0], [4.0],
500
+ [*Tuesday*], [8.0], [14.5], [5.0],
501
+ [*Wednesday*], [9.0], [18.5], [13.0],
502
+ )
503
+ ```
504
+
505
+ This makes the table lines a bit less wide and uses a bluish gray. You can see
506
+ that we added a width in point to a color to achieve our customized stroke. This
507
+ addition yields a value of the [stroke type]($stroke). Alternatively, you can
508
+ use the dictionary representation for strokes which allows you to access
509
+ advanced features such as dashed lines.
510
+
511
+ The previous example showed how to use the stroke argument in the table
512
+ function's invocation. Alternatively, you can specify the stroke argument in the
513
+ `table`'s set rule. This will have exactly the same effect on all subsequent
514
+ `table` calls as if the stroke argument was specified in the argument list. This
515
+ is useful if you are writing a template or want to style your whole document.
516
+
517
+ ```typ
518
+ // Renders the exact same as the last example
519
+ #set table(stroke: 0.5pt + rgb("666675"))
520
+
521
+ #table(
522
+ columns: 4,
523
+ [*Monday*], [11.5], [13.0], [4.0],
524
+ [*Tuesday*], [8.0], [14.5], [5.0],
525
+ [*Wednesday*], [9.0], [18.5], [13.0],
526
+ )
527
+ ```
528
+
529
+ For small tables, you sometimes want to suppress all strokes because they add
530
+ too much visual noise. To do this, just set the stroke argument to `{none}`:
531
+
532
+ ```example
533
+ #table(
534
+ columns: 4,
535
+ stroke: none,
536
+ [*Monday*], [11.5], [13.0], [4.0],
537
+ [*Tuesday*], [8.0], [14.5], [5.0],
538
+ [*Wednesday*], [9.0], [18.5], [13.0],
539
+ )
540
+ ```
541
+
542
+ If you want more fine-grained control of where lines get placed in your table,
543
+ you can also pass a dictionary with the keys `top`, `left`, `right`, `bottom`
544
+ (controlling the respective cell sides), `x`, `y` (controlling vertical and
545
+ horizontal strokes), and `rest` (covers all strokes not styled by other
546
+ dictionary entries). All keys are optional; omitted keys will be treated as if
547
+ their value was the default value. For example, to get a table with only
548
+ horizontal lines, you can do this:
549
+
550
+ ```example
551
+ #table(
552
+ columns: 2,
553
+ stroke: (x: none),
554
+ align: horizon,
555
+ [☒], [Close cabin door],
556
+ [☐], [Start engines],
557
+ [☐], [Radio tower],
558
+ [☐], [Push back],
559
+ )
560
+ ```
561
+
562
+ This turns off all vertical strokes and leaves the horizontal strokes in place.
563
+ To achieve the reverse effect (only horizontal strokes), set the stroke argument
564
+ to `{(y: none)}` instead.
565
+
566
+ [Further down in the guide](#stroke-functions), we cover how to use a function
567
+ in the stroke argument to customize all strokes individually. This is how you
568
+ achieve more complex stroking patterns.
569
+
570
+ ### Adding individual lines in the table { #individual-lines }
571
+ If you want to add a single horizontal or vertical line in your table, for
572
+ example to separate a group of rows, you can use the [`table.hline`] and
573
+ [`table.vline`] elements for horizontal and vertical lines, respectively. Add
574
+ them to the argument list of the `table` function just like you would add
575
+ individual cells and a header.
576
+
577
+ Let's take a look at the following example from the reference:
578
+
579
+ ```example
580
+ #set table.hline(stroke: 0.6pt)
581
+
582
+ #table(
583
+ stroke: none,
584
+ columns: (auto, 1fr),
585
+ // Morning schedule abridged.
586
+ [14:00], [Talk: Tracked Layout],
587
+ [15:00], [Talk: Automations],
588
+ [16:00], [Workshop: Tables],
589
+ table.hline(),
590
+ [19:00], [Day 1 Attendee Mixer],
591
+ )
592
+ ```
593
+
594
+ In this example, you can see that we have placed a call to `table.hline` between
595
+ the cells, producing a horizontal line at that spot. We also used a set rule on
596
+ the element to reduce its stroke width to make it fit better with the weight of
597
+ the font.
598
+
599
+ By default, Typst places horizontal and vertical lines after the current row or
600
+ column, depending on their position in the argument list. You can also manually
601
+ move them to a different position by adding the `y` (for `hline`) or `x` (for
602
+ `vline`) argument. For example, the code below would produce the same result:
603
+
604
+ ```typ
605
+ #set table.hline(stroke: 0.6pt)
606
+
607
+ #table(
608
+ stroke: none,
609
+ columns: (auto, 1fr),
610
+ // Morning schedule abridged.
611
+ table.hline(y: 3),
612
+ [14:00], [Talk: Tracked Layout],
613
+ [15:00], [Talk: Automations],
614
+ [16:00], [Workshop: Tables],
615
+ [19:00], [Day 1 Attendee Mixer],
616
+ )
617
+ ```
618
+
619
+ Let's imagine you are working with a template that shows none of the table
620
+ strokes except for one between the first and second row. Now, since you have one
621
+ table that also has labels in the first column, you want to add an extra
622
+ vertical line to it. However, you do not want this vertical line to cross into
623
+ the top row. You can achieve this with the `start` argument:
624
+
625
+ ```example
626
+ >>> #set page(width: 12cm)
627
+ >>> #show table.cell.where(y: 0): strong
628
+ >>> #set table(stroke: (_, y) => if y == 0 { (bottom: 1pt) })
629
+ // Base template already configured tables, but we need some
630
+ // extra configuration for this table.
631
+ #{
632
+ set table(align: (x, _) => if x == 0 { left } else { right })
633
+ show table.cell.where(x: 0): smallcaps
634
+ table(
635
+ columns: (auto, 1fr, 1fr, 1fr),
636
+ table.vline(x: 1, start: 1),
637
+ table.header[Trainset][Top Speed][Length][Weight],
638
+ [TGV Réseau], [320 km/h], [200m], [383t],
639
+ [ICE 403], [330 km/h], [201m], [409t],
640
+ [Shinkansen N700], [300 km/h], [405m], [700t],
641
+ )
642
+ }
643
+ ```
644
+
645
+ In this example, we have added `table.vline` at the start of our positional
646
+ argument list. But because the line is not supposed to go to the left of the
647
+ first column, we specified the `x` argument as `{1}`. We also set the `start`
648
+ argument to `{1}` so that the line does only start after the first row.
649
+
650
+ The example also contains two more things: We use the align argument with a
651
+ function to right-align the data in all but the first column and use a show rule
652
+ to make the first column of table cells appear in small capitals. Because these
653
+ styles are specific to this one table, we put everything into a [code
654
+ block]($scripting/#blocks), so that the styling does not affect any further
655
+ tables.
656
+
657
+ ### Overriding the strokes of a single cell { #stroke-override }
658
+ Imagine you want to change the stroke around a single cell. Maybe your cell is
659
+ very important and needs highlighting! For this scenario, there is the
660
+ [`table.cell` function]($table.cell). Instead of adding your content directly in
661
+ the argument list of the table, you wrap it in a `table.cell` call. Now, you can
662
+ use `table.cell`'s argument list to override the table properties, such as the
663
+ stroke, for this cell only.
664
+
665
+ Here's an example with a matrix of two of the Big Five personality factors, with
666
+ one intersection highlighted.
667
+
668
+ ```example
669
+ >>> #set page(width: 16cm)
670
+ #table(
671
+ columns: 3,
672
+ stroke: (x: none),
673
+
674
+ [], [*High Neuroticism*], [*Low Neuroticism*],
675
+
676
+ [*High Agreeableness*],
677
+ table.cell(stroke: orange + 2pt)[
678
+ _Sensitive_ \ Prone to emotional distress but very empathetic.
679
+ ],
680
+ [_Compassionate_ \ Caring and stable, often seen as a supportive figure.],
681
+
682
+ [*Low Agreeableness*],
683
+ [_Contentious_ \ Competitive and easily agitated.],
684
+ [_Detached_ \ Independent and calm, may appear aloof.],
685
+ )
686
+ ```
687
+
688
+ Above, you can see that we used the `table.cell` element in the table's argument
689
+ list and passed the cell content to it. We have used its `stroke` argument to
690
+ set a wider orange stroke. Despite the fact that we disabled vertical strokes on
691
+ the table, the orange stroke appeared on all sides of the modified cell, showing
692
+ that the table's stroke configuration is overwritten.
693
+
694
+ ### Complex document-wide stroke customization { #stroke-functions }
695
+ This section explains how to customize all lines at once in one or multiple
696
+ tables. This allows you to draw only the first horizontal line or omit the outer
697
+ lines, without knowing how many cells the table has. This is achieved by
698
+ providing a function to the table's `stroke` parameter. The function should
699
+ return a stroke given the zero-indexed x and y position of the current cell. You
700
+ should only need these functions if you are a template author, do not use a
701
+ template, or need to heavily customize your tables. Otherwise, your template
702
+ should set appropriate default table strokes.
703
+
704
+ For example, this is a set rule that draws all horizontal lines except for the
705
+ very first and last line.
706
+
707
+ ```example
708
+ #show table.cell.where(x: 0): set text(style: "italic")
709
+ #show table.cell.where(y: 0): set text(style: "normal", weight: "bold")
710
+ #set table(stroke: (_, y) => if y > 0 { (top: 0.8pt) })
711
+
712
+ #table(
713
+ columns: 3,
714
+ align: center + horizon,
715
+ table.header[Technique][Advantage][Drawback],
716
+ [Diegetic], [Immersive], [May be contrived],
717
+ [Extradiegetic], [Breaks immersion], [Obtrusive],
718
+ [Omitted], [Fosters engagement], [May fracture audience],
719
+ )
720
+ ```
721
+
722
+ In the set rule, we pass a function that receives two arguments, assigning the
723
+ vertical coordinate to `y` and discarding the horizontal coordinate. It then
724
+ returns a stroke dictionary with a `{0.8pt}` top stroke for all but the first
725
+ line. The cells in the first line instead implicitly receive `{none}` as the
726
+ return value. You can easily modify this function to just draw the inner
727
+ vertical lines instead as `{(x, _) => if x > 0 { (left: 0.8pt) }}`.
728
+
729
+ Let's try a few more stroking functions. The next function will only draw a line
730
+ below the first row:
731
+
732
+ ```example
733
+ >>> #show table.cell: it => if it.x == 0 and it.y > 0 {
734
+ >>> set text(style: "italic")
735
+ >>> it
736
+ >>> } else {
737
+ >>> it
738
+ >>> }
739
+ >>>
740
+ >>> #show table.cell.where(y: 0): strong
741
+ #set table(stroke: (_, y) => if y == 0 { (bottom: 1pt) })
742
+
743
+ <<< // Table as seen above
744
+ >>> #table(
745
+ >>> columns: 3,
746
+ >>> align: center + horizon,
747
+ >>> table.header[Technique][Advantage][Drawback],
748
+ >>> [Diegetic], [Immersive], [May be contrived],
749
+ >>> [Extradiegetic], [Breaks immersion], [Obtrusive],
750
+ >>> [Omitted], [Fosters engagement], [May fracture audience],
751
+ >>> )
752
+ ```
753
+
754
+ If you understood the first example, it becomes obvious what happens here. We
755
+ check if we are in the first row. If so, we return a bottom stroke. Otherwise,
756
+ we'll return `{none}` implicitly.
757
+
758
+ The next example shows how to draw all but the outer lines:
759
+
760
+ ```example
761
+ >>> #show table.cell: it => if it.x == 0 and it.y > 0 {
762
+ >>> set text(style: "italic")
763
+ >>> it
764
+ >>> } else {
765
+ >>> it
766
+ >>> }
767
+ >>>
768
+ >>> #show table.cell.where(y: 0): strong
769
+ #set table(stroke: (x, y) => (
770
+ left: if x > 0 { 0.8pt },
771
+ top: if y > 0 { 0.8pt },
772
+ ))
773
+
774
+ <<< // Table as seen above
775
+ >>> #table(
776
+ >>> columns: 3,
777
+ >>> align: center + horizon,
778
+ >>> table.header[Technique][Advantage][Drawback],
779
+ >>> [Diegetic], [Immersive], [May be contrived],
780
+ >>> [Extradiegetic], [Breaks immersion], [Obtrusive],
781
+ >>> [Omitted], [Fosters engagement], [May fracture audience],
782
+ >>> )
783
+ ```
784
+
785
+ This example uses both the `x` and `y` coordinates. It omits the left stroke in
786
+ the first column and the top stroke in the first row. The right and bottom lines
787
+ are not drawn.
788
+
789
+ Finally, here is a table that draws all lines except for the vertical lines in
790
+ the first row and horizontal lines in the table body. It looks a bit like a
791
+ calendar.
792
+
793
+ ```example
794
+ >>> #show table.cell: it => if it.x == 0 and it.y > 0 {
795
+ >>> set text(style: "italic")
796
+ >>> it
797
+ >>> } else {
798
+ >>> it
799
+ >>> }
800
+ >>>
801
+ >>> #show table.cell.where(y: 0): strong
802
+ #set table(stroke: (x, y) => (
803
+ left: if x == 0 or y > 0 { 1pt } else { 0pt },
804
+ right: 1pt,
805
+ top: if y <= 1 { 1pt } else { 0pt },
806
+ bottom: 1pt,
807
+ ))
808
+
809
+ <<< // Table as seen above
810
+ >>> #table(
811
+ >>> columns: 3,
812
+ >>> align: center + horizon,
813
+ >>> table.header[Technique][Advantage][Drawback],
814
+ >>> [Diegetic], [Immersive], [May be contrived],
815
+ >>> [Extradiegetic], [Breaks immersion], [Obtrusive],
816
+ >>> [Omitted], [Fosters engagement], [May fracture audience],
817
+ >>> )
818
+ ```
819
+
820
+ This example is a bit more complex. We start by drawing all the strokes on the
821
+ right of the cells. But this means that we have drawn strokes in the top row,
822
+ too, and we don't need those! We use the fact that `left` will override `right`
823
+ and only draw the left line if we are not in the first row or if we are in the
824
+ first column. In all other cases, we explicitly remove the left line. Finally,
825
+ we draw the horizontal lines by first setting the bottom line and then for the
826
+ first two rows with the `top` key, suppressing all other top lines. The last
827
+ line appears because there is no `top` line that could suppress it.
828
+
829
+ ### How to achieve a double line? { #double-stroke }
830
+ Typst does not yet have a native way to draw double strokes, but there are
831
+ multiple ways to emulate them, for example with [tilings]($tiling). We will
832
+ show a different workaround in this section: Table gutters.
833
+
834
+ Tables can space their cells apart using the `gutter` argument. When a gutter is
835
+ applied, a stroke is drawn on each of the now separated cells. We can
836
+ selectively add gutter between the rows or columns for which we want to draw a
837
+ double line. The `row-gutter` and `column-gutter` arguments allow us to do this.
838
+ They accept arrays of gutter values. Let's take a look at an example:
839
+
840
+ ```example
841
+ #table(
842
+ columns: 3,
843
+ stroke: (x: none),
844
+ row-gutter: (2.2pt, auto),
845
+ table.header[Date][Exercise Type][Calories Burned],
846
+ [2023-03-15], [Swimming], [400],
847
+ [2023-03-17], [Weightlifting], [250],
848
+ [2023-03-18], [Yoga], [200],
849
+ )
850
+ ```
851
+
852
+ We can see that we used an array for `row-gutter` that specifies a `{2.2pt}` gap
853
+ between the first and second row. It then continues with `auto` (which is the
854
+ default, in this case `{0pt}` gutter) which will be the gutter between all other
855
+ rows, since it is the last entry in the array.
856
+
857
+ ## How to align the contents of the cells in my table? { #alignment }
858
+ You can use multiple mechanisms to align the content in your table. You can
859
+ either use the `table` function's `align` argument to set the alignment for your
860
+ whole table (or use it in a set rule to set the alignment for tables throughout
861
+ your document) or the [`align`] function (or `table.cell`'s `align` argument) to
862
+ override the alignment of a single cell.
863
+
864
+ When using the `table` function's align argument, you can choose between three
865
+ methods to specify an [alignment]:
866
+
867
+ - Just specify a single alignment like `right` (aligns in the top-right corner)
868
+ or `center + horizon` (centers all cell content). This changes the alignment
869
+ of all cells.
870
+ - Provide an array. Typst will cycle through this array for each column.
871
+ - Provide a function that is passed the horizontal `x` and vertical `y`
872
+ coordinate of a cell and returns an alignment.
873
+
874
+ For example, this travel itinerary right-aligns the day column and left-aligns
875
+ everything else by providing an array in the `align` argument:
876
+
877
+ ```example
878
+ >>> #set page(width: 12cm)
879
+ #set text(font: "IBM Plex Sans")
880
+ #show table.cell.where(y: 0): set text(weight: "bold")
881
+
882
+ #table(
883
+ columns: 4,
884
+ align: (right, left, left, left),
885
+ fill: (_, y) => if calc.odd(y) { green.lighten(90%) },
886
+ stroke: none,
887
+
888
+ table.header[Day][Location][Hotel or Apartment][Activities],
889
+ [1], [Paris, France], [Hôtel de l'Europe], [Arrival, Evening River Cruise],
890
+ [2], [Paris, France], [Hôtel de l'Europe], [Louvre Museum, Eiffel Tower],
891
+ [3], [Lyon, France], [Lyon City Hotel], [City Tour, Local Cuisine Tasting],
892
+ [4], [Geneva, Switzerland], [Lakeview Inn], [Lake Geneva, Red Cross Museum],
893
+ [5], [Zermatt, Switzerland], [Alpine Lodge], [Visit Matterhorn, Skiing],
894
+ )
895
+ ```
896
+
897
+ However, this example does not yet look perfect — the header cells should be
898
+ bottom-aligned. Let's use a function instead to do so:
899
+
900
+ ```example
901
+ >>> #set page(width: 12cm)
902
+ #set text(font: "IBM Plex Sans")
903
+ #show table.cell.where(y: 0): set text(weight: "bold")
904
+
905
+ #table(
906
+ columns: 4,
907
+ align: (x, y) =>
908
+ if x == 0 { right } else { left } +
909
+ if y == 0 { bottom } else { top },
910
+ fill: (_, y) => if calc.odd(y) { green.lighten(90%) },
911
+ stroke: none,
912
+
913
+ table.header[Day][Location][Hotel or Apartment][Activities],
914
+ [1], [Paris, France], [Hôtel de l'Europe], [Arrival, Evening River Cruise],
915
+ [2], [Paris, France], [Hôtel de l'Europe], [Louvre Museum, Eiffel Tower],
916
+ <<< // ... remaining days omitted
917
+ >>> [3], [Lyon, France], [Lyon City Hotel], [City Tour, Local Cuisine Tasting],
918
+ >>> [4], [Geneva, Switzerland], [Lakeview Inn], [Lake Geneva, Red Cross Museum],
919
+ >>> [5], [Zermatt, Switzerland], [Alpine Lodge], [Visit Matterhorn, Skiing],
920
+ )
921
+ ```
922
+
923
+ In the function, we calculate a horizontal and vertical alignment based on
924
+ whether we are in the first column (`{x == 0}`) or the first row (`{y == 0}`).
925
+ We then make use of the fact that we can add horizontal and vertical alignments
926
+ with `+` to receive a single, two-dimensional alignment.
927
+
928
+ You can find an example of using `table.cell` to change a single cell's
929
+ alignment on [its reference page]($table.cell).
930
+
931
+ ## How to merge cells? { #merge-cells }
932
+ When a table contains logical groupings or the same data in multiple adjacent
933
+ cells, merging multiple cells into a single, larger cell can be advantageous.
934
+ Another use case for cell groups are table headers with multiple rows: That way,
935
+ you can group for example a sales data table by quarter in the first row and by
936
+ months in the second row.
937
+
938
+ A merged cell spans multiple rows and/or columns. You can achieve it with the
939
+ [`table.cell`] function's `rowspan` and `colspan` arguments: Just specify how
940
+ many rows or columns you want your cell to span.
941
+
942
+ The example below contains an attendance calendar for an office with in-person
943
+ and remote days for each team member. To make the table more glanceable, we
944
+ merge adjacent cells with the same value:
945
+
946
+ ```example
947
+ >>> #set page(width: 22cm)
948
+ #let ofi = [Office]
949
+ #let rem = [_Remote_]
950
+ #let lea = [*On leave*]
951
+
952
+ #show table.cell.where(y: 0): set text(
953
+ fill: white,
954
+ weight: "bold",
955
+ )
956
+
957
+ #table(
958
+ columns: 6 * (1fr,),
959
+ align: (x, y) => if x == 0 or y == 0 { left } else { center },
960
+ stroke: (x, y) => (
961
+ // Separate black cells with white strokes.
962
+ left: if y == 0 and x > 0 { white } else { black },
963
+ rest: black,
964
+ ),
965
+ fill: (_, y) => if y == 0 { black },
966
+
967
+ table.header(
968
+ [Team member],
969
+ [Monday],
970
+ [Tuesday],
971
+ [Wednesday],
972
+ [Thursday],
973
+ [Friday]
974
+ ),
975
+ [Evelyn Archer],
976
+ table.cell(colspan: 2, ofi),
977
+ table.cell(colspan: 2, rem),
978
+ ofi,
979
+ [Lila Montgomery],
980
+ table.cell(colspan: 5, lea),
981
+ [Nolan Pearce],
982
+ rem,
983
+ table.cell(colspan: 2, ofi),
984
+ rem,
985
+ ofi,
986
+ )
987
+ ```
988
+
989
+ In the example, we first define variables with "Office", "Remote", and "On
990
+ leave" so we don't have to write these labels out every time. We can then use
991
+ these variables in the table body either directly or in a `table.cell` call if
992
+ the team member spends multiple consecutive days in office, remote, or on leave.
993
+
994
+ The example also contains a black header (created with `table`'s `fill`
995
+ argument) with white strokes (`table`'s `stroke` argument) and white text (set
996
+ by the `table.cell` set rule). Finally, we align all the content of all table
997
+ cells in the body in the center. If you want to know more about the functions
998
+ passed to `align`, `stroke`, and `fill`, you can check out the sections on
999
+ [alignment], [strokes](#stroke-functions), and [striped
1000
+ tables](#fills).
1001
+
1002
+ This table would be a great candidate for fully automated generation from an
1003
+ external data source! Check out the [section about importing
1004
+ data](#importing-data) to learn more about that.
1005
+
1006
+ ## How to rotate a table? { #rotate-table }
1007
+ When tables have many columns, a portrait paper orientation can quickly get
1008
+ cramped. Hence, you'll sometimes want to switch your tables to landscape
1009
+ orientation. There are two ways to accomplish this in Typst:
1010
+
1011
+ - If you want to rotate only the table but not the other content of the page and
1012
+ the page itself, use the [`rotate` function]($rotate) with the `reflow`
1013
+ argument set to `{true}`.
1014
+ - If you want to rotate the whole page the table is on, you can use the [`page`
1015
+ function]($page) with its `flipped` argument set to `{true}`. The header,
1016
+ footer, and page number will now also appear on the long edge of the page.
1017
+ This has the advantage that the table will appear right side up when read on a
1018
+ computer, but it also means that a page in your document has different
1019
+ dimensions than all the others, which can be jarring to your readers.
1020
+
1021
+ Below, we will demonstrate both techniques with a student grade book table.
1022
+
1023
+ First, we will rotate the table on the page. The example also places some text
1024
+ on the right of the table.
1025
+
1026
+ ```example
1027
+ #set page("a5", columns: 2, numbering: "— 1 —")
1028
+ >>> #set page(margin: auto)
1029
+ #show table.cell.where(y: 0): set text(weight: "bold")
1030
+
1031
+ #rotate(
1032
+ -90deg,
1033
+ reflow: true,
1034
+
1035
+ table(
1036
+ columns: (1fr,) + 5 * (auto,),
1037
+ inset: (x: 0.6em,),
1038
+ stroke: (_, y) => (
1039
+ x: 1pt,
1040
+ top: if y <= 1 { 1pt } else { 0pt },
1041
+ bottom: 1pt,
1042
+ ),
1043
+ align: (left, right, right, right, right, left),
1044
+
1045
+ table.header(
1046
+ [Student Name],
1047
+ [Assignment 1], [Assignment 2],
1048
+ [Mid-term], [Final Exam],
1049
+ [Total Grade],
1050
+ ),
1051
+ [Jane Smith], [78%], [82%], [75%], [80%], [B],
1052
+ [Alex Johnson], [90%], [95%], [94%], [96%], [A+],
1053
+ [John Doe], [85%], [90%], [88%], [92%], [A],
1054
+ [Maria Garcia], [88%], [84%], [89%], [85%], [B+],
1055
+ [Zhang Wei], [93%], [89%], [90%], [91%], [A-],
1056
+ [Marina Musterfrau], [96%], [91%], [74%], [69%], [B-],
1057
+ ),
1058
+ )
1059
+
1060
+ #lorem(80)
1061
+ ```
1062
+
1063
+
1064
+ What we have here is a two-column document on ISO A5 paper with page numbers on
1065
+ the bottom. The table has six columns and contains a few customizations to
1066
+ [stroke](#strokes), alignment and spacing. But the most important part is that
1067
+ the table is wrapped in a call to the `rotate` function with the `reflow`
1068
+ argument being `{true}`. This will make the table rotate 90 degrees
1069
+ counterclockwise. The reflow argument is needed so that the table's rotation
1070
+ affects the layout. If it was omitted, Typst would lay out the page as if the
1071
+ table was not rotated (`{true}` might become the default in the future).
1072
+
1073
+ The example also shows how to produce many columns of the same size: To the
1074
+ initial `{1fr}` column, we add an array with five `{auto}` items that we
1075
+ create by multiplying an array with one `{auto}` item by five. Note that arrays
1076
+ with just one item need a trailing comma to distinguish them from merely
1077
+ parenthesized expressions.
1078
+
1079
+ The second example shows how to rotate the whole page, so that the table stays
1080
+ upright:
1081
+
1082
+ ```example
1083
+ #set page("a5", numbering: "— 1 —")
1084
+ >>> #set page(margin: auto)
1085
+ #show table.cell.where(y: 0): set text(weight: "bold")
1086
+
1087
+ #page(flipped: true)[
1088
+ #table(
1089
+ columns: (1fr,) + 5 * (auto,),
1090
+ inset: (x: 0.6em,),
1091
+ stroke: (_, y) => (
1092
+ x: 1pt,
1093
+ top: if y <= 1 { 1pt } else { 0pt },
1094
+ bottom: 1pt,
1095
+ ),
1096
+ align: (left, right, right, right, right, left),
1097
+
1098
+ table.header(
1099
+ [Student Name],
1100
+ [Assignment 1], [Assignment 2],
1101
+ [Mid-term], [Final Exam],
1102
+ [Total Grade],
1103
+ ),
1104
+ [Jane Smith], [78%], [82%], [75%], [80%], [B],
1105
+ [Alex Johnson], [90%], [95%], [94%], [96%], [A+],
1106
+ [John Doe], [85%], [90%], [88%], [92%], [A],
1107
+ [Maria Garcia], [88%], [84%], [89%], [85%], [B+],
1108
+ [Zhang Wei], [93%], [89%], [90%], [91%], [A-],
1109
+ [Marina Musterfrau], [96%], [91%], [74%], [69%], [B-],
1110
+ )
1111
+
1112
+ #pad(x: 15%, top: 1.5em)[
1113
+ = Winter 2023/24 results
1114
+ #lorem(80)
1115
+ ]
1116
+ ]
1117
+ ```
1118
+
1119
+ Here, we take the same table and the other content we want to set with it and
1120
+ put it into a call to the [`page`] function while supplying `{true}` to the
1121
+ `flipped` argument. This will instruct Typst to create new pages with width and
1122
+ height swapped and place the contents of the function call onto a new page.
1123
+ Notice how the page number is also on the long edge of the paper now. At the
1124
+ bottom of the page, we use the [`pad`] function to constrain the width of the
1125
+ paragraph to achieve a nice and legible line length.
1126
+
1127
+ ## How to break a table across pages? { #table-across-pages }
1128
+ It is best to contain a table on a single page. However, some tables just have
1129
+ many rows, so breaking them across pages becomes unavoidable. Fortunately, Typst
1130
+ supports breaking tables across pages out of the box. If you are using the
1131
+ [`table.header`] and [`table.footer`] functions, their contents will be repeated
1132
+ on each page as the first and last rows, respectively. If you want to disable
1133
+ this behavior, you can set `repeat` to `{false}` on either of them.
1134
+
1135
+ If you have placed your table inside of a [figure], it becomes unable to break
1136
+ across pages by default. However, you can change this behavior. Let's take a
1137
+ look:
1138
+
1139
+ ```example
1140
+ #set page(width: 9cm, height: 6cm)
1141
+ #show table.cell.where(y: 0): set text(weight: "bold")
1142
+ #show figure: set block(breakable: true)
1143
+
1144
+ #figure(
1145
+ caption: [Training regimen for Marathon],
1146
+ table(
1147
+ columns: 3,
1148
+ fill: (_, y) => if y == 0 { gray.lighten(75%) },
1149
+
1150
+ table.header[Week][Distance (km)][Time (hh:mm:ss)],
1151
+ [1], [5], [00:30:00],
1152
+ [2], [7], [00:45:00],
1153
+ [3], [10], [01:00:00],
1154
+ [4], [12], [01:10:00],
1155
+ [5], [15], [01:25:00],
1156
+ [6], [18], [01:40:00],
1157
+ [7], [20], [01:50:00],
1158
+ [8], [22], [02:00:00],
1159
+ [...], [...], [...],
1160
+ table.footer[_Goal_][_42.195_][_02:45:00_],
1161
+ )
1162
+ )
1163
+ ```
1164
+
1165
+ A figure automatically produces a [block] which cannot break by default.
1166
+ However, we can reconfigure the block of the figure using a show rule to make it
1167
+ `breakable`. Now, the figure spans multiple pages with the headers and footers
1168
+ repeating.
1169
+
1170
+ ## How to import data into a table? { #importing-data }
1171
+ Often, you need to put data that you obtained elsewhere into a table. Sometimes,
1172
+ this is from Microsoft Excel or Google Sheets, sometimes it is from a dataset
1173
+ on the web or from your experiment. Fortunately, Typst can load many [common
1174
+ file formats]($category/data-loading), so you can use scripting to include their
1175
+ data in a table.
1176
+
1177
+ The most common file format for tabular data is CSV. You can obtain a CSV file
1178
+ from Excel by choosing "Save as" in the _File_ menu and choosing the file format
1179
+ "CSV UTF-8 (Comma-delimited) (.csv)". Save the file and, if you are using the
1180
+ web app, upload it to your project.
1181
+
1182
+ In our case, we will be building a table about Moore's Law. For this purpose, we
1183
+ are using a statistic with [how many transistors the average microprocessor
1184
+ consists of per year from Our World in
1185
+ Data](https://ourworldindata.org/grapher/transistors-per-microprocessor). Let's
1186
+ start by pressing the "Download" button to get a CSV file with the raw data.
1187
+
1188
+ Be sure to move the file to your project or somewhere Typst can see it, if you
1189
+ are using the CLI. Once you did that, we can open the file to see how it is
1190
+ structured:
1191
+
1192
+ ```csv
1193
+ Entity,Code,Year,Transistors per microprocessor
1194
+ World,OWID_WRL,1971,2308.2417
1195
+ World,OWID_WRL,1972,3554.5222
1196
+ World,OWID_WRL,1974,6097.5625
1197
+ ```
1198
+
1199
+ The file starts with a header and contains four columns: Entity (which is to
1200
+ whom the metric applies), Code, the year, and the number of transistors per
1201
+ microprocessor. Only the last two columns change between each row, so we can
1202
+ disregard "Entity" and "Code".
1203
+
1204
+ First, let's start by loading this file with the [`csv`] function. It accepts
1205
+ the file name of the file we want to load as a string argument:
1206
+
1207
+ ```typ
1208
+ #let moore = csv("moore.csv")
1209
+ ```
1210
+
1211
+ We have loaded our file (assuming we named it `moore.csv`) and [bound
1212
+ it]($scripting/#bindings) to the new variable `moore`. This will not produce any
1213
+ output, so there's nothing to see yet. If we want to examine what Typst loaded,
1214
+ we can either hover the name of the variable in the web app or print some items
1215
+ from the array:
1216
+
1217
+ ```example
1218
+ #let moore = csv("moore.csv")
1219
+
1220
+ #moore.slice(0, 3)
1221
+ ```
1222
+
1223
+ With the arguments `{(0, 3)}`, the [`slice`]($array.slice) method returns the
1224
+ first three items in the array (with the indices 0, 1, and 2). We can see that
1225
+ each row is its own array with one item per cell.
1226
+
1227
+ Now, let's write a loop that will transform this data into an array of cells
1228
+ that we can use with the table function.
1229
+
1230
+ ```example
1231
+ #let moore = csv("moore.csv")
1232
+
1233
+ #table(
1234
+ columns: 2,
1235
+ ..for (.., year, count) in moore {
1236
+ (year, count)
1237
+ }
1238
+ )
1239
+ ```
1240
+
1241
+ The example above uses a for loop that iterates over the rows in our CSV file
1242
+ and returns an array for each iteration. We use the for loop's
1243
+ [destructuring]($scripting/#bindings) capability to discard all but the last two
1244
+ items of each row. We then create a new array with just these two. Because Typst
1245
+ will concatenate the array results of all the loop iterations, we get a
1246
+ one-dimensional array in which the year column and the number of transistors
1247
+ alternate. We can then insert the array as cells. For this we use the [spread
1248
+ operator]($arguments/#spreading) (`..`). By prefixing an array, or, in our case
1249
+ an expression that yields an array, with two dots, we tell Typst that the
1250
+ array's items should be used as positional arguments.
1251
+
1252
+ Alternatively, we can also use the [`map`]($array.map), [`slice`]($array.slice),
1253
+ and [`flatten`]($array.flatten) array methods to write this in a more functional
1254
+ style:
1255
+
1256
+ ```typ
1257
+ #let moore = csv("moore.csv")
1258
+
1259
+ #table(
1260
+ columns: moore.first().len(),
1261
+ ..moore.map(m => m.slice(2)).flatten(),
1262
+ )
1263
+ ```
1264
+
1265
+ This example renders the same as the previous one, but first uses the `map`
1266
+ function to change each row of the data. We pass a function to map that gets run
1267
+ on each row of the CSV and returns a new value to replace that row with. We use
1268
+ it to discard the first two columns with `slice`. Then, we spread the data into
1269
+ the `table` function. However, we need to pass a one-dimensional array and
1270
+ `moore`'s value is two-dimensional (that means that each of its row values
1271
+ contains an array with the cell data). That's why we call `flatten` which
1272
+ converts it to a one-dimensional array. We also extract the number of columns
1273
+ from the data itself.
1274
+
1275
+ Now that we have nice code for our table, we should try to also make the table
1276
+ itself nice! The transistor counts go from millions in 1995 to trillions in 2021
1277
+ and changes are difficult to see with so many digits. We could try to present
1278
+ our data logarithmically to make it more digestible:
1279
+
1280
+ ```example
1281
+ #let moore = csv("moore.csv")
1282
+ #let moore-log = moore.slice(1).map(m => {
1283
+ let (.., year, count) = m
1284
+ let log = calc.log(float(count))
1285
+ let rounded = str(calc.round(log, digits: 2))
1286
+ (year, rounded)
1287
+ })
1288
+
1289
+ #show table.cell.where(x: 0): strong
1290
+
1291
+ #table(
1292
+ columns: moore-log.first().len(),
1293
+ align: right,
1294
+ fill: (_, y) => if calc.odd(y) { rgb("D7D9E0") },
1295
+ stroke: none,
1296
+
1297
+ table.header[Year][Transistor count ($log_10$)],
1298
+ table.hline(stroke: rgb("4D4C5B")),
1299
+ ..moore-log.flatten(),
1300
+ )
1301
+ ```
1302
+
1303
+ In this example, we first drop the header row from the data since we are adding
1304
+ our own. Then, we discard all but the last two columns as above. We do this by
1305
+ [destructuring]($scripting/#bindings) the array `m`, discarding all but the two
1306
+ last items. We then convert the string in `count` to a floating point number,
1307
+ calculate its logarithm and store it in the variable `log`. Finally, we round it
1308
+ to two digits, convert it to a string, and store it in the variable `rounded`.
1309
+ Then, we return an array with `year` and `rounded` that replaces the original
1310
+ row. In our table, we have added our custom header that tells the reader that
1311
+ we've applied a logarithm to the values. Then, we spread the flattened data as
1312
+ above.
1313
+
1314
+ We also styled the table with [stripes](#fills), a
1315
+ [horizontal line](#individual-lines) below the first row, [aligned](#alignment)
1316
+ everything to the right, and emboldened the first column. Click on the links to
1317
+ go to the relevant guide sections and see how it's done!
1318
+
1319
+ ## What if I need the table function for something that isn't a table? { #table-and-grid }
1320
+ Tabular layouts of content can be useful not only for matrices of closely
1321
+ related data, like shown in the examples throughout this guide, but also for
1322
+ presentational purposes. Typst differentiates between grids that are for layout
1323
+ and presentational purposes only and tables, in which the arrangement of the
1324
+ cells itself conveys information.
1325
+
1326
+ To make this difference clear to other software and allow templates to heavily
1327
+ style tables, Typst has two functions for grid and table layout:
1328
+
1329
+ - The [`table`] function explained throughout this guide which is intended for
1330
+ tabular data.
1331
+ - The [`grid`] function which is intended for presentational purposes and page
1332
+ layout.
1333
+
1334
+ Both elements work the same way and have the same arguments. You can apply
1335
+ everything you have learned about tables in this guide to grids. There are only
1336
+ three differences:
1337
+
1338
+ - You'll need to use the [`grid.cell`], [`grid.vline`], and [`grid.hline`]
1339
+ elements instead of [`table.cell`], [`table.vline`], and [`table.hline`].
1340
+ - The grid has different defaults: It draws no strokes by default and has no
1341
+ spacing (`inset`) inside of its cells.
1342
+ - Elements like `figure` do not react to grids since they are supposed to have
1343
+ no semantical bearing on the document structure.
sources/docs/guides/welcome.md ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ description: Guides for Typst.
3
+ ---
4
+
5
+ # Guides
6
+ Welcome to the Guides section! Here, you'll find helpful material for specific
7
+ user groups or use cases. Currently, two guides are available: An introduction
8
+ to Typst for LaTeX users, and a detailed look at page setup. Feel free to
9
+ propose other topics for guides!
10
+
11
+ ## List of Guides
12
+ - [Guide for LaTeX users]($guides/guide-for-latex-users)
13
+ - [Page setup guide]($guides/page-setup-guide)
14
+ - [Table guide]($guides/table-guide)
sources/docs/overview.md ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ description: |
3
+ Learn how to use Typst to compose documents faster. Get started with the
4
+ tutorial, or dive into the reference.
5
+ ---
6
+
7
+ # Overview
8
+ Welcome to Typst's documentation! Typst is a new markup-based typesetting system
9
+ for the sciences. It is designed to be an alternative both to advanced tools
10
+ like LaTeX and simpler tools like Word and Google Docs. Our goal with Typst is
11
+ to build a typesetting tool that is highly capable _and_ a pleasure to use.
12
+
13
+ This documentation is split into two parts: A beginner-friendly tutorial that
14
+ introduces Typst through a practical use case and a comprehensive reference that
15
+ explains all of Typst's concepts and features.
16
+
17
+ We also invite you to join the community we're building around Typst. Typst is
18
+ still a very young project, so your feedback is more than valuable.
sources/docs/reference/export/html.md ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="info-box">
2
+
3
+ Typst's HTML export is currently under active development. The feature is still
4
+ very incomplete and only available for experimentation behind a feature flag. Do
5
+ not use this feature for production use cases. In the CLI, you can experiment
6
+ with HTML export by passing `--features html` or setting the `TYPST_FEATURES`
7
+ environment variables to `html`. In the web app, HTML export is not available at
8
+ this time. Visit the [tracking issue](https://github.com/typst/typst/issues/5512)
9
+ to follow progress on HTML export and learn more about planned features.
10
+ </div>
11
+
12
+ HTML files describe a document structurally. The aim of Typst's HTML export is
13
+ to capture the structure of an input document and produce semantically rich HTML
14
+ that retains this structure. The resulting HTML should be accessible,
15
+ human-readable, and editable by hand and downstream tools.
16
+
17
+ PDF, PNG, and SVG export, in contrast, all produce _visual_ representations of a
18
+ fully-laid out document. This divergence in the formats' intents means that
19
+ Typst cannot simply produce perfect HTML for your existing Typst documents. It
20
+ cannot always know what the best semantic HTML representation of your content
21
+ is.
22
+
23
+ Instead, it gives _you_ full control: You can check the current export format
24
+ through the [`target`] function and when it is set to HTML, generate [raw HTML
25
+ elements]($html.elem). The primary intended use of these elements is in
26
+ templates and show rules. This way, the document's contents can be fully
27
+ agnostic to the export target and content can be shared between PDF and HTML
28
+ export.
29
+
30
+ Currently, Typst will always output a single HTML file. Support for outputting
31
+ directories with multiple HTML documents and assets, as well as support for
32
+ outputting fragments that can be integrated into other HTML documents is
33
+ planned.
34
+
35
+ Typst currently does not output CSS style sheets, instead focussing on emitting
36
+ semantic markup. You can of course write your own CSS styles and still benefit
37
+ from sharing your _content_ between PDF and HTML. For the future, we plan to
38
+ give you the option of automatically emitting CSS, taking more of your existing
39
+ set rules into account.
40
+
41
+ # Exporting as HTML
42
+ ## Command Line
43
+ Pass `--format html` to the `compile` or `watch` subcommand or provide an output
44
+ file name that ends with `.html`. Note that you must also pass `--features html`
45
+ or set `TYPST_FEATURES=html` to enable this experimental export target.
46
+
47
+ When using `typst watch`, Typst will spin up a live-reloading HTTP server. You
48
+ can configure it as follows:
49
+
50
+ - Pass `--port` to change the port. (Defaults to the first free port in the
51
+ range 3000-3005.)
52
+ - Pass `--no-reload` to disable injection of a live reload script. (The HTML
53
+ that is written to disk isn't affected either way.)
54
+ - Pass `--no-serve` to disable the server altogether.
55
+
56
+ ## Web App
57
+ Not currently available.
58
+
59
+ # HTML-specific functionality
60
+ Typst exposes HTML-specific functionality in the global `html` module. See below
61
+ for the definitions it contains.
sources/docs/reference/export/pdf.md ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ PDF files focus on accurately describing documents visually, but also have
2
+ facilities for annotating their structure. This hybrid approach makes
3
+ them a good fit for document exchange: They render exactly the same on every
4
+ device, but also support extraction of a document's content and structure (at
5
+ least to an extent). Unlike PNG files, PDFs are not bound to a specific
6
+ resolution. Hence, you can view them at any size without incurring a loss of
7
+ quality.
8
+
9
+ # PDF standards
10
+ The International Standards Organization (ISO) has published the base PDF
11
+ standard and various standards that extend it to make PDFs more suitable for
12
+ specific use-cases. By default, Typst exports PDF 1.7 files. Adobe Acrobat 8 and
13
+ later as well as all other commonly used PDF viewers are compatible with this
14
+ PDF version.
15
+
16
+ ## PDF/A
17
+ Typst optionally supports emitting PDF/A-conformant files. PDF/A files are
18
+ geared towards maximum compatibility with current and future PDF tooling. They
19
+ do not rely on difficult-to-implement or proprietary features and contain
20
+ exhaustive metadata. This makes them suitable for long-term archival.
21
+
22
+ The PDF/A Standard has multiple versions (_parts_ in ISO terminology) and most
23
+ parts have multiple profiles that indicate the file's conformance level.
24
+ Currently, Typst supports these PDF/A output profiles:
25
+
26
+ - PDF/A-2b: The basic conformance level of ISO 19005-2. This version of PDF/A is
27
+ based on PDF 1.7 and results in self-contained, archivable PDF files.
28
+
29
+ - PDF/A-3b: The basic conformance level of ISO 19005-3. This version of PDF/A is
30
+ based on PDF 1.7 and results in archivable PDF files that can contain
31
+ arbitrary other related files as [attachments]($pdf.embed). The only
32
+ difference between it and PDF/A-2b is the capability to embed
33
+ non-PDF/A-conformant files within.
34
+
35
+ When choosing between exporting PDF/A and regular PDF, keep in mind that PDF/A
36
+ files contain additional metadata, and that some readers will prevent the user
37
+ from modifying a PDF/A file. Some features of Typst may be disabled depending on
38
+ the PDF standard you choose.
39
+
40
+ # Exporting as PDF
41
+ ## Command Line
42
+ PDF is Typst's default export format. Running the `compile` or `watch`
43
+ subcommand without specifying a format will create a PDF. When exporting to PDF,
44
+ you have the following configuration options:
45
+
46
+ - Which PDF standards Typst should enforce conformance with by specifying
47
+ `--pdf-standard` followed by one or multiple comma-separated standards. Valid
48
+ standards are `1.7`, `a-2b`, and `a-3b`. By default, Typst outputs
49
+ PDF-1.7-compliant files.
50
+
51
+ - Which pages to export by specifying `--pages` followed by a comma-separated
52
+ list of numbers or dash-separated number ranges. Ranges can be half-open.
53
+ Example: `2,3,7-9,11-`.
54
+
55
+ ## Web App
56
+ Click the quick download button at the top right to export a PDF with default
57
+ settings. For further configuration, click "File" > "Export as" > "PDF" or click
58
+ the downwards-facing arrow next to the quick download button and select "Export
59
+ as PDF". When exporting to PDF, you have the following configuration options:
60
+
61
+ - Which PDF standards Typst should enforce conformance with. By default, Typst
62
+ outputs PDF-1.7-compliant files. Valid additional standards are `A-2b` and
63
+ `A-3b`.
64
+
65
+ - Which pages to export. Valid options are "All pages", "Current page", and
66
+ "Custom ranges". Custom ranges are a comma-separated list of numbers or
67
+ dash-separated number ranges. Ranges can be half-open. Example: `2,3,7-9,11-`.
68
+
69
+ # PDF-specific functionality
70
+ Typst exposes PDF-specific functionality in the global `pdf` module. See below
71
+ for the definitions it contains.
sources/docs/reference/export/png.md ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Instead of creating a PDF, Typst can also directly render pages to PNG raster
2
+ graphics. PNGs are losslessly compressed images that can contain one page at a
3
+ time. When exporting a multi-page document, Typst will emit multiple PNGs. PNGs
4
+ are a good choice when you want to use Typst's output in an image editing
5
+ software or when you can use none of Typst's other export formats.
6
+
7
+ In contrast to Typst's other export formats, PNGs are bound to a specific
8
+ resolution. When exporting to PNG, you can configure the resolution as pixels
9
+ per inch (PPI). If the medium you view the PNG on has a finer resolution than
10
+ the PNG you exported, you will notice a loss of quality. Typst calculates the
11
+ resolution of your PNGs based on each page's physical dimensions and the PPI. If
12
+ you need guidance for choosing a PPI value, consider the following:
13
+
14
+ - A value of 300 or 600 is typical for desktop printing.
15
+ - Professional prints of detailed graphics can go up to 1200 PPI.
16
+ - If your document is only viewed at a distance, e.g. a poster, you may choose a
17
+ smaller value than 300.
18
+ - If your document is viewed on screens, a typical PPI value for a smartphone is
19
+ 400-500.
20
+
21
+ Because PNGs only contain a pixel raster, the text within cannot be extracted
22
+ automatically (without OCR), for example by copy/paste or a screen reader. If
23
+ you need the text to be accessible, export a PDF or HTML file instead.
24
+
25
+ PNGs can have transparent backgrounds. By default, Typst will output a PNG with
26
+ an opaque white background. You can make the background transparent using
27
+ `[#set page(fill: none)]`. Learn more on the
28
+ [`page` function's reference page]($page.fill).
29
+
30
+ # Exporting as PNG
31
+ ## Command Line
32
+ Pass `--format png` to the `compile` or `watch` subcommand or provide an output
33
+ file name that ends with `.png`.
34
+
35
+ If your document has more than one page, Typst will create multiple image files.
36
+ The output file name must then be a template string containing at least one of
37
+ - `[{p}]`, which will be replaced by the page number
38
+ - `[{0p}]`, which will be replaced by the zero-padded page number (so that all
39
+ numbers have the same length)
40
+ - `[{t}]`, which will be replaced by the total number of pages
41
+
42
+ When exporting to PNG, you have the following configuration options:
43
+
44
+ - Which resolution to render at by specifying `--ppi` followed by a number of
45
+ pixels per inch. The default is `144`.
46
+
47
+ - Which pages to export by specifying `--pages` followed by a comma-separated
48
+ list of numbers or dash-separated number ranges. Ranges can be half-open.
49
+ Example: `2,3,7-9,11-`.
50
+
51
+ ## Web App
52
+ Click "File" > "Export as" > "PNG" or click the downwards-facing arrow next to
53
+ the quick download button and select "Export as PNG". When exporting to PNG, you
54
+ have the following configuration options:
55
+
56
+ - The resolution at which the pages should be rendered, as a number of pixels
57
+ per inch. The default is `144`.
58
+
59
+ - Which pages to export. Valid options are "All pages", "Current page", and
60
+ "Custom ranges". Custom ranges are a comma-separated list of numbers or
61
+ dash-separated number ranges. Ranges can be half-open. Example: `2,3,7-9,11-`.
sources/docs/reference/export/svg.md ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Instead of creating a PDF, Typst can also directly render pages to scalable
2
+ vector graphics (SVGs), which are the preferred format for embedding vector
3
+ graphics in web pages. Like PDF files, SVGs display your document exactly how
4
+ you have laid it out in Typst. Likewise, they share the benefit of not being
5
+ bound to a specific resolution. Hence, you can print or view SVG files on any
6
+ device without incurring a loss of quality. (Note that font printing quality may
7
+ be better with a PDF.) In contrast to a PDF, an SVG cannot contain multiple
8
+ pages. When exporting a multi-page document, Typst will emit multiple SVGs.
9
+
10
+ SVGs can represent text in two ways: By embedding the text itself and rendering
11
+ it with the fonts available on the viewer's computer or by embedding the shapes
12
+ of each glyph in the font used to create the document. To ensure that the SVG
13
+ file looks the same across all devices it is viewed on, Typst chooses the latter
14
+ method. This means that the text in the SVG cannot be extracted automatically,
15
+ for example by copy/paste or a screen reader. If you need the text to be
16
+ accessible, export a PDF or HTML file instead.
17
+
18
+ SVGs can have transparent backgrounds. By default, Typst will output an SVG with
19
+ an opaque white background. You can make the background transparent using
20
+ `[#set page(fill: none)]`. Learn more on the
21
+ [`page` function's reference page]($page.fill).
22
+
23
+ # Exporting as SVG
24
+ ## Command Line
25
+ Pass `--format svg` to the `compile` or `watch` subcommand or provide an output
26
+ file name that ends with `.svg`.
27
+
28
+ If your document has more than one page, Typst will create multiple image files.
29
+ The output file name must then be a template string containing at least one of
30
+ - `[{p}]`, which will be replaced by the page number
31
+ - `[{0p}]`, which will be replaced by the zero-padded page number (so that all
32
+ numbers have the same length)
33
+ - `[{t}]`, which will be replaced by the total number of pages
34
+
35
+ When exporting to SVG, you have the following configuration options:
36
+
37
+ - Which pages to export by specifying `--pages` followed by a comma-separated
38
+ list of numbers or dash-separated number ranges. Ranges can be half-open.
39
+ Example: `2,3,7-9,11-`.
40
+
41
+ ## Web App
42
+ Click "File" > "Export as" > "SVG" or click the downwards-facing arrow next to
43
+ the quick download button and select "Export as SVG". When exporting to SVG, you
44
+ have the following configuration options:
45
+
46
+ - Which pages to export. Valid options are "All pages", "Current page", and
47
+ "Custom ranges". Custom ranges are a comma-separated list of numbers or
48
+ dash-separated number ranges. Ranges can be half-open. Example: `2,3,7-9,11-`.
sources/docs/reference/language/context.md ADDED
@@ -0,0 +1,233 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ description: |
3
+ How to deal with content that reacts to its location in the document.
4
+ ---
5
+
6
+ # Context
7
+ Sometimes, we want to create content that reacts to its location in the
8
+ document. This could be a localized phrase that depends on the configured text
9
+ language or something as simple as a heading number which prints the right
10
+ value based on how many headings came before it. However, Typst code isn't
11
+ directly aware of its location in the document. Some code at the beginning of
12
+ the source text could yield content that ends up at the back of the document.
13
+
14
+ To produce content that is reactive to its surroundings, we must thus
15
+ specifically instruct Typst: We do this with the `{context}` keyword, which
16
+ precedes an expression and ensures that it is computed with knowledge of its
17
+ environment. In return, the context expression itself ends up opaque. We cannot
18
+ directly access whatever results from it in our code, precisely because it is
19
+ contextual: There is no one correct result, there may be multiple results in
20
+ different places of the document. For this reason, everything that depends on
21
+ the contextual data must happen inside of the context expression.
22
+
23
+ Aside from explicit context expressions, context is also established implicitly
24
+ in some places that are also aware of their location in the document:
25
+ [Show rules]($styling/#show-rules) provide context[^1] and numberings in the
26
+ outline, for instance, also provide the proper context to resolve counters.
27
+
28
+ ## Style context
29
+ With set rules, we can adjust style properties for parts or the whole of our
30
+ document. We cannot access these without a known context, as they may change
31
+ throughout the course of the document. When context is available, we can
32
+ retrieve them simply by accessing them as fields on the respective element
33
+ function.
34
+
35
+ ```example
36
+ #set text(lang: "de")
37
+ #context text.lang
38
+ ```
39
+
40
+ As explained above, a context expression is reactive to the different
41
+ environments it is placed into. In the example below, we create a single context
42
+ expression, store it in the `value` variable and use it multiple times. Each use
43
+ properly reacts to the current surroundings.
44
+
45
+ ```example
46
+ #let value = context text.lang
47
+ #value
48
+
49
+ #set text(lang: "de")
50
+ #value
51
+
52
+ #set text(lang: "fr")
53
+ #value
54
+ ```
55
+
56
+ Crucially, upon creation, `value` becomes opaque [content] that we cannot peek
57
+ into. It can only be resolved when placed somewhere because only then the
58
+ context is known. The body of a context expression may be evaluated zero, one,
59
+ or multiple times, depending on how many different places it is put into.
60
+
61
+ ## Location context
62
+ We've already seen that context gives us access to set rule values. But it can
63
+ do more: It also lets us know _where_ in the document we currently are, relative
64
+ to other elements, and absolutely on the pages. We can use this information to
65
+ create very flexible interactions between different document parts. This
66
+ underpins features like heading numbering, the table of contents, or page
67
+ headers dependent on section headings.
68
+
69
+ Some functions like [`counter.get`]($counter.get) implicitly access the current
70
+ location. In the example below, we want to retrieve the value of the heading
71
+ counter. Since it changes throughout the document, we need to first enter a
72
+ context expression. Then, we use `get` to retrieve the counter's current value.
73
+ This function accesses the current location from the context to resolve the
74
+ counter value. Counters have multiple levels and `get` returns an array with the
75
+ resolved numbers. Thus, we get the following result:
76
+
77
+ ```example
78
+ #set heading(numbering: "1.")
79
+
80
+ = Introduction
81
+ #lorem(5)
82
+
83
+ #context counter(heading).get()
84
+
85
+ = Background
86
+ #lorem(5)
87
+
88
+ #context counter(heading).get()
89
+ ```
90
+
91
+ For more flexibility, we can also use the [`here`] function to directly extract
92
+ the current [location] from the context. The example below
93
+ demonstrates this:
94
+
95
+ - We first have `{counter(heading).get()}`, which resolves to `{(2,)}` as
96
+ before.
97
+ - We then use the more powerful [`counter.at`] with [`here`], which in
98
+ combination is equivalent to `get`, and thus get `{(2,)}`.
99
+ - Finally, we use `at` with a [label] to retrieve the value of the counter at a
100
+ _different_ location in the document, in our case that of the introduction
101
+ heading. This yields `{(1,)}`. Typst's context system gives us time travel
102
+ abilities and lets us retrieve the values of any counters and states at _any_
103
+ location in the document.
104
+
105
+ ```example
106
+ #set heading(numbering: "1.")
107
+
108
+ = Introduction <intro>
109
+ #lorem(5)
110
+
111
+ = Background <back>
112
+ #lorem(5)
113
+
114
+ #context [
115
+ #counter(heading).get() \
116
+ #counter(heading).at(here()) \
117
+ #counter(heading).at(<intro>)
118
+ ]
119
+ ```
120
+
121
+ As mentioned before, we can also use context to get the physical position of
122
+ elements on the pages. We do this with the [`locate`] function, which works
123
+ similarly to `counter.at`: It takes a location or other [selector] that resolves
124
+ to a unique element (could also be a label) and returns the position on the
125
+ pages for that element.
126
+
127
+ ```example
128
+ Background is at: \
129
+ #context locate(<back>).position()
130
+
131
+ = Introduction <intro>
132
+ #lorem(5)
133
+ #pagebreak()
134
+
135
+ = Background <back>
136
+ #lorem(5)
137
+ ```
138
+
139
+ There are other functions that make use of the location context, most
140
+ prominently [`query`]. Take a look at the
141
+ [introspection]($category/introspection) category for more details on those.
142
+
143
+ ## Nested contexts
144
+ Context is also accessible from within function calls nested in context blocks.
145
+ In the example below, `foo` itself becomes a contextual function, just like
146
+ [`to-absolute`]($length.to-absolute) is.
147
+
148
+ ```example
149
+ #let foo() = 1em.to-absolute()
150
+ #context {
151
+ foo() == text.size
152
+ }
153
+ ```
154
+
155
+ Context blocks can be nested. Contextual code will then always access the
156
+ innermost context. The example below demonstrates this: The first `text.lang`
157
+ will access the outer context block's styles and as such, it will **not**
158
+ see the effect of `{set text(lang: "fr")}`. The nested context block around the
159
+ second `text.lang`, however, starts after the set rule and will thus show
160
+ its effect.
161
+
162
+ ```example
163
+ #set text(lang: "de")
164
+ #context [
165
+ #set text(lang: "fr")
166
+ #text.lang \
167
+ #context text.lang
168
+ ]
169
+ ```
170
+
171
+ You might wonder why Typst ignores the French set rule when computing the first
172
+ `text.lang` in the example above. The reason is that, in the general case, Typst
173
+ cannot know all the styles that will apply as set rules can be applied to
174
+ content after it has been constructed. Below, `text.lang` is already computed
175
+ when the template function is applied. As such, it cannot possibly be aware of
176
+ the language change to French in the template.
177
+
178
+ ```example
179
+ #let template(body) = {
180
+ set text(lang: "fr")
181
+ upper(body)
182
+ }
183
+
184
+ #set text(lang: "de")
185
+ #context [
186
+ #show: template
187
+ #text.lang \
188
+ #context text.lang
189
+ ]
190
+ ```
191
+
192
+ The second `text.lang`, however, _does_ react to the language change because
193
+ evaluation of its surrounding context block is deferred until the styles for it
194
+ are known. This illustrates the importance of picking the right insertion point for a context to get access to precisely the right styles.
195
+
196
+ The same also holds true for the location context. Below, the first
197
+ `{c.display()}` call will access the outer context block and will thus not see
198
+ the effect of `{c.update(2)}` while the second `{c.display()}` accesses the inner context and will thus see it.
199
+
200
+ ```example
201
+ #let c = counter("mycounter")
202
+ #c.update(1)
203
+ #context [
204
+ #c.update(2)
205
+ #c.display() \
206
+ #context c.display()
207
+ ]
208
+ ```
209
+
210
+ ## Compiler iterations
211
+ To resolve contextual interactions, the Typst compiler processes your document
212
+ multiple times. For instance, to resolve a `locate` call, Typst first provides a
213
+ placeholder position, layouts your document and then recompiles with the known
214
+ position from the finished layout. The same approach is taken to resolve
215
+ counters, states, and queries. In certain cases, Typst may even need more than
216
+ two iterations to resolve everything. While that's sometimes a necessity, it may
217
+ also be a sign of misuse of contextual functions (e.g. of
218
+ [state]($state/#caution)). If Typst cannot resolve everything within five
219
+ attempts, it will stop and output the warning "layout did not converge within 5
220
+ attempts."
221
+
222
+ A very careful reader might have noticed that not all of the functions presented
223
+ above actually make use of the current location. While
224
+ `{counter(heading).get()}` definitely depends on it,
225
+ `{counter(heading).at(<intro>)}`, for instance, does not. However, it still
226
+ requires context. While its value is always the same _within_ one compilation
227
+ iteration, it may change over the course of multiple compiler iterations. If one
228
+ could call it directly at the top level of a module, the whole module and its
229
+ exports could change over the course of multiple compiler iterations, which
230
+ would not be desirable.
231
+
232
+ [^1]: Currently, all show rules provide styling context, but only show rules on
233
+ [locatable]($location/#locatable) elements provide a location context.
sources/docs/reference/language/scripting.md ADDED
@@ -0,0 +1,373 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ description: Automate your document with Typst's scripting capabilities.
3
+ ---
4
+
5
+ # Scripting
6
+ Typst embeds a powerful scripting language. You can automate your documents and
7
+ create more sophisticated styles with code. Below is an overview over the
8
+ scripting concepts.
9
+
10
+ ## Expressions
11
+ In Typst, markup and code are fused into one. All but the most common elements
12
+ are created with _functions._ To make this as convenient as possible, Typst
13
+ provides compact syntax to embed a code expression into markup: An expression is
14
+ introduced with a hash (`#`) and normal markup parsing resumes after the
15
+ expression is finished. If a character would continue the expression but should
16
+ be interpreted as text, the expression can forcibly be ended with a semicolon
17
+ (`;`).
18
+
19
+ ```example
20
+ #emph[Hello] \
21
+ #emoji.face \
22
+ #"hello".len()
23
+ ```
24
+
25
+ The example above shows a few of the available expressions, including
26
+ [function calls]($function), [field accesses]($scripting/#fields), and
27
+ [method calls]($scripting/#methods). More kinds of expressions are
28
+ discussed in the remainder of this chapter. A few kinds of expressions are not
29
+ compatible with the hash syntax (e.g. binary operator expressions). To embed
30
+ these into markup, you can use parentheses, as in `[#(1 + 2)]`.
31
+
32
+ ## Blocks
33
+ To structure your code and embed markup into it, Typst provides two kinds of
34
+ _blocks:_
35
+
36
+ - **Code block:** `{{ let x = 1; x + 2 }}` \
37
+ When writing code, you'll probably want to split up your computation into
38
+ multiple statements, create some intermediate variables and so on. Code blocks
39
+ let you write multiple expressions where one is expected. The individual
40
+ expressions in a code block should be separated by line breaks or semicolons.
41
+ The output values of the individual expressions in a code block are joined to
42
+ determine the block's value. Expressions without useful output, like `{let}`
43
+ bindings yield `{none}`, which can be joined with any value without effect.
44
+
45
+ - **Content block:** `{[*Hey* there!]}` \
46
+ With content blocks, you can handle markup/content as a programmatic value,
47
+ store it in variables and pass it to [functions]($function). Content
48
+ blocks are delimited by square brackets and can contain arbitrary markup. A
49
+ content block results in a value of type [content]. An arbitrary number of
50
+ content blocks can be passed as trailing arguments to functions. That is,
51
+ `{list([A], [B])}` is equivalent to `{list[A][B]}`.
52
+
53
+ Content and code blocks can be nested arbitrarily. In the example below,
54
+ `{[hello ]}` is joined with the output of `{a + [ the ] + b}` yielding
55
+ `{[hello from the *world*]}`.
56
+
57
+ ```example
58
+ #{
59
+ let a = [from]
60
+ let b = [*world*]
61
+ [hello ]
62
+ a + [ the ] + b
63
+ }
64
+ ```
65
+
66
+ ## Bindings and Destructuring { #bindings }
67
+ As already demonstrated above, variables can be defined with `{let}` bindings.
68
+ The variable is assigned the value of the expression that follows the `=` sign.
69
+ The assignment of a value is optional, if no value is assigned, the variable
70
+ will be initialized as `{none}`. The `{let}` keyword can also be used to create
71
+ a [custom named function]($function/#defining-functions). Variables can be
72
+ accessed for the rest of the containing block (or the rest of the file if there
73
+ is no containing block).
74
+
75
+ ```example
76
+ #let name = "Typst"
77
+ This is #name's documentation.
78
+ It explains #name.
79
+
80
+ #let add(x, y) = x + y
81
+ Sum is #add(2, 3).
82
+ ```
83
+
84
+ Let bindings can also be used to destructure [arrays]($array) and
85
+ [dictionaries]($dictionary). In this case, the left-hand side of the
86
+ assignment should mirror an array or dictionary. The `..` operator can be used
87
+ once in the pattern to collect the remainder of the array's or dictionary's
88
+ items.
89
+
90
+ ```example
91
+ #let (x, y) = (1, 2)
92
+ The coordinates are #x, #y.
93
+
94
+ #let (a, .., b) = (1, 2, 3, 4)
95
+ The first element is #a.
96
+ The last element is #b.
97
+
98
+ #let books = (
99
+ Shakespeare: "Hamlet",
100
+ Homer: "The Odyssey",
101
+ Austen: "Persuasion",
102
+ )
103
+
104
+ #let (Austen,) = books
105
+ Austen wrote #Austen.
106
+
107
+ #let (Homer: h) = books
108
+ Homer wrote #h.
109
+
110
+ #let (Homer, ..other) = books
111
+ #for (author, title) in other [
112
+ #author wrote #title.
113
+ ]
114
+ ```
115
+
116
+ You can use the underscore to discard elements in a destructuring pattern:
117
+
118
+ ```example
119
+ #let (_, y, _) = (1, 2, 3)
120
+ The y coordinate is #y.
121
+ ```
122
+
123
+ Destructuring also works in argument lists of functions ...
124
+
125
+ ```example
126
+ #let left = (2, 4, 5)
127
+ #let right = (3, 2, 6)
128
+ #left.zip(right).map(
129
+ ((a,b)) => a + b
130
+ )
131
+ ```
132
+
133
+ ... and on the left-hand side of normal assignments. This can be useful to
134
+ swap variables among other things.
135
+
136
+ ```example
137
+ #{
138
+ let a = 1
139
+ let b = 2
140
+ (a, b) = (b, a)
141
+ [a = #a, b = #b]
142
+ }
143
+ ```
144
+
145
+ ## Conditionals
146
+ With a conditional, you can display or compute different things depending on
147
+ whether some condition is fulfilled. Typst supports `{if}`, `{else if}` and
148
+ `{else}` expressions. When the condition evaluates to `{true}`, the conditional
149
+ yields the value resulting from the if's body, otherwise yields the value
150
+ resulting from the else's body.
151
+
152
+ ```example
153
+ #if 1 < 2 [
154
+ This is shown
155
+ ] else [
156
+ This is not.
157
+ ]
158
+ ```
159
+
160
+ Each branch can have a code or content block as its body.
161
+
162
+ - `{if condition {..}}`
163
+ - `{if condition [..]}`
164
+ - `{if condition [..] else {..}}`
165
+ - `{if condition [..] else if condition {..} else [..]}`
166
+
167
+ ## Loops
168
+ With loops, you can repeat content or compute something iteratively. Typst
169
+ supports two types of loops: `{for}` and `{while}` loops. The former iterate
170
+ over a specified collection whereas the latter iterate as long as a condition
171
+ stays fulfilled. Just like blocks, loops _join_ the results from each iteration
172
+ into one value.
173
+
174
+ In the example below, the three sentences created by the for loop join together
175
+ into a single content value and the length-1 arrays in the while loop join
176
+ together into one larger array.
177
+
178
+ ```example
179
+ #for c in "ABC" [
180
+ #c is a letter.
181
+ ]
182
+
183
+ #let n = 2
184
+ #while n < 10 {
185
+ n = (n * 2) - 1
186
+ (n,)
187
+ }
188
+ ```
189
+
190
+ For loops can iterate over a variety of collections:
191
+
192
+ - `{for value in array {..}}` \
193
+ Iterates over the items in the [array]. The destructuring syntax described in
194
+ [Let binding]($scripting/#bindings) can also be used here.
195
+
196
+ - `{for pair in dict {..}}` \
197
+ Iterates over the key-value pairs of the [dictionary]. The pairs can also be
198
+ destructured by using `{for (key, value) in dict {..}}`. It is more efficient
199
+ than `{for pair in dict.pairs() {..}}` because it doesn't create a temporary
200
+ array of all key-value pairs.
201
+
202
+ - `{for letter in "abc" {..}}` \
203
+ Iterates over the characters of the [string]($str). Technically, it iterates
204
+ over the grapheme clusters of the string. Most of the time, a grapheme cluster
205
+ is just a single codepoint. However, a grapheme cluster could contain multiple
206
+ codepoints, like a flag emoji.
207
+
208
+ - `{for byte in bytes("😀") {..}}` \
209
+ Iterates over the [bytes], which can be converted from a [string]($str) or
210
+ [read] from a file without encoding. Each byte value is an [integer]($int)
211
+ between `{0}` and `{255}`.
212
+
213
+ To control the execution of the loop, Typst provides the `{break}` and
214
+ `{continue}` statements. The former performs an early exit from the loop while
215
+ the latter skips ahead to the next iteration of the loop.
216
+
217
+ ```example
218
+ #for letter in "abc nope" {
219
+ if letter == " " {
220
+ break
221
+ }
222
+
223
+ letter
224
+ }
225
+ ```
226
+
227
+ The body of a loop can be a code or content block:
228
+
229
+ - `{for .. in collection {..}}`
230
+ - `{for .. in collection [..]}`
231
+ - `{while condition {..}}`
232
+ - `{while condition [..]}`
233
+
234
+ ## Fields
235
+ You can use _dot notation_ to access fields on a value. For values of type
236
+ [`content`], you can also use the [`fields`]($content.fields) function to list
237
+ the fields.
238
+
239
+ The value in question can be either:
240
+ - a [dictionary] that has the specified key,
241
+ - a [symbol] that has the specified modifier,
242
+ - a [module] containing the specified definition,
243
+ - [content] consisting of an element that has the specified field. The
244
+ available fields match the arguments of the
245
+ [element function]($function/#element-functions) that were given when the
246
+ element was constructed.
247
+
248
+ ```example
249
+ #let it = [= Heading]
250
+ #it.body \
251
+ #it.depth \
252
+ #it.fields()
253
+
254
+ #let dict = (greet: "Hello")
255
+ #dict.greet \
256
+ #emoji.face
257
+
258
+ ```
259
+
260
+ ## Methods
261
+ A _method call_ is a convenient way to call a function that is scoped to a
262
+ value's [type]. For example, we can call the [`str.len`]($str.len) function in
263
+ the following two equivalent ways:
264
+
265
+ ```example
266
+ #str.len("abc") is the same as
267
+ #"abc".len()
268
+ ```
269
+
270
+ The structure of a method call is `{value.method(..args)}` and its equivalent
271
+ full function call is `{type(value).method(value, ..args)}`. The documentation
272
+ of each type lists its scoped functions. You cannot currently define your own
273
+ methods.
274
+
275
+ ```example
276
+ #let values = (1, 2, 3, 4)
277
+ #values.pop() \
278
+ #values.len() \
279
+
280
+ #("a, b, c"
281
+ .split(", ")
282
+ .join[ --- ])
283
+
284
+ #"abc".len() is the same as
285
+ #str.len("abc")
286
+ ```
287
+
288
+ There are a few special functions that modify the value they are called on (e.g.
289
+ [`array.push`]($array.push)). These functions _must_ be called in method form.
290
+ In some cases, when the method is only called for its side effect, its return
291
+ value should be ignored (and not participate in joining). The canonical way to
292
+ discard a value is with a let binding: `{let _ = array.remove(1)}`.
293
+
294
+ ## Modules
295
+ You can split up your Typst projects into multiple files called _modules._ A
296
+ module can refer to the content and definitions of another module in multiple
297
+ ways:
298
+
299
+ - **Including:** `{include "bar.typ"}` \
300
+ Evaluates the file at the path `bar.typ` and returns the resulting [content].
301
+
302
+ - **Import:** `{import "bar.typ"}` \
303
+ Evaluates the file at the path `bar.typ` and inserts the resulting [module]
304
+ into the current scope as `bar` (filename without extension). You can use the
305
+ `as` keyword to rename the imported module: `{import "bar.typ" as baz}`. You
306
+ can import nested items using dot notation: `{import "bar.typ": baz.a}`.
307
+
308
+ - **Import items:** `{import "bar.typ": a, b}` \
309
+ Evaluates the file at the path `bar.typ`, extracts the values of the variables
310
+ `a` and `b` (that need to be defined in `bar.typ`, e.g. through `{let}`
311
+ bindings) and defines them in the current file. Replacing `a, b` with `*`
312
+ loads all variables defined in a module. You can use the `as` keyword to
313
+ rename the individual items: `{import "bar.typ": a as one, b as two}`
314
+
315
+ Instead of a path, you can also use a [module value]($module), as shown in the
316
+ following example:
317
+
318
+ ```example
319
+ #import emoji: face
320
+ #face.grin
321
+ ```
322
+
323
+ ## Packages
324
+ To reuse building blocks across projects, you can also create and import Typst
325
+ _packages._ A package import is specified as a triple of a namespace, a name,
326
+ and a version.
327
+
328
+ ```example
329
+ >>> #let add(x, y) = x + y
330
+ <<< #import "@preview/example:0.1.0": add
331
+ #add(2, 7)
332
+ ```
333
+
334
+ The `preview` namespace contains packages shared by the community. You can find
335
+ all available community packages on [Typst Universe]($universe).
336
+
337
+ If you are using Typst locally, you can also create your own system-local
338
+ packages. For more details on this, see the
339
+ [package repository](https://github.com/typst/packages).
340
+
341
+ ## Operators
342
+ The following table lists all available unary and binary operators with effect,
343
+ arity (unary, binary) and precedence level (higher binds stronger). Some
344
+ operations, such as [modulus]($calc.rem-euclid), do not have a special syntax
345
+ and can be achieved using functions from the
346
+ [`calc`]($category/foundations/calc) module.
347
+
348
+ | Operator | Effect | Arity | Precedence |
349
+ |:----------:|---------------------------------|:------:|:----------:|
350
+ | `{-}` | Negation | Unary | 7 |
351
+ | `{+}` | No effect (exists for symmetry) | Unary | 7 |
352
+ | `{*}` | Multiplication | Binary | 6 |
353
+ | `{/}` | Division | Binary | 6 |
354
+ | `{+}` | Addition | Binary | 5 |
355
+ | `{-}` | Subtraction | Binary | 5 |
356
+ | `{==}` | Check equality | Binary | 4 |
357
+ | `{!=}` | Check inequality | Binary | 4 |
358
+ | `{<}` | Check less-than | Binary | 4 |
359
+ | `{<=}` | Check less-than or equal | Binary | 4 |
360
+ | `{>}` | Check greater-than | Binary | 4 |
361
+ | `{>=}` | Check greater-than or equal | Binary | 4 |
362
+ | `{in}` | Check if in collection | Binary | 4 |
363
+ | `{not in}` | Check if not in collection | Binary | 4 |
364
+ | `{not}` | Logical "not" | Unary | 3 |
365
+ | `{and}` | Short-circuiting logical "and" | Binary | 3 |
366
+ | `{or}` | Short-circuiting logical "or" | Binary | 2 |
367
+ | `{=}` | Assignment | Binary | 1 |
368
+ | `{+=}` | Add-Assignment | Binary | 1 |
369
+ | `{-=}` | Subtraction-Assignment | Binary | 1 |
370
+ | `{*=}` | Multiplication-Assignment | Binary | 1 |
371
+ | `{/=}` | Division-Assignment | Binary | 1 |
372
+
373
+ [semver]: https://semver.org/
sources/docs/reference/language/styling.md ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ description: All concepts needed to style your document with Typst.
3
+ ---
4
+
5
+ # Styling
6
+ Typst includes a flexible styling system that automatically applies styling of
7
+ your choice to your document. With _set rules,_ you can configure basic
8
+ properties of elements. This way, you create most common styles. However, there
9
+ might not be a built-in property for everything you wish to do. For this reason,
10
+ Typst further supports _show rules_ that can completely redefine the appearance
11
+ of elements.
12
+
13
+ ## Set rules
14
+ With set rules, you can customize the appearance of elements. They are written
15
+ as a [function call]($function) to an [element
16
+ function]($function/#element-functions) preceded by the `{set}` keyword (or
17
+ `[#set]` in markup). Only optional parameters of that function can be provided
18
+ to the set rule. Refer to each function's documentation to see which parameters
19
+ are optional. In the example below, we use two set rules to change the
20
+ [font family]($text.font) and [heading numbering]($heading.numbering).
21
+
22
+ ```example
23
+ #set heading(numbering: "I.")
24
+ #set text(
25
+ font: "New Computer Modern"
26
+ )
27
+
28
+ = Introduction
29
+ With set rules, you can style
30
+ your document.
31
+ ```
32
+
33
+ A top level set rule stays in effect until the end of the file. When nested
34
+ inside of a block, it is only in effect until the end of that block. With a
35
+ block, you can thus restrict the effect of a rule to a particular segment of
36
+ your document. Below, we use a content block to scope the list styling to one
37
+ particular list.
38
+
39
+ ```example
40
+ This list is affected: #[
41
+ #set list(marker: [--])
42
+ - Dash
43
+ ]
44
+
45
+ This one is not:
46
+ - Bullet
47
+ ```
48
+
49
+ Sometimes, you'll want to apply a set rule conditionally. For this, you can use
50
+ a _set-if_ rule.
51
+
52
+ ```example
53
+ #let task(body, critical: false) = {
54
+ set text(red) if critical
55
+ [- #body]
56
+ }
57
+
58
+ #task(critical: true)[Food today?]
59
+ #task(critical: false)[Work deadline]
60
+ ```
61
+
62
+ ## Show rules
63
+ With show rules, you can deeply customize the look of a type of element. The
64
+ most basic form of show rule is a _show-set rule._ Such a rule is written as the
65
+ `{show}` keyword followed by a [selector], a colon and then a set rule. The most
66
+ basic form of selector is an [element function]($function/#element-functions).
67
+ This lets the set rule only apply to the selected element. In the example below,
68
+ headings become dark blue while all other text stays black.
69
+
70
+ ```example
71
+ #show heading: set text(navy)
72
+
73
+ = This is navy-blue
74
+ But this stays black.
75
+ ```
76
+
77
+ With show-set rules you can mix and match properties from different functions to
78
+ achieve many different effects. But they still limit you to what is predefined
79
+ in Typst. For maximum flexibility, you can instead write a show rule that
80
+ defines how to format an element from scratch. To write such a show rule,
81
+ replace the set rule after the colon with an arbitrary [function]. This function
82
+ receives the element in question and can return arbitrary content. The available
83
+ [fields]($scripting/#fields) on the element passed to the function again match
84
+ the parameters of the respective element function. Below, we define a show rule
85
+ that formats headings for a fantasy encyclopedia.
86
+
87
+ ```example
88
+ #set heading(numbering: "(I)")
89
+ #show heading: it => [
90
+ #set align(center)
91
+ #set text(font: "Inria Serif")
92
+ \~ #emph(it.body)
93
+ #counter(heading).display(
94
+ it.numbering
95
+ ) \~
96
+ ]
97
+
98
+ = Dragon
99
+ With a base health of 15, the
100
+ dragon is the most powerful
101
+ creature.
102
+
103
+ = Manticore
104
+ While less powerful than the
105
+ dragon, the manticore gets
106
+ extra style points.
107
+ ```
108
+
109
+ Like set rules, show rules are in effect until the end of the current block or
110
+ file.
111
+
112
+ Instead of a function, the right-hand side of a show rule can also take a
113
+ literal string or content block that should be directly substituted for the
114
+ element. And apart from a function, the left-hand side of a show rule can also
115
+ take a number of other _selectors_ that define what to apply the transformation
116
+ to:
117
+
118
+ - **Everything:** `{show: rest => ..}` \
119
+ Transform everything after the show rule. This is useful to apply a more
120
+ complex layout to your whole document without wrapping everything in a giant
121
+ function call.
122
+
123
+ - **Text:** `{show "Text": ..}` \
124
+ Style, transform or replace text.
125
+
126
+ - **Regex:** `{show regex("\w+"): ..}` \
127
+ Select and transform text with a regular expression for even more flexibility.
128
+ See the documentation of the [`regex` type]($regex) for details.
129
+
130
+ - **Function with fields:** `{show heading.where(level: 1): ..}` \
131
+ Transform only elements that have the specified fields. For example, you might
132
+ want to only change the style of level-1 headings.
133
+
134
+ - **Label:** `{show <intro>: ..}` \
135
+ Select and transform elements that have the specified label. See the
136
+ documentation of the [`label` type]($label) for more details.
137
+
138
+ ```example
139
+ #show "Project": smallcaps
140
+ #show "badly": "great"
141
+
142
+ We started Project in 2019
143
+ and are still working on it.
144
+ Project is progressing badly.
145
+ ```
sources/docs/reference/language/syntax.md ADDED
@@ -0,0 +1,215 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ description: |
3
+ A compact reference for Typst's syntax. Learn more about the language within
4
+ markup, math, and code mode.
5
+ ---
6
+
7
+ # Syntax
8
+ Typst is a markup language. This means that you can use simple syntax to
9
+ accomplish common layout tasks. The lightweight markup syntax is complemented by
10
+ set and show rules, which let you style your document easily and automatically.
11
+ All this is backed by a tightly integrated scripting language with built-in and
12
+ user-defined functions.
13
+
14
+ ## Modes
15
+ Typst has three syntactical modes: Markup, math, and code. Markup mode is the
16
+ default in a Typst document, math mode lets you write mathematical formulas, and
17
+ code mode lets you use Typst's scripting features.
18
+
19
+ You can switch to a specific mode at any point by referring to the following
20
+ table:
21
+
22
+ | New mode | Syntax | Example |
23
+ |----------|---------------------------------|---------------------------------|
24
+ | Code | Prefix the code with `#` | `[Number: #(1 + 2)]` |
25
+ | Math | Surround equation with `[$..$]` | `[$-x$ is the opposite of $x$]` |
26
+ | Markup | Surround markup with `[[..]]` | `{let name = [*Typst!*]}` |
27
+
28
+ Once you have entered code mode with `#`, you don't need to use further hashes
29
+ unless you switched back to markup or math mode in between.
30
+
31
+ ## Markup
32
+ Typst provides built-in markup for the most common document elements. Most of
33
+ the syntax elements are just shortcuts for a corresponding function. The table
34
+ below lists all markup that is available and links to the best place to learn
35
+ more about their syntax and usage.
36
+
37
+ | Name | Example | See |
38
+ | ------------------ | ---------------------------- | ------------------------ |
39
+ | Paragraph break | Blank line | [`parbreak`] |
40
+ | Strong emphasis | `[*strong*]` | [`strong`] |
41
+ | Emphasis | `[_emphasis_]` | [`emph`] |
42
+ | Raw text | ``[`print(1)`]`` | [`raw`] |
43
+ | Link | `[https://typst.app/]` | [`link`] |
44
+ | Label | `[<intro>]` | [`label`] |
45
+ | Reference | `[@intro]` | [`ref`] |
46
+ | Heading | `[= Heading]` | [`heading`] |
47
+ | Bullet list | `[- item]` | [`list`] |
48
+ | Numbered list | `[+ item]` | [`enum`] |
49
+ | Term list | `[/ Term: description]` | [`terms`] |
50
+ | Math | `[$x^2$]` | [Math]($category/math) |
51
+ | Line break | `[\]` | [`linebreak`] |
52
+ | Smart quote | `['single' or "double"]` | [`smartquote`] |
53
+ | Symbol shorthand | `[~]`, `[---]` | [Symbols]($category/symbols/sym) |
54
+ | Code expression | `[#rect(width: 1cm)]` | [Scripting]($scripting/#expressions) |
55
+ | Character escape | `[Tweet at us \#ad]` | [Below](#escapes) |
56
+ | Comment | `[/* block */]`, `[// line]` | [Below](#comments) |
57
+
58
+ ## Math mode { #math }
59
+ Math mode is a special markup mode that is used to typeset mathematical
60
+ formulas. It is entered by wrapping an equation in `[$]` characters. This works
61
+ both in markup and code. The equation will be typeset into its own block if it
62
+ starts and ends with at least one space (e.g. `[$ x^2 $]`). Inline math can be
63
+ produced by omitting the whitespace (e.g. `[$x^2$]`). An overview over the
64
+ syntax specific to math mode follows:
65
+
66
+ | Name | Example | See |
67
+ | ---------------------- | ------------------------ | ------------------------ |
68
+ | Inline math | `[$x^2$]` | [Math]($category/math) |
69
+ | Block-level math | `[$ x^2 $]` | [Math]($category/math) |
70
+ | Bottom attachment | `[$x_1$]` | [`attach`]($category/math/attach) |
71
+ | Top attachment | `[$x^2$]` | [`attach`]($category/math/attach) |
72
+ | Fraction | `[$1 + (a+b)/5$]` | [`frac`]($math.frac) |
73
+ | Line break | `[$x \ y$]` | [`linebreak`] |
74
+ | Alignment point | `[$x &= 2 \ &= 3$]` | [Math]($category/math) |
75
+ | Variable access | `[$#x$, $pi$]` | [Math]($category/math) |
76
+ | Field access | `[$arrow.r.long$]` | [Scripting]($scripting/#fields) |
77
+ | Implied multiplication | `[$x y$]` | [Math]($category/math) |
78
+ | Symbol shorthand | `[$->$]`, `[$!=$]` | [Symbols]($category/symbols/sym) |
79
+ | Text/string in math | `[$a "is natural"$]` | [Math]($category/math) |
80
+ | Math function call | `[$floor(x)$]` | [Math]($category/math) |
81
+ | Code expression | `[$#rect(width: 1cm)$]` | [Scripting]($scripting/#expressions) |
82
+ | Character escape | `[$x\^2$]` | [Below](#escapes) |
83
+ | Comment | `[$/* comment */$]` | [Below](#comments) |
84
+
85
+ ## Code mode { #code }
86
+ Within code blocks and expressions, new expressions can start without a leading
87
+ `#` character. Many syntactic elements are specific to expressions. Below is
88
+ a table listing all syntax that is available in code mode:
89
+
90
+ | Name | Example | See |
91
+ | ------------------------ | ----------------------------- | ---------------------------------- |
92
+ | None | `{none}` | [`none`] |
93
+ | Auto | `{auto}` | [`auto`] |
94
+ | Boolean | `{false}`, `{true}` | [`bool`] |
95
+ | Integer | `{10}`, `{0xff}` | [`int`] |
96
+ | Floating-point number | `{3.14}`, `{1e5}` | [`float`] |
97
+ | Length | `{2pt}`, `{3mm}`, `{1em}`, .. | [`length`] |
98
+ | Angle | `{90deg}`, `{1rad}` | [`angle`] |
99
+ | Fraction | `{2fr}` | [`fraction`] |
100
+ | Ratio | `{50%}` | [`ratio`] |
101
+ | String | `{"hello"}` | [`str`] |
102
+ | Label | `{<intro>}` | [`label`] |
103
+ | Math | `[$x^2$]` | [Math]($category/math) |
104
+ | Raw text | ``[`print(1)`]`` | [`raw`] |
105
+ | Variable access | `{x}` | [Scripting]($scripting/#blocks) |
106
+ | Code block | `{{ let x = 1; x + 2 }}` | [Scripting]($scripting/#blocks) |
107
+ | Content block | `{[*Hello*]}` | [Scripting]($scripting/#blocks) |
108
+ | Parenthesized expression | `{(1 + 2)}` | [Scripting]($scripting/#blocks) |
109
+ | Array | `{(1, 2, 3)}` | [Array]($array) |
110
+ | Dictionary | `{(a: "hi", b: 2)}` | [Dictionary]($dictionary) |
111
+ | Unary operator | `{-x}` | [Scripting]($scripting/#operators) |
112
+ | Binary operator | `{x + y}` | [Scripting]($scripting/#operators) |
113
+ | Assignment | `{x = 1}` | [Scripting]($scripting/#operators) |
114
+ | Field access | `{x.y}` | [Scripting]($scripting/#fields) |
115
+ | Method call | `{x.flatten()}` | [Scripting]($scripting/#methods) |
116
+ | Function call | `{min(x, y)}` | [Function]($function) |
117
+ | Argument spreading | `{min(..nums)}` | [Arguments]($arguments) |
118
+ | Unnamed function | `{(x, y) => x + y}` | [Function]($function) |
119
+ | Let binding | `{let x = 1}` | [Scripting]($scripting/#bindings) |
120
+ | Named function | `{let f(x) = 2 * x}` | [Function]($function) |
121
+ | Set rule | `{set text(14pt)}` | [Styling]($styling/#set-rules) |
122
+ | Set-if rule | `{set text(..) if .. }` | [Styling]($styling/#set-rules) |
123
+ | Show-set rule | `{show heading: set block(..)}` | [Styling]($styling/#show-rules) |
124
+ | Show rule with function | `{show raw: it => {..}}` | [Styling]($styling/#show-rules) |
125
+ | Show-everything rule | `{show: template}` | [Styling]($styling/#show-rules) |
126
+ | Context expression | `{context text.lang}` | [Context]($context) |
127
+ | Conditional | `{if x == 1 {..} else {..}}` | [Scripting]($scripting/#conditionals) |
128
+ | For loop | `{for x in (1, 2, 3) {..}}` | [Scripting]($scripting/#loops) |
129
+ | While loop | `{while x < 10 {..}}` | [Scripting]($scripting/#loops) |
130
+ | Loop control flow | `{break, continue}` | [Scripting]($scripting/#loops) |
131
+ | Return from function | `{return x}` | [Function]($function) |
132
+ | Include module | `{include "bar.typ"}` | [Scripting]($scripting/#modules) |
133
+ | Import module | `{import "bar.typ"}` | [Scripting]($scripting/#modules) |
134
+ | Import items from module | `{import "bar.typ": a, b, c}` | [Scripting]($scripting/#modules) |
135
+ | Comment | `{/* block */}`, `{// line}` | [Below](#comments) |
136
+
137
+ ## Comments
138
+ Comments are ignored by Typst and will not be included in the output. This is
139
+ useful to exclude old versions or to add annotations. To comment out a single
140
+ line, start it with `//`:
141
+ ```example
142
+ // our data barely supports
143
+ // this claim
144
+
145
+ We show with $p < 0.05$
146
+ that the difference is
147
+ significant.
148
+ ```
149
+
150
+ Comments can also be wrapped between `/*` and `*/`. In this case, the comment
151
+ can span over multiple lines:
152
+ ```example
153
+ Our study design is as follows:
154
+ /* Somebody write this up:
155
+ - 1000 participants.
156
+ - 2x2 data design. */
157
+ ```
158
+
159
+ ## Escape sequences { #escapes }
160
+ Escape sequences are used to insert special characters that are hard to type or
161
+ otherwise have special meaning in Typst. To escape a character, precede it with
162
+ a backslash. To insert any Unicode codepoint, you can write a hexadecimal escape
163
+ sequence: `[\u{1f600}]`. The same kind of escape sequences also work in
164
+ [strings]($str).
165
+
166
+ ```example
167
+ I got an ice cream for
168
+ \$1.50! \u{1f600}
169
+ ```
170
+
171
+ ## Paths
172
+ Typst has various features that require a file path to reference external
173
+ resources such as images, Typst files, or data files. Paths are represented as
174
+ [strings]($str). There are two kinds of paths: Relative and absolute.
175
+
176
+ - A **relative path** searches from the location of the Typst file where the
177
+ feature is invoked. It is the default:
178
+ ```typ
179
+ #image("images/logo.png")
180
+ ```
181
+
182
+ - An **absolute path** searches from the _root_ of the project. It starts with a
183
+ leading `/`:
184
+ ```typ
185
+ #image("/assets/logo.png")
186
+ ```
187
+
188
+ ### Project root
189
+ By default, the project root is the parent directory of the main Typst file.
190
+ For security reasons, you cannot read any files outside of the root directory.
191
+
192
+ If you want to set a specific folder as the root of your project, you can use
193
+ the CLI's `--root` flag. Make sure that the main file is contained in the
194
+ folder's subtree!
195
+ ```bash
196
+ typst compile --root .. file.typ
197
+ ```
198
+
199
+ In the web app, the project itself is the root directory. You can always read
200
+ all files within it, no matter which one is previewed (via the eye toggle next
201
+ to each Typst file in the file panel).
202
+
203
+ ### Paths and packages
204
+ A package can only load files from its own directory. Within it, absolute paths
205
+ point to the package root, rather than the project root. For this reason, it
206
+ cannot directly load files from the project directory. If a package needs
207
+ resources from the project (such as a logo image), you must pass the already
208
+ loaded image, e.g. as a named parameter `{logo: image("mylogo.svg")}`. Note that
209
+ you can then still customize the image's appearance with a set rule within the
210
+ package.
211
+
212
+ In the future, paths might become a
213
+ [distinct type from strings](https://github.com/typst/typst/issues/971), so that
214
+ they can retain knowledge of where they were constructed. This way, resources
215
+ could be loaded from a different root.
sources/docs/reference/library/data-loading.md ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ Data loading from external files.
2
+
3
+ These functions help you with loading and embedding data, for example from the
4
+ results of an experiment.
sources/docs/reference/library/foundations.md ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ Foundational types and functions.
2
+
3
+ Here, you'll find documentation for basic data types like [integers]($int) and
4
+ [strings]($str) as well as details about core computational functions.
sources/docs/reference/library/introspection.md ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ Interactions between document parts.
2
+
3
+ This category is home to Typst's introspection capabilities: With the `counter`
4
+ function, you can access and manipulate page, section, figure, and equation
5
+ counters or create custom ones. Meanwhile, the `query` function lets you search
6
+ for elements in the document to construct things like a list of figures or
7
+ headers which show the current chapter title.
8
+
9
+ Most of the functions are _contextual._ It is recommended to read the chapter on
10
+ [context] before continuing here.
sources/docs/reference/library/layout.md ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ Arranging elements on the page in different ways.
2
+
3
+ By combining layout functions, you can create complex and automatic layouts.
sources/docs/reference/library/math.md ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Typst has special [syntax]($syntax/#math) and library functions to typeset
2
+ mathematical formulas. Math formulas can be displayed inline with text or as
3
+ separate blocks. They will be typeset into their own block if they start and end
4
+ with at least one space (e.g. `[$ x^2 $]`).
5
+
6
+ # Variables
7
+ In math, single letters are always displayed as is. Multiple letters, however,
8
+ are interpreted as variables and functions. To display multiple letters
9
+ verbatim, you can place them into quotes and to access single letter variables,
10
+ you can use the [hash syntax]($scripting/#expressions).
11
+
12
+ ```example
13
+ $ A = pi r^2 $
14
+ $ "area" = pi dot "radius"^2 $
15
+ $ cal(A) :=
16
+ { x in RR | x "is natural" } $
17
+ #let x = 5
18
+ $ #x < 17 $
19
+ ```
20
+
21
+ # Symbols
22
+ Math mode makes a wide selection of [symbols]($category/symbols/sym) like `pi`,
23
+ `dot`, or `RR` available. Many mathematical symbols are available in different
24
+ variants. You can select between different variants by applying
25
+ [modifiers]($symbol) to the symbol. Typst further recognizes a number of
26
+ shorthand sequences like `=>` that approximate a symbol. When such a shorthand
27
+ exists, the symbol's documentation lists it.
28
+
29
+ ```example
30
+ $ x < y => x gt.eq.not y $
31
+ ```
32
+
33
+ # Line Breaks
34
+ Formulas can also contain line breaks. Each line can contain one or multiple
35
+ _alignment points_ (`&`) which are then aligned.
36
+
37
+ ```example
38
+ $ sum_(k=0)^n k
39
+ &= 1 + ... + n \
40
+ &= (n(n+1)) / 2 $
41
+ ```
42
+
43
+ # Function calls
44
+ Math mode supports special function calls without the hash prefix. In these
45
+ "math calls", the argument list works a little differently than in code:
46
+
47
+ - Within them, Typst is still in "math mode". Thus, you can write math directly
48
+ into them, but need to use hash syntax to pass code expressions (except for
49
+ strings, which are available in the math syntax).
50
+ - They support positional and named arguments, as well as argument spreading.
51
+ - They don't support trailing content blocks.
52
+ - They provide additional syntax for 2-dimensional argument lists. The semicolon
53
+ (`;`) merges preceding arguments separated by commas into an array argument.
54
+
55
+ ```example
56
+ $ frac(a^2, 2) $
57
+ $ vec(1, 2, delim: "[") $
58
+ $ mat(1, 2; 3, 4) $
59
+ $ mat(..#range(1, 5).chunks(2)) $
60
+ $ lim_x =
61
+ op("lim", limits: #true)_x $
62
+ ```
63
+
64
+ To write a verbatim comma or semicolon in a math call, escape it with a
65
+ backslash. The colon on the other hand is only recognized in a special way if
66
+ directly preceded by an identifier, so to display it verbatim in those cases,
67
+ you can just insert a space before it.
68
+
69
+ Functions calls preceded by a hash are normal code function calls and not
70
+ affected by these rules.
71
+
72
+ # Alignment
73
+ When equations include multiple _alignment points_ (`&`), this creates blocks of
74
+ alternatingly right- and left-aligned columns. In the example below, the
75
+ expression `(3x + y) / 7` is right-aligned and `= 9` is left-aligned. The word
76
+ "given" is also left-aligned because `&&` creates two alignment points in a row,
77
+ alternating the alignment twice. `& &` and `&&` behave exactly the same way.
78
+ Meanwhile, "multiply by 7" is right-aligned because just one `&` precedes it.
79
+ Each alignment point simply alternates between right-aligned/left-aligned.
80
+
81
+ ```example
82
+ $ (3x + y) / 7 &= 9 && "given" \
83
+ 3x + y &= 63 & "multiply by 7" \
84
+ 3x &= 63 - y && "subtract y" \
85
+ x &= 21 - y/3 & "divide by 3" $
86
+ ```
87
+
88
+ # Math fonts
89
+ You can set the math font by with a [show-set rule]($styling/#show-rules) as
90
+ demonstrated below. Note that only special OpenType math fonts are suitable for
91
+ typesetting maths.
92
+
93
+ ```example
94
+ #show math.equation: set text(font: "Fira Math")
95
+ $ sum_(i in NN) 1 + i $
96
+ ```
97
+
98
+ # Math module
99
+ All math functions are part of the `math` [module]($scripting/#modules), which
100
+ is available by default in equations. Outside of equations, they can be accessed
101
+ with the `math.` prefix.
sources/docs/reference/library/model.md ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Document structuring.
2
+
3
+ Here, you can find functions to structure your document and interact with that
4
+ structure. This includes section headings, figures, bibliography management,
5
+ cross-referencing and more.
sources/docs/reference/library/symbols.md ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ These two modules give names to symbols and emoji to make them easy to insert
2
+ with a normal keyboard. Alternatively, you can also always directly enter
3
+ Unicode symbols into your text and formulas. In addition to the symbols listed
4
+ below, math mode defines `dif` and `Dif`. These are not normal symbol values
5
+ because they also affect spacing and font style.
sources/docs/reference/library/text.md ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ Text styling.
2
+
3
+ The [text function]($text) is of particular interest.
sources/docs/reference/library/visualize.md ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Drawing and data visualization.
2
+
3
+ If you want to create more advanced drawings or plots, also have a look at the
4
+ [CetZ](https://github.com/johannes-wolf/cetz) package as well as more
5
+ specialized [packages]($universe) for your use case.
sources/docs/reference/welcome.md ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ description: |
3
+ The Typst reference is a systematic and comprehensive guide to the Typst
4
+ typesetting language.
5
+ ---
6
+
7
+ # Reference
8
+ This reference documentation is a comprehensive guide to all of Typst's syntax,
9
+ concepts, types, and functions. If you are completely new to Typst, we recommend
10
+ starting with the [tutorial] and then coming back to the reference to learn more
11
+ about Typst's features as you need them.
12
+
13
+ ## Language
14
+ The reference starts with a language part that gives an overview over
15
+ [Typst's syntax]($syntax) and contains information about concepts involved in
16
+ [styling documents,]($styling) using
17
+ [Typst's scripting capabilities.]($scripting)
18
+
19
+ ## Functions
20
+ The second part includes chapters on all functions used to insert, style, transform,
21
+ and layout content in Typst documents. Each function is documented with a
22
+ description of its purpose, a list of its parameters, and examples of how to use
23
+ it.
24
+
25
+ The final part of the reference explains all functions that are used within
26
+ Typst's code mode to manipulate and transform data. Just as in the previous
27
+ part, each function is documented with a description of its purpose, a list of
28
+ its parameters, and examples of how to use it.
sources/docs/tutorial/1-writing.md ADDED
@@ -0,0 +1,308 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ description: Typst's tutorial.
3
+ ---
4
+
5
+ # Writing in Typst
6
+ Let's get started! Suppose you got assigned to write a technical report for
7
+ university. It will contain prose, maths, headings, and figures. To get started,
8
+ you create a new project on the Typst app. You'll be taken to the editor where
9
+ you see two panels: A source panel where you compose your document and a
10
+ preview panel where you see the rendered document.
11
+
12
+ ![Typst app screenshot](1-writing-app.png)
13
+
14
+ You already have a good angle for your report in mind. So let's start by writing
15
+ the introduction. Enter some text in the editor panel. You'll notice that the
16
+ text immediately appears on the previewed page.
17
+
18
+ ```example
19
+ In this report, we will explore the
20
+ various factors that influence fluid
21
+ dynamics in glaciers and how they
22
+ contribute to the formation and
23
+ behaviour of these natural structures.
24
+ ```
25
+
26
+ _Throughout this tutorial, we'll show code examples like this one. Just like in the app, the first panel contains markup and the second panel shows a preview. We shrunk the page to fit the examples so you can see what's going on._
27
+
28
+ The next step is to add a heading and emphasize some text. Typst uses simple
29
+ markup for the most common formatting tasks. To add a heading, enter the `=`
30
+ character and to emphasize some text with italics, enclose it in
31
+ `[_underscores_]`.
32
+
33
+ ```example
34
+ = Introduction
35
+ In this report, we will explore the
36
+ various factors that influence _fluid
37
+ dynamics_ in glaciers and how they
38
+ contribute to the formation and
39
+ behaviour of these natural structures.
40
+ ```
41
+
42
+ That was easy! To add a new paragraph, just add a blank line in between two
43
+ lines of text. If that paragraph needs a subheading, produce it by typing `==`
44
+ instead of `=`. The number of `=` characters determines the nesting level of the
45
+ heading.
46
+
47
+ Now we want to list a few of the circumstances that influence glacier dynamics.
48
+ To do that, we use a numbered list. For each item of the list, we type a `+`
49
+ character at the beginning of the line. Typst will automatically number the
50
+ items.
51
+
52
+ ```example
53
+ + The climate
54
+ + The topography
55
+ + The geology
56
+ ```
57
+
58
+ If we wanted to add a bulleted list, we would use the `-` character instead of
59
+ the `+` character. We can also nest lists: For example, we can add a sub-list to
60
+ the first item of the list above by indenting it.
61
+
62
+ ```example
63
+ + The climate
64
+ - Temperature
65
+ - Precipitation
66
+ + The topography
67
+ + The geology
68
+ ```
69
+
70
+ ## Adding a figure { #figure }
71
+ You think that your report would benefit from a figure. Let's add one. Typst
72
+ supports images in the formats PNG, JPEG, GIF, and SVG. To add an image file to
73
+ your project, first open the _file panel_ by clicking the box icon in the left
74
+ sidebar. Here, you can see a list of all files in your project. Currently, there
75
+ is only one: The main Typst file you are writing in. To upload another file,
76
+ click the button with the arrow in the top-right corner. This opens the upload
77
+ dialog, in which you can pick files to upload from your computer. Select an
78
+ image file for your report.
79
+
80
+ ![Upload dialog](1-writing-upload.png)
81
+
82
+ We have seen before that specific symbols (called _markup_) have specific
83
+ meaning in Typst. We can use `=`, `-`, `+`, and `_` to create headings, lists
84
+ and emphasized text, respectively. However, having a special symbol for
85
+ everything we want to insert into our document would soon become cryptic and
86
+ unwieldy. For this reason, Typst reserves markup symbols only for the most
87
+ common things. Everything else is inserted with _functions._ For our image to
88
+ show up on the page, we use Typst's [`image`] function.
89
+
90
+ ```example
91
+ #image("glacier.jpg")
92
+ ```
93
+
94
+ In general, a function produces some output for a set of _arguments_. When you
95
+ _call_ a function within markup, you provide the arguments and Typst inserts the
96
+ result (the function's _return value_) into the document. In our case, the
97
+ `image` function takes one argument: The path to the image file. To call a
98
+ function in markup, we first need to type the `#` character, immediately
99
+ followed by the name of the function. Then, we enclose the arguments in
100
+ parentheses. Typst recognizes many different data types within argument lists.
101
+ Our file path is a short [string of text]($str), so we need to enclose it in
102
+ double quotes.
103
+
104
+ The inserted image uses the whole width of the page. To change that, pass the
105
+ `width` argument to the `image` function. This is a _named_ argument and
106
+ therefore specified as a `name: value` pair. If there are multiple arguments,
107
+ they are separated by commas, so we first need to put a comma behind the path.
108
+
109
+ ```example
110
+ #image("glacier.jpg", width: 70%)
111
+ ```
112
+
113
+ The `width` argument is a [relative length]($relative). In our case, we
114
+ specified a percentage, determining that the image shall take up `{70%}` of the
115
+ page's width. We also could have specified an absolute value like `{1cm}` or
116
+ `{0.7in}`.
117
+
118
+ Just like text, the image is now aligned at the left side of the page by
119
+ default. It's also lacking a caption. Let's fix that by using the [figure]
120
+ function. This function takes the figure's contents as a positional argument and
121
+ an optional caption as a named argument.
122
+
123
+ Within the argument list of the `figure` function, Typst is already in code
124
+ mode. This means, you now have to remove the hash before the image function call.
125
+ The hash is only needed directly in markup (to disambiguate text from function
126
+ calls).
127
+
128
+ The caption consists of arbitrary markup. To give markup to a function, we
129
+ enclose it in square brackets. This construct is called a _content block._
130
+
131
+ ```example
132
+ #figure(
133
+ image("glacier.jpg", width: 70%),
134
+ caption: [
135
+ _Glaciers_ form an important part
136
+ of the earth's climate system.
137
+ ],
138
+ )
139
+ ```
140
+
141
+ You continue to write your report and now want to reference the figure. To do
142
+ that, first attach a label to figure. A label uniquely identifies an element in
143
+ your document. Add one after the figure by enclosing some name in angle
144
+ brackets. You can then reference the figure in your text by writing an `[@]`
145
+ symbol followed by that name. Headings and equations can also be labelled to
146
+ make them referenceable.
147
+
148
+ ```example
149
+ Glaciers as the one shown in
150
+ @glaciers will cease to exist if
151
+ we don't take action soon!
152
+
153
+ #figure(
154
+ image("glacier.jpg", width: 70%),
155
+ caption: [
156
+ _Glaciers_ form an important part
157
+ of the earth's climate system.
158
+ ],
159
+ ) <glaciers>
160
+ ```
161
+
162
+ <div class="info-box">
163
+
164
+ So far, we've passed content blocks (markup in square brackets) and strings
165
+ (text in double quotes) to our functions. Both seem to contain text. What's the
166
+ difference?
167
+
168
+ A content block can contain text, but also any other kind of markup, function
169
+ calls, and more, whereas a string is really just a _sequence of characters_ and
170
+ nothing else.
171
+
172
+ For example, the image function expects a path to an image file.
173
+ It would not make sense to pass, e.g., a paragraph of text or another image as
174
+ the image's path parameter. That's why only strings are allowed here.
175
+ In contrast, strings work wherever content is expected because text is a
176
+ valid kind of content.
177
+ </div>
178
+
179
+ ## Adding a bibliography { #bibliography }
180
+ As you write up your report, you need to back up some of your claims. You can
181
+ add a bibliography to your document with the [`bibliography`] function. This
182
+ function expects a path to a bibliography file.
183
+
184
+ Typst's native bibliography format is
185
+ [Hayagriva](https://github.com/typst/hayagriva/blob/main/docs/file-format.md),
186
+ but for compatibility you can also use BibLaTeX files. As your classmate has
187
+ already done a literature survey and sent you a `.bib` file, you'll use that
188
+ one. Upload the file through the file panel to access it in Typst.
189
+
190
+ Once the document contains a bibliography, you can start citing from it.
191
+ Citations use the same syntax as references to a label. As soon as you cite a
192
+ source for the first time, it will appear in the bibliography section of your
193
+ document. Typst supports different citation and bibliography styles. Consult the
194
+ [reference]($bibliography.style) for more details.
195
+
196
+ ```example
197
+ = Methods
198
+ We follow the glacier melting models
199
+ established in @glacier-melt.
200
+
201
+ #bibliography("works.bib")
202
+ ```
203
+
204
+ ## Maths
205
+ After fleshing out the methods section, you move on to the meat of the document:
206
+ Your equations. Typst has built-in mathematical typesetting and uses its own
207
+ math notation. Let's start with a simple equation. We wrap it in `[$]` signs
208
+ to let Typst know it should expect a mathematical expression:
209
+
210
+ ```example
211
+ The equation $Q = rho A v + C$
212
+ defines the glacial flow rate.
213
+ ```
214
+
215
+ The equation is typeset inline, on the same line as the surrounding text. If you
216
+ want to have it on its own line instead, you should insert a single space at its
217
+ start and end:
218
+
219
+ ```example
220
+ The flow rate of a glacier is
221
+ defined by the following equation:
222
+
223
+ $ Q = rho A v + C $
224
+ ```
225
+
226
+ We can see that Typst displayed the single letters `Q`, `A`, `v`, and `C` as-is,
227
+ while it translated `rho` into a Greek letter. Math mode will always show single
228
+ letters verbatim. Multiple letters, however, are interpreted as symbols,
229
+ variables, or function names. To imply a multiplication between single letters,
230
+ put spaces between them.
231
+
232
+ If you want to have a variable that consists of multiple letters, you can
233
+ enclose it in quotes:
234
+
235
+ ```example
236
+ The flow rate of a glacier is given
237
+ by the following equation:
238
+
239
+ $ Q = rho A v + "time offset" $
240
+ ```
241
+
242
+ You'll also need a sum formula in your paper. We can use the `sum` symbol and
243
+ then specify the range of the summation in sub- and superscripts:
244
+
245
+ ```example
246
+ Total displaced soil by glacial flow:
247
+
248
+ $ 7.32 beta +
249
+ sum_(i=0)^nabla Q_i / 2 $
250
+ ```
251
+
252
+ To add a subscript to a symbol or variable, type a `_` character and then the
253
+ subscript. Similarly, use the `^` character for a superscript. If your
254
+ sub- or superscript consists of multiple things, you must enclose them
255
+ in round parentheses.
256
+
257
+ The above example also showed us how to insert fractions: Simply put a `/`
258
+ character between the numerator and the denominator and Typst will automatically
259
+ turn it into a fraction. Parentheses are smartly resolved, so you can enter your
260
+ expression as you would into a calculator and Typst will replace parenthesized
261
+ sub-expressions with the appropriate notation.
262
+
263
+ ```example
264
+ Total displaced soil by glacial flow:
265
+
266
+ $ 7.32 beta +
267
+ sum_(i=0)^nabla
268
+ (Q_i (a_i - epsilon)) / 2 $
269
+ ```
270
+
271
+ Not all math constructs have special syntax. Instead, we use functions, just
272
+ like the `image` function we have seen before. For example, to insert a column
273
+ vector, we can use the [`vec`]($math.vec) function. Within math mode, function
274
+ calls don't need to start with the `#` character.
275
+
276
+ ```example
277
+ $ v := vec(x_1, x_2, x_3) $
278
+ ```
279
+
280
+ Some functions are only available within math mode. For example, the
281
+ [`cal`]($math.cal) function is used to typeset calligraphic letters commonly
282
+ used for sets. The [math section of the reference]($category/math) provides a
283
+ complete list of all functions that math mode makes available.
284
+
285
+ One more thing: Many symbols, such as the arrow, have a lot of variants. You can
286
+ select among these variants by appending a dot and a modifier name to a symbol's
287
+ name:
288
+
289
+ ```example
290
+ $ a arrow.squiggly b $
291
+ ```
292
+
293
+ This notation is also available in markup mode, but the symbol name must be
294
+ preceded with `#sym.` there. See the [symbols section]($category/symbols/sym)
295
+ for a list of all available symbols.
296
+
297
+ ## Review
298
+ You have now seen how to write a basic document in Typst. You learned how to
299
+ emphasize text, write lists, insert images, align content, and typeset
300
+ mathematical expressions. You also learned about Typst's functions. There are
301
+ many more kinds of content that Typst lets you insert into your document, such
302
+ as [tables]($table), [shapes]($category/visualize), and [code blocks]($raw). You
303
+ can peruse the [reference] to learn more about these and other features.
304
+
305
+ For the moment, you have completed writing your report. You have already saved a
306
+ PDF by clicking on the download button in the top right corner. However, you
307
+ think the report could look a bit less plain. In the next section, we'll learn
308
+ how to customize the look of our document.
sources/docs/tutorial/2-formatting.md ADDED
@@ -0,0 +1,280 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ description: Typst's tutorial.
3
+ ---
4
+
5
+ # Formatting
6
+ So far, you have written a report with some text, a few equations and images.
7
+ However, it still looks very plain. Your teaching assistant does not yet know
8
+ that you are using a new typesetting system, and you want your report to fit in
9
+ with the other student's submissions. In this chapter, we will see how to format
10
+ your report using Typst's styling system.
11
+
12
+ ## Set rules
13
+ As we have seen in the previous chapter, Typst has functions that _insert_
14
+ content (e.g. the [`image`] function) and others that _manipulate_ content that
15
+ they received as arguments (e.g. the [`align`] function). The first impulse you
16
+ might have when you want, for example, to change the font, could be to look
17
+ for a function that does that and wrap the complete document in it.
18
+
19
+ ```example
20
+ #text(font: "New Computer Modern")[
21
+ = Background
22
+ In the case of glaciers, fluid
23
+ dynamics principles can be used
24
+ to understand how the movement
25
+ and behaviour of the ice is
26
+ influenced by factors such as
27
+ temperature, pressure, and the
28
+ presence of other fluids (such as
29
+ water).
30
+ ]
31
+ ```
32
+
33
+ Wait, shouldn't all arguments of a function be specified within parentheses? Why
34
+ is there a second set of square brackets with content _after_ the parentheses?
35
+ The answer is that, as passing content to a function is such a common thing to
36
+ do in Typst, there is special syntax for it: Instead of putting the content
37
+ inside of the argument list, you can write it in square brackets directly after
38
+ the normal arguments, saving on punctuation.
39
+
40
+ As seen above, that works. With the [`text`] function, we can adjust the font
41
+ for all text within it. However, wrapping the document in countless functions
42
+ and applying styles selectively and in-situ can quickly become cumbersome.
43
+
44
+ Fortunately, Typst has a more elegant solution. With _set rules,_ you can apply
45
+ style properties to all occurrences of some kind of content. You write a set
46
+ rule by entering the `{set}` keyword, followed by the name of the function whose
47
+ properties you want to set, and a list of arguments in parentheses.
48
+
49
+ ```example
50
+ #set text(
51
+ font: "New Computer Modern"
52
+ )
53
+
54
+ = Background
55
+ In the case of glaciers, fluid
56
+ dynamics principles can be used
57
+ to understand how the movement
58
+ and behaviour of the ice is
59
+ influenced by factors such as
60
+ temperature, pressure, and the
61
+ presence of other fluids (such as
62
+ water).
63
+ ```
64
+
65
+ <div class="info-box">
66
+
67
+ Want to know in more technical terms what is happening here?
68
+
69
+ Set rules can be conceptualized as setting default values
70
+ for some of the parameters of a function for all future
71
+ uses of that function.
72
+ </div>
73
+
74
+ ## The autocomplete panel { #autocomplete }
75
+ If you followed along and tried a few things in the app, you might have noticed
76
+ that always after you enter a `#` character, a panel pops up to show you the
77
+ available functions, and, within an argument list, the available parameters.
78
+ That's the autocomplete panel. It can be very useful while you are writing your
79
+ document: You can apply its suggestions by hitting the Return key or navigate to
80
+ the desired completion with the arrow keys. The panel can be dismissed by
81
+ hitting the Escape key and opened again by typing `#` or hitting
82
+ <kbd>Ctrl</kbd> + <kbd>Space</kbd>. Use the autocomplete panel to discover the
83
+ right arguments for functions. Most suggestions come with a small description of
84
+ what they do.
85
+
86
+ ![Autocomplete panel](2-formatting-autocomplete.png)
87
+
88
+ ## Set up the page { #page-setup }
89
+ Back to set rules: When writing a rule, you choose the function depending on
90
+ what type of element you want to style. Here is a list of some functions that
91
+ are commonly used in set rules:
92
+
93
+ - [`text`] to set font family, size, color, and other properties of text
94
+ - [`page`] to set the page size, margins, headers, enable columns, and footers
95
+ - [`par`] to justify paragraphs, set line spacing, and more
96
+ - [`heading`] to set the appearance of headings and enable numbering
97
+ - [`document`] to set the metadata contained in the PDF output, such as title
98
+ and author
99
+
100
+ Not all function parameters can be set. In general, only parameters that tell
101
+ a function _how_ to do something can be set, not those that tell it _what_ to
102
+ do it with. The function reference pages indicate which parameters are settable.
103
+
104
+ Let's add a few more styles to our document. We want larger margins and a serif
105
+ font. For the purposes of the example, we'll also set another page size.
106
+
107
+ ```example
108
+ #set page(
109
+ paper: "a6",
110
+ margin: (x: 1.8cm, y: 1.5cm),
111
+ )
112
+ #set text(
113
+ font: "New Computer Modern",
114
+ size: 10pt
115
+ )
116
+ #set par(
117
+ justify: true,
118
+ leading: 0.52em,
119
+ )
120
+
121
+ = Introduction
122
+ In this report, we will explore the
123
+ various factors that influence fluid
124
+ dynamics in glaciers and how they
125
+ contribute to the formation and
126
+ behaviour of these natural structures.
127
+
128
+ >>> Glacier displacement is influenced
129
+ >>> by a number of factors, including
130
+ >>> + The climate
131
+ >>> + The topography
132
+ >>> + The geology
133
+ >>>
134
+ >>> This report will present a physical
135
+ >>> model of glacier displacement and
136
+ >>> dynamics, and will explore the
137
+ >>> influence of these factors on the
138
+ >>> movement of large bodies of ice.
139
+ <<< ...
140
+
141
+ #align(center + bottom)[
142
+ #image("glacier.jpg", width: 70%)
143
+
144
+ *Glaciers form an important
145
+ part of the earth's climate
146
+ system.*
147
+ ]
148
+ ```
149
+
150
+ There are a few things of note here.
151
+
152
+ First is the [`page`] set rule. It receives two arguments: the page size and
153
+ margins for the page. The page size is a string. Typst accepts [many standard
154
+ page sizes,]($page.paper) but you can also specify a custom page size. The
155
+ margins are specified as a [dictionary.]($dictionary) Dictionaries are a
156
+ collection of key-value pairs. In this case, the keys are `x` and `y`, and the
157
+ values are the horizontal and vertical margins, respectively. We could also have
158
+ specified separate margins for each side by passing a dictionary with the keys
159
+ `{left}`, `{right}`, `{top}`, and `{bottom}`.
160
+
161
+ Next is the set [`text`] set rule. Here, we set the font size to `{10pt}` and
162
+ font family to `{"New Computer Modern"}`. The Typst app comes with many fonts
163
+ that you can try for your document. When you are in the text function's argument
164
+ list, you can discover the available fonts in the autocomplete panel.
165
+
166
+ We have also set the spacing between lines (a.k.a. leading): It is specified as
167
+ a [length] value, and we used the `em` unit to specify the leading relative to
168
+ the size of the font: `{1em}` is equivalent to the current font size (which
169
+ defaults to `{11pt}`).
170
+
171
+ Finally, we have bottom aligned our image by adding a vertical alignment to our
172
+ center alignment. Vertical and horizontal alignments can be combined with the
173
+ `{+}` operator to yield a 2D alignment.
174
+
175
+ ## A hint of sophistication { #sophistication }
176
+ To structure our document more clearly, we now want to number our headings. We
177
+ can do this by setting the `numbering` parameter of the [`heading`] function.
178
+
179
+ ```example
180
+ >>> #set text(font: "New Computer Modern")
181
+ #set heading(numbering: "1.")
182
+
183
+ = Introduction
184
+ #lorem(10)
185
+
186
+ == Background
187
+ #lorem(12)
188
+
189
+ == Methods
190
+ #lorem(15)
191
+ ```
192
+
193
+ We specified the string `{"1."}` as the numbering parameter. This tells Typst to
194
+ number the headings with arabic numerals and to put a dot between the number of
195
+ each level. We can also use [letters, roman numerals, and symbols]($numbering)
196
+ for our headings:
197
+
198
+ ```example
199
+ >>> #set text(font: "New Computer Modern")
200
+ #set heading(numbering: "1.a")
201
+
202
+ = Introduction
203
+ #lorem(10)
204
+
205
+ == Background
206
+ #lorem(12)
207
+
208
+ == Methods
209
+ #lorem(15)
210
+ ```
211
+
212
+ This example also uses the [`lorem`] function to generate some placeholder text.
213
+ This function takes a number as an argument and generates that many words of
214
+ _Lorem Ipsum_ text.
215
+
216
+ <div class="info-box">
217
+
218
+ Did you wonder why the headings and text set rules apply to all text and headings,
219
+ even if they are not produced with the respective functions?
220
+
221
+ Typst internally calls the `heading` function every time you write
222
+ `[= Conclusion]`. In fact, the function call `[#heading[Conclusion]]` is
223
+ equivalent to the heading markup above. Other markup elements work similarly,
224
+ they are only _syntax sugar_ for the corresponding function calls.
225
+ </div>
226
+
227
+ ## Show rules
228
+ You are already pretty happy with how this turned out. But one last thing needs
229
+ to be fixed: The report you are writing is intended for a larger project and
230
+ that project's name should always be accompanied by a logo, even in prose.
231
+
232
+ You consider your options. You could add an `[#image("logo.svg")]` call before
233
+ every instance of the logo using search and replace. That sounds very tedious.
234
+ Instead, you could maybe
235
+ [define a custom function]($function/#defining-functions) that always yields the
236
+ logo with its image. However, there is an even easier way:
237
+
238
+ With show rules, you can redefine how Typst displays certain elements. You
239
+ specify which elements Typst should show differently and how they should look.
240
+ Show rules can be applied to instances of text, many functions, and even the
241
+ whole document.
242
+
243
+ ```example
244
+ #show "ArtosFlow": name => box[
245
+ #box(image(
246
+ "logo.svg",
247
+ height: 0.7em,
248
+ ))
249
+ #name
250
+ ]
251
+
252
+ This report is embedded in the
253
+ ArtosFlow project. ArtosFlow is a
254
+ project of the Artos Institute.
255
+ ```
256
+
257
+ There is a lot of new syntax in this example: We write the `{show}` keyword,
258
+ followed by a string of text we want to show differently and a colon. Then, we
259
+ write a function that takes the content that shall be shown as an argument.
260
+ Here, we called that argument `name`. We can now use the `name` variable in the
261
+ function's body to print the ArtosFlow name. Our show rule adds the logo image
262
+ in front of the name and puts the result into a box to prevent linebreaks from
263
+ occurring between logo and name. The image is also put inside of a box, so that
264
+ it does not appear in its own paragraph.
265
+
266
+ The calls to the first box function and the image function did not require a
267
+ leading `#` because they were not embedded directly in markup. When Typst
268
+ expects code instead of markup, the leading `#` is not needed to access
269
+ functions, keywords, and variables. This can be observed in parameter lists,
270
+ function definitions, and [code blocks]($scripting).
271
+
272
+ ## Review
273
+ You now know how to apply basic formatting to your Typst documents. You learned
274
+ how to set the font, justify your paragraphs, change the page dimensions, and
275
+ add numbering to your headings with set rules. You also learned how to use a
276
+ basic show rule to change how text appears throughout your document.
277
+
278
+ You have handed in your report. Your supervisor was so happy with it that they
279
+ want to adapt it into a conference paper! In the next section, we will learn how
280
+ to format your document as a paper using more advanced show rules and functions.
sources/docs/tutorial/3-advanced.md ADDED
@@ -0,0 +1,546 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ description: Typst's tutorial.
3
+ ---
4
+
5
+ # Advanced Styling
6
+ In the previous two chapters of this tutorial, you have learned how to write a
7
+ document in Typst and how to change its formatting. The report you wrote
8
+ throughout the last two chapters got a straight A and your supervisor wants to
9
+ base a conference paper on it! The report will of course have to comply with the
10
+ conference's style guide. Let's see how we can achieve that.
11
+
12
+ Before we start, let's create a team, invite your supervisor and add them to the
13
+ team. You can do this by going back to the app dashboard with the back icon in
14
+ the top left corner of the editor. Then, choose the plus icon in the left
15
+ toolbar and create a team. Finally, click on the new team and go to its settings
16
+ by clicking 'manage team' next to the team name. Now you can invite your
17
+ supervisor by email.
18
+
19
+ ![The team settings](3-advanced-team-settings.png)
20
+
21
+ Next, move your project into the team: Open it, going to its settings by
22
+ choosing the gear icon in the left toolbar and selecting your new team from the
23
+ owners dropdown. Don't forget to save your changes!
24
+
25
+ Now, your supervisor can also edit the project and you can both see the changes
26
+ in real time. You can join our [Discord server](https://discord.gg/2uDybryKPe)
27
+ to find other users and try teams with them!
28
+
29
+ ## The conference guidelines { #guidelines }
30
+ The layout guidelines are available on the conference website. Let's take a look
31
+ at them:
32
+
33
+ - The font should be an 11pt serif font
34
+ - The title should be in 17pt and bold
35
+ - The paper contains a single-column abstract and two-column main text
36
+ - The abstract should be centered
37
+ - The main text should be justified
38
+ - First level section headings should be 13pt, centered, and rendered in small
39
+ capitals
40
+ - Second level headings are run-ins, italicized and have the same size as the
41
+ body text
42
+ - Finally, the pages should be US letter sized, numbered in the center of the
43
+ footer and the top right corner of each page should contain the title of the
44
+ paper
45
+
46
+ We already know how to do many of these things, but for some of them, we'll need
47
+ to learn some new tricks.
48
+
49
+ ## Writing the right set rules { #set-rules }
50
+ Let's start by writing some set rules for the document.
51
+
52
+ ```example
53
+ #set page(
54
+ >>> margin: auto,
55
+ paper: "us-letter",
56
+ header: align(right)[
57
+ A fluid dynamic model for
58
+ glacier flow
59
+ ],
60
+ numbering: "1",
61
+ )
62
+ #set par(justify: true)
63
+ #set text(
64
+ font: "Libertinus Serif",
65
+ size: 11pt,
66
+ )
67
+
68
+ #lorem(600)
69
+ ```
70
+
71
+ You are already familiar with most of what is going on here. We set the text
72
+ size to `{11pt}` and the font to Libertinus Serif. We also enable paragraph
73
+ justification and set the page size to US letter.
74
+
75
+ The `header` argument is new: With it, we can provide content to fill the top
76
+ margin of every page. In the header, we specify our paper's title as requested
77
+ by the conference style guide. We use the `align` function to align the text to
78
+ the right.
79
+
80
+ Last but not least is the `numbering` argument. Here, we can provide a
81
+ [numbering pattern]($numbering) that defines how to number the pages. By
82
+ setting into to `{"1"}`, Typst only displays the bare page number. Setting it to
83
+ `{"(1/1)"}` would have displayed the current page and total number of pages
84
+ surrounded by parentheses. And we could even have provided a completely custom
85
+ function here to format things to our liking.
86
+
87
+ ## Creating a title and abstract { #title-and-abstract }
88
+ Now, let's add a title and an abstract. We'll start with the title. We center
89
+ align it and increase its font weight by enclosing it in `[*stars*]`.
90
+
91
+ ```example
92
+ >>> #set page(width: 300pt, margin: 30pt)
93
+ >>> #set text(font: "Libertinus Serif", 11pt)
94
+ #align(center, text(17pt)[
95
+ *A fluid dynamic model
96
+ for glacier flow*
97
+ ])
98
+ ```
99
+
100
+ This looks right. We used the `text` function to override the previous text
101
+ set rule locally, increasing the size to 17pt for the function's argument. Let's
102
+ also add the author list: Since we are writing this paper together with our
103
+ supervisor, we'll add our own and their name.
104
+
105
+ ```example
106
+ >>> #set page(width: 300pt, margin: 30pt)
107
+ >>> #set text(font: "Libertinus Serif", 11pt)
108
+ >>>
109
+ >>> #align(center, text(17pt)[
110
+ >>> *A fluid dynamic model
111
+ >>> for glacier flow*
112
+ >>> ])
113
+ #grid(
114
+ columns: (1fr, 1fr),
115
+ align(center)[
116
+ Therese Tungsten \
117
+ Artos Institute \
118
+ #link("mailto:[email protected]")
119
+ ],
120
+ align(center)[
121
+ Dr. John Doe \
122
+ Artos Institute \
123
+ #link("mailto:[email protected]")
124
+ ]
125
+ )
126
+ ```
127
+
128
+ The two author blocks are laid out next to each other. We use the [`grid`]
129
+ function to create this layout. With a grid, we can control exactly how large
130
+ each column is and which content goes into which cell. The `columns` argument
131
+ takes an array of [relative lengths]($relative) or [fractions]($fraction). In
132
+ this case, we passed it two equal fractional sizes, telling it to split the
133
+ available space into two equal columns. We then passed two content arguments to
134
+ the grid function. The first with our own details, and the second with our
135
+ supervisors'. We again use the `align` function to center the content within the
136
+ column. The grid takes an arbitrary number of content arguments specifying the
137
+ cells. Rows are added automatically, but they can also be manually sized with
138
+ the `rows` argument.
139
+
140
+ Now, let's add the abstract. Remember that the conference wants the abstract to
141
+ be set ragged and centered.
142
+
143
+ ```example:0,0,612,317.5
144
+ >>> #set text(font: "Libertinus Serif", 11pt)
145
+ >>> #set par(justify: true)
146
+ >>> #set page(
147
+ >>> "us-letter",
148
+ >>> margin: auto,
149
+ >>> header: align(right + horizon)[
150
+ >>> A fluid dynamic model for
151
+ >>> glacier flow
152
+ >>> ],
153
+ >>> numbering: "1",
154
+ >>> )
155
+ >>>
156
+ >>> #align(center, text(17pt)[
157
+ >>> *A fluid dynamic model
158
+ >>> for glacier flow*
159
+ >>> ])
160
+ >>>
161
+ >>> #grid(
162
+ >>> columns: (1fr, 1fr),
163
+ >>> align(center)[
164
+ >>> Therese Tungsten \
165
+ >>> Artos Institute \
166
+ >>> #link("mailto:[email protected]")
167
+ >>> ],
168
+ >>> align(center)[
169
+ >>> Dr. John Doe \
170
+ >>> Artos Institute \
171
+ >>> #link("mailto:[email protected]")
172
+ >>> ]
173
+ >>> )
174
+ >>>
175
+ <<< ...
176
+
177
+ #align(center)[
178
+ #set par(justify: false)
179
+ *Abstract* \
180
+ #lorem(80)
181
+ ]
182
+ >>> #lorem(600)
183
+ ```
184
+
185
+ Well done! One notable thing is that we used a set rule within the content
186
+ argument of `align` to turn off justification for the abstract. This does not
187
+ affect the remainder of the document even though it was specified after the
188
+ first set rule because content blocks _scope_ styling. Anything set within a
189
+ content block will only affect the content within that block.
190
+
191
+ Another tweak could be to save the paper title in a variable, so that we do not
192
+ have to type it twice, for header and title. We can do that with the `{let}`
193
+ keyword:
194
+
195
+ ```example:single
196
+ #let title = [
197
+ A fluid dynamic model
198
+ for glacier flow
199
+ ]
200
+
201
+ <<< ...
202
+
203
+ >>> #set text(font: "Libertinus Serif", 11pt)
204
+ >>> #set par(justify: true)
205
+ #set page(
206
+ >>> "us-letter",
207
+ >>> margin: auto,
208
+ header: align(
209
+ right + horizon,
210
+ title
211
+ ),
212
+ <<< ...
213
+ >>> numbering: "1",
214
+ )
215
+
216
+ #align(center, text(17pt)[
217
+ *#title*
218
+ ])
219
+
220
+ <<< ...
221
+
222
+ >>> #grid(
223
+ >>> columns: (1fr, 1fr),
224
+ >>> align(center)[
225
+ >>> Therese Tungsten \
226
+ >>> Artos Institute \
227
+ >>> #link("mailto:[email protected]")
228
+ >>> ],
229
+ >>> align(center)[
230
+ >>> Dr. John Doe \
231
+ >>> Artos Institute \
232
+ >>> #link("mailto:[email protected]")
233
+ >>> ]
234
+ >>> )
235
+ >>>
236
+ >>> #align(center)[
237
+ >>> #set par(justify: false)
238
+ >>> *Abstract* \
239
+ >>> #lorem(80)
240
+ >>> ]
241
+ >>>
242
+ >>> #lorem(600)
243
+ ```
244
+
245
+ After we bound the content to the `title` variable, we can use it in functions
246
+ and also within markup (prefixed by `#`, like functions). This way, if we decide
247
+ on another title, we can easily change it in one place.
248
+
249
+ ## Adding columns and headings { #columns-and-headings }
250
+ The paper above unfortunately looks like a wall of lead. To fix that, let's add
251
+ some headings and switch our paper to a two-column layout. Fortunately, that's
252
+ easy to do: We just need to amend our `page` set rule with the `columns`
253
+ argument.
254
+
255
+ By adding `{columns: 2}` to the argument list, we have wrapped the whole
256
+ document in two columns. However, that would also affect the title and authors
257
+ overview. To keep them spanning the whole page, we can wrap them in a function
258
+ call to [`{place}`]($place). Place expects an alignment and the content it
259
+ should place as positional arguments. Using the named `{scope}` argument, we can
260
+ decide if the items should be placed relative to the current column or its
261
+ parent (the page). There is one more thing to configure: If no other arguments
262
+ are provided, `{place}` takes its content out of the flow of the document and
263
+ positions it over the other content without affecting the layout of other
264
+ content in its container:
265
+
266
+ ```example
267
+ #place(
268
+ top + center,
269
+ rect(fill: black),
270
+ )
271
+ #lorem(30)
272
+ ```
273
+
274
+ If we hadn't used `{place}` here, the square would be in its own line, but here
275
+ it overlaps the few lines of text following it. Likewise, that text acts like as
276
+ if there was no square. To change this behavior, we can pass the argument
277
+ `{float: true}` to ensure that the space taken up by the placed item at the top
278
+ or bottom of the page is not occupied by any other content.
279
+
280
+ ```example:single
281
+ >>> #let title = [
282
+ >>> A fluid dynamic model
283
+ >>> for glacier flow
284
+ >>> ]
285
+ >>>
286
+ >>> #set text(font: "Libertinus Serif", 11pt)
287
+ >>> #set par(justify: true)
288
+ >>>
289
+ #set page(
290
+ >>> margin: auto,
291
+ paper: "us-letter",
292
+ header: align(
293
+ right + horizon,
294
+ title
295
+ ),
296
+ numbering: "1",
297
+ columns: 2,
298
+ )
299
+
300
+ #place(
301
+ top + center,
302
+ float: true,
303
+ scope: "parent",
304
+ clearance: 2em,
305
+ )[
306
+ >>> #text(
307
+ >>> 17pt,
308
+ >>> weight: "bold",
309
+ >>> title,
310
+ >>> )
311
+ >>>
312
+ >>> #grid(
313
+ >>> columns: (1fr, 1fr),
314
+ >>> [
315
+ >>> Therese Tungsten \
316
+ >>> Artos Institute \
317
+ >>> #link("mailto:[email protected]")
318
+ >>> ],
319
+ >>> [
320
+ >>> Dr. John Doe \
321
+ >>> Artos Institute \
322
+ >>> #link("mailto:[email protected]")
323
+ >>> ]
324
+ >>> )
325
+ <<< ...
326
+
327
+ #par(justify: false)[
328
+ *Abstract* \
329
+ #lorem(80)
330
+ ]
331
+ ]
332
+
333
+ = Introduction
334
+ #lorem(300)
335
+
336
+ = Related Work
337
+ #lorem(200)
338
+ ```
339
+
340
+ In this example, we also used the `clearance` argument of the `{place}` function
341
+ to provide the space between it and the body instead of using the [`{v}`]($v)
342
+ function. We can also remove the explicit `{align(center, ..)}` calls around the
343
+ various parts since they inherit the center alignment from the placement.
344
+
345
+ Now there is only one thing left to do: Style our headings. We need to make them
346
+ centered and use small capitals. Because the `heading` function does not offer
347
+ a way to set any of that, we need to write our own heading show rule.
348
+
349
+ ```example:50,250,265,270
350
+ >>> #let title = [
351
+ >>> A fluid dynamic model
352
+ >>> for glacier flow
353
+ >>> ]
354
+ >>>
355
+ >>> #set text(font: "Libertinus Serif", 11pt)
356
+ >>> #set par(justify: true)
357
+ >>> #set page(
358
+ >>> "us-letter",
359
+ >>> margin: auto,
360
+ >>> header: align(
361
+ >>> right + horizon,
362
+ >>> title
363
+ >>> ),
364
+ >>> numbering: "1",
365
+ >>> columns: 2,
366
+ >>> )
367
+ #show heading: it => [
368
+ #set align(center)
369
+ #set text(13pt, weight: "regular")
370
+ #block(smallcaps(it.body))
371
+ ]
372
+
373
+ <<< ...
374
+ >>>
375
+ >>> #place(
376
+ >>> top + center,
377
+ >>> float: true,
378
+ >>> scope: "parent",
379
+ >>> clearance: 2em,
380
+ >>> )[
381
+ >>> #text(
382
+ >>> 17pt,
383
+ >>> weight: "bold",
384
+ >>> title,
385
+ >>> )
386
+ >>>
387
+ >>> #grid(
388
+ >>> columns: (1fr, 1fr),
389
+ >>> [
390
+ >>> Therese Tungsten \
391
+ >>> Artos Institute \
392
+ >>> #link("mailto:[email protected]")
393
+ >>> ],
394
+ >>> [
395
+ >>> Dr. John Doe \
396
+ >>> Artos Institute \
397
+ >>> #link("mailto:[email protected]")
398
+ >>> ]
399
+ >>> )
400
+ >>>
401
+ >>> #par(justify: false)[
402
+ >>> *Abstract* \
403
+ >>> #lorem(80)
404
+ >>> ]
405
+ >>> ]
406
+ >>>
407
+ >>> = Introduction
408
+ >>> #lorem(35)
409
+ >>>
410
+ >>> == Motivation
411
+ >>> #lorem(45)
412
+ ```
413
+
414
+ This looks great! We used a show rule that applies to all headings. We give it a
415
+ function that gets passed the heading as a parameter. That parameter can be used
416
+ as content but it also has some fields like `title`, `numbers`, and `level` from
417
+ which we can compose a custom look. Here, we are center-aligning, setting the
418
+ font weight to `{"regular"}` because headings are bold by default, and use the
419
+ [`smallcaps`] function to render the heading's title in small capitals.
420
+
421
+ The only remaining problem is that all headings look the same now. The
422
+ "Motivation" and "Problem Statement" subsections ought to be italic run in
423
+ headers, but right now, they look indistinguishable from the section headings. We
424
+ can fix that by using a `where` selector on our set rule: This is a
425
+ [method]($scripting/#methods) we can call on headings (and other
426
+ elements) that allows us to filter them by their level. We can use it to
427
+ differentiate between section and subsection headings:
428
+
429
+ ```example:50,250,265,245
430
+ >>> #let title = [
431
+ >>> A fluid dynamic model
432
+ >>> for glacier flow
433
+ >>> ]
434
+ >>>
435
+ >>> #set text(font: "Libertinus Serif", 11pt)
436
+ >>> #set par(justify: true)
437
+ >>> #set page(
438
+ >>> "us-letter",
439
+ >>> margin: auto,
440
+ >>> header: align(
441
+ >>> right + horizon,
442
+ >>> title
443
+ >>> ),
444
+ >>> numbering: "1",
445
+ >>> columns: 2,
446
+ >>> )
447
+ >>>
448
+ #show heading.where(
449
+ level: 1
450
+ ): it => block(width: 100%)[
451
+ #set align(center)
452
+ #set text(13pt, weight: "regular")
453
+ #smallcaps(it.body)
454
+ ]
455
+
456
+ #show heading.where(
457
+ level: 2
458
+ ): it => text(
459
+ size: 11pt,
460
+ weight: "regular",
461
+ style: "italic",
462
+ it.body + [.],
463
+ )
464
+ >>>
465
+ >>> #place(
466
+ >>> top + center,
467
+ >>> float: true,
468
+ >>> scope: "parent",
469
+ >>> clearance: 2em,
470
+ >>> )[
471
+ >>> #text(
472
+ >>> 17pt,
473
+ >>> weight: "bold",
474
+ >>> title,
475
+ >>> )
476
+ >>>
477
+ >>> #grid(
478
+ >>> columns: (1fr, 1fr),
479
+ >>> [
480
+ >>> Therese Tungsten \
481
+ >>> Artos Institute \
482
+ >>> #link("mailto:[email protected]")
483
+ >>> ],
484
+ >>> [
485
+ >>> Dr. John Doe \
486
+ >>> Artos Institute \
487
+ >>> #link("mailto:[email protected]")
488
+ >>> ]
489
+ >>> )
490
+ >>>
491
+ >>> #par(justify: false)[
492
+ >>> *Abstract* \
493
+ >>> #lorem(80)
494
+ >>> ]
495
+ >>> ]
496
+ >>>
497
+ >>> = Introduction
498
+ >>> #lorem(35)
499
+ >>>
500
+ >>> == Motivation
501
+ >>> #lorem(45)
502
+ ```
503
+
504
+ This looks great! We wrote two show rules that each selectively apply to the
505
+ first and second level headings. We used a `where` selector to filter the
506
+ headings by their level. We then rendered the subsection headings as run-ins. We
507
+ also automatically add a period to the end of the subsection headings.
508
+
509
+ Let's review the conference's style guide:
510
+ - The font should be an 11pt serif font ✓
511
+ - The title should be in 17pt and bold ✓
512
+ - The paper contains a single-column abstract and two-column main text ✓
513
+ - The abstract should be centered ✓
514
+ - The main text should be justified ✓
515
+ - First level section headings should be centered, rendered in small caps and in
516
+ 13pt ✓
517
+ - Second level headings are run-ins, italicized and have the same size as the
518
+ body text ✓
519
+ - Finally, the pages should be US letter sized, numbered in the center and the
520
+ top right corner of each page should contain the title of the paper ✓
521
+
522
+ We are now in compliance with all of these styles and can submit the paper to
523
+ the conference! The finished paper looks like this:
524
+
525
+ <img
526
+ src="3-advanced-paper.png"
527
+ alt="The finished paper"
528
+ style="box-shadow: 0 4px 12px rgb(89 85 101 / 20%); width: 500px; max-width: 100%; display: block; margin: 24px auto;"
529
+ >
530
+
531
+ ## Review
532
+ You have now learned how to create headers and footers, how to use functions and
533
+ scopes to locally override styles, how to create more complex layouts with the
534
+ [`grid`] function and how to write show rules for individual functions, and the
535
+ whole document. You also learned how to use the
536
+ [`where` selector]($styling/#show-rules) to filter the headings by their level.
537
+
538
+ The paper was a great success! You've met a lot of like-minded researchers at
539
+ the conference and are planning a project which you hope to publish at the same
540
+ venue next year. You'll need to write a new paper using the same style guide
541
+ though, so maybe now you want to create a time-saving template for you and your
542
+ team?
543
+
544
+ In the next section, we will learn how to create templates that can be reused in
545
+ multiple documents. This is a more advanced topic, so feel free to come back
546
+ to it later if you don't feel up to it right now.
sources/docs/tutorial/4-template.md ADDED
@@ -0,0 +1,406 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ description: Typst's tutorial.
3
+ ---
4
+
5
+ # Making a Template
6
+ In the previous three chapters of this tutorial, you have learned how to write a
7
+ document in Typst, apply basic styles, and customize its appearance in-depth to
8
+ comply with a publisher's style guide. Because the paper you wrote in the
9
+ previous chapter was a tremendous success, you have been asked to write a
10
+ follow-up article for the same conference. This time, you want to take the style
11
+ you created in the previous chapter and turn it into a reusable template. In
12
+ this chapter you will learn how to create a template that you and your team can
13
+ use with just one show rule. Let's get started!
14
+
15
+ ## A toy template { #toy-template }
16
+ In Typst, templates are functions in which you can wrap your whole document. To
17
+ learn how to do that, let's first review how to write your very own functions.
18
+ They can do anything you want them to, so why not go a bit crazy?
19
+
20
+ ```example
21
+ #let amazed(term) = box[✨ #term ✨]
22
+
23
+ You are #amazed[beautiful]!
24
+ ```
25
+
26
+ This function takes a single argument, `term`, and returns a content block with
27
+ the `term` surrounded by sparkles. We also put the whole thing in a box so that
28
+ the term we are amazed by cannot be separated from its sparkles by a line break.
29
+
30
+ Many functions that come with Typst have optional named parameters. Our
31
+ functions can also have them. Let's add a parameter to our function that lets us
32
+ choose the color of the text. We need to provide a default color in case the
33
+ parameter isn't given.
34
+
35
+ ```example
36
+ #let amazed(term, color: blue) = {
37
+ text(color, box[✨ #term ✨])
38
+ }
39
+
40
+ You are #amazed[beautiful]!
41
+ I am #amazed(color: purple)[amazed]!
42
+ ```
43
+
44
+ Templates now work by wrapping our whole document in a custom function like
45
+ `amazed`. But wrapping a whole document in a giant function call would be
46
+ cumbersome! Instead, we can use an "everything" show rule to achieve the same
47
+ with cleaner code. To write such a show rule, put a colon directly after the
48
+ show keyword and then provide a function. This function is given the rest of the
49
+ document as a parameter. The function can then do anything with this content.
50
+ Since the `amazed` function can be called with a single content argument, we can
51
+ just pass it by name to the show rule. Let's try it:
52
+
53
+ ```example
54
+ >>> #let amazed(term, color: blue) = {
55
+ >>> text(color, box[✨ #term ✨])
56
+ >>> }
57
+ #show: amazed
58
+ I choose to focus on the good
59
+ in my life and let go of any
60
+ negative thoughts or beliefs.
61
+ In fact, I am amazing!
62
+ ```
63
+
64
+ Our whole document will now be passed to the `amazed` function, as if we wrapped
65
+ it around it. Of course, this is not especially useful with this particular
66
+ function, but when combined with set rules and named arguments, it can be very
67
+ powerful.
68
+
69
+ ## Embedding set and show rules { #set-and-show-rules }
70
+ To apply some set and show rules to our template, we can use `set` and `show`
71
+ within a content block in our function and then insert the document into
72
+ that content block.
73
+
74
+ ```example
75
+ #let template(doc) = [
76
+ #set text(font: "Inria Serif")
77
+ #show "something cool": [Typst]
78
+ #doc
79
+ ]
80
+
81
+ #show: template
82
+ I am learning something cool today.
83
+ It's going great so far!
84
+ ```
85
+
86
+ Just like we already discovered in the previous chapter, set rules will apply to
87
+ everything within their content block. Since the everything show rule passes our
88
+ whole document to the `template` function, the text set rule and string show
89
+ rule in our template will apply to the whole document. Let's use this knowledge
90
+ to create a template that reproduces the body style of the paper we wrote in the
91
+ previous chapter.
92
+
93
+ ```example
94
+ #let conf(title, doc) = {
95
+ set page(
96
+ paper: "us-letter",
97
+ >>> margin: auto,
98
+ header: align(
99
+ right + horizon,
100
+ title
101
+ ),
102
+ columns: 2,
103
+ <<< ...
104
+ )
105
+ set par(justify: true)
106
+ set text(
107
+ font: "Libertinus Serif",
108
+ size: 11pt,
109
+ )
110
+
111
+ // Heading show rules.
112
+ <<< ...
113
+ >>> show heading.where(
114
+ >>> level: 1
115
+ >>> ): it => block(
116
+ >>> align(center,
117
+ >>> text(
118
+ >>> 13pt,
119
+ >>> weight: "regular",
120
+ >>> smallcaps(it.body),
121
+ >>> )
122
+ >>> ),
123
+ >>> )
124
+ >>> show heading.where(
125
+ >>> level: 2
126
+ >>> ): it => box(
127
+ >>> text(
128
+ >>> 11pt,
129
+ >>> weight: "regular",
130
+ >>> style: "italic",
131
+ >>> it.body + [.],
132
+ >>> )
133
+ >>> )
134
+
135
+ doc
136
+ }
137
+
138
+ #show: doc => conf(
139
+ [Paper title],
140
+ doc,
141
+ )
142
+
143
+ = Introduction
144
+ #lorem(90)
145
+
146
+ <<< ...
147
+ >>> == Motivation
148
+ >>> #lorem(140)
149
+ >>>
150
+ >>> == Problem Statement
151
+ >>> #lorem(50)
152
+ >>>
153
+ >>> = Related Work
154
+ >>> #lorem(200)
155
+ ```
156
+
157
+ We copy-pasted most of that code from the previous chapter. The two differences
158
+ are this:
159
+
160
+ 1. We wrapped everything in the function `conf` using an everything show rule.
161
+ The function applies a few set and show rules and echoes the content it has
162
+ been passed at the end.
163
+
164
+ 2. Moreover, we used a curly-braced code block instead of a content block. This
165
+ way, we don't need to prefix all set rules and function calls with a `#`. In
166
+ exchange, we cannot write markup directly in the code block anymore.
167
+
168
+ Also note where the title comes from: We previously had it inside of a variable.
169
+ Now, we are receiving it as the first parameter of the template function. To do
170
+ so, we passed a closure (that's a function without a name that is used right
171
+ away) to the everything show rule. We did that because the `conf` function
172
+ expects two positional arguments, the title and the body, but the show rule will
173
+ only pass the body. Therefore, we add a new function definition that allows us
174
+ to set a paper title and use the single parameter from the show rule.
175
+
176
+ ## Templates with named arguments { #named-arguments }
177
+ Our paper in the previous chapter had a title and an author list. Let's add
178
+ these things to our template. In addition to the title, we want our template to
179
+ accept a list of authors with their affiliations and the paper's abstract. To
180
+ keep things readable, we'll add those as named arguments. In the end, we want it
181
+ to work like this:
182
+
183
+ ```typ
184
+ #show: doc => conf(
185
+ title: [Towards Improved Modelling],
186
+ authors: (
187
+ (
188
+ name: "Theresa Tungsten",
189
+ affiliation: "Artos Institute",
190
+ email: "[email protected]",
191
+ ),
192
+ (
193
+ name: "Eugene Deklan",
194
+ affiliation: "Honduras State",
195
+ email: "[email protected]",
196
+ ),
197
+ ),
198
+ abstract: lorem(80),
199
+ doc,
200
+ )
201
+
202
+ ...
203
+ ```
204
+
205
+ Let's build this new template function. First, we add a default value to the
206
+ `title` argument. This way, we can call the template without specifying a title.
207
+ We also add the named `authors` and `abstract` parameters with empty defaults.
208
+ Next, we copy the code that generates title, abstract and authors from the
209
+ previous chapter into the template, replacing the fixed details with the
210
+ parameters.
211
+
212
+ The new `authors` parameter expects an [array] of [dictionaries]($dictionary)
213
+ with the keys `name`, `affiliation` and `email`. Because we can have an
214
+ arbitrary number of authors, we dynamically determine if we need one, two or
215
+ three columns for the author list. First, we determine the number of authors
216
+ using the [`.len()`]($array.len) method on the `authors` array. Then, we set the
217
+ number of columns as the minimum of this count and three, so that we never
218
+ create more than three columns. If there are more than three authors, a new row
219
+ will be inserted instead. For this purpose, we have also added a `row-gutter`
220
+ parameter to the `grid` function. Otherwise, the rows would be too close
221
+ together. To extract the details about the authors from the dictionary, we use
222
+ the [field access syntax]($scripting/#fields).
223
+
224
+ We still have to provide an argument to the grid for each author: Here is where
225
+ the array's [`map` method]($array.map) comes in handy. It takes a function as an
226
+ argument that gets called with each item of the array. We pass it a function
227
+ that formats the details for each author and returns a new array containing
228
+ content values. We've now got one array of values that we'd like to use as
229
+ multiple arguments for the grid. We can do that by using the
230
+ [`spread` operator]($arguments). It takes an array and applies each of its items
231
+ as a separate argument to the function.
232
+
233
+ The resulting template function looks like this:
234
+
235
+ ```typ
236
+ #let conf(
237
+ title: none,
238
+ authors: (),
239
+ abstract: [],
240
+ doc,
241
+ ) = {
242
+ // Set and show rules from before.
243
+ >>> #set page(columns: 2)
244
+ <<< ...
245
+
246
+ set align(center)
247
+ text(17pt, title)
248
+
249
+ let count = authors.len()
250
+ let ncols = calc.min(count, 3)
251
+ grid(
252
+ columns: (1fr,) * ncols,
253
+ row-gutter: 24pt,
254
+ ..authors.map(author => [
255
+ #author.name \
256
+ #author.affiliation \
257
+ #link("mailto:" + author.email)
258
+ ]),
259
+ )
260
+
261
+ par(justify: false)[
262
+ *Abstract* \
263
+ #abstract
264
+ ]
265
+
266
+ set align(left)
267
+ doc
268
+ }
269
+ ```
270
+
271
+ ## A separate file { #separate-file }
272
+ Most of the time, a template is specified in a different file and then imported
273
+ into the document. This way, the main file you write in is kept clutter free and
274
+ your template is easily reused. Create a new text file in the file panel by
275
+ clicking the plus button and name it `conf.typ`. Move the `conf` function
276
+ definition inside of that new file. Now you can access it from your main file by
277
+ adding an import before the show rule. Specify the path of the file between the
278
+ `{import}` keyword and a colon, then name the function that you want to import.
279
+
280
+ Another thing that you can do to make applying templates just a bit more elegant
281
+ is to use the [`.with`]($function.with) method on functions to pre-populate all
282
+ the named arguments. This way, you can avoid spelling out a closure and
283
+ appending the content argument at the bottom of your template list. Templates on
284
+ [Typst Universe]($universe) are designed to work with this style of function
285
+ call.
286
+
287
+ ```example:single
288
+ >>> #let conf(
289
+ >>> title: none,
290
+ >>> authors: (),
291
+ >>> abstract: [],
292
+ >>> doc,
293
+ >>> ) = {
294
+ >>> set text(font: "Libertinus Serif", 11pt)
295
+ >>> set par(justify: true)
296
+ >>> set page(
297
+ >>> "us-letter",
298
+ >>> margin: auto,
299
+ >>> header: align(
300
+ >>> right + horizon,
301
+ >>> title
302
+ >>> ),
303
+ >>> numbering: "1",
304
+ >>> columns: 2,
305
+ >>> )
306
+ >>>
307
+ >>> show heading.where(
308
+ >>> level: 1
309
+ >>> ): it => block(
310
+ >>> align(center,
311
+ >>> text(
312
+ >>> 13pt,
313
+ >>> weight: "regular",
314
+ >>> smallcaps(it.body),
315
+ >>> )
316
+ >>> ),
317
+ >>> )
318
+ >>> show heading.where(
319
+ >>> level: 2
320
+ >>> ): it => box(
321
+ >>> text(
322
+ >>> 11pt,
323
+ >>> weight: "regular",
324
+ >>> style: "italic",
325
+ >>> it.body + [.],
326
+ >>> )
327
+ >>> )
328
+ >>>
329
+ >>> place(
330
+ >>> top,
331
+ >>> float: true,
332
+ >>> scope: "parent",
333
+ >>> clearance: 2em,
334
+ >>> {
335
+ >>> set align(center)
336
+ >>> text(17pt, title)
337
+ >>> let count = calc.min(authors.len(), 3)
338
+ >>> grid(
339
+ >>> columns: (1fr,) * count,
340
+ >>> row-gutter: 24pt,
341
+ >>> ..authors.map(author => [
342
+ >>> #author.name \
343
+ >>> #author.affiliation \
344
+ >>> #link("mailto:" + author.email)
345
+ >>> ]),
346
+ >>> )
347
+ >>> par(justify: false)[
348
+ >>> *Abstract* \
349
+ >>> #abstract
350
+ >>> ]
351
+ >>> },
352
+ >>> )
353
+ >>> doc
354
+ >>>}
355
+ <<< #import "conf.typ": conf
356
+ #show: conf.with(
357
+ title: [
358
+ Towards Improved Modelling
359
+ ],
360
+ authors: (
361
+ (
362
+ name: "Theresa Tungsten",
363
+ affiliation: "Artos Institute",
364
+ email: "[email protected]",
365
+ ),
366
+ (
367
+ name: "Eugene Deklan",
368
+ affiliation: "Honduras State",
369
+ email: "[email protected]",
370
+ ),
371
+ ),
372
+ abstract: lorem(80),
373
+ )
374
+
375
+ = Introduction
376
+ #lorem(90)
377
+
378
+ == Motivation
379
+ #lorem(140)
380
+
381
+ == Problem Statement
382
+ #lorem(50)
383
+
384
+ = Related Work
385
+ #lorem(200)
386
+ ```
387
+
388
+ We have now converted the conference paper into a reusable template for that
389
+ conference! Why not share it in the [Forum](https://forum.typst.app/) or on
390
+ [Typst's Discord server](https://discord.gg/2uDybryKPe) so that others can use
391
+ it too?
392
+
393
+ ## Review
394
+ Congratulations, you have completed Typst's Tutorial! In this section, you have
395
+ learned how to define your own functions and how to create and apply templates
396
+ that define reusable document styles. You've made it far and learned a lot. You
397
+ can now use Typst to write your own documents and share them with others.
398
+
399
+ We are still a super young project and are looking for feedback. If you have any
400
+ questions, suggestions or you found a bug, please let us know
401
+ in the [Forum](https://forum.typst.app/),
402
+ on our [Discord server](https://discord.gg/2uDybryKPe),
403
+ on [GitHub](https://github.com/typst/typst/),
404
+ or via the web app's feedback form (always available in the Help menu).
405
+
406
+ So what are you waiting for? [Sign up](https://typst.app) and write something!
sources/docs/tutorial/welcome.md ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ description: Typst's tutorial.
3
+ ---
4
+
5
+ # Tutorial
6
+ Welcome to Typst's tutorial! In this tutorial, you will learn how to write and
7
+ format documents in Typst. We will start with everyday tasks and gradually
8
+ introduce more advanced features. This tutorial does not assume prior knowledge
9
+ of Typst, other markup languages, or programming. We do assume that you know how
10
+ to edit a text file.
11
+
12
+ The best way to start is to sign up to the Typst app for free and follow along
13
+ with the steps below. The app gives you instant preview, syntax highlighting and
14
+ helpful autocompletions. Alternatively, you can follow along in your local text
15
+ editor with the [open-source CLI](https://github.com/typst/typst).
16
+
17
+ ## When to use Typst { #when-typst }
18
+ Before we get started, let's check what Typst is and when to use it. Typst is a
19
+ markup language for typesetting documents. It is designed to be easy to learn,
20
+ fast, and versatile. Typst takes text files with markup in them and outputs
21
+ PDFs.
22
+
23
+ Typst is a good choice for writing any long form text such as essays, articles,
24
+ scientific papers, books, reports, and homework assignments. Moreover, Typst is
25
+ a great fit for any documents containing mathematical notation, such as papers
26
+ in the math, physics, and engineering fields. Finally, due to its strong styling
27
+ and automation features, it is an excellent choice for any set of documents that
28
+ share a common style, such as a book series.
29
+
30
+ ## What you will learn { #learnings }
31
+ This tutorial has four chapters. Each chapter builds on the previous one. Here
32
+ is what you will learn in each of them:
33
+
34
+ 1. [Writing in Typst:]($tutorial/writing-in-typst) Learn how to write text and
35
+ insert images, equations, and other elements.
36
+ 2. [Formatting:]($tutorial/formatting) Learn how to adjust the formatting
37
+ of your document, including font size, heading styles, and more.
38
+ 3. [Advanced Styling:]($tutorial/advanced-styling) Create a complex page
39
+ layout for a scientific paper with typographic features such as an author
40
+ list and run-in headings.
41
+ 4. [Making a Template:]($tutorial/making-a-template) Build a reusable template
42
+ from the paper you created in the previous chapter.
43
+
44
+ We hope you'll enjoy Typst!
sources/tests/README.md ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Tests
2
+
3
+ ## Directory structure
4
+ Top level directory structure:
5
+ - `src`: Testing code.
6
+ - `suite`: Input files. Mostly organized in parallel to the code. Each file can
7
+ contain multiple tests, each of which is a section of Typst code
8
+ following `--- {name} ---`.
9
+ - `ref`: References which the output is compared with to determine whether a
10
+ test passed or failed.
11
+ - `store`: Store for PNG, PDF, and SVG output files produced by the tests.
12
+
13
+ ## Running the tests
14
+ Running all tests (including unit tests):
15
+ ```bash
16
+ cargo test --workspace
17
+ ```
18
+
19
+ Running just the integration tests (the tests in this directory):
20
+ ```bash
21
+ cargo test --workspace --test tests
22
+ ```
23
+
24
+ You may want to [make yourself an alias](#making-an-alias) `testit` so that you can
25
+ write shorter commands. In the examples below, we will use this alias.
26
+
27
+ Running all tests with the given name pattern. You can use
28
+ [regular expression](https://docs.rs/regex/latest/regex/)s.
29
+ ```bash
30
+ testit math # The name has "math" anywhere
31
+ testit math page # The name has "math" or "page" anywhere
32
+ testit "^math" "^page" # The name begins with "math" or "page"
33
+ testit "^(math|page)" # Same as above.
34
+ ```
35
+
36
+ Running all tests discovered under given paths:
37
+ ```bash
38
+ testit -p tests/suite/math/attach.typ
39
+ testit -p tests/suite/model -p tests/suite/text
40
+ ```
41
+
42
+ Running tests that begin with `issue` under a given path:
43
+ ```bash
44
+ testit "^issue" -p tests/suite/model
45
+ ```
46
+
47
+ Running a test with the exact test name `math-attach-mixed`.
48
+ ```bash
49
+ testit --exact math-attach-mixed
50
+ ```
51
+
52
+ You may find more options in the help message:
53
+ ```bash
54
+ testit --help
55
+ ```
56
+
57
+ To make the integration tests go faster they don't generate PDFs or SVGs by
58
+ default. Pass the `--pdf` or `--svg` flag to generate those. Mind that PDFs and
59
+ SVGs are **not** tested automatically at the moment, so you should always check
60
+ the output manually when making changes.
61
+ ```bash
62
+ testit --pdf
63
+ ```
64
+
65
+ ## Writing tests
66
+ The syntax for an individual test is `--- {name} {attr}* ---` followed by some
67
+ Typst code that should be tested. The name must be globally unique in the test
68
+ suite, so that tests can be easily migrated across files. A test name can be
69
+ followed by space-separated attributes. For instance, `--- my-test html ---`
70
+ adds the `html` modifier to `my-test`, instructing the test runner to also
71
+ test HTML output. The following attributes are currently defined:
72
+
73
+ - `render`: Tests paged output against a reference image (the default, only
74
+ needs to be specified when `html` is also specified to enable both at the
75
+ same)
76
+ - `html`: Tests HTML output against a reference HTML file. Disables the `render`
77
+ default.
78
+ - `large`: Permits a reference image size exceeding 20 KiB. Should be used
79
+ sparingly.
80
+
81
+ There are, broadly speaking, three kinds of tests:
82
+
83
+ - Tests that just ensure that the code runs successfully: Those typically make
84
+ use of `test` or `assert.eq` (both are very similar, `test` is just shorter)
85
+ to ensure certain properties hold when executing the Typst code.
86
+
87
+ - Tests that ensure the code emits particular diagnostic messages: Those have
88
+ inline annotations like `// Error: 2-7 thing was wrong`. An annotation can
89
+ start with either "Error", "Warning", or "Hint". The range designates the
90
+ code span the diagnostic message refers to in the first non-comment line
91
+ below. If the code span is in a line further below, you can write ranges
92
+ like `3:2-3:7` to indicate the 2-7 column in the 3rd non-comment line.
93
+
94
+ - Tests that ensure certain output is produced:
95
+
96
+ - Visual output: By default, the compiler produces paged output, renders it
97
+ with the `typst-render` crate, and compares it against a reference image
98
+ stored in the repository. The test runner automatically detects whether a
99
+ test has visual output and requires a reference image in this case.
100
+
101
+ To prevent bloat, it is important that the test images are kept as small as
102
+ possible. To that effect, the test runner enforces a maximum size of 20 KiB.
103
+ If you're updating a test and hit `reference output size exceeds`, see the
104
+ section on "Updating reference images" below. If truly necessary, the size
105
+ limit can be lifted by adding a `large` attribute after the test name, but
106
+ this should be the case very rarely.
107
+
108
+ - HTML output: When a test has the `html` attribute, the compiler produces
109
+ HTML output and compares it against a reference file stored in the
110
+ repository. By default, this enables testing of paged output, but you can
111
+ test both at once by passing both `render` and `html` as attributes.
112
+
113
+ If you have the choice between writing a test using assertions or using
114
+ reference images, prefer assertions. This makes the test easier to understand
115
+ in isolation and prevents bloat due to images.
116
+
117
+ ## Updating reference images
118
+ If you created a new test or fixed a bug in an existing test, you may need to
119
+ update the reference output used for comparison. For this, you can use the
120
+ `--update` flag:
121
+ ```bash
122
+ testit --exact my-test-name --update
123
+ ```
124
+
125
+ For visual tests, this will generally generate compressed reference images (to
126
+ remain within the size limit).
127
+
128
+ If you use the VS Code test helper extension (see the `tools` folder), you can
129
+ alternatively use the save button to update the reference output.
130
+
131
+ ## Making an alias
132
+ If you want to have a quicker way to run the tests, consider adding a shortcut
133
+ to your shell profile so that you can simply write something like:
134
+ ```bash
135
+ testit --exact my-test-name
136
+ ```
137
+
138
+ ### Bash
139
+ Open your Bash configuration by executing `nano ~/.bashrc`.
140
+ ```bash
141
+ alias testit="cargo test --workspace --test tests --"
142
+ ```
143
+
144
+ ### PowerShell
145
+ Open your PowerShell profile by executing `notepad $profile`.
146
+ ```ps
147
+ function testit {
148
+ cargo test --workspace --test tests -- $args
149
+ }
150
+ ```