Import documentation

Co-Authored-By: Martin Haug <mhaug@live.de>
This commit is contained in:
Laurenz 2023-02-06 11:50:03 +01:00
parent 2e87dcdbe0
commit 0bb0f1c98f
32 changed files with 3435 additions and 0 deletions

26
assets/files/cylinder.svg Normal file
View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="uuid-687246ef-c282-44c1-b632-089ccaaded98" data-name="Ebene 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 32 32">
<defs>
<style>
.uuid-b242de72-c4d3-4028-9f50-e25a891b77c6 {
fill: #a3a7b7;
}
.uuid-b242de72-c4d3-4028-9f50-e25a891b77c6, .uuid-0c7f9eba-fb5c-4f1c-9149-e06b72f4e892 {
stroke: #000;
stroke-miterlimit: 10;
stroke-width: .5px;
}
.uuid-0c7f9eba-fb5c-4f1c-9149-e06b72f4e892 {
fill: url(#uuid-216aa58e-14ce-460d-a686-ba949a4e197d);
}
</style>
<linearGradient id="uuid-216aa58e-14ce-460d-a686-ba949a4e197d" data-name="Unbenannter Verlauf 15" x1="8.321" y1="16.001" x2="23.679" y2="16.001" gradientUnits="userSpaceOnUse">
<stop offset=".699" stop-color="#fff"/>
<stop offset="1" stop-color="#caccd6"/>
</linearGradient>
</defs>
<path class="uuid-0c7f9eba-fb5c-4f1c-9149-e06b72f4e892" d="m23.679,7.031v17.941c0,1.407-3.435,2.56-7.679,2.56s-7.679-1.152-7.679-2.56V7.031c0-1.418,3.435-2.56,7.679-2.56s7.679,1.141,7.679,2.56Z"/>
<ellipse class="uuid-b242de72-c4d3-4028-9f50-e25a891b77c6" cx="16" cy="7.029" rx="7.681" ry="2.56"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

3
assets/files/data.csv Normal file
View File

@ -0,0 +1,3 @@
0..2,small
3..5,medium
6..,big
1 0..2 small
2 3..5 medium
3 6.. big

10
assets/files/data.html Normal file
View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Example document</title>
</head>
<body>
<h1>Hello, world!</h1>
</body>
</html>

24
assets/files/docs.svg Normal file
View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;filter:url(#Adobe_OpacityMaskFilter);}
.st1{mask:url(#path-1-inside-1_1588_6259_00000173119138975477980210000007733088185808470454_);}
.st2{fill:none;stroke:#000000;stroke-width:1.25;}
.st3{fill:none;stroke:#000000;}
</style>
<defs>
<filter id="Adobe_OpacityMaskFilter" filterUnits="userSpaceOnUse" x="-1.6" y="-2" width="18.5" height="20">
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
</filter>
</defs>
<mask maskUnits="userSpaceOnUse" x="-1.6" y="-2" width="18.5" height="20" id="path-1-inside-1_1588_6259_00000173119138975477980210000007733088185808470454_">
<path class="st0" d="M0.9,3.3c0-1.8,1.5-3.3,3.3-3.3h10.7v15.9H4.1c-1.8,0-3.3-1.5-3.3-3.3V3.3z"/>
</mask>
<path class="st1" d="M-1.6,3.3C-1.6,0.4,0.8-2,3.7-2h13.2l-4.1,4.1H4.1c-0.5,0-0.8,0.5-0.8,1.2H-1.6z M16.9,18H3.7
c-2.9,0-5.3-2.4-5.3-5.3h4.9c0,0.7,0.4,1.2,0.8,1.2h8.7L16.9,18z M3.7,18c-2.9,0-5.3-2.4-5.3-5.3V3.3C-1.6,0.4,0.8-2,3.7-2l0.4,4.1
c-0.5,0-0.8,0.5-0.8,1.2v9.4c0,0.7,0.4,1.2,0.8,1.2L3.7,18z M16.9-2v20l-4.1-4.1V2.1L16.9-2z"/>
<line class="st2" x1="5" y1="5.3" x2="9.9" y2="5.3"/>
<line class="st3" x1="5" y1="8.8" x2="7.8" y2="8.8"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

22
assets/files/example.xml Normal file
View File

@ -0,0 +1,22 @@
<?xml version="1.0"?>
<news>
<article>
<title>2022 Budget approved</title>
<author>John Doe</author>
<date>2022-12-19</date>
<content>
<p>The 2022 budget has been approved by the Senate.</p>
<p>The budget is $1.2 trillion.</p>
<p>It is expected to be signed by the President next week.</p>
</content>
</article>
<article>
<title>Tigers win the World Series</title>
<author>Jane Doe</author>
<date>2022-12-20</date>
<content>
<p>The Tigers have won the World Series.</p>
<p>They beat the Giants 4 to 3.</p>
</content>
</article>
</news>

BIN
assets/files/glacier.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

5
assets/files/logo.svg Normal file
View File

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.90387 2.23401C2.91909 4.55853 3.351 8.1331 5.64329 10.2912C8.24577 12.7414 11.8071 12.7414 14.6835 12.7414" stroke="#001666" stroke-width="1.25"/>
<path d="M1.4903 8.35903C1.50283 10.6836 1.4903 14.3902 4.49755 14.3902C8.65229 14.3902 6.67331 7.41699 14.8248 7.41699" stroke="#001666" stroke-width="1.25"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.5745 10.7414L12.0165 11.1834L13.5745 12.7414L12.0165 14.2995L11.5745 14.7414L12.4584 15.6253L12.9003 15.1834L14.9003 13.1834L15.3423 12.7414L14.9003 12.2995L12.9003 10.2995L12.4584 9.85754L11.5745 10.7414Z" fill="#001666"/>
</svg>

After

Width:  |  Height:  |  Size: 699 B

BIN
assets/files/molecular.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

5
assets/files/monday.json Normal file
View File

@ -0,0 +1,5 @@
{
"temperature": 18.5,
"unit": "C",
"weather": "sunny"
}

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="uuid-22146e6c-a168-4821-bd5a-dea57c5059e7" data-name="Ebene 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<defs>
<style>
.uuid-2456d980-f63b-4fa8-8dc4-6bc7ec43cb9d {
fill: #a3a7b7;
}
.uuid-603863eb-1f17-44fc-809f-235048ac00d5 {
fill: none;
stroke: #000;
stroke-miterlimit: 10;
stroke-width: .5px;
}
</style>
</defs>
<polygon class="uuid-2456d980-f63b-4fa8-8dc4-6bc7ec43cb9d" points="29.689 20.18 15.999 26.07 15.999 5.93 29.689 20.18"/>
<polygon class="uuid-603863eb-1f17-44fc-809f-235048ac00d5" points="29.686 20.177 15.999 26.067 2.311 20.177 15.999 5.933 29.686 20.177"/>
<line class="uuid-603863eb-1f17-44fc-809f-235048ac00d5" x1="15.999" y1="5.933" x2="15.999" y2="26.067"/>
</svg>

After

Width:  |  Height:  |  Size: 830 B

View File

@ -0,0 +1,5 @@
{
"temperature": 14.5,
"unit": "C",
"weather": "windy"
}

BIN
assets/files/typing.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 600 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 753 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 790 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 655 KiB

View File

@ -0,0 +1,111 @@
---
description: |
Learn what has changed in the latest Typst releases and move your documents
forward.
---
# Changelog
## February 2, 2023
- Merged text and math symbols, renamed a few symbols
(including `infty` to `infinity` with the alias `oo`)
- Fixed missing italic mappings
- Math italics correction is now applied properly
- Parentheses now scale in `[$zeta(x/2)$]`
- Fixed placement of large root index
- Fixed spacing in `[$abs(-x)$]`
- Fixed inconsistency between text and identifiers in math
- Accents are now ignored when positioning superscripts
- Fixed vertical alignment in matrices
- Fixed `text` set rule in `raw` show rule
- Heading and list markers now parse consistently
- Allow arbitrary math directly in content
## January 30, 2023
[Go to the announcement blog post.](https://typst.app/blog/2023/january-update)
- New expression syntax in markup/math
- Blocks cannot be directly embedded in markup anymore
- Like other expressions, they now require a leading hashtag
- More expressions available with hashtag, including literals
(`[#"string"]`) as well as field access and method call
without space: `[#emoji.face]`
- New import syntax
- `[#import "module.typ"]` creates binding named `module`
- `[#import "module.typ": a, b]` or `[#import "module.typ": *]` to import items
- `[#import emoji: face, turtle]` to import from already bound module
- New symbol handling
- Removed symbol notation
- Symbols are now in modules: `{sym}`, `{emoji}`, and `{math}`
- Math module also reexports all of `{sym}`
- Modified through field access, still order-independent
- Unknown modifiers are not allowed anymore
- Support for custom symbol definitions with `symbol` function
- Symbols now listed in documentation
- New `{math}` module
- Contains all math-related functions
- Variables and function calls directly in math (without hashtag) access this
module instead of the global scope, but can also access local variables
- Can be explicitly used in code, e.g. `[#set math.vec(delim: "[")]`
- Delimiter matching in math
- Any opening delimiters matches any closing one
- When matched, they automatically scale
- To prevent scaling, escape them
- To forcibly match two delimiters, use `lr` function
- Line breaks may occur between matched delimiters
- Delimiters may also be unbalanced
- You can also use the `lr` function to scale the brackets
(or just one bracket) to a specific size manually
- Multi-line math with alignment
- The `\` character inserts a line break
- The `&` character defines an alignment point
- Alignment points also work for underbraces, vectors, cases, and matrices
- Multiple alignment points are supported
- More capable math function calls
- Function calls directly in math can now take code expressions with hashtag
- They can now also take named arguments
- Within math function calls, semicolons turn preceding arguments to arrays to
support matrices: `[$mat(1, 2; 3, 4)$]`
- Arbitrary content in math
- Text, images, and other arbitrary content can now be embedded in math
- Math now also supports font fallback to support e.g. CJK and emoji
- More math features
- New text operators: `op` function, `lim`, `max`, etc.
- New matrix function: `mat`
- New n-ary roots with `root` function: `[$root(3, x)$]`
- New under- and overbraces, -brackets, and -lines
- New `abs` and `norm` functions
- New shorthands: `[|`, `|]`, and `||`
- New `attach` function, overridable attachments with `script` and `limit`
- Manual spacing in math, with `h`, `thin`, `med`, `thick` and `quad`
- Symbols and other content may now be used like a function, e.g. `[$zeta(x)$]`
- Added Fira Math font, removed Noto Sans Math font
- Support for alternative math fonts through
`[#show math.formula: set text("Fira Math")]`
- More library improvements
- New `calc` module, `abs`, `min`, `max`, `even`, `odd` and `mod` moved there
- New `message` argument on `{assert}` function
- The `pairs` method on dictionaries now returns an array of length-2 arrays
instead of taking a closure
- The method call `{dict.at("key")}` now always fails if `"key"` doesn't exist
Previously, it was allowed in assignments. Alternatives are `{dict.key = x}`
and `{dict.insert("key", x)}`.
- Smarter editor functionality
- Autocompletion for local variables
- Autocompletion for methods available on a value
- Autocompletion for symbols and modules
- Autocompletion for imports
- Hover over an identifier to see its value(s)
- Further editor improvements
- New Font menu with previews
- Single projects may now be shared with share links
- New dashboard experience if projects are shared with you
- Keyboard Shortcuts are now listed in the menus and there are more of them
- New Offline indicator
- Tooltips for all buttons
- Improved account protection
- Moved Status indicator into the error list button
- Fixes
- Multiple bug fixes for incremental parser
- Fixed closure parameter capturing
- Fixed tons of math bugs
- Bugfixes for performance, file management, editing reliability
- Added redirection to the page originally navigated to after signin

View File

@ -0,0 +1,69 @@
---
description: |
Join the Typst community, get help from other users and have a say in the
future of Typst.
---
# Community
Hey and welcome to the Community page! We're so glad you're here. Typst is
developed by a super early-stage startup and is still in its infancy, but it
would be pointless without people like you who are interested in it.
We would love to not only hear from you but to also provide spaces where you can
discuss any topic around Typst, typesetting, writing, the sciences, and
typography with other likeminded people.
For the time being, **we would like to invite you to our [Discord
server](https://discord.gg/2uDybryKPe).** The server is open for everyone, even
if you do not have preview access to Typst yet. Of course, you are also very
welcome to connect with us on social media
([Twitter](https://twitter.com/typstapp/),
[Instagram](https://instagram.com/typstapp/),
[LinkedIn](https://linkedin.com/company/typst), and
[Github](https://github.com/typst)).
## What to share?
For our community, we want to foster versatility and inclusivity.
You are welcome to post about any topic that you think would interest other
community members, but if you need a little inspiration, here are a few ideas:
- Share and discuss your thoughts and ideas for new features or improvements
you'd like to see in Typst
- Showcase documents you've created with Typst, or share any unique or creative
ways you've used the platform
- Share importable files or templates that you use to style your documents
- Alert us of bugs you encounter while using Typst
## Infrastructure test
We will start a small-scale test of our product and infrastructure with a few
people from our wait list, starting on December 26th, 2022. More wait list
members will be invited throughout the infrastructure test. Everyone who has
product access and is on our Discord server will receive access to a private
text and speech channel.
The Typst compiler is still under active development and breaking changes can
occur at any point. The compiler will remain closed source until Typst goes into
public beta. Currently, we plan to start our public beta and open source Typst
in March of 2023.
We will update the members of our Discord server and our social media followers
when new features become available in the preview. We'll also update you on the
development progress of large features, such as math typesetting. A development
tracker will become available on the documentation pages soon.
## Community Rules
We want to make our community a safe and inclusive space for everyone.
Therefore, we will not tolerate any sexual harassment, sexism, political
attacks, derogatory language or personal insults, racism, doxing, and other
inappropriate behavior. We pledge to remove members that are in violation of
these rules. [Contact us](https://typst.app/contact/) if you think another
community member acted inappropriately towards you. All complaints will be
reviewed and investigated promptly and fairly.
In addition, our [privacy policy](https://typst.app/privacy/) applies on all
community spaces operated by us, such as the Discord server. Please also note
that the terms of service and privacy policies of the respective services apply.
## See you soon!
Thanks again for learning more about Typst. We would be delighted to meet you on
our [Discord server](https://discord.gg/2uDybryKPe)!

View File

@ -0,0 +1,12 @@
---
description: |
Learn how to use Typst to compose documents faster. Get started with the
tutorial, or dive into the reference.
---
# Overview
Welcome to Typst's documentation! Typst is a new markup-based typesetting system for the sciences. It is designed to be an alternative both to advanced tools like LaTeX and simpler tools like Word and Google Docs. Typst's focus lies on the intersection of simplicity and power. We are building a highly capable tool that is at the same time easy to understand and use.
This documentation is split into two parts: A beginner-friendly tutorial that introduces Typst through a practical use case and a comprehensive reference that explains all of Typst's concepts and features.
We also invite you to join the community we're building around Typst. Typst is still a very young project, so your feedback is more than valuable.

View File

@ -0,0 +1,147 @@
types: |
To style your document, you need to work with values of different kinds: Lengths
specifying the size of your elements, colors for your text and shapes, and more.
Typst categorizes these into clearly defined _types_ and tells you where it
expects which type of value.
Apart from very basic types for numeric values and typical types known from
programming languages, Typst provides a special type for _content._ A value of
this type can hold anything that you can enter into your document: Text,
elements like headings and shapes, and style information.
In some places of Typst more specialized data types are used. Instead of listing
all of them here, they are explained where they are relevant.
basics: |
Basic structural elements of documents.
text: |
Style and transform your text.
The [text function]($func/text) is of particular interest.
math: |
Typst has special [syntax]($syntax/#math) and library functions
to typeset mathematical formulas. Math formulas can be displayed inline with
text or as separate blocks. They will be typeset into their own block if they
start and end with at least one space (e.g. `[$ x^2 $]`).
In math, single letters are always displayed as is. Multiple letters, however,
are interpreted as variables and functions. To display multiple letters
verbatim, you can place them into quotes and to access single letter
variables, you can use the
[hashtag syntax]($scripting/#expressions).
```example
$ A = pi r^2 $
$ "area" = pi dot "radius"^2 $
$ cal(A) :=
{ x in RR | x "is natural" } $
```
Math mode defines a wide selection of [symbols]($category/math/symbols) like
`pi`, `dot`, or `RR`. Many mathematical symbols are available in different
variants. You can select between different variants by applying
[modifiers]($type/symbol) to the symbol. Typst further recognizes a number of
shorthand sequences like `=>` that approximate a symbol. When such a shorthand
exists, the symbol's documentation lists it.
```example
$ x < y => x gt.eq.not y $
```
Formulas can also contain line breaks. Each line can contain one or multiple
_alignment points_ (`&`) which are then aligned.
```example
$ sum_(x=0)^n
&= 1 + ... + n \
&= (n(n+1)) / 2 $
```
Math mode supports special function calls without the hashtag prefix. In these
"math calls", the argument list works a little differently than in code:
- Within them, Typst is still in "math mode". Thus, you can write math directly
into them, but need to use hashtag syntax to pass code expressions (except
for strings, which are available in the math syntax).
- They support positional and named arguments, but don't support
trailing content blocks and argument spreading.
- They provide additional syntax for 2-dimensional argument lists. The
semicolon (`;`) merges preceding arguments separated by commas into an array
argument.
```example
$ frac(a^2, 2) $
$ vec(1, 2, delim: "[") $
$ mat(1, 2; 3, 4) $
$ lim_x =
op("lim", limits: #true)_x $
```
To write a verbatim comma or semicolon in a math call, escape it with a
backslash. The colon on the other hand is only recognized in a special way if
directly preceded by an identifier, so to display it verbatim in those cases,
you can just insert a space before it.
Functions calls preceded by a hashtag are normal code function calls and not
affected by these rules.
layout: |
Arrange elements on the page.
Combine layout functions to create complex and automatic layouts.
visualize: |
Draw and visualize data.
_Note:_ Functions for plotting and diagrams are not yet available. They will
be in the future.
meta: |
Modify and use document metadata.
Here, you can also find functions to work with other elements in the document,
such as labels and headings.
symbols: |
These two modules give names to symbols and emoji to make them easy to insert
with a normal keyboard. Alternatively, you can also always directly enter
Unicode symbols into your text and formulas. In addition to the symbols listed
below, math mode defines `dif` and `Dif`. These are not normal symbol values
because they also affect spacing and font style.
sym: |
Insert general symbols by name.
For example, `#sym.arrow` produces the → symbol. Within
[formulas]($category/math), these symbols can be used without the `#sym.`
prefix.
emoji: |
Insert emoji by name.
For example, `#emoji.face` produces the 😀 emoji. If you frequently use
certain emojis, you can also import them from the `emoji` module (`[#import
emoji: face]`) to use them without the `#emoji.` prefix.
foundations: |
Foundational functions.
calculate: |
Calculate with and process numeric values.
These functions are part of the `calc` module and not imported by default. In
addition to the functions listed below, the `calc` module also defines the
constants `pi`, `e`, `inf`, and `nan`.
construct: |
Construct and convert between values of different types.
data-loading: |
Load data from external files.
These functions help you with embedding data from experiments and APIs in your
documents.
utility: |
Useful utility functions.

View File

@ -0,0 +1,63 @@
- name: variants
title: Variants
functions: ["serif", "sans", "frak", "mono", "bb", "cal"]
description: |
Alternate typefaces within formulas.
These functions are distinct from the [`text`]($func/text) function because
math fonts contain multiple variants of each letter.
- name: styles
title: Styles
functions: ["upright", "italic", "bold"]
description: |
Alternate letterforms within formulas.
These functions are distinct from the [`text`]($func/text) function because
math fonts contain multiple variants of each letter.
- name: underover
title: Under/Over
functions: [
"underline",
"overline",
"underbrace",
"overbrace",
"underbracket",
"overbracket",
]
description: |
Delimiters above or below parts of a formula.
The braces and brackets further allow you to add an optional annotation
below or above themselves.
- name: roots
title: Roots
functions: ["root", "sqrt"]
description: Square and non-square roots.
- name: attach
title: Attach
functions: ["attach", "scripts", "limits"]
description: |
Subscript, superscripts, and limits.
The `attach` function backs the `[$a_b^c$]` syntax that adds top and bottom
attachments to a part of a formula. Attachments can be displayed either as
sub/superscripts, or limits. Typst automatically decides which is more
suitable depending on the base, but you can also control this manually with
the `scripts` and `limits` functions.
- name: lr
title: Left/Right
functions: ["lr", "abs", "norm", "floor", "ceil"]
description: |
Delimiter matching.
The `lr` function allows you to match two delimiters and scale them with the
content they contain. While this also happens automatically for delimiters
that match syntactically, `lr` allows you to match two arbitrary delimiters
and control their size exactly. Apart from the `lr` function, Typst provides
a few more functions that create delimiter pairings for absolute, ceiled,
and floored values as well as norms.

View File

@ -0,0 +1,265 @@
---
description: Automate your document with Typst's scripting capabilities.
---
# Scripting
Typst embeds a powerful scripting language. You can automate your documents and
create more sophisticated styles with code. Below is an overview over the
scripting concepts.
## Expressions { #expressions }
In Typst, markup and code are fused into one. All but the most common elements
are created with _functions._ To make this as convenient as possible, Typst
provides compact syntax to embed a code expression into markup: An expression is
introduced with a hashtag (`#`) and normal markup parsing resumes after the
expression is finished. If a character would continue the expression but should
be interpreted as text, the expression can forcibly be ended with a semicolon
(`;`).
```example
#rect[Hello] \
#emoji.face \
#"hello".len()
```
The example above shows a few of the available expressions, including
[function calls]($type/function),
[field accesses]($scripting/#fields), and
[method calls]($scripting/#methods). More kinds of expressions are
discussed in the remainder of this chapter. A few kinds of expressions are not
compatible with the hashtag syntax (e.g. binary operator expressions). To embed
these into markup, you can use parentheses, as in `[#(1 + 2)]`.
## Blocks { #blocks }
To structure your code and embed markup into it, Typst provides two kinds of
_blocks:_
- **Code block:** `{{ let x = 1; x + 2 }}` \
When writing code, you'll probably want to split up your computation into
multiple statements, create some intermediate variables and so on. Code blocks
let you write multiple expressions where one is expected. The individual
expressions in a code block should be separated by line breaks or semicolons.
The output values of the individual expressions in a code block are joined to
determine the block's value. Expressions without useful output, like `{let}`
bindings yield `{none}`, which can be joined with any value without effect.
- **Content block:** `{[*Hey* there!]}` \
With content blocks, you can handle markup/content as a programmatic value,
store it in variables and pass it to [functions]($type/function). Content
blocks are delimited by square brackets and can contain arbitrary markup. A
content block results in a value of type [content]($type/content). An
arbitrary number of content blocks can be passed as trailing arguments to
functions. That is, `{list([A], [B])}` is equivalent to `{list[A][B]}`.
Content and code blocks can be nested arbitrarily. In the example below,
`{[hello]}` is joined with the output of `{a + [ the ] + b}` yielding
`{[hello from the *world*]}`.
```example
#{
let a = [from]
let b = [*world*]
[hello ]
a + [ the ] + b
}
```
## Let bindings { #bindings }
As already demonstrated above, variables can be defined with `{let}` bindings.
The variable is assigned the value of the expression that follows the `=` sign.
The assignment of a value is optional, if no value is assigned, the variable
will be initialized as `{none}`. The `{let}` keyword can also be used to create
a [custom named function]($type/function/#definitions). Let bindings can be
accessed for the rest of the containing block or document.
```example
#let name = "Typst"
This is #name's documentation.
It explains #name.
#let add(x, y) = x + y
Sum is #add(2, 3).
```
## Conditionals { #conditionals }
With a conditional, you can display or compute different things depending on
whether some condition is fulfilled. Typst supports `{if}`, `{else if}` and
`{else}` expression. When the condition evaluates to `{true}`, the conditional
yields the value resulting from the if's body, otherwise yields the value
resulting from the else's body.
```example
#if 1 < 2 [
This is shown
] else [
This is not.
]
```
Each branch can have a code or content block as its body.
- `{if condition {..}}`
- `{if condition [..]}`
- `{if condition [..] else {..}}`
- `{if condition [..] else if condition {..} else [..]}`
## Loops { #loops }
With loops, you can repeat content or compute something iteratively. Typst
supports two types of loops: `{for}` and `{while}` loops. The former iterate
over a specified collection whereas the latter iterate as long as a condition
stays fulfilled. Just like blocks, loops _join_ the results from each iteration
into one value.
In the example below, the three sentences created by the for loop join together
into a single content value and the length-1 arrays in the while loop join
together into one larger array.
```example
#for c in "ABC" [
#c is a letter.
]
#let n = 2
#while n < 10 {
n = (n * 2) - 1
(n,)
}
```
For loops can iterate over a variety of collections:
- `{for letter in "abc" {..}}` \
Iterates over the characters of the [string]($type/string).
(Technically, iterates over the grapheme clusters of the string. Most of the
time, a grapheme cluster is just a single character/codepoint. However, some
constructs like flag emojis that consist of multiple codepoints are still only
one cluster.)
- `{for value in array {..}}` \
`{for index, value in array {..}}`\
Iterates over the items in the [array]($type/array). Can also provide the
index of each element.
- `{for value in dict {..}}` \
`{for key, value in dict {..}}` \
Iterates over the values or keys and values of the
[dictionary]($type/dictionary).
- `{for value in args {..}}` \
`{for name, value in args {..}}` \
Iterates over the values or names and values of the
[arguments]($type/arguments). For positional arguments, the `name` is
`{none}`.
To control the execution of the loop, Typst provides the `{break}` and
`{continue}` statements. The former performs an early exit from the loop while
the latter skips ahead to the next iteration of the loop.
```example
#for letter in "abc nope" {
if letter == " " {
break
}
letter
}
```
The body of a loop can be a code or content block:
- `{for .. in collection {..}}`
- `{for .. in collection [..]}`
- `{while condition [..]}`
- `{while condition [..]}`
## Fields { #fields }
You can use _dot notation_ to access fields on a value. The value in question
can be either:
- a [dictionary]($type/dictionary) that has the specified key,
- a [symbols]($type/symbol) that has the specified modifier,
- a [module]($type/module) containing the specified definition,
- [content]($type/content) that exposes the specified field. Most elements
expose some or all of the non-settable arguments passed to them as fields.
```example
#let dict = (greet: "Hello")
#dict.greet \
#emoji.face
```
## Methods { #methods }
A method is a kind of a [function]($type/function) that is tightly coupled with
a specific type. It is called on a value of its type using the same dot notation
that is also used for fields: `{value.method(..)}`. The
[type documentation]($type) lists the available methods for each of the built-in
types. You cannot define your own methods.
```example
#let array = (1, 2, 3, 4)
#array.pop() \
#array.len() \
#("a, b, c"
.split(", ")
.join[ --- ])
```
Methods are the only functions in Typst that can modify the value they are
called on.
## Modules { #modules }
You can split up your Typst projects into multiple files called _modules._ A
module can refer to the content and definitions of another module in multiple
ways:
- **Including:** `{include "bar.typ"}` \
Evaluates the file at the path `bar.typ` and returns the resulting
[content]($type/content).
- **Import:** `{import "bar.typ"}` \
Evaluates the file at the path `bar.typ` and inserts the resulting
[module]($type/module) into the current scope as `bar` (filename without
extension).
- **Import items:** `{import "bar.typ": a, b}` \
Evaluates the file at the path `bar.typ`, extracts the values of the variables
`a` and `b` (that need to be defined in `bar.typ`, e.g. through `{let}`
bindings) and defines them in the current file.Replacing `a, b` with `*` loads
all variables defined in a module.
Instead of a path, you can also use a [module value]($type/module), as shown in
the following example:
```example
#import emoji: face
#face.grin
```
## Operators { #operators }
The following table lists all available unary and binary operators with effect,
arity (unary, binary) and precedence level (higher binds stronger).
| Operator | Effect | Arity | Precedence |
|:----------:|---------------------------------|:------:|:----------:|
| `{-}` | Negation | Unary | 7 |
| `{+}` | No effect (exists for symmetry) | Unary | 7 |
| `{*}` | Multiplication | Binary | 6 |
| `{/}` | Division | Binary | 6 |
| `{+}` | Addition | Binary | 5 |
| `{-}` | Subtraction | Binary | 5 |
| `{==}` | Check equality | Binary | 4 |
| `{!=}` | Check inequality | Binary | 4 |
| `{<}` | Check less-than | Binary | 4 |
| `{<=}` | Check less-than or equal | Binary | 4 |
| `{>}` | Check greater-than | Binary | 4 |
| `{>=}` | Check greater-than or equal | Binary | 4 |
| `{in}` | Check if in collection | Binary | 4 |
| `{not in}` | Check if not in collection | Binary | 4 |
| `{not}` | Logical "not" | Unary | 3 |
| `{and}` | Short-circuiting logical "and" | Binary | 3 |
| `{or}` | Short-circuiting logical "or | Binary | 2 |
| `{=}` | Assignment | Binary | 1 |
| `{+=}` | Add-Assignment | Binary | 1 |
| `{-=}` | Subtraction-Assignment | Binary | 1 |
| `{*=}` | Multiplication-Assignment | Binary | 1 |
| `{/=}` | Division-Assignment | Binary | 1 |

View File

@ -0,0 +1,141 @@
---
description: All concepts needed to style your document with Typst.
---
# Styling
Typst includes a flexible styling system that automatically applies styling of
your choice to your document. With _set rules,_ you can configure basic
properties of elements. This way, you create most common styles. However, there
might not be a built-in property for everything you wish to do. For this reason,
Typst further supports _show rules_ that can completely redefine the appearance
of elements.
## Set rules { #set-rules }
With set rules, you can customize the appearance of elements. They are written
as a [function call]($type/function) to the respective function preceded by the
`{set}` keyword (or `[#set]` in markup). Only settable parameters must be
provided as arguments. Refer to each function's documentation for a list of
settable parameters. In the example below, we use two set rules to change the
[font family]($func/text.family) and
[heading numbering]($func/heading.numbering) style.
```example
#set text("Latin Modern Roman")
#set heading(numbering: "I.")
= Introduction
With set rules, you can style
your document.
```
A top level set rule stays in effect until the end of the file. When nested
inside of a block, it is only in effect until the end of that block. With a
block, you can thus restrict the effect of a rule to a particular segment of
your document. Below, we use a content block to scope the list styling to one
particular list.
```example
This list is affected:
#[#set list(marker: [--])
- Dash]
This one is not:
- Bullet
```
Sometimes, you'll want to apply a set rule conditionally. For this, you can use
a _set-if_ rule.
```example
#let task(body, critical: false) = {
set text(red) if critical
[- #body]
}
#task(critical: true)[Food today?]
#task(critical: false)[Work deadline]
```
## Show rules { #show-rules }
With show rules, you can deeply customize the look of a type of element. The
most basic form of show rule is a _show-set rule._ Such a rule is written as the
`{show}` keyword followed by a function name, a colon and then a set rule. This
lets the set rule only apply to the selected element. In the example below,
headings become dark blue while all other text stays black.
```example
#show heading: set text(navy)
= This is navy-blue
But this stays black.
```
With show-set rules you can mix and match properties from different functions to
achieve many different effects. But they still limit you to what is predefined
in Typst. For maximum flexibility, you can instead write a show rule that
defines how to format an element from scratch. To write such a show rule,
replace the set rule behind the colon with an arbitrary
[function]($type/function). This functions receives the element in question and
can return arbitrary content. Different
[fields]($scripting/#fields) are available on the element passed
to the function. Below, we define a show rule that formats headings for a
fantasy encyclopedia.
```example
#set heading(numbering: "(I)")
#show heading: it => block[
#set align(center)
#set text("Inria Serif")
\~ _#it.title;_
#it.numbers \~
]
= Dragon
With a base health of 15, the
dragon is the most powerful
creature.
= Manticore
While less powerful than the
dragon, the manticore gets
extra style points.
```
Like set rules, show rules are in effect until the end of the current block or
file.
Instead of a function, the right-hand side of a show rule can also take a
literal string or content block that should be directly substituted for the
element. And apart from a function, the left-hand side of a show rule can also
take a number of other _selectors_ that define what to apply the transformation
to:
- **Everything:** `{show rest => ..}` \
Transform everything after the show rule. This is useful to apply a more
complex layout to your whole document without wrapping everything in a giant
function call.
- **Text:** `{show "Text": ..}` \
Style, transform or replace text.
- **Regex:** `{show regex("\w+"): ..}` \
Select and transform text with a regular expression for even more flexibility.
See the documentation of the [`regex` function]($func/regex) for details.
- **Function with fields:** `{show heading.where(level: 1): ..}` \
Transform only elements that have the specified fields. For example, you might
want to only change the style of level-1 headings.
- **Label:** `{show <intro>: ..}` \
Select and transform elements that have the specified label.
See the documentation of the [`label` function]($func/label) for more details.
```example
#set text("Noto Serif")
#show "Project": smallcaps
#show "badly": "great"
We started Project in 2019
and are still working on it.
Project is progressing badly.
```

View File

@ -0,0 +1,136 @@
---
description: |
A compact reference for Typst's syntax. Learn more about the language within
markup, math, and code mode.
---
# Syntax
Typst is a markup language. This means that you can use simple syntax to
accomplish common layout tasks. The lightweight markup syntax is complemented by
set and show rules, which let you style your document easily and automatically.
All this is backed by a tightly integrated scripting language with built-in and
user-defined functions.
## Markup { #markup }
Typst provides built-in markup for the most common document elements. Most of
the syntax elements are just shortcuts for a corresponding function. The table
below lists all markup that is available and links to the best place to learn
more about their syntax and usage.
| Name | Example | See |
| ------------------ | ------------------------ | ---------------------------- |
| Paragraph break | Blank line | [`parbreak`]($func/parbreak) |
| Strong emphasis | `[*strong*]` | [`strong`]($func/strong) |
| Emphasis | `[_emphasis_]` | [`emph`]($func/emph) |
| Raw text | ``[`print(1)`]`` | [`raw`]($func/raw) |
| Link | `[https://typst.app/]` | [`link`]($func/link) |
| Label | `[<intro>]` | [`label`]($func/label) |
| Reference | `[@intro]` | [`ref`]($func/ref) |
| Heading | `[= Heading]` | [`heading`]($func/heading) |
| Bullet list | `[- item]` | [`list`]($func/list) |
| Numbered list | `[+ item]` | [`enum`]($func/enum) |
| Term list | `[/ Term: description]` | [`terms`]($func/terms) |
| Math | `[$x^2$]` | [Math]($category/math) |
| Line break | `[\]` | [`linebreak`]($func/linebreak) |
| Smart quote | `['single' or "double"]` | [`smartquote`]($func/smartquote) |
| Symbol shorthand | `[~, ---]` | [Symbols]($category/symbols/sym) |
| Code expression | `[#rect(width: 1cm)]` | [Scripting]($scripting/#expressions) |
| Character escape | `[Tweet at us \#ad]` | [Below](#escapes) |
| Comment | `[/* block */, // line]` | [Below](#comments) |
## Math mode { #math }
Math mode is a special markup mode that is used to typeset mathematical
formulas. It is entered by wrapping a formula in `[$]` characters. The formula
will be typeset into its own block if it starts and ends with at least one space
(e.g. `[$ x^2 $]`). Inline math can be produced by omitting the whitespace (e.g.
`[$x^2$]`). An overview over the syntax specific to math mode follows:
| Name | Example | See |
| ---------------------- | ------------------------ | ------------------------ |
| Inline math | `[$x^2$]` | [Math]($category/math) |
| Block-level math | `[$ x^2 $]` | [Math]($category/math) |
| Bottom attachment | `[$x_1$]` | [`attach`]($category/math/attach) |
| Top attachment | `[$x^2$]` | [`attach`]($category/math/attach) |
| Fraction | `[$1 + (a+b)/5$]` | [`frac`]($func/frac) |
| Line break | `[$x \ y ]` | [`linebreak`]($func/linebreak) |
| Alignment point | `[$x &= 2 \ &= 3$]` | [Math]($category/math) |
| Variable access | `[$pi$]` | [Math]($category/math) |
| Field access | `[$arrow.r.long$]` | [Scripting]($scripting/#fields) |
| Implied multiplication | `[$x y$]` | [Math]($category/math) |
| Symbol shorthand | `[$->, !=$]` | [Symbols]($category/symbols/sym) |
| Text/string in math | `[$a "is natural"$]` | [Math]($category/math) |
| Math function call | `[$floor(x)$]` | [Math]($category/math) |
| Code expression | `[$#rect(width: 1cm)$]` | [Scripting]($scripting/#expressions) |
| Character escape | `[$x\^2$]` | [Below](#escapes) |
| Comment | `[$/* comment */$]` | [Below](#comments) |
## Code mode { #code }
Within code blocks and expressions, new expressions can start without a leading
`#` character. Many syntactic elements are specific to expressions. Below is
a table listing all syntax that is available in code mode:
| Name | Example | See |
| ------------------------ | ----------------------------- | ---------------------------------------------------- |
| Variable access | `{x}` | [Scripting]($scripting/#blocks) |
| Any literal | `{1pt, "hey"}` | [Types]($types) |
| Code block | `{{ let x = 1; x + 2 }}` | [Scripting]($scripting/#blocks) |
| Content block | `{[*Hello*]}` | [Scripting]($scripting/#blocks) |
| Parenthesized expression | `{(1 + 2)}` | [Scripting]($scripting/#blocks) |
| Array | `{(1, 2, 3)}` | [Array]($type/array) |
| Dictionary | `{(a: "hi", b: 2)}` | [Dictionary]($type/dictionary) |
| Unary operator | `{-x}` | [Scripting]($scripting/#operators) |
| Binary operator | `{x + y}` | [Scripting]($scripting/#operators) |
| Assignment | `{x = 1}` | [Scripting]($scripting/#operators) |
| Field access | `{x.y}` | [Scripting]($scripting/#fields) |
| Method call | `{x.flatten()}` | [Scripting]($scripting/#methods) |
| Function call | `{min(x, y)}` | [Function]($type/function) |
| Unnamed function | `{(x, y) => x + y}` | [Function]($type/function) |
| Let binding | `{let x = 1}` | [Scripting]($scripting/#bindings) |
| Named function | `{let f(x) = 2 * x}` | [Function]($type/function) |
| Set rule | `{set text(14pt)}` | [Styling]($styling/#set-rules) |
| Set-if rule | `{set text(..) if .. }` | [Styling]($styling/#set-rules) |
| Show rule | `{show raw: it => {..}}` | [Styling]($styling/#set-rules) |
| Show-set rule | `{show par: set block(..)}` | [Styling]($styling/#show-rules) |
| Conditional | `{if x == 1 {..} else {..}}` | [Scripting]($scripting/#conditionals) |
| For loop | `{for x in (1, 2, 3) {..}}` | [Scripting]($scripting/#loops) |
| While loop | `{while x < 10 {..}}` | [Scripting]($scripting/#loops) |
| Loop control flow | `{break, continue}` | [Scripting]($scripting/#loops) |
| Return from function | `{return x}` | [Function]($type/function) |
| Include module | `{include "bar.typ"}` | [Scripting]($scripting/#modules) |
| Import module | `{import "bar.typ"}` | [Scripting]($scripting/#modules) |
| Import items from module | `{import "bar.typ": a, b, c}` | [Scripting]($scripting/#modules) |
| Comment | `[/* block */, // line]` | [Below](#comments) |
## Comments { #comments }
Comments are ignored by Typst and will not be included in the output. This
is useful to exclude old versions or to add annotations.
To comment out a single line, start it with `//`:
```example
// our data barely supports
// this claim
We show with $p < 0.05$
that the difference is
significant.
```
Comments can also be wrapped between `/*` and `*/`. In this case, the comment
can span over multiple lines:
```example
Our study design is as follows:
/* Somebody write this up:
- 1000 participants.
- 2x2 data design. */
```
## Escape sequences { #escapes }
Escape sequences are used to insert special characters that are otherwise have
special meaning in Typst. To escape a character, precede it with a backslash. To
insert any Unicode codepoint, you can write a hexadecimal escape sequence:
`[\u{1f600}]`. The same kind of escape sequences also work in
[strings]($type/string).
```example
I got an ice cream for
\$1.50! \u{1f600}
```

837
docs/src/reference/types.md Normal file
View File

@ -0,0 +1,837 @@
# None
A type that indicates the absence of any other value.
The none type has exactly one value: `{none}`.
When inserted into the document, it is not visible.
This is also the value that is produced by empty code blocks.
It can be [joined]($scripting/#blocks) with any value, yielding
the other value.
## Example
```example
Not visible: #none
```
# Auto
A type that indicates a smart default.
The auto type has exactly one value: `{auto}`.
Parameters that support the `{auto}` value have some smart default or contextual
behaviour. A good example is the [text direction]($func/text.dir) parameter.
Setting it to `{auto}` lets Typst automatically determine the direction from the
[text language]($func/text.lang).
# Boolean
A value with two states.
The boolean type has two values: `{true}` and `{false}`. It denotes whether
something is active or enabled.
## Example
```example
#false \
#true \
#(1 < 2)
```
# Integer
A whole number.
The number can be negative, zero, or positive. As Typst uses 64 bits to store
integers, integers cannot be smaller than `{-9223372036854775808}` or larger than
`{9223372036854775807}`.
## Example
```example
#(1 + 2) \
#(2 - 5) \
#(3 + 4 < 8)
```
# Float
A floating-pointer number.
A limited-precision representation of a real number. Typst uses 64 bits to
store floats. Wherever a float is expected, you can also pass an
[integer]($type/integer).
## Example
```example
#3.14 \
#1e4 \
#(10 / 4)
```
# Length
A size or distance, possibly expressed with contextual units.
Typst supports the following length units:
- Points: `{72pt}`
- Millimeters: `{254mm}`
- Centimeters: `{2.54cm}`
- Inches: `{1in}`
- Relative to font size: `{2.5em}`
## Example
```example
#rect(width: 20pt) \
#rect(width: 2em) \
#rect(width: 1in)
```
# Angle
An angle describing a rotation.
Typst supports the following angular units:
- Degrees: `{180deg}`
- Radians: `{3.14rad}`
## Example
```example
#rotate(10deg)[Hello there!]
```
# Ratio
A ratio of a whole.
Written as a number, followed by a percent sign.
## Example
```example
#set align(center)
#scale(x: 150%)[
Scaled apart.
]
```
# Relative Length
A length in relation to some known length.
This type is a combination of a [length]($type/length) with a
[ratio]($type/ratio). It results from addition and subtraction
of a length and a ratio. Wherever a relative length is expected, you can also
use a bare length or ratio.
## Example
```example
#rect(width: 100% - 50pt)
```
# Fraction
Defines how the the remaining space in a layout is distributed.
Each fractionally sized element gets space based on the ratio of its fraction to
the sum of all fractions.
For more details, also see the [h]($func/h) and [v]($func/v) functions and the
[grid function]($func/grid).
## Example
```example
Left #h(1fr) Left-ish #h(2fr) Right
```
# Color
A color in a specific color space.
Typst supports:
- sRGB through the [`rgb` function]($func/rgb)
- Device CMYK through [`cmyk` function]($func/cmyk)
- D65 Gray through the [`luma` function]($func/luma)
Furthermore, Typst provides the following built-in colors:
`black`, `gray`, `silver`, `white`, `navy`, `blue`, `aqua`, `teal`, `eastern`,
`purple`, `fuchsia`, `maroon`, `red`, `orange`, `yellow`, `olive`, `green`, and
`lime`.
## Methods
### lighten()
Lightens a color.
- amount: ratio (positional, required)
The factor to lighten the color by.
### darken()
Darkens a color.
- amount: ratio (positional, required)
The factor to darken the color by.
### negate()
Produces the negative of the color.
# Symbol
A Unicode symbol.
Typst defines common symbols so that they can easily be written with standard
keyboards. The symbols are defined in modules, from which they can be accessed
using [field access notation]($scripting/#fields):
- General symbols are defined in the [`sym` module]($category/symbols/sym)
- Emoji are defined in the [`emoji` module]($category/symbols/emoji)
Moreover, you can define custom symbols with the [symbol]($func/symbol)
function.
```example
#sym.arrow.r \
#sym.gt.eq.not \
$gt.eq.not$ \
#emoji.face.halo
```
Many symbols have different variants, which can be selected by appending the
modifiers with dot notation. The order of the modifiers is not relevant. Visit
the documentation pages of the symbol modules and click on a symbol to see its
available variants.
```example
$arrow.l$ \
$arrow.r$ \
$arrow.t.quad$
```
# String
A sequence of Unicode codepoints.
You can iterate over the characters (or rather, grapheme clusters) of the string
using a [for loop]($scripting/#loops). Strings can be added with
the `+` operator, [joined together]($scripting/#blocks) and
multiplied with integers.
Typst provides utility methods for string manipulation. Many of these methods
(e.g., `split`, `trim` and `replace`) operate on _patterns:_ A pattern can be
either a string or a [regular expression]($func/regex). This makes the methods
quite versatile.
_Note:_ Currently all lengths and indices are expressed in terms of UTF-8 bytes.
This _might_ change to grapheme clusters in the future.
### Example
```example
#"hello world!" \
#"\"hello\n world\"!" \
#"1 2 3".split() \
#"1,2;3".split(regex("[,;]")) \
#(regex("\d+") in "ten euros") \
#(regex("\d+") in "10 euros")
```
### Escape sequences
Just like in markup, you can escape a few symbols in strings:
- `[\\]` for a backslash
- `[\"]` for a quote
- `[\n]` for a newline
- `[\r]` for a carriage return
- `[\t]` for a tab
- `[\u{1f600}]` for a hexadecimal Unicode escape sequence
## Methods
### len()
The length of the string in UTF-8 encoded bytes.
- returns: integer
### first()
Extract the first character (or rather, grapheme cluster) of the string.
Fails with an error if the string is empty.
- returns: any
### last()
Extract the last character (or rather, grapheme cluster) of the string.
Fails with an error if the string is empty.
- returns: any
### at()
Extract the first character (or rather, grapheme cluster) after the specified
index. Fails with an error if the index is out of bounds.
- index: integer (positional, required)
The byte index.
- returns: string
### slice()
Extract a substring of the string.
Fails with an error if the start or end index is out of bounds.
- start: integer (positional, required)
The start byte index (inclusive).
- end: integer (positional)
The end byte index (exclusive). If omitted, the whole slice until the end of the
string is extracted.
- count: integer (named)
The number of bytes to extract. This is equivalent to passing `start + count`
as the `end` position. Mutually exclusive with `end`.
- returns: string
### contains()
Whether the string contains the specified pattern.
This method also has dedicated syntax: You can write `{"bc" in "abcd"}` instead
of `{"abcd".contains("bc")}`.
- pattern: string or regex (positional, required)
The pattern to search for.
- returns: boolean
### starts-with()
Whether the string starts with the specified pattern.
- pattern: string or regex (positional, required)
The pattern the string might start with.
- returns: boolean
### ends-with()
Whether the string ends with the specified pattern.
- pattern: string or regex (positional, required)
The pattern the string might end with.
- returns: boolean
### find()
Searches for the specified pattern in the string and returns the first match
as a string or `{none}` if there is no match.
- pattern: string or regex (positional, required)
The pattern to search for.
- returns: string or none
### position()
Searches for the specified pattern in the string and returns the index of the
first match as an integer or `{none}` if there is no match.
- pattern: string or regex (positional, required)
The pattern to search for.
- returns: integer or none
### match()
Searches for the specified pattern in the string and returns a dictionary
with details about the first match or `{none}` if there is no match.
The returned dictionary has the following keys:
* `start`: The start offset of the match
* `end`: The end offset of the match
* `text`: The text that matched.
* `captures`: An array containing a string for each matched capturing group. The
first item of the array contains the first matched capturing, not the whole
match! This is empty unless the `pattern` was a regex with capturing groups.
- pattern: string or regex (positional, required)
The pattern to search for.
- returns: dictionary or none
### matches()
Searches for the specified pattern in the string and returns an array of
dictionaries with details about all matches. For details about the returned
dictionaries, see above.
- pattern: string or regex (positional, required)
The pattern to search for.
- returns: array
### replace()
Replaces all or a specified number of matches of a pattern with a replacement
string and returns the resulting string.
- pattern: string or regex (positional, required)
The pattern to search for.
- replacement: string (positional, required)
The string to replace the matches with.
- count: integer (named)
If given, only the first `count` matches of the pattern are placed.
- returns: string
### trim()
Removes matches of a pattern from one or both sides of the string, once or
repeatedly and returns the resulting string.
- pattern: string or regex (positional, required)
The pattern to search for.
- at: alignment (named)
Can be `start` or `end` to only trim the start or end of the string.
If omitted, both sides are trimmed.
- repeat: boolean (named)
Whether to repeatedly removes matches of the pattern or just once.
Defaults to `{true}`.
- returns: string
### split()
Splits a string at matches of a specified pattern and returns an array of
the resulting parts.
- pattern: string or regex (positional)
The pattern to split at. Defaults to whitespace.
- returns: array
# Content
Representation of text, elements, and more.
This type is at the heart of Typst. All markup you write and most
[functions]($type/function) you call produce content values. You
can create a content value by enclosing markup in square brackets. This is also
how you pass content to functions. Typst does not allow you to peek into
content, but you can affect its appearance in various ways using set and show
rules. See the chapter on [styling]($styling) for more details.
```example
#type([*Hello!*]) \
#strong[Hello!]
```
Content can be added with the `+` operator,
[joined together]($scripting/#blocks) and multiplied with
integers. Wherever content is expected, you can also pass a
[string]($type/string) or `{none}`.
### Reactivity
Content is reactive to the styles that are active where it is inserted.
When you write a set or show rule, content that was _created_ before the show
rule is stilled affected by the show rule if it is _inserted_ after the show
rule.
```example
// Content is created here.
#let mytext = [= A heading]
// But still affected by the
// styles that are active here.
#show heading: set text(green)
#mytext
```
# Array
A sequence of values.
You can construct an array by enclosing a comma-separated sequence of values
in parentheses. The values do not have to be of the same type.
You can access and update array elements with the `.at()` method. Indices are
zero-based and negative indices wrap around to the end of the array. You can
iterate over an array using a [for loop]($scripting/#loops).
Arrays can be added together with the `+` operator,
[joined together]($scripting/#blocks) and multiplied with
integers.
Empty parenthesis yield an array of length zero and a parentheses-wrapped value
with trailing comma yields an array of length one.
## Example
```example
#let values = (1, 7, 4, -3, 2)
#values.at(0) \
#(values.at(0) = 3)
#values.at(-1) \
#values.find(calc.even) \
#values.filter(calc.odd) \
#values.map(calc.abs) \
#values.rev() \
#(1, (2, 3)).flatten() \
#(("A", "B", "C")
.join(", ", last: " and "))
```
## Methods
### len()
The number of values in the array.
- returns: integer
### first()
Returns the first element in the array.
May be used on the left-hand side of an assignment.
Fails with an error if the array is empty.
- returns: any
### last()
Returns the last element in the array.
May be used on the left-hand side of an assignment.
Fails with an error if the array is empty.
- returns: any
### at()
Returns the element at the specified index in the array.
May be used on the left-hand side of an assignment.
Fails with an error if the index is out of bounds.
- index: integer (positional, required)
The index at which to retrieve the element.
- returns: any
### push()
Add a value to the end of the array.
- value: any (positional, required)
The value to insert at the end of the array.
### pop()
Remove the last element from the array and return it.
Fails with an error if the array is empty.
- returns: any
The removed last value.
### insert()
Insert a value into the array at the specified index.
Fails with an error if the index is out of bounds.
- index: integer (positional, required)
The index at which to insert the element.
- value: any (positional, required)
The value to insert into the array.
### remove()
Remove the value at the specified index from the array and return it.
- index: integer (positional, required)
The index at which to remove the element.
- returns: any
### slice()
Extract a subslice of the array.
Fails with an error if the start or index is out of bounds.
- start: integer (positional, required)
The start index (inclusive).
- end: integer (positional)
The end index (exclusive). If omitted, the whole slice until the end of the
array is extracted.
- count: integer (named)
The number of elements to extract. This is equivalent to passing `start +
count` as the `end` position. Mutually exclusive with `end`.
- returns: array
### contains()
Whether the array contains the specified value.
This method also has dedicated syntax: You can write `{2 in (1, 2, 3)}` instead
of `{(1, 2, 3).contains(2)}`.
- value: any (positional, required)
The value to search for.
- returns: boolean
### find()
Searches for an element for which the given function returns `{true}` and
returns the first match or `{none}` if there is no match.
- searcher: function (positional, required)
The function to apply to each element. Must return a boolean.
- returns: any or none
### position()
Searches for an element for which the given function returns `{true}` and
returns the index of the first match or `{none}` if there is no match.
- searcher: function (positional, required)
The function to apply to each element. Must return a boolean.
- returns: integer or none
### filter()
Produces a new array with only the elements from the original one for which the
given function returns true.
- test: function (positional, required)
The function to apply to each element. Must return a boolean.
- returns: array
### map()
Produces a new array in which all elements from the original one were
transformed with the given function.
- mapper: function (positional, required)
The function to apply to each element.
- returns: array
### fold()
Folds all elements into a single value using an accumulator function.
- init: any (positional, required)
The initial value to start with.
- folder: function (positional, required)
The folding function. Must have two parameters: One for the accumulated value
and one for an element.
- returns: any
### any()
Whether the given function returns `{true}` for any element in the array.
- test: function (positional, required)
The function to apply to each element. Must return a boolean.
- returns: boolean
### all()
Whether the given function returns `{true}` for all elements in the array.
- test: function (positional, required)
The function to apply to each element. Must return a boolean.
- returns: boolean
### flatten()
Combine all nested arrays into a single flat one.
- returns: array
### rev()
Return a new array with the same elements, but in reverse order.
- returns: array
### join()
Combine all elements in the array into one.
- separator: any (positional)
A value to insert between each element of the array.
- last: any (named)
An alternative separator between the last two elements
- returns: any
### sorted()
Return a new array with the same elements, but sorted.
- returns: array
# Dictionary
A map from string keys to values.
You can construct a dictionary by enclosing comma-separated `key: value` pairs
in parentheses. The values do not have to be of the same type.
A dictionary is conceptually similar to an array, but it is indexed by strings
instead of integers. You can access and create dictionary entries with the
`.at()` method. If you know the key statically, you can alternatively use
[field access notation]($scripting/#fields) (`.key`) to access
the value. Dictionaries can be added with the `+` operator and
[joined together]($scripting/#blocks).
You can iterate over the pairs in a dictionary using a
[for loop]($scripting/#loops).
Dictionaries are always ordered by key.
Since empty parentheses already yield an empty array, you have to use the
special `(:)` syntax to create an empty dictionary.
## Example
```example
#let dict = (
name: "Typst",
born: 2019,
)
#dict.name \
#(dict.launch = 20)
#dict.len() \
#dict.keys() \
#dict.values() \
#dict.at("born") \
#dict.insert("city", "Berlin ")
```
## Methods
### len()
The number of pairs in the dictionary.
- returns: integer
### at()
Returns the value associated with the specified key in the dictionary.
May be used on the left-hand side of an assignment if the key is already
present in the dictionary.
Fails with an error if the key is not part of the dictionary.
- index: integer (positional, required)
The index at which to retrieve the element.
- returns: any
### insert()
Insert a new pair into the dictionary and return the value.
- key: string (positional, required)
The key of the pair that should be inserted.
- value: any (positional, required)
The value of the pair that should be inserted.
### keys()
Returns the keys of the dictionary as an array in sorted order.
- returns: array
### values()
Returns the values of the dictionary as an array in key-order.
- returns: array
### pairs()
Call a function for each key-value pair and return the results in an array.
- mapper: function (positional, required)
The function to apply to each pair. Gets passed the key and value as two
separate arguments.
- returns: array
### remove()
Remove a pair from the dictionary by key and return the value.
- key: string (positional, required)
The key of the pair that should be removed.
- returns: any
# Function
A mapping from argument values to a return value.
You can call a function by writing a comma-separated list of function
_arguments_ enclosed in parentheses directly after the function name.
Additionally, you can pass any number of trailing content blocks arguments to a
function _after_ the normal argument list. If the normal argument list would
become empty, it can be omitted. Typst supports positional and named arguments.
The former are identified by position and type, while the later are written as
`name: value`.
Within math mode, function calls have special behaviour. See the
[math documentation]($category/math) for more details.
### Example
```example
// Call a function.
#list([A], [B])
// Named arguments and trailing
// content blocks.
#enum(start: 2)[A][B]
// Version without parentheses.
#list[A][B]
```
Functions are a fundamental building block of Typst. Typst provides functions
for a variety of typesetting tasks. Moreover, the markup you write is backed by
functions and all styling happens through functions. This reference lists all
available functions and how you can use them. Please also refer to the
documentation about [set]($styling/#set-rules) and
[show]($styling/#show-rules) rules to learn about additional ways
you can work with functions in Typst.
### Defining functions { #definitions }
You can define your own function with a
[let binding]($scripting/#bindings) that has a parameter list after
the binding's name. The parameter list can contain positional parameters,
named parameters with default values and
[argument sinks]($type/arguments).
The right-hand side of the binding can be a block or any other expression. It
defines the function's return value and can depend on the parameters.
```example
#let alert(body, fill: red) = {
set text(white)
set align(center)
rect(
fill: fill,
inset: 8pt,
radius: 4pt,
[*Warning:\ #body*],
)
}
#alert[
Danger is imminent!
]
#alert(fill: blue)[
KEEP OFF TRACKS
]
```
### Unnamed functions { #unnamed }
You can also created an unnamed function without creating a binding by
specifying a parameter list followed by `=>` and the function body. If your
function has just one parameter, the parentheses around the parameter list are
optional. Unnamed functions are mainly useful for show rules, but also for
settable properties that take functions like the page function's
[`footer`]($func/page.footer) property.
```example
#show "once?": it => [#it #it]
once?
```
### Notable fact
In Typst, all functions are _pure._ This means that for the same
arguments, they always return the same result. They cannot "remember" things to
produce another value when they are called a second time.
## Methods
### with()
Returns a new function that has the given arguments pre-applied.
- arguments: any (variadic)
The named and positional arguments to apply.
- returns: function
### where()
Returns a selector that filters for elements belonging to this function
whose fields have the values of the given arguments.
- fields: any (named, variadic)
The field values to filter by.
- returns: selector
# Arguments
Captured arguments to a function.
Like built-in functions, custom functions can also take a variable number of
arguments. You can specify an _argument sink_ which collects all excess
arguments as `..sink`. The resulting `sink` value is of the `arguments` type. It
exposes methods to access the positional and named arguments and is iterable
with a [for loop]($scripting/#loops). Inversely, you can spread
arguments, arrays and dictionaries into a function call with the spread operator:
`{func(..args)}`.
## Example
```example
#let format(title, ..authors) = [
*{title}* \
_Written by {authors
.pos()
.join(", ", last: " and ")}._
]
#format("ArtosFlow", "Jane", "Joe")
```
## Methods
### pos()
Returns the captured positional arguments as an array.
- returns: array
### named()
Returns the captured named arguments as a dictionary.
- returns: dictionary
# Module
An evaluated module, either built-in or resulting from a file.
You can access definitions from the module using
[field access notation]($scripting/#fields) and interact with it using the
[import and include syntaxes]($scripting/#modules).
## Example
```example
<<< #import "utils.typ"
<<< #utils.add(2, 5)
<<< #import utils: sub
<<< #sub(1, 4)
>>> #7
>>>
>>> #(-3)
```

View File

@ -0,0 +1,29 @@
---
description: |
The Typst reference is a systematic and comprehensive guide to the Typst
typesetting language.
---
# Reference
This reference documentation is a comprehensive guide to all of Typst's
syntax, concepts, types, and functions. If you are completely new to Typst, we
recommend starting with the [tutorial]($tutorial) and then coming back to
the reference to learn more about Typst's features as you need them.
## Language
The reference starts with a language part that gives an overview over [Typst's
syntax]($syntax) and contains information about concepts involved in
[styling documents,]($styling) using
[Typst's scripting capabilities,]($scripting) and a detailed documentation of
all [data types]($types) in Typst.
## Functions
The second part includes chapters on all functions used to insert, style, transform,
and layout content in Typst documents. Each function is documented with a
description of its purpose, a list of its parameters, and examples of how to use
it.
The final part of the reference explains all functions that are used within
Typst's code mode to manipulate and transform data. Just as in the previous
part, each function is documented with a description of its purpose, a list of
its parameters, and examples of how to use it.

View File

@ -0,0 +1,269 @@
---
description: Typst's tutorial.
---
# Writing in Typst
Let's get started! Suppose you got assigned to write a technical report for
university. It will contain prose, maths, headings, and figures. To get started,
you create a new project on the Typst app. You'll be taken to the editor where
you see two panels: A source panel where you compose your document and a
preview panel where you see the rendered document.
![Typst app screenshot](1-writing-app.png)
You already have a good angle for your report in mind. So let's start by writing
the introduction. Enter some text in the editor panel. You'll notice that the
text immediately appears on the previewed page.
```example
In this report, we will explore the
various factors that influence fluid
dynamics in glaciers and how they
contribute to the formation and
behavior of these natural structures.
```
_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._
The next step is to add a heading and emphasize some text. Typst uses simple
markup for the most common formatting tasks. To add a heading, enter the `=`
character and to emphasize some text with italics, enclose it in
`[_underscores_]`.
```example
= Introduction
In this report, we will explore the
various factors that influence _fluid
dynamics_ in glaciers and how they
contribute to the formation and
behavior of these natural structures.
```
That was easy! To add a new paragraph, just add a blank line in between two
lines of text. If that paragraph needs a subheading, produce it by typing `==`
instead of `=`. The number of `=` characters determines the nesting level of the
heading.
Now we want to list a few of the circumstances that influence glacier dynamics.
To do that, we use a numbered list. For each item of the list, we type a `+`
character at the beginning of the line. Typst will automatically number the
items.
```example
+ The climate
+ The topography
+ The geology
```
If we wanted to add a bulleted list, we would use the `-` character instead of the
`+` character. We can also nest lists: For example, we can add a sub-list to the
first item of the list above by indenting it.
```example
+ The climate
- Temperature
- Precipitation
+ The topography
+ The geology
```
## Adding images
You think that your report would benefit from a figure. Let's add one. Typst
supports images in the formats PNG, JPEG, GIF, and SVG. To add an image file to
your project, first open the _file panel_ by clicking the box icon in the left
sidebar. Here, you can see a list of all files in your project. Currently, there
is only one: The main Typst file you are writing in. To upload another file,
click the button with the arrow in the top-right corner. This opens the upload
dialog, in which you can pick files to upload from your computer. Select an
image file for your report.
![Upload dialog](1-writing-upload.png)
We have seen before that specific symbols (called _markup_) have specific
meaning in Typst. We can use `=`, `-`, `+`, and `_` to create headings, lists
and emphasized text, respectively. However, having a special symbol for
everything we want to insert into our document would soon become cryptic and
unwieldy. For this reason, Typst reserves markup symbols only for the most common
things. Everything else is inserted with _functions._ For our image to show up
on the page, we use Typst's [`image`]($func/image) function.
```example
#image("glacier.jpg")
```
In general, a function produces some output for a set of _arguments_. When you
_call_ a function within markup, you provide the arguments and Typst inserts the
result (the function's _return value_) into the document. In our case, the
`image` function takes one argument: The path to the image file. To call a
function, we first need to type the `#` character, immediately followed by the
name of the function. Then, we enclose the arguments in parentheses. Typst
recognizes many different data types within argument lists. Our file path is a
short [string of text]($type/string), so we need to enclose it
in double quotes.
The inserted image uses the whole width of the page. To change that, pass the
`width` argument to the `image` function. This is a _named_ argument and
therefore specified as a `name: value` pair. If there are multiple arguments,
they are separated by commas, so we first need to put a comma behind the path.
```example
#image("glacier.jpg", width: 70%)
```
The `width` argument is a
[relative length]($type/relative-length). In our case, we specified a
percentage, determining that the image shall take up `{70%}` of the page's
width. We also could have specified an absolute value like `{1cm}` or `{0.7in}`.
Just like text, the image is aligned at the left side of the page by default.
That looks a bit awkward. Let's center it and add a caption. We achieve this by
using the [`align`]($func/align) function. This function takes an `alignment` as
its first argument and then the content that we want to align as the second
argument:
```example
#align(center)[
#image("glacier.jpg", width: 70%)
_Glaciers form an important
part of the earth's climate
system._
]
```
Did you spot the closing bracket `]` at the end of the example? Both the
argument and the caption are enclosed in the same square brackets. Therefore,
the `align` function centers both of them.
But wait, shouldn't the arguments of a function be specified within parentheses?
Why is there a second set of square brackets with the aligned content after the
parentheses?
The answer is that, as passing content to a function is such a common thing
to do in Typst, there is special syntax for it: Instead of putting the content
inside of the argument list, you can write it in square brackets directly after
the normal arguments, saving on punctuation. We call markup in square brackets
a _content block._
<div class="info-box">
So far, we've passed content blocks (markup in square brackets) and strings
(text in double quotes) to our functions. Both seem to contain text. What's the
difference?
A content block can contain text, but also any other kind of markup, function
calls, and more, whereas a string is really just a _sequence of characters_ and
nothing else.
For example, the image function expects a path to an image file.
It would not make sense to pass, e.g., a paragraph of text or a another image as
the image's path parameter. That's why only strings are allowed here.
On the contrary, strings work wherever content is expected because text is a
kind of valid content.
</div>
## Maths
After fleshing out the introduction, you move on to the meat of the document:
Your equations. Typst has built-in mathematical typesetting and uses its own
math notation. Let's start with a simple equation. We wrap it in `[$]` signs
to let Typst know it should expect a mathematical expression:
```example
The equation $Q = rho A v + C$
defines the glacial flow rate.
```
The equation is typeset inline, on the same line as the surrounding text. If you
want to have it on its own line instead, you should insert a single space at its
start and end:
```example
The flow rate of a glacier is
defined by the following equation:
$ Q = rho A v + C $
```
We can see that Typst displayed the single letters `Q`, `A`, `v`, and `C` as-is,
while it translated `rho` into a Greek letter. Math mode will always show single
letters verbatim. Multiple letters, however, are interpreted as symbols,
variables, or function names. To imply a multiplication between single letters,
put spaces between them.
If you want to have a variable that consists of multiple letters, you can
enclose it in quotes:
```example
The flow rate of a glacier is given by
the following equation:
$ Q = rho A v + "time offset" $
```
You'll also need a sum formula in your paper. We can use the `sum` symbol and
then specify the range of the summation in sub- and superscripts:
```example
Total displaced soil by glacial flow:
$ 7.32 beta +
sum_(i=0)^nabla Q_i / 2 $
```
To add a subscript to a symbol or variable, type a `_` character and then the
superscript. Similarly, use the `^` character for a superscript. If your
sub- or superscript consists of multiple things, you must enclose them
in round parentheses.
The above example also showed us how to insert fractions: Simply put a `/`
character between the numerator and the denominator and Typst will automatically
turn it into a fraction. Parentheses are smartly resolved, so you can enter your
expression as you would into a calculator and Typst will replace parenthesized
sub-expressions with the appropriate notation.
```example
Total displaced soil by glacial flow:
$ 7.32 beta +
sum_(i=0)^nabla
(Q_i (a_i - epsilon)) / 2 $
```
Not all math constructs have special syntax. Instead, we use functions, just
like the `image` function we have seen before. For example, to insert a column
vector, we can use the [`vec`]($func/vec) function. Within math mode, function
calls don't need to start with the `#` character.
```example
$ v := vec(x_1, x_2, x_3) $
```
Some functions are only available within math mode. For example, the
[`cal`]($func/cal) function is used to typeset calligraphic letters commonly used for
sets. The [math section of the reference]($category/math) provides a
complete list of all functions that math mode makes available.
One more thing: Many symbols, such as the arrow, have a lot of variants. You can
select among these variants by appending a dot and a modifier name to a symbol's
name:
```example
$ a arrow.squiggly b $
```
This notation is also available in markup mode, but the complete symbol name
with modifiers must then be enclosed in colons. See the documentation of the [text]($category/text) and [math sections]($category/math) for more details.
## Review
You have now seen how to write a basic document in Typst. You learned how to
emphasize text, write lists, insert images, align content, and typeset
mathematical expressions. You also learned about Typst's functions. There are
many more kinds of content that Typst lets you insert into your document, such
as [tables]($func/table), [shapes]($category/visualize), and
[code blocks]($func/raw). You can peruse the [reference]($reference) to learn
more about these and other features.
For the moment, you have completed writing your report. You have already saved a
PDF by clicking on the download button in the top right corner. However, you
think the report could look a bit less plain. In the next section, we'll learn
how to customize the look of our document.

View File

@ -0,0 +1,273 @@
---
description: Typst's tutorial.
---
# Formatting
So far, you have written a report with some text, a few equations and images.
However, it still looks very plain. Your teaching assistant does not yet know
that you are using a new typesetting system, and you want your report to fit in
with the other student's submissions. In this chapter, we will see how to format
your report using Typst's styling system.
## Set rules
As we have seen in the previous chapter, Typst has functions that _insert_
content (e.g. the [`image`]($func/image) function) and others that _manipulate_
content that they received as arguments (e.g. the [`align`]($func/align)
function). The first impulse you might have when you want, for example, to
justify the report, could be to look for a function that does that and wrap the
complete document in it.
```example
#par(justify: true)[
= Background
In the case of glaciers, fluid
dynamics principles can be used
to understand how the movement
and behavior of the ice is
influenced by factors such as
temperature, pressure, and the
presence of other fluids (such as
water).
]
```
As seen above, that works. The [`par`]($func/par) function justifies all
paragraphs within it. However, wrapping the document in countless functions and
applying styles selectively and in-situ can quickly become cumbersome.
Fortunately, Typst has a more elegant solution. With _set rules,_ you can apply
style properties to all occurrences of some kind of content. You write a set
rule by entering the `{set}` keyword, followed by the name of the function whose
properties you want to set, and a list of arguments in parentheses.
```example
#set par(justify: true)
= Background
In the case of glaciers, fluid
dynamics principles can be used
to understand how the movement
and behavior of the ice is
influenced by factors such as
temperature, pressure, and the
presence of other fluids (such as
water).
```
<div class="info-box">
Want to know in more technical terms what is happening here?
Set rules can be conceptualized as setting default values
for some of the parameters of a function for all future
uses of that function.
</div>
## The autocomplete panel
If you followed along and tried a few things in the app, you might have noticed
that always after you enter a `#` character, a panel pops up to show you the
available functions, and, within an argument list, the available parameters.
That's the autocomplete panel. It can be very useful while you are writing your
document: You can apply its suggestions by hitting the Return key or navigate to
the desired completion with the arrow keys. The panel can be dismissed by
hitting the Escape key and opened again by typing `#` or hitting
<kbd>Ctrl</kbd> + <kbd>Space</kbd>. Use the autocomplete panel to discover the
right arguments for functions. Most suggestions come with a small description of
what they do.
![Autocomplete panel](2-formatting-autocomplete.png)
## Set up the page
Back to set rules: When writing a rule, you choose the function depending on
what type of element you want to style. Here is a list of some functions that
are commonly used in set rules:
- [`text`]($func/text) to set font family, size, color, and other properties of
text
- [`page`]($func/page) to set the page size, margins, headers, enable columns,
and footers
- [`par`]($func/par) to justify paragraphs, set line spacing, and more
- [`heading`]($func/heading) to set the appearance of headings and enable
numbering
- [`document`]($func/document) to set the metadata contained in the PDF output,
such as title and author
Not all function parameters can be set. In general, only parameters that tell
a function _how_ to do something can be set, not those that tell it _what_ to
do it with. The function reference pages indicate which parameters are settable.
Let's add a few more styles to our document. We want larger margins and a serif
font. For the purposes of the example, we'll also set another page size.
```example
#set text(10pt, "Latin Modern Roman")
#set page(
"a6",
margin: (x: 1.8cm, y: 1.5cm),
)
#set par(
justify: true,
leading: 0.52em,
)
= Introduction
In this report, we will explore the
various factors that influence fluid
dynamics in glaciers and how they
contribute to the formation and
behavior of these natural structures.
>>> Glacier displacement is influenced
>>> by a number of factors, including
>>> + The climate
>>> + The topography
>>> + The geology
>>>
>>> This report will present a physical
>>> model of glacier displacement and
>>> dynamics, and will explore the
>>> influence of these factors on the
>>> movement of large bodies of ice.
<<< ...
#align(center + bottom)[
#image("glacier.jpg", width: 70%)
*Glaciers form an important
part of the earth's climate
system.*
]
```
There are a few things of note here.
First is the [`page`]($func/page) set rule. It receives two arguments: the page
size and margins for the page. The page size is a string. Typst accepts
[many standard page sizes,]($func/page.paper) but you can also specify a custom
page size. The margins are specified as a [dictionary.]($type/dictionary)
Dictionaries are a collection of key-value pairs. In this case, the keys are `x`
and `y`, and the values are the horizontal and vertical margins, respectively.
We could also have specified separate margins for each side by passing a
dictionary with the keys `{left}`, `{right}`, `{top}`, and `{bottom}`.
Next is the set [`text`]($func/text) set rule. Here, we set the font size to
`{10pt}` and font family to `{"Latin Modern Roman"}`. The Typst app comes with
many fonts that you can try for your document. When you are in the text
function's argument list, you can discover the available fonts in the
autocomplete panel.
We have also set the spacing between lines (a.k.a. leading): It is specified as
a [length]($type/length) value, and we used the `em` unit to specify the leading
relative to the size of the font: `{1em}` is equivalent to the current font size
(which defaults to `{11pt}`).
Finally, we have bottom aligned our image by adding a vertical alignment to our
center alignment. Vertical and horizontal alignments can be combined with the
`{+}` operator to yield a 2D alignment.
## A hint of sophistication
To structure our document more clearly, we now want to number our headings. We
can do this by setting the `numbering` parameter of the
[`heading`]($func/heading) function.
```example
>>> #set text("Latin Modern Roman")
#set heading(numbering: "1.")
= Introduction
#lorem(10)
== Background
#lorem(12)
== Methods
#lorem(15)
```
We specified the string `{"1."}` as the numbering parameter. This tells Typst to
number the headings with arabic numerals and to put a dot between the number of
each level. We can also use
[letters, roman numerals, and symbols]($func/numbering) for our headings:
```example
>>> #set text("Latin Modern Roman")
#set heading(numbering: "1.a")
= Introduction
#lorem(10)
== Background
#lorem(12)
== Methods
#lorem(15)
```
This example also uses the [`lorem`]($func/lorem) function to generate some
placeholder text. This function takes a number as an argument and generates that
many words of _Lorem Ipsum_ text.
<div class="info-box">
Did you wonder why the headings and text set rules apply to all text and headings,
even if they are not produced with the respective functions?
Typst internally calls the `heading` function every time you write `[= Conclusion]`.
In fact, the function call `[#heading[Conclusion]]` is equivalent to the heading
markup above. Other markup elements work similarly, they are only
_syntax sugar_ for the corresponding function calls.
</div>
## Show rules
You are already pretty happy with how this turned out. But one last thing needs
to be fixed: The report you are writing is intended for a larger project and
that project's name should always be accompanied by a logo, even in prose.
You consider your options. You could add an `[#image("logo.svg")]` call before
every instance of the logo using search and replace. That sounds very tedious.
Instead, you could maybe
[define a custom function]($type/function/#definitions) that always yields the logo with its image. However, there is an even easier way:
With show rules, you can redefine how Typst displays certain elements. You
specify which elements Typst should show differently and how they should look.
Show rules can be applied to instances of text, many functions, and even the
whole document.
```example
#show "ArtosFlow": name => box[
#box(image(
"logo.svg",
height: 0.7em,
))
#name
]
This report is embedded in the
ArtosFlow project. ArtosFlow is a
project of the Artos Institute.
```
There is a lot of new syntax in this example: We write the `{show}` keyword,
followed by a string of text we want to show differently and a colon. Then, we
write a function that takes the content that shall be shown as an argument.
Here, we called that argument `name`. We can now use the `name` variable in the
function's body to print the ArtosFlow name. Our show rule adds the logo image
in front of the name and puts the result into a box to prevent linebreaks from
occurring between logo and name. The image is also put inside of a box, so that
it does not appear in its own paragraph.
The calls to the first box function and the image function did not require a
leading `#` because they were not embedded directly in markup. When Typst
expects code instead of markup, the leading `#` is not needed to access
functions, keywords, and variables. This can be observed in parameter lists,
function definitions, and [code blocks]($scripting).
## Review
You now know how to apply basic formatting to your Typst documents. You learned
how to set the font, justify your paragraphs, change the page dimensions, and
add numbering to your headings with set rules. You also learned how to use a
basic show rule to change how text appears throughout your document.
You have handed in your report. Your supervisor was so happy with it that they
want to adapt it into a conference paper! In the next section, we will learn how
to format your document as a paper using more advanced show rules and functions.

View File

@ -0,0 +1,531 @@
---
description: Typst's tutorial.
---
# Advanced Styling
In the previous two chapters of this tutorial, you have learned how to write a
document in Typst and how to change its formatting. The report you wrote
throughout the last two chapters got a straight A and your supervisor wants to
base a conference paper on it! The report will of course have to comply with the
conference's style guide. Let's see how we can achieve that.
Before we start, let's create a team, invite your supervisor and add them to the
team. You can do this by going back to the app dashboard with the four-circles
icon in the top left corner of the editor. Then, choose the plus icon in the
left toolbar and create a team. Finally, click on the new team and go to its
settings by clicking 'manage team' next to the team name. Now you can invite
your supervisor by email.
![The team settings](3-advanced-team-settings.png)
Next, move your project into the team: Open it, going to its settings by
choosing the gear icon in the left toolbar and selecting your new team from the
owners dropdown. Don't forget to save your changes!
Now, your supervisor can also edit the project and you can both see the changes
in real time. You can join our [Discord server](https://discord.gg/2uDybryKPe)
to find others with preview access and try teams with them!
## The conference guidelines
The layout guidelines are available on the conference website. Let's take a look
at them:
- The font should be an 11pt serif font
- The title should be in 17pt and bold
- The paper contains a single-column abstract and two-column main text
- The abstract should be centered
- The main text should be justified
- First level section headings should be 13pt, centered, and rendered in small
capitals
- Second level headings are run-ins, italicized and have the same size as the
body text
- Finally, the pages should be US letter sized, numbered in the center of the
footer and the top left corner of each page should contain the title of the
paper
We already know how to do many of these things, but for some of them, we'll need
to learn some new tricks.
## Writing the right set rules
Let's start by writing some set rules for the document.
```example
#set text(11pt, "Linux Libertine")
#set par(justify: true)
#set page(
>>> margin: auto,
paper: "us-letter",
header: align(right + horizon)[
A fluid dynamic model for
glacier flow
],
footer: nr => align(
center + horizon,
[#nr],
),
)
#lorem(600)
```
You are already familiar with most of what is going on here. We set the text
size to `{11pt}` and the font to Linux Libertine. We also enable paragraph
justification and set the page size to US letter.
The `header` and `footer` arguments are new: With these, we can provide content
to fill the top and bottom margins of every page. In the header, we specify our
paper's title as requested by the conference style guide. We use the `align`
function to align the text to the right and the `horizon` keyword to make sure
that it is vertically centered in the margin.
Because we need a page number in the footer, we have to put different content
onto each page. To do that, we can pass a
[custom function]($type/function) to the footer argument that defines
how the footer should look for a given page number. Typst provides the page
number to this function. Once more, we use the `align` function to center the
page number horizontally and vertically.
We have to put the page variable into square brackets and prefix it with a
hashtag because the align function expects
[content,]($type/content) but the page number is an
[integer]($type/integer).
## Creating a title and abstract
Now, let's add a title and an abstract. We'll start with the title. We center
align it and increase its font weight by enclosing it in `[*stars*]`.
```example
>>> #set page(width: 300pt, margin: 30pt)
>>> #set text(11pt, "Linux Libertine")
#align(center, text(17pt)[
*A fluid dynamic model
for glacier flow*
])
```
This looks right. We used the `text` function to override the previous text
set rule locally, increasing the size to 17pt for the function's argument. Let's
also add the author list: Since we are writing this paper together with our
supervisor, we'll add our own and their name.
```example
>>> #set page(width: 300pt, margin: 30pt)
>>> #set text(11pt, "Linux Libertine")
>>>
>>> #align(center, text(17pt)[
>>> *A fluid dynamic model
>>> for glacier flow*
>>> ])
#grid(
columns: (1fr, 1fr),
align(center)[
Therese Tungsten \
Artos Institute \
#link("mailto:tung@artos.edu")
],
align(center)[
Dr. John Doe \
Artos Institute \
#link("mailto:doe@artos.edu")
]
)
```
The two author blocks are laid out next to each other. We use the
[`grid`]($func/grid) function to create this layout. With a grid, we can control
exactly how large each column is and which content goes into which cell. The
`columns` argument takes an array of [relative lengths]($type/relative-length)
or [fractions]($type/fraction). In this case, we passed it two equal fractional
sizes, telling it to split the available space into two equal columns. We then
passed two content arguments to the grid function. The first with our own
details, and the second with our supervisors'. We again use the `align` function
to center the content within the column. The grid takes an arbitrary number of
content arguments specifying the cells. Rows are added automatically, but they
can also be manually sized with the `rows` argument.
Now, let's add the abstract. Remember that the conference wants the abstract to
be set ragged and centered.
```example:0,0,612,317.5
>>> #set text(11pt, "Linux Libertine")
>>> #set par(justify: true)
>>> #set page(
>>> "us-letter",
>>> margin: auto,
>>> header: align(right + horizon)[
>>> A fluid dynamic model for
>>> glacier flow
>>> ],
>>> footer: page => align(
>>> center+horizon,
>>> [#page]
>>> ),
>>> )
>>>
>>> #align(center, text(17pt)[
>>> *A fluid dynamic model
>>> for glacier flow*
>>> ])
>>>
>>> #grid(
>>> columns: (1fr, 1fr),
>>> align(center)[
>>> Therese Tungsten \
>>> Artos Institute \
>>> #link("mailto:tung@artos.edu")
>>> ],
>>> align(center)[
>>> Dr. John Doe \
>>> Artos Institute \
>>> #link("mailto:doe@artos.edu")
>>> ]
>>> )
>>>
<<< ...
#align(center)[
#set par(justify: false)
*Abstract* \
#lorem(80)
]
>>> #lorem(600)
```
Well done! One notable thing is that we used a set rule within the content
argument of `align` to turn off justification for the abstract. This does not
affect the remainder of the document even though it was specified after the
first set rule because content blocks _scope_ styling. Anything set within a
content block will only affect the content within that block.
Another tweak could be to save the paper title in a variable, so that we do not
have to type it twice, for header and title. We can do that with the `{let}`
keyword:
```example
#let title = [
A fluid dynamic model
for glacier flow
]
<<< ...
>>> #set text(11pt, "Linux Libertine")
>>> #set par(justify: true)
#set page(
>>> "us-letter",
>>> margin: auto,
header: align(
right + horizon,
title
),
<<< ...
>>> footer: page => align(
>>> center+horizon,
>>> [#page]
>>> ),
)
#align(center, text(17pt)[
*#title*
])
<<< ...
>>> #grid(
>>> columns: (1fr, 1fr),
>>> align(center)[
>>> Therese Tungsten \
>>> Artos Institute \
>>> #link("mailto:tung@artos.edu")
>>> ],
>>> align(center)[
>>> Dr. John Doe \
>>> Artos Institute \
>>> #link("mailto:doe@artos.edu")
>>> ]
>>> )
>>>
>>> #align(center)[
>>> #set par(justify: false)
>>> *Abstract* \
>>> #lorem(80)
>>> ]
>>>
>>> #lorem(600)
```
After we bound the content to the `title` variable, we can use it in functions
and also within markup (prefixed by `#`, like functions). This way, if we decide
on another title, we can easily change it in one place.
## Adding columns and headings
The paper above unfortunately looks like a wall of lead. To fix that, let's add
some headings and switch our paper to a two-column layout. The
[`columns`]($func/columns) function takes a number and content, and layouts the
content into the specified number of columns. Since we want everything after the
abstract to be in two columns, we need to apply the column function to our whole
document.
Instead of wrapping the whole document in a giant function call, we can use an
"everything" show rule. This show rule does not feature a colon. Instead, we
directly provide a function that is given the rest of the document as a
parameter. We have called the parameter `rest` here, but you are free to choose
any name. The rule can then do anything with this content. In our case, it
passes it on to the `columns` function.
```example
>>> #let title = [
>>> A fluid dynamic model
>>> for glacier flow
>>> ]
>>>
>>> #set text(11pt, "Linux Libertine")
>>> #set par(justify: true)
>>> #set page(
>>> "us-letter",
>>> margin: auto,
>>> header: align(
>>> right + horizon,
>>> title
>>> ),
>>> footer: page => align(
>>> center+horizon,
>>> [#page]
>>> ),
>>> )
>>>
>>> #align(center, text(
>>> 17pt,
>>> weight: "bold",
>>> title,
>>> ))
>>>
>>> #grid(
>>> columns: (1fr, 1fr),
>>> align(center)[
>>> Therese Tungsten \
>>> Artos Institute \
>>> #link("mailto:tung@artos.edu")
>>> ],
>>> align(center)[
>>> Dr. John Doe \
>>> Artos Institute \
>>> #link("mailto:doe@artos.edu")
>>> ]
>>> )
>>>
>>> #align(center)[
>>> #set par(justify: false)
>>> *Abstract* \
>>> #lorem(80)
>>> ]
>>> #v(4mm)
<<< ...
#show rest => columns(2, rest)
= Introduction
#lorem(300)
= Related Work
#lorem(200)
```
Now there is only one thing left to do: Style our headings. We need to make them
centered and use small capitals. Because the `heading` function does not offer
a way to set any of that, we need to write our own heading show rule.
```example:50,250,265,270
>>> #let title = [
>>> A fluid dynamic model
>>> for glacier flow
>>> ]
>>>
>>> #set text(11pt, "Linux Libertine")
>>> #set par(justify: true)
>>> #set page(
>>> "us-letter",
>>> margin: auto,
>>> header: align(
>>> right + horizon,
>>> title
>>> ),
>>> footer: page => align(
>>> center + horizon,
>>> [#page]
>>> ),
>>> )
#show heading: it => block[
#set align(center)
#set text(12pt, weight: "regular")
#smallcaps(it.title)
]
<<< ...
>>>
>>> #align(center, text(
>>> 17pt,
>>> weight: "bold",
>>> title,
>>> ))
>>>
>>> #grid(
>>> columns: (1fr, 1fr),
>>> align(center)[
>>> Therese Tungsten \
>>> Artos Institute \
>>> #link("mailto:tung@artos.edu")
>>> ],
>>> align(center)[
>>> Dr. John Doe \
>>> Artos Institute \
>>> #link("mailto:doe@artos.edu")
>>> ]
>>> )
>>>
>>> #align(center)[
>>> #set par(justify: false)
>>> *Abstract* \
>>> #lorem(80)
>>> ]
>>>
>>> #v(4mm)
>>> #show rest => columns(2, rest)
>>>
>>> = Introduction
>>> #lorem(35)
>>>
>>> == Motivation
>>> #lorem(45)
```
This looks great! We used a show rule that applies to all headings. We give it a
function that gets passed the heading as a parameter. That parameter can be used
as content but it also has some fields like `title`, `numbers`, and `level` from
which we can compose a custom look. Here, we are center-aligning, setting the
font weight to `{"regular"}` because headings are bold by default, and use the
[`smallcaps`]($func/smallcaps) function to render the heading's title in small capitals.
The only remaining problem is that all headings look the same now. The
"Motivation" and "Problem Statement" subsections ought to be italic run in
headers, but right now, they look indistinguishable from the section headings. We
can fix that by using a `where` selector on our set rule: This is a
[method]($scripting/#methods) we can call on headings (and other
elements) that allows us to filter them by their level. We can use it to
differentiate between section and subsection headings:
```example:50,250,265,245
>>> #let title = [
>>> A fluid dynamic model
>>> for glacier flow
>>> ]
>>>
>>> #set text(11pt, "Linux Libertine")
>>> #set par(justify: true)
>>> #set page(
>>> "us-letter",
>>> margin: auto,
>>> header: align(
>>> right + horizon,
>>> title
>>> ),
>>> footer: page => align(
>>> center + horizon,
>>> [#page]
>>> ),
>>> )
>>>
#show heading.where(
level: 1
): it => block[
#set align(center)
#set text(12pt, weight: "regular")
#smallcaps(it.title)
]
#show heading.where(
level: 2
): it => text(
size: 11pt,
weight: "regular",
style: "italic",
it.title + [.],
)
>>>
>>> #align(center, text(
>>> 17pt,
>>> weight: "bold",
>>> title,
>>> ))
>>>
>>> #grid(
>>> columns: (1fr, 1fr),
>>> align(center)[
>>> Therese Tungsten \
>>> Artos Institute \
>>> #link("mailto:tung@artos.edu")
>>> ],
>>> align(center)[
>>> Dr. John Doe \
>>> Artos Institute \
>>> #link("mailto:doe@artos.edu")
>>> ]
>>> )
>>>
>>> #align(center)[
>>> #set par(justify: false)
>>> *Abstract* \
>>> #lorem(80)
>>> ]
>>>
>>> #v(4mm)
>>> #show rest => columns(2, rest)
>>>
>>> = Introduction
>>> #lorem(35)
>>>
>>> == Motivation
>>> #lorem(45)
```
This looks great! We wrote two show rules that each selectively apply to the
first and second level headings. We used a `where` selector to filter the
headings by their level. We then rendered the subsection headings as run-ins. We
also automatically add a period to the end of the subsection headings.
Let's review the conference's style guide:
- The font should be an 11pt serif font ✓
- The title should be in 17pt and bold ✓
- The paper contains a single-column abstract and two-column main text ✓
- The abstract should be centered ✓
- The main text should be justified ✓
- First level section headings should be centered, rendered in small caps and in 13pt ✓
- Second level headings are run-ins, italicized and have the same size as the
body text ✓
- Finally, the pages should be US letter sized, numbered in the center and the
top left corner of each page should contain the title of the paper ✓
We are now in compliance with all of these styles and can submit the paper to
the conference! The finished paper looks like this:
<img
src="3-advanced-paper.png"
alt="The finished paper"
style="box-shadow: 0 4px 12px rgb(89 85 101 / 20%); width: 500px; max-width: 100%; display: block; margin: 24px auto;"
>
## Review
You have now learned how to create headers and footers, how to use functions and
scopes to locally override styles, how to create more complex layouts with the [`grid`]($func/grid) function and how to write show rules for individual functions, and the whole document. You also learned how to use the
[`where` selector]($styling/#show-rules) to filter the headings by their level.
The paper was a great success! You've met a lot of like-minded researchers at
the conference and are planning a project which you hope to publish at the same
venue next year. You'll need to write a new paper using the same style guide
though, so maybe now you want to create a time-saving template for you and your
team?
In the next section, we will learn how to create templates that can be reused in
multiple documents. This is a more advanced topic, so feel free to come back
to it later if you don't feel up to it right now.

View File

@ -0,0 +1,378 @@
---
description: Typst's tutorial.
---
# Making a Template
In the previous three chapters of this tutorial, you have learned how to write a
document in Typst, apply basic styles, and customize its appearance in-depth to
comply with a publisher's style guide. Because the paper you wrote in the
previous chapter was a tremendous success, you have been asked to write a
follow-up article for the same conference. This time, you want to take the style
you created in the previous chapter and turn it into a reusable template. In
this chapter you will learn how to create a template that you and your team can
use with just one show rule. Let's get started!
## A toy template
In Typst, templates are functions in which you can wrap your whole document. To
learn how to do that, let's first review how to write your very own functions.
They can do anything you want them to, so why not go a bit crazy?
```example
#let amazed(term) = box[✨ #term ✨]
You are #amazed[beautiful]!
```
This function takes a single argument, `term`, and returns a content block with
the `term` surrounded by sparkles. We also put the whole thing in a box so that
the term we are amazed by cannot be separated from its sparkles by a line break.
Many functions that come with Typst have optional named parameters. Our
functions can also have them. Let's add a parameter to our function that lets us
choose the color of the text. We need to provide a default color in case the
parameter isn't given.
```example
#let amazed(term, color: blue) = {
text(color, box[✨ #term ✨])
}
You are #amazed[beautiful]!
I am #amazed(color: purple)[amazed]!
```
Templates now work by using an "everything" show rule that applies the custom
function to our whole document. Let's do that with our `amazed` function.
```example
>>> #let amazed(term, color: blue) = {
>>> text(color, box[✨ #term ✨])
>>> }
#show amazed
I choose to focus on the good
in my life and let go of any
negative thoughts or beliefs.
In fact, I am amazing!
```
Our whole document will now be passed to the `amazed` function, as if we
wrapped it around it. This is not especially useful with this particular
function, but when combined with set rules and named arguments, it can be very
powerful.
## Embedding set and show rules
To apply some set and show rules to our template, we can use `set` and `show`
within a content block in our function and then insert the document into
that content block.
```example
#let template(doc) = [
#set text("Inria Serif")
#show "something cool": [Typst]
#doc
]
#show template
I am learning something cool today.
It's going great so far!
```
Just like we already discovered in the previous chapter, set rules will apply to
everything within their content block. Since the everything show rule passes our
whole document to the `template` function, the text set rule and string show
rule in our template will apply to the whole document. Let's use this knowledge
to create a template that reproduces the body style of the paper we wrote in the
previous chapter.
```example
#let conf(title, doc) = {
set text(11pt, "Linux Libertine")
set par(justify: true)
set page(
paper: "us-letter",
>>> margin: auto,
header: align(
right + horizon,
title
),
<<< ...
)
// Heading show rules.
<<< ...
>>> show heading.where(
>>> level: 1
>>> ): it => block(
>>> align(center,
>>> text(
>>> 13pt,
>>> weight: "regular",
>>> smallcaps(it.title),
>>> )
>>> ),
>>> )
>>> show heading.where(
>>> level: 2
>>> ): it => box(
>>> text(
>>> 11pt,
>>> weight: "regular",
>>> style: "italic",
>>> it.title + [.],
>>> )
>>> )
columns(2, doc)
}
#show doc => conf([Paper title], doc)
= Introduction
#lorem(90)
<<< ...
>>> == Motivation
>>> #lorem(140)
>>>
>>> == Problem Statement
>>> #lorem(50)
>>>
>>> = Related Work
>>> #lorem(200)
```
We copy-pasted most of that code from the previous chapter. The only two
differences are that we wrapped everything in the function `conf` and are
calling the columns function directly on the `doc` argument as it already
contains the content of the document. Moreover, we used a curly-braced code
block instead of a content block. This way, we don't need to prefix all set
rules and function calls with a `#`. In exchange, we cannot write markup
directly into it anymore.
Also note where the title comes from: We previously had it inside of a variable.
Now, we are receiving it as the first parameter of the template function.
Thus, we must specify it in the show rule where we call the template.
## Templates with named arguments
Our paper in the previous chapter had a title and an author list. Lets add these
things to our template. In addition to the title, we want our template to accept
a list of authors with their affiliations and the paper's abstract. To keep
things readable, we'll add those as named arguments. In the end, we want it to
work like this:
```typ
#show doc => conf(
title: [Towards Improved Modelling],
authors: (
(
name: "Theresa Tungsten",
affiliation: "Artos Institute",
email: "tung@artos.edu",
),
(
name: "Eugene Deklan",
affiliation: "Honduras State",
email: "e.deklan@hstate.hn",
),
),
abstract: lorem(80),
doc,
)
...
```
Let's build this new template function. First, we add a default value to the
`title` argument. This way, we can call the template without specifying a title.
We also add the named `authors` and `abstract` parameters with empty defaults.
Next, we copy the code that generates title, abstract and authors from the
previous chapter into the template, replacing the fixed details with the
parameters.
The new `authors` parameter expects an [array]($type/array) of
[dictionaries]($type/dictionary) with the keys `name`, `affiliation` and
`email`. Because we can have an arbitrary number of authors, we dynamically
determine if we need one, two or three columns for the author list. First, we
determine the number of authors using the [`.len()`]($type/array.len) method on
the `authors` array. Then, we set the number of columns as the minimum of this
count and three, so that we never create more than three columns. If there are
more than three authors, a new row will be inserted instead. For this purpose,
we have also added a `row-gutter` parameter to the `grid` function. Otherwise,
the rows would be too close together. To extract the details about the authors
from the dictionary, we use the [field access syntax]($scripting/#fields).
We still have to provide an argument to the grid for each author: Here is where
the array's [`map` method]($type/array.map) comes in handy. It takes a function
as an argument that gets called with each element of the array. We pass it a
function that formats the details for each author and returns a new array
containing content values. We've now got one array of values that we'd like to
use as multiple arguments for the grid. We can do that by using the
[`spread` operator]($type/arguments). It takes an array and applies each of its elements as a separate argument to the function.
The resulting template function looks like this:
```typ
#let conf(
title: none,
authors: (),
abstract: [],
doc,
) = {
// Set and show rules from before.
<<< ...
set align(center)
text(17pt, title)
let count = authors.len()
let ncols = calc.min(count, 3)
grid(
columns: (1fr,) * ncols,
row-gutter: 24pt,
..authors.map(author => [
{author.name} \
{author.affiliation} \
#link("mailto:" + author.email)
]),
)
par(justify: false)[
*Abstract* \
#abstract
]
set align(left)
columns(2, doc)
}
```
## A separate file
Most of the time, a template is specified in a different file and then imported
into the document. This way, the main file you write in is kept clutter free and
your template is easily reused. Create a new text file in the file panel by
clicking the plus button and name it `conf.typ`. Move the `conf` function
definition inside of that new file. Now you can access it from your main file by
adding an import before the show rule. Name the function that you want to import
from another file between the `{import}` and `{from}` keywords and specify the
path of the file after the `{from}` keyword.
```example
>>> #let conf(
>>> title: none,
>>> authors: (),
>>> abstract: [],
>>> doc,
>>> ) = {
>>> set text(11pt, "Linux Libertine")
>>> set par(justify: true)
>>> set page(
>>> "us-letter",
>>> margin: auto,
>>> header: align(
>>> right + horizon,
>>> title
>>> ),
>>> footer: page => align(
>>> center + horizon,
>>> [#page]
>>> ),
>>> )
>>>
>>> show heading.where(
>>> level: 1
>>> ): it => block(
>>> align(center,
>>> text(
>>> 13pt,
>>> weight: "regular",
>>> smallcaps(it.title),
>>> )
>>> ),
>>> )
>>> show heading.where(
>>> level: 2
>>> ): it => box(
>>> text(
>>> 11pt,
>>> weight: "regular",
>>> style: "italic",
>>> it.title + [.],
>>> )
>>> )
>>>
>>> set align(center)
>>> text(17pt, title)
>>>
>>> let count = calc.min(authors.len(), 3)
>>> grid(
>>> columns: (1fr,) * count,
>>> row-gutter: 24pt,
>>> ..authors.map(author => [
>>> {author.name} \
>>> {author.affiliation} \
>>> #link("mailto:" + author.email)
>>> ]),
>>> )
>>>
>>> par(justify: false)[
>>> *Abstract* \
>>> #abstract
>>> ]
>>>
>>> set align(left)
>>> columns(2, doc)
>>>}
<<< #import conf from "conf.typ"
#show doc => conf(
title: [
Towards Improved Modelling
],
authors: (
(
name: "Theresa Tungsten",
affiliation: "Artos Institute",
email: "tung@artos.edu",
),
(
name: "Eugene Deklan",
affiliation: "Honduras State",
email: "e.deklan@hstate.hn",
),
),
abstract: lorem(80),
doc,
)
= Introduction
#lorem(90)
== Motivation
#lorem(140)
== Problem Statement
#lorem(50)
= Related Work
#lorem(200)
```
We have now converted the conference paper into a reusable template for that
conference! Why not share it on
[Typst's Discord server](https://discord.gg/2uDybryKPe) so that others can use
it too?
## Review
Congratulations, you have completed Typst's Tutorial! In this section, you have
learned how to define your own functions and how to create and apply templates
that define reusable document styles. You've made it far and learned a lot. You
can now use Typst to write your own documents and share them with others.
We are still a super young project and are looking for feedback. If you have any
questions, suggestions or found a bug, please let us know on
[Typst's Discord server](https://discord.gg/2uDybryKPe), on our
[contact form](https://typst.app/contact), or on
[social media.](https://twitter.com/typstapp)
So what are you waiting for? Go forth and write something! Or, if you haven't
got access yet, [sign up for the wait list](https://typst.app).

View File

@ -0,0 +1,54 @@
---
description: Typst's tutorial.
---
# Tutorial
Welcome to Typst's tutorial! In this tutorial, you will learn how to write and
format documents in Typst. We will start with everyday tasks and gradually
introduce more advanced features. This tutorial does not assume prior knowledge
of Typst, other Markup languages, or programming. We do assume that you know how
to edit a text file.
The best way to start is to open the Typst app and follow along with the
steps below. Do not have preview access yet?
[Sign up for the wait list](https://typst.app).
## When to use Typst
Before we get started, let's check what Typst is and when to use it. Typst is a
markup language for typesetting documents. It is designed to be easy to learn,
fast, and versatile. Typst takes text files with markup in them and outputs
PDFs.
Typst is a good choice for writing any long form text such as essays, articles,
scientific papers, books, reports, and homework assignments. Moreover, Typst is
a great fit for any documents containing mathematical notation, such as papers
in the math, physics, and engineering fields. Finally, due to its strong styling
and automation features, it is an excellent choice for any set of documents that
share a common style, such as a book series.
## How to get access to Typst
Starting December 26th, 2022, we are conducting a closed infrastructure test
into which we invite a small number of people from our wait list. A few months
later we will start a public beta of our web app and open source Typst
(currently planned for March of 2023).
At that point, we will also give you the option to download a local command line
compiler for Typst. This way, you can always compile your documents
independently from our web app. Still, the web app offers many useful feature
like live preview, autocompletion and collaboration for teams.
## What you will learn
This tutorial has four chapters. Each chapter builds on the previous one. Here is
what you will learn in each of them:
1. [Writing in Typst:]($tutorial/writing-in-typst) Learn how to write text and
insert images, equations, and other elements.
2. [Formatting:]($tutorial/formatting) Learn how to adjust the formatting
of your document, including font size, heading styles, and more.
3. [Advanced Styling:]($tutorial/advanced-styling) Create a complex page
layout for a scientific paper with typographic features such as an author
list and run-in headings.
4. [Making a Template:]($tutorial/making-a-template) Build a reusable template
from the paper you created in the previous chapter.
We hope you'll enjoy Typst!