From 029ae4a5ea7ad1e52112ce26b6d38ce1750dae3f Mon Sep 17 00:00:00 2001 From: Laurenz Date: Wed, 5 Feb 2025 14:24:10 +0100 Subject: Export target docs (#5812) Co-authored-by: Martin Haug <3874949+reknih@users.noreply.github.com> --- docs/reference/language/context.md | 233 ++++++++++++++++++++++ docs/reference/language/scripting.md | 373 +++++++++++++++++++++++++++++++++++ docs/reference/language/styling.md | 145 ++++++++++++++ docs/reference/language/syntax.md | 215 ++++++++++++++++++++ 4 files changed, 966 insertions(+) create mode 100644 docs/reference/language/context.md create mode 100644 docs/reference/language/scripting.md create mode 100644 docs/reference/language/styling.md create mode 100644 docs/reference/language/syntax.md (limited to 'docs/reference/language') diff --git a/docs/reference/language/context.md b/docs/reference/language/context.md new file mode 100644 index 00000000..bdd520f5 --- /dev/null +++ b/docs/reference/language/context.md @@ -0,0 +1,233 @@ +--- +description: | + How to deal with content that reacts to its location in the document. +--- + +# Context +Sometimes, we want to create content that reacts to its location in the +document. This could be a localized phrase that depends on the configured text +language or something as simple as a heading number which prints the right +value based on how many headings came before it. However, Typst code isn't +directly aware of its location in the document. Some code at the beginning of +the source text could yield content that ends up at the back of the document. + +To produce content that is reactive to its surroundings, we must thus +specifically instruct Typst: We do this with the `{context}` keyword, which +precedes an expression and ensures that it is computed with knowledge of its +environment. In return, the context expression itself ends up opaque. We cannot +directly access whatever results from it in our code, precisely because it is +contextual: There is no one correct result, there may be multiple results in +different places of the document. For this reason, everything that depends on +the contextual data must happen inside of the context expression. + +Aside from explicit context expressions, context is also established implicitly +in some places that are also aware of their location in the document: +[Show rules]($styling/#show-rules) provide context[^1] and numberings in the +outline, for instance, also provide the proper context to resolve counters. + +## Style context +With set rules, we can adjust style properties for parts or the whole of our +document. We cannot access these without a known context, as they may change +throughout the course of the document. When context is available, we can +retrieve them simply by accessing them as fields on the respective element +function. + +```example +#set text(lang: "de") +#context text.lang +``` + +As explained above, a context expression is reactive to the different +environments it is placed into. In the example below, we create a single context +expression, store it in the `value` variable and use it multiple times. Each use +properly reacts to the current surroundings. + +```example +#let value = context text.lang +#value + +#set text(lang: "de") +#value + +#set text(lang: "fr") +#value +``` + +Crucially, upon creation, `value` becomes opaque [content] that we cannot peek +into. It can only be resolved when placed somewhere because only then the +context is known. The body of a context expression may be evaluated zero, one, +or multiple times, depending on how many different places it is put into. + +## Location context +We've already seen that context gives us access to set rule values. But it can +do more: It also lets us know _where_ in the document we currently are, relative +to other elements, and absolutely on the pages. We can use this information to +create very flexible interactions between different document parts. This +underpins features like heading numbering, the table of contents, or page +headers dependent on section headings. + +Some functions like [`counter.get`]($counter.get) implicitly access the current +location. In the example below, we want to retrieve the value of the heading +counter. Since it changes throughout the document, we need to first enter a +context expression. Then, we use `get` to retrieve the counter's current value. +This function accesses the current location from the context to resolve the +counter value. Counters have multiple levels and `get` returns an array with the +resolved numbers. Thus, we get the following result: + +```example +#set heading(numbering: "1.") + += Introduction +#lorem(5) + +#context counter(heading).get() + += Background +#lorem(5) + +#context counter(heading).get() +``` + +For more flexibility, we can also use the [`here`] function to directly extract +the current [location] from the context. The example below +demonstrates this: + +- We first have `{counter(heading).get()}`, which resolves to `{(2,)}` as + before. +- We then use the more powerful [`counter.at`] with [`here`], which in + combination is equivalent to `get`, and thus get `{(2,)}`. +- Finally, we use `at` with a [label] to retrieve the value of the counter at a + _different_ location in the document, in our case that of the introduction + heading. This yields `{(1,)}`. Typst's context system gives us time travel + abilities and lets us retrieve the values of any counters and states at _any_ + location in the document. + +```example +#set heading(numbering: "1.") + += Introduction +#lorem(5) + += Background +#lorem(5) + +#context [ + #counter(heading).get() \ + #counter(heading).at(here()) \ + #counter(heading).at() +] +``` + +As mentioned before, we can also use context to get the physical position of +elements on the pages. We do this with the [`locate`] function, which works +similarly to `counter.at`: It takes a location or other [selector] that resolves +to a unique element (could also be a label) and returns the position on the +pages for that element. + +```example +Background is at: \ +#context locate().position() + += Introduction +#lorem(5) +#pagebreak() + += Background +#lorem(5) +``` + +There are other functions that make use of the location context, most +prominently [`query`]. Take a look at the +[introspection]($category/introspection) category for more details on those. + +## Nested contexts +Context is also accessible from within function calls nested in context blocks. +In the example below, `foo` itself becomes a contextual function, just like +[`to-absolute`]($length.to-absolute) is. + +```example +#let foo() = 1em.to-absolute() +#context { + foo() == text.size +} +``` + +Context blocks can be nested. Contextual code will then always access the +innermost context. The example below demonstrates this: The first `text.lang` +will access the outer context block's styles and as such, it will **not** +see the effect of `{set text(lang: "fr")}`. The nested context block around the +second `text.lang`, however, starts after the set rule and will thus show +its effect. + +```example +#set text(lang: "de") +#context [ + #set text(lang: "fr") + #text.lang \ + #context text.lang +] +``` + +You might wonder why Typst ignores the French set rule when computing the first +`text.lang` in the example above. The reason is that, in the general case, Typst +cannot know all the styles that will apply as set rules can be applied to +content after it has been constructed. Below, `text.lang` is already computed +when the template function is applied. As such, it cannot possibly be aware of +the language change to French in the template. + +```example +#let template(body) = { + set text(lang: "fr") + upper(body) +} + +#set text(lang: "de") +#context [ + #show: template + #text.lang \ + #context text.lang +] +``` + +The second `text.lang`, however, _does_ react to the language change because +evaluation of its surrounding context block is deferred until the styles for it +are known. This illustrates the importance of picking the right insertion point for a context to get access to precisely the right styles. + +The same also holds true for the location context. Below, the first +`{c.display()}` call will access the outer context block and will thus not see +the effect of `{c.update(2)}` while the second `{c.display()}` accesses the inner context and will thus see it. + +```example +#let c = counter("mycounter") +#c.update(1) +#context [ + #c.update(2) + #c.display() \ + #context c.display() +] +``` + +## Compiler iterations +To resolve contextual interactions, the Typst compiler processes your document +multiple times. For instance, to resolve a `locate` call, Typst first provides a +placeholder position, layouts your document and then recompiles with the known +position from the finished layout. The same approach is taken to resolve +counters, states, and queries. In certain cases, Typst may even need more than +two iterations to resolve everything. While that's sometimes a necessity, it may +also be a sign of misuse of contextual functions (e.g. of +[state]($state/#caution)). If Typst cannot resolve everything within five +attempts, it will stop and output the warning "layout did not converge within 5 +attempts." + +A very careful reader might have noticed that not all of the functions presented +above actually make use of the current location. While +`{counter(heading).get()}` definitely depends on it, +`{counter(heading).at()}`, for instance, does not. However, it still +requires context. While its value is always the same _within_ one compilation +iteration, it may change over the course of multiple compiler iterations. If one +could call it directly at the top level of a module, the whole module and its +exports could change over the course of multiple compiler iterations, which +would not be desirable. + +[^1]: Currently, all show rules provide styling context, but only show rules on + [locatable]($location/#locatable) elements provide a location context. diff --git a/docs/reference/language/scripting.md b/docs/reference/language/scripting.md new file mode 100644 index 00000000..5e0f1555 --- /dev/null +++ b/docs/reference/language/scripting.md @@ -0,0 +1,373 @@ +--- +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 +In Typst, markup and code are fused into one. All but the most common elements +are created with _functions._ To make this as convenient as possible, Typst +provides compact syntax to embed a code expression into markup: An expression is +introduced with a hash (`#`) and normal markup parsing resumes after the +expression is finished. If a character would continue the expression but should +be interpreted as text, the expression can forcibly be ended with a semicolon +(`;`). + +```example +#emph[Hello] \ +#emoji.face \ +#"hello".len() +``` + +The example above shows a few of the available expressions, including +[function calls]($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 hash syntax (e.g. binary operator expressions). To embed +these into markup, you can use parentheses, as in `[#(1 + 2)]`. + +## 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]($function). Content + blocks are delimited by square brackets and can contain arbitrary markup. A + content block results in a value of type [content]. An arbitrary number of + content blocks can be passed as trailing arguments to functions. That is, + `{list([A], [B])}` is equivalent to `{list[A][B]}`. + +Content and code blocks can be nested arbitrarily. In the example below, +`{[hello ]}` is joined with the output of `{a + [ the ] + b}` yielding +`{[hello from the *world*]}`. + +```example +#{ + let a = [from] + let b = [*world*] + [hello ] + a + [ the ] + b +} +``` + +## Bindings and Destructuring { #bindings } +As already demonstrated above, variables can be defined with `{let}` bindings. +The variable is assigned the value of the expression that follows the `=` sign. +The assignment of a value is optional, if no value is assigned, the variable +will be initialized as `{none}`. The `{let}` keyword can also be used to create +a [custom named function]($function/#defining-functions). Variables can be +accessed for the rest of the containing block (or the rest of the file if there +is no containing block). + +```example +#let name = "Typst" +This is #name's documentation. +It explains #name. + +#let add(x, y) = x + y +Sum is #add(2, 3). +``` + +Let bindings can also be used to destructure [arrays]($array) and +[dictionaries]($dictionary). In this case, the left-hand side of the +assignment should mirror an array or dictionary. The `..` operator can be used +once in the pattern to collect the remainder of the array's or dictionary's +items. + +```example +#let (x, y) = (1, 2) +The coordinates are #x, #y. + +#let (a, .., b) = (1, 2, 3, 4) +The first element is #a. +The last element is #b. + +#let books = ( + Shakespeare: "Hamlet", + Homer: "The Odyssey", + Austen: "Persuasion", +) + +#let (Austen,) = books +Austen wrote #Austen. + +#let (Homer: h) = books +Homer wrote #h. + +#let (Homer, ..other) = books +#for (author, title) in other [ + #author wrote #title. +] +``` + +You can use the underscore to discard elements in a destructuring pattern: + +```example +#let (_, y, _) = (1, 2, 3) +The y coordinate is #y. +``` + +Destructuring also works in argument lists of functions ... + +```example +#let left = (2, 4, 5) +#let right = (3, 2, 6) +#left.zip(right).map( + ((a,b)) => a + b +) +``` + +... and on the left-hand side of normal assignments. This can be useful to +swap variables among other things. + +```example +#{ + let a = 1 + let b = 2 + (a, b) = (b, a) + [a = #a, b = #b] +} +``` + +## Conditionals +With a conditional, you can display or compute different things depending on +whether some condition is fulfilled. Typst supports `{if}`, `{else if}` and +`{else}` expressions. 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 +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 value in array {..}}` \ + Iterates over the items in the [array]. The destructuring syntax described in + [Let binding]($scripting/#bindings) can also be used here. + +- `{for pair in dict {..}}` \ + Iterates over the key-value pairs of the [dictionary]. The pairs can also be + destructured by using `{for (key, value) in dict {..}}`. It is more efficient + than `{for pair in dict.pairs() {..}}` because it doesn't create a temporary + array of all key-value pairs. + +- `{for letter in "abc" {..}}` \ + Iterates over the characters of the [string]($str). Technically, it iterates + over the grapheme clusters of the string. Most of the time, a grapheme cluster + is just a single codepoint. However, a grapheme cluster could contain multiple + codepoints, like a flag emoji. + +- `{for byte in bytes("😀") {..}}` \ + Iterates over the [bytes], which can be converted from a [string]($str) or + [read] from a file without encoding. Each byte value is an [integer]($int) + between `{0}` and `{255}`. + +To control the execution of the loop, Typst provides the `{break}` and +`{continue}` statements. The former performs an early exit from the loop while +the latter skips ahead to the next iteration of the loop. + +```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 +You can use _dot notation_ to access fields on a value. For values of type +[`content`], you can also use the [`fields`]($content.fields) function to list +the fields. + +The value in question can be either: +- a [dictionary] that has the specified key, +- a [symbol] that has the specified modifier, +- a [module] containing the specified definition, +- [content] consisting of an element that has the specified field. The + available fields match the arguments of the + [element function]($function/#element-functions) that were given when the + element was constructed. + +```example +#let it = [= Heading] +#it.body \ +#it.depth \ +#it.fields() + +#let dict = (greet: "Hello") +#dict.greet \ +#emoji.face + +``` + +## Methods +A _method call_ is a convenient way to call a function that is scoped to a +value's [type]. For example, we can call the [`str.len`]($str.len) function in +the following two equivalent ways: + +```example +#str.len("abc") is the same as +#"abc".len() +``` + +The structure of a method call is `{value.method(..args)}` and its equivalent +full function call is `{type(value).method(value, ..args)}`. The documentation +of each type lists its scoped functions. You cannot currently define your own +methods. + +```example +#let values = (1, 2, 3, 4) +#values.pop() \ +#values.len() \ + +#("a, b, c" + .split(", ") + .join[ --- ]) + +#"abc".len() is the same as +#str.len("abc") +``` + +There are a few special functions that modify the value they are called on (e.g. +[`array.push`]($array.push)). These functions _must_ be called in method form. +In some cases, when the method is only called for its side effect, its return +value should be ignored (and not participate in joining). The canonical way to +discard a value is with a let binding: `{let _ = array.remove(1)}`. + +## Modules +You can split up your Typst projects into multiple files called _modules._ A +module can refer to the content and definitions of another module in multiple +ways: + +- **Including:** `{include "bar.typ"}` \ + Evaluates the file at the path `bar.typ` and returns the resulting [content]. + +- **Import:** `{import "bar.typ"}` \ + Evaluates the file at the path `bar.typ` and inserts the resulting [module] + into the current scope as `bar` (filename without extension). You can use the + `as` keyword to rename the imported module: `{import "bar.typ" as baz}`. You + can import nested items using dot notation: `{import "bar.typ": baz.a}`. + +- **Import items:** `{import "bar.typ": a, b}` \ + Evaluates the file at the path `bar.typ`, extracts the values of the variables + `a` and `b` (that need to be defined in `bar.typ`, e.g. through `{let}` + bindings) and defines them in the current file. Replacing `a, b` with `*` + loads all variables defined in a module. You can use the `as` keyword to + rename the individual items: `{import "bar.typ": a as one, b as two}` + +Instead of a path, you can also use a [module value]($module), as shown in the +following example: + +```example +#import emoji: face +#face.grin +``` + +## Packages +To reuse building blocks across projects, you can also create and import Typst +_packages._ A package import is specified as a triple of a namespace, a name, +and a version. + +```example +>>> #let add(x, y) = x + y +<<< #import "@preview/example:0.1.0": add +#add(2, 7) +``` + +The `preview` namespace contains packages shared by the community. You can find +all available community packages on [Typst Universe]($universe). + +If you are using Typst locally, you can also create your own system-local +packages. For more details on this, see the +[package repository](https://github.com/typst/packages). + +## Operators +The following table lists all available unary and binary operators with effect, +arity (unary, binary) and precedence level (higher binds stronger). Some +operations, such as [modulus]($calc.rem-euclid), do not have a special syntax +and can be achieved using functions from the +[`calc`]($category/foundations/calc) module. + +| Operator | Effect | Arity | Precedence | +|:----------:|---------------------------------|:------:|:----------:| +| `{-}` | Negation | Unary | 7 | +| `{+}` | No effect (exists for symmetry) | Unary | 7 | +| `{*}` | Multiplication | Binary | 6 | +| `{/}` | Division | Binary | 6 | +| `{+}` | Addition | Binary | 5 | +| `{-}` | Subtraction | Binary | 5 | +| `{==}` | Check equality | Binary | 4 | +| `{!=}` | Check inequality | Binary | 4 | +| `{<}` | Check less-than | Binary | 4 | +| `{<=}` | Check less-than or equal | Binary | 4 | +| `{>}` | Check greater-than | Binary | 4 | +| `{>=}` | Check greater-than or equal | Binary | 4 | +| `{in}` | Check if in collection | Binary | 4 | +| `{not in}` | Check if not in collection | Binary | 4 | +| `{not}` | Logical "not" | Unary | 3 | +| `{and}` | Short-circuiting logical "and" | Binary | 3 | +| `{or}` | Short-circuiting logical "or" | Binary | 2 | +| `{=}` | Assignment | Binary | 1 | +| `{+=}` | Add-Assignment | Binary | 1 | +| `{-=}` | Subtraction-Assignment | Binary | 1 | +| `{*=}` | Multiplication-Assignment | Binary | 1 | +| `{/=}` | Division-Assignment | Binary | 1 | + +[semver]: https://semver.org/ diff --git a/docs/reference/language/styling.md b/docs/reference/language/styling.md new file mode 100644 index 00000000..b0b7ab71 --- /dev/null +++ b/docs/reference/language/styling.md @@ -0,0 +1,145 @@ +--- +description: All concepts needed to style your document with Typst. +--- + +# Styling +Typst includes a flexible styling system that automatically applies styling of +your choice to your document. With _set rules,_ you can configure basic +properties of elements. This way, you create most common styles. However, there +might not be a built-in property for everything you wish to do. For this reason, +Typst further supports _show rules_ that can completely redefine the appearance +of elements. + +## Set rules +With set rules, you can customize the appearance of elements. They are written +as a [function call]($function) to an [element +function]($function/#element-functions) preceded by the `{set}` keyword (or +`[#set]` in markup). Only optional parameters of that function can be provided +to the set rule. Refer to each function's documentation to see which parameters +are optional. In the example below, we use two set rules to change the +[font family]($text.font) and [heading numbering]($heading.numbering). + +```example +#set heading(numbering: "I.") +#set text( + font: "New Computer Modern" +) + += Introduction +With set rules, you can style +your document. +``` + +A top level set rule stays in effect until the end of the file. When nested +inside of a block, it is only in effect until the end of that block. With a +block, you can thus restrict the effect of a rule to a particular segment of +your document. Below, we use a content block to scope the list styling to one +particular list. + +```example +This list is affected: #[ + #set list(marker: [--]) + - Dash +] + +This one is not: +- Bullet +``` + +Sometimes, you'll want to apply a set rule conditionally. For this, you can use +a _set-if_ rule. + +```example +#let task(body, critical: false) = { + set text(red) if critical + [- #body] +} + +#task(critical: true)[Food today?] +#task(critical: false)[Work deadline] +``` + +## Show rules +With show rules, you can deeply customize the look of a type of element. The +most basic form of show rule is a _show-set rule._ Such a rule is written as the +`{show}` keyword followed by a [selector], a colon and then a set rule. The most +basic form of selector is an [element function]($function/#element-functions). +This lets the set rule only apply to the selected element. In the example below, +headings become dark blue while all other text stays black. + +```example +#show heading: set text(navy) + += This is navy-blue +But this stays black. +``` + +With show-set rules you can mix and match properties from different functions to +achieve many different effects. But they still limit you to what is predefined +in Typst. For maximum flexibility, you can instead write a show rule that +defines how to format an element from scratch. To write such a show rule, +replace the set rule after the colon with an arbitrary [function]. This function +receives the element in question and can return arbitrary content. The available +[fields]($scripting/#fields) on the element passed to the function again match +the parameters of the respective element function. Below, we define a show rule +that formats headings for a fantasy encyclopedia. + +```example +#set heading(numbering: "(I)") +#show heading: it => [ + #set align(center) + #set text(font: "Inria Serif") + \~ #emph(it.body) + #counter(heading).display( + it.numbering + ) \~ +] + += Dragon +With a base health of 15, the +dragon is the most powerful +creature. + += Manticore +While less powerful than the +dragon, the manticore gets +extra style points. +``` + +Like set rules, show rules are in effect until the end of the current block or +file. + +Instead of a function, the right-hand side of a show rule can also take a +literal string or content block that should be directly substituted for the +element. And apart from a function, the left-hand side of a show rule can also +take a number of other _selectors_ that define what to apply the transformation +to: + +- **Everything:** `{show: rest => ..}` \ + Transform everything after the show rule. This is useful to apply a more + complex layout to your whole document without wrapping everything in a giant + function call. + +- **Text:** `{show "Text": ..}` \ + Style, transform or replace text. + +- **Regex:** `{show regex("\w+"): ..}` \ + Select and transform text with a regular expression for even more flexibility. + See the documentation of the [`regex` type]($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 : ..}` \ + Select and transform elements that have the specified label. See the + documentation of the [`label` type]($label) for more details. + +```example +#show "Project": smallcaps +#show "badly": "great" + +We started Project in 2019 +and are still working on it. +Project is progressing badly. +``` diff --git a/docs/reference/language/syntax.md b/docs/reference/language/syntax.md new file mode 100644 index 00000000..fdc4d154 --- /dev/null +++ b/docs/reference/language/syntax.md @@ -0,0 +1,215 @@ +--- +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. + +## Modes +Typst has three syntactical modes: Markup, math, and code. Markup mode is the +default in a Typst document, math mode lets you write mathematical formulas, and +code mode lets you use Typst's scripting features. + +You can switch to a specific mode at any point by referring to the following +table: + +| New mode | Syntax | Example | +|----------|---------------------------------|---------------------------------| +| Code | Prefix the code with `#` | `[Number: #(1 + 2)]` | +| Math | Surround equation with `[$..$]` | `[$-x$ is the opposite of $x$]` | +| Markup | Surround markup with `[[..]]` | `{let name = [*Typst!*]}` | + +Once you have entered code mode with `#`, you don't need to use further hashes +unless you switched back to markup or math mode in between. + +## Markup +Typst provides built-in markup for the most common document elements. Most of +the syntax elements are just shortcuts for a corresponding function. The table +below lists all markup that is available and links to the best place to learn +more about their syntax and usage. + +| Name | Example | See | +| ------------------ | ---------------------------- | ------------------------ | +| Paragraph break | Blank line | [`parbreak`] | +| Strong emphasis | `[*strong*]` | [`strong`] | +| Emphasis | `[_emphasis_]` | [`emph`] | +| Raw text | ``[`print(1)`]`` | [`raw`] | +| Link | `[https://typst.app/]` | [`link`] | +| Label | `[]` | [`label`] | +| Reference | `[@intro]` | [`ref`] | +| Heading | `[= Heading]` | [`heading`] | +| Bullet list | `[- item]` | [`list`] | +| Numbered list | `[+ item]` | [`enum`] | +| Term list | `[/ Term: description]` | [`terms`] | +| Math | `[$x^2$]` | [Math]($category/math) | +| Line break | `[\]` | [`linebreak`] | +| Smart quote | `['single' or "double"]` | [`smartquote`] | +| Symbol shorthand | `[~]`, `[---]` | [Symbols]($category/symbols/sym) | +| Code expression | `[#rect(width: 1cm)]` | [Scripting]($scripting/#expressions) | +| Character escape | `[Tweet at us \#ad]` | [Below](#escapes) | +| Comment | `[/* block */]`, `[// line]` | [Below](#comments) | + +## Math mode { #math } +Math mode is a special markup mode that is used to typeset mathematical +formulas. It is entered by wrapping an equation in `[$]` characters. This works +both in markup and code. The equation will be typeset into its own block if it +starts and ends with at least one space (e.g. `[$ x^2 $]`). Inline math can be +produced by omitting the whitespace (e.g. `[$x^2$]`). An overview over the +syntax specific to math mode follows: + +| Name | Example | See | +| ---------------------- | ------------------------ | ------------------------ | +| Inline math | `[$x^2$]` | [Math]($category/math) | +| Block-level math | `[$ x^2 $]` | [Math]($category/math) | +| Bottom attachment | `[$x_1$]` | [`attach`]($category/math/attach) | +| Top attachment | `[$x^2$]` | [`attach`]($category/math/attach) | +| Fraction | `[$1 + (a+b)/5$]` | [`frac`]($math.frac) | +| Line break | `[$x \ y$]` | [`linebreak`] | +| Alignment point | `[$x &= 2 \ &= 3$]` | [Math]($category/math) | +| Variable access | `[$#x$, $pi$]` | [Math]($category/math) | +| Field access | `[$arrow.r.long$]` | [Scripting]($scripting/#fields) | +| Implied multiplication | `[$x y$]` | [Math]($category/math) | +| Symbol shorthand | `[$->$]`, `[$!=$]` | [Symbols]($category/symbols/sym) | +| Text/string in math | `[$a "is natural"$]` | [Math]($category/math) | +| Math function call | `[$floor(x)$]` | [Math]($category/math) | +| Code expression | `[$#rect(width: 1cm)$]` | [Scripting]($scripting/#expressions) | +| Character escape | `[$x\^2$]` | [Below](#escapes) | +| Comment | `[$/* comment */$]` | [Below](#comments) | + +## Code mode { #code } +Within code blocks and expressions, new expressions can start without a leading +`#` character. Many syntactic elements are specific to expressions. Below is +a table listing all syntax that is available in code mode: + +| Name | Example | See | +| ------------------------ | ----------------------------- | ---------------------------------- | +| None | `{none}` | [`none`] | +| Auto | `{auto}` | [`auto`] | +| Boolean | `{false}`, `{true}` | [`bool`] | +| Integer | `{10}`, `{0xff}` | [`int`] | +| Floating-point number | `{3.14}`, `{1e5}` | [`float`] | +| Length | `{2pt}`, `{3mm}`, `{1em}`, .. | [`length`] | +| Angle | `{90deg}`, `{1rad}` | [`angle`] | +| Fraction | `{2fr}` | [`fraction`] | +| Ratio | `{50%}` | [`ratio`] | +| String | `{"hello"}` | [`str`] | +| Label | `{}` | [`label`] | +| Math | `[$x^2$]` | [Math]($category/math) | +| Raw text | ``[`print(1)`]`` | [`raw`] | +| Variable access | `{x}` | [Scripting]($scripting/#blocks) | +| 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]($array) | +| Dictionary | `{(a: "hi", b: 2)}` | [Dictionary]($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]($function) | +| Argument spreading | `{min(..nums)}` | [Arguments]($arguments) | +| Unnamed function | `{(x, y) => x + y}` | [Function]($function) | +| Let binding | `{let x = 1}` | [Scripting]($scripting/#bindings) | +| Named function | `{let f(x) = 2 * x}` | [Function]($function) | +| Set rule | `{set text(14pt)}` | [Styling]($styling/#set-rules) | +| Set-if rule | `{set text(..) if .. }` | [Styling]($styling/#set-rules) | +| Show-set rule | `{show heading: set block(..)}` | [Styling]($styling/#show-rules) | +| Show rule with function | `{show raw: it => {..}}` | [Styling]($styling/#show-rules) | +| Show-everything rule | `{show: template}` | [Styling]($styling/#show-rules) | +| Context expression | `{context text.lang}` | [Context]($context) | +| 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]($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 are ignored by Typst and will not be included in the output. This is +useful to exclude old versions or to add annotations. To comment out a single +line, start it with `//`: +```example +// our data barely supports +// this claim + +We show with $p < 0.05$ +that the difference is +significant. +``` + +Comments can also be wrapped between `/*` and `*/`. In this case, the comment +can span over multiple lines: +```example +Our study design is as follows: +/* Somebody write this up: + - 1000 participants. + - 2x2 data design. */ +``` + +## Escape sequences { #escapes } +Escape sequences are used to insert special characters that are hard to type or +otherwise have special meaning in Typst. To escape a character, precede it with +a backslash. To insert any Unicode codepoint, you can write a hexadecimal escape +sequence: `[\u{1f600}]`. The same kind of escape sequences also work in +[strings]($str). + +```example +I got an ice cream for +\$1.50! \u{1f600} +``` + +## Paths +Typst has various features that require a file path to reference external +resources such as images, Typst files, or data files. Paths are represented as +[strings]($str). There are two kinds of paths: Relative and absolute. + +- A **relative path** searches from the location of the Typst file where the + feature is invoked. It is the default: + ```typ + #image("images/logo.png") + ``` + +- An **absolute path** searches from the _root_ of the project. It starts with a + leading `/`: + ```typ + #image("/assets/logo.png") + ``` + +### Project root +By default, the project root is the parent directory of the main Typst file. +For security reasons, you cannot read any files outside of the root directory. + +If you want to set a specific folder as the root of your project, you can use +the CLI's `--root` flag. Make sure that the main file is contained in the +folder's subtree! +```bash +typst compile --root .. file.typ +``` + +In the web app, the project itself is the root directory. You can always read +all files within it, no matter which one is previewed (via the eye toggle next +to each Typst file in the file panel). + +### Paths and packages +A package can only load files from its own directory. Within it, absolute paths +point to the package root, rather than the project root. For this reason, it +cannot directly load files from the project directory. If a package needs +resources from the project (such as a logo image), you must pass the already +loaded image, e.g. as a named parameter `{logo: image("mylogo.svg")}`. Note that +you can then still customize the image's appearance with a set rule within the +package. + +In the future, paths might become a +[distinct type from strings](https://github.com/typst/typst/issues/971), so that +they can retain knowledge of where they were constructed. This way, resources +could be loaded from a different root. -- cgit v1.2.3