summaryrefslogtreecommitdiff
path: root/docs/tutorial
diff options
context:
space:
mode:
Diffstat (limited to 'docs/tutorial')
-rw-r--r--docs/tutorial/1-writing.md308
-rw-r--r--docs/tutorial/2-formatting.md283
-rw-r--r--docs/tutorial/3-advanced.md509
-rw-r--r--docs/tutorial/4-template.md380
-rw-r--r--docs/tutorial/welcome.md44
5 files changed, 1524 insertions, 0 deletions
diff --git a/docs/tutorial/1-writing.md b/docs/tutorial/1-writing.md
new file mode 100644
index 00000000..a2a2ca65
--- /dev/null
+++ b/docs/tutorial/1-writing.md
@@ -0,0 +1,308 @@
+---
+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 a figure { #figure }
+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 in markup, 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 now aligned at the left side of the page by
+default. It's also lacking a caption. Let's fix that by using the
+[figure]($func/figure) function. This function takes the figure's contents as a
+positional argument and an optional caption as a named argument.
+
+Within the argument list of the `figure` function, Typst is already in code mode. This means, you can now remove the hashtag before the image function call.
+The hashtag is only needed directly in markup (to disambiguate text from function calls).
+
+The caption consists of arbitrary markup. To give markup to a function, we
+enclose it in square brackets. This construct is called a _content block._
+
+```example
+#figure(
+ image("glacier.jpg", width: 70%),
+ caption: [
+ _Glaciers_ form an important part
+ of the earth's climate system.
+ ],
+)
+```
+
+You continue to write your report and now want to reference the figure. To do
+that, first attach a label to figure. A label uniquely identifies an element in
+your document. Add one after the figure by enclosing some name in angle
+brackets. You can then reference the figure in your text by writing an `[@]`
+symbol followed by that name. Headings and equations can also be labelled to
+make them referenceable.
+
+```example
+Glaciers as the one shown in
+@glaciers will cease to exist if
+we don't take action soon!
+
+#figure(
+ image("glacier.jpg", width: 70%),
+ caption: [
+ _Glaciers_ form an important part
+ of the earth's climate system.
+ ],
+) <glaciers>
+```
+
+<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 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
+valid kind of content.
+</div>
+
+## Adding a bibliography { #bibliography }
+As you write up your report, you need to back up some of your claims. You can
+add a bibliography to your document with the
+[`bibliography`]($func/bibliography) function. This function expects a path
+to a bibliography file.
+
+Typst's native bibliography format is
+[Hayagriva](https://github.com/typst/hayagriva/blob/main/docs/file-format.md),
+but for compatibility you can also use BibLaTeX files. As your classmate has
+already done a literature survey and sent you a `.bib` file, you'll use that
+one. Upload the file through the file panel to access it in Typst.
+
+Once the document contains a bibliography, you can start citing from it.
+Citations use the same syntax as references to a label. As soon as you cite a
+source for the first time, it will appear in the bibliography section of your
+document. Typst supports different citation and bibliography styles. Consult the
+[reference]($func/bibliography.style) for more details.
+
+```example
+= Methods
+We follow the glacier melting models
+established in @glacier-melt.
+
+#bibliography("works.bib")
+```
+
+## Maths { #maths }
+After fleshing out the methods section, 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
+subscript. 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/math.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/math.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 symbol name must be
+preceded with `#sym.` there. See the [symbols section]($category/symbols/sym)
+for a list of all available symbols.
+
+## Review { #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.
diff --git a/docs/tutorial/2-formatting.md b/docs/tutorial/2-formatting.md
new file mode 100644
index 00000000..c231b878
--- /dev/null
+++ b/docs/tutorial/2-formatting.md
@@ -0,0 +1,283 @@
+---
+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 { #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).
+]
+```
+
+Wait, shouldn't all arguments of a function be specified within parentheses? Why
+is there a second set of square brackets with 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.
+
+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 { #autocomplete }
+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 { #page-setup }
+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(
+ font: "New Computer Modern",
+ size: 10pt
+)
+#set page(
+ paper: "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 `{"New Computer Modern"}`. 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 { #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(font: "New Computer Modern")
+#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(font: "New Computer Modern")
+#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 { #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 { #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.
diff --git a/docs/tutorial/3-advanced.md b/docs/tutorial/3-advanced.md
new file mode 100644
index 00000000..42a810fd
--- /dev/null
+++ b/docs/tutorial/3-advanced.md
@@ -0,0 +1,509 @@
+---
+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 { #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 { #set-rules }
+Let's start by writing some set rules for the document.
+
+```example
+#set page(
+>>> margin: auto,
+ paper: "us-letter",
+ header: align(right)[
+ A fluid dynamic model for
+ glacier flow
+ ],
+ numbering: "1",
+)
+#set par(justify: true)
+#set text(
+ font: "Linux Libertine",
+ size: 11pt,
+)
+
+#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` argument is new: With it, we can provide content to fill the top
+margin 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.
+
+Last but not least is the `numbering` argument. Here, we can provide a
+[numbering pattern]($func/numbering) that defines how to number the pages. By
+setting into to `{"1"}`, Typst only displays the bare page number. Setting it to
+`{"(1/1)"}` would have displayed the current page and total number of pages
+surrounded by parentheses. And we could even have provided a completely custom
+function here to format things to our liking.
+
+## Creating a title and abstract { #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(font: "Linux Libertine", 11pt)
+#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(font: "Linux Libertine", 11pt)
+>>>
+>>> #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(font: "Linux Libertine", 11pt)
+>>> #set par(justify: true)
+>>> #set page(
+>>> "us-letter",
+>>> margin: auto,
+>>> header: align(right + horizon)[
+>>> A fluid dynamic model for
+>>> glacier flow
+>>> ],
+>>> numbering: "1",
+>>> )
+>>>
+>>> #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:single
+#let title = [
+ A fluid dynamic model
+ for glacier flow
+]
+
+<<< ...
+
+>>> #set text(font: "Linux Libertine", 11pt)
+>>> #set par(justify: true)
+#set page(
+>>> "us-letter",
+>>> margin: auto,
+ header: align(
+ right + horizon,
+ title
+ ),
+<<< ...
+>>> numbering: "1",
+)
+
+#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 { #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. To write such a show rule, put a colon directly behind
+the show keyword and then provide a function. This function 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 function can then do anything with this
+content. In our case, it passes it on to the `columns` function.
+
+```example:single
+>>> #let title = [
+>>> A fluid dynamic model
+>>> for glacier flow
+>>> ]
+>>>
+>>> #set text(font: "Linux Libertine", 11pt)
+>>> #set par(justify: true)
+>>> #set page(
+>>> "us-letter",
+>>> margin: auto,
+>>> header: align(
+>>> right + horizon,
+>>> title
+>>> ),
+>>> numbering: "1",
+>>> )
+>>>
+>>> #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(font: "Linux Libertine", 11pt)
+>>> #set par(justify: true)
+>>> #set page(
+>>> "us-letter",
+>>> margin: auto,
+>>> header: align(
+>>> right + horizon,
+>>> title
+>>> ),
+>>> numbering: "1",
+>>> )
+#show heading: it => [
+ #set align(center)
+ #set text(12pt, weight: "regular")
+ #block(smallcaps(it.body))
+]
+
+<<< ...
+>>>
+>>> #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(font: "Linux Libertine", 11pt)
+>>> #set par(justify: true)
+>>> #set page(
+>>> "us-letter",
+>>> margin: auto,
+>>> header: align(
+>>> right + horizon,
+>>> title
+>>> ),
+>>> numbering: "1",
+>>> )
+>>>
+#show heading.where(
+ level: 1
+): it => block(width: 100%)[
+ #set align(center)
+ #set text(12pt, weight: "regular")
+ #smallcaps(it.body)
+]
+
+#show heading.where(
+ level: 2
+): it => text(
+ size: 11pt,
+ weight: "regular",
+ style: "italic",
+ it.body + [.],
+)
+>>>
+>>> #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 { #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.
diff --git a/docs/tutorial/4-template.md b/docs/tutorial/4-template.md
new file mode 100644
index 00000000..320f82b2
--- /dev/null
+++ b/docs/tutorial/4-template.md
@@ -0,0 +1,380 @@
+---
+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 { #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 { #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(font: "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 page(
+ paper: "us-letter",
+>>> margin: auto,
+ header: align(
+ right + horizon,
+ title
+ ),
+<<< ...
+ )
+ set par(justify: true)
+ set text(
+ font: "Linux Libertine",
+ size: 11pt,
+ )
+
+ // Heading show rules.
+<<< ...
+>>> show heading.where(
+>>> level: 1
+>>> ): it => block(
+>>> align(center,
+>>> text(
+>>> 13pt,
+>>> weight: "regular",
+>>> smallcaps(it.body),
+>>> )
+>>> ),
+>>> )
+>>> show heading.where(
+>>> level: 2
+>>> ): it => box(
+>>> text(
+>>> 11pt,
+>>> weight: "regular",
+>>> style: "italic",
+>>> it.body + [.],
+>>> )
+>>> )
+
+ 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 { #named-arguments }
+Our paper in the previous chapter had a title and an author list. Let's 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 item 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 items 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 { #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. Specify the path of the file between the
+`{import}` keyword and a colon, then name the function that you
+want to import.
+
+```example:single
+>>> #let conf(
+>>> title: none,
+>>> authors: (),
+>>> abstract: [],
+>>> doc,
+>>> ) = {
+>>> set text(font: "Linux Libertine", 11pt)
+>>> set par(justify: true)
+>>> set page(
+>>> "us-letter",
+>>> margin: auto,
+>>> header: align(
+>>> right + horizon,
+>>> title
+>>> ),
+>>> numbering: "1",
+>>> )
+>>>
+>>> show heading.where(
+>>> level: 1
+>>> ): it => block(
+>>> align(center,
+>>> text(
+>>> 13pt,
+>>> weight: "regular",
+>>> smallcaps(it.body),
+>>> )
+>>> ),
+>>> )
+>>> show heading.where(
+>>> level: 2
+>>> ): it => box(
+>>> text(
+>>> 11pt,
+>>> weight: "regular",
+>>> style: "italic",
+>>> it.body + [.],
+>>> )
+>>> )
+>>>
+>>> 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.typ": conf
+#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 { #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 you 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? [Sign up](https://typst.app) and write something!
diff --git a/docs/tutorial/welcome.md b/docs/tutorial/welcome.md
new file mode 100644
index 00000000..530336cb
--- /dev/null
+++ b/docs/tutorial/welcome.md
@@ -0,0 +1,44 @@
+---
+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 sign up to the Typst app for free and follow along
+with the steps below. The app gives you instant preview, syntax highlighting and
+helpful autocompletions. Alternatively, you can follow along in your local text
+editor with the [open-source CLI](https://github.com/typst/typst).
+
+## When to use Typst { #when-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.
+
+## What you will learn { #learnings }
+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!