From 42afa410ae561eb5b267080d088bca529a5d0b54 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Wed, 17 May 2023 14:38:03 +0200 Subject: Better documentation outlines --- docs/Cargo.toml | 1 + docs/src/general/changelog.md | 6 +- docs/src/general/community.md | 10 +- docs/src/general/guide-for-latex-users.md | 592 ------------------------------ docs/src/guides/guide-for-latex-users.md | 592 ++++++++++++++++++++++++++++++ docs/src/guides/welcome.md | 11 + docs/src/html.rs | 114 +++++- docs/src/lib.rs | 210 ++++++++++- docs/src/reference/groups.yml | 12 +- docs/src/reference/welcome.md | 4 +- docs/src/tutorial/1-writing.md | 8 +- docs/src/tutorial/2-formatting.md | 12 +- docs/src/tutorial/3-advanced.md | 10 +- docs/src/tutorial/4-template.md | 10 +- docs/src/tutorial/welcome.md | 4 +- 15 files changed, 938 insertions(+), 658 deletions(-) delete mode 100644 docs/src/general/guide-for-latex-users.md create mode 100644 docs/src/guides/guide-for-latex-users.md create mode 100644 docs/src/guides/welcome.md (limited to 'docs') diff --git a/docs/Cargo.toml b/docs/Cargo.toml index 326e85a9..c84a24ab 100644 --- a/docs/Cargo.toml +++ b/docs/Cargo.toml @@ -20,6 +20,7 @@ once_cell = "1" pulldown-cmark = "0.9" serde = { version = "1", features = ["derive"] } serde_yaml = "0.8" +typed-arena = "2" unicode_names2 = "0.6.0" unscanny = "0.1" yaml-front-matter = "0.1" diff --git a/docs/src/general/changelog.md b/docs/src/general/changelog.md index 54c8d0c3..c53d9d98 100644 --- a/docs/src/general/changelog.md +++ b/docs/src/general/changelog.md @@ -5,7 +5,7 @@ description: | --- # Changelog -## April 26, 2023 (v0.3.0) +## Version 0.3.0 (April 26, 2023) { #v0.3.0 } - **Breaking changes:** - Renamed a few symbols: What was previous `dot.op` is now just `dot` and the basic dot is `dot.basic`. The same applies to `ast` and `tilde`. @@ -77,7 +77,7 @@ description: | -## April 11, 2023 (v0.2.0) +## Version 0.2.0 (April 11, 2023) { #v0.2.0 } - **Breaking changes:** - Removed support for iterating over index and value in [for loops]($scripting/#loops). This is now handled via unpacking and @@ -119,7 +119,7 @@ description: | -## April 04, 2023 (v0.1.0) +## Version 0.1.0 (April 04, 2023) { #v0.1.0 } - **Breaking changes:** - When using the CLI, you now have to use subcommands: - `typst compile file.typ` or `typst c file.typ` to create a PDF diff --git a/docs/src/general/community.md b/docs/src/general/community.md index 020c7b5f..32d2d185 100644 --- a/docs/src/general/community.md +++ b/docs/src/general/community.md @@ -22,7 +22,7 @@ welcome to connect with us on social media [LinkedIn](https://linkedin.com/company/typst), and [GitHub](https://github.com/typst)). -## What to share? +## What to share? { #want-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: @@ -34,7 +34,7 @@ community members, but if you need a little inspiration, here are a few ideas: - Share importable files or templates that you use to style your documents - Alert us of bugs you encounter while using Typst -## Beta test +## Beta test { #beta-test } We are starting a public beta test of our product on March 21st, 2023. The Typst compiler is still under active development and breaking changes can occur at any point. The compiler is developed in the open on @@ -45,7 +45,7 @@ when new features become available in the preview. We'll also update you on the development progress of large features. A development tracker will become available on the documentation pages soon. -## How to support Typst +## How to support Typst { #support-typst } If you want to support Typst, there are multiple ways to do that! You can [contribute to the code](https://github.com/typst/typst) or [translate the strings in Typst](https://github.com/search?q=repo%3Atypst%2Ftypst+impl+LocalName+for&type=code) @@ -54,7 +54,7 @@ to your native language if it's not supported yet. You can also help us by sponsorship tiers are available and all of them come with a set of goodies. No matter how you contribute, thank you for your support! -## Community Rules +## Community Rules { #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 @@ -67,6 +67,6 @@ 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! +## See you soon! { #see-you } Thanks again for learning more about Typst. We would be delighted to meet you on our [Discord server](https://discord.gg/2uDybryKPe)! diff --git a/docs/src/general/guide-for-latex-users.md b/docs/src/general/guide-for-latex-users.md deleted file mode 100644 index 0e1688ff..00000000 --- a/docs/src/general/guide-for-latex-users.md +++ /dev/null @@ -1,592 +0,0 @@ ---- -description: | - Are you a LaTeX user? This guide explains the differences and - similarities between Typst and LaTeX so you can get started quickly. ---- - -# Guide for LaTeX users -This page is a good starting point if you have used LaTeX before and want to try -Typst. We will explore the main differences between these two systems from a -user perspective. Although Typst is not built upon LaTeX and has a different -syntax, you will learn how to use your LaTeX skills to get a head start. - - - -Just like LaTeX, Typst is a markup-based typesetting system: You compose your -document in a text file and mark it up with commands and other syntax. Then, you -use a compiler to typeset the source file into a PDF. However, Typst also -differs from LaTeX in several aspects: For one, Typst uses more dedicated syntax -(like you may know from Markdown) for common tasks. Typst's commands are also -more principled: They all work the same, so unlike in LaTeX, you just need to -understand a few general concepts instead of learning different conventions for -each package. Moreover Typst compiles faster than LaTeX: Compilation usually -takes milliseconds, not seconds, so the web app and the compiler can both -provide instant previews. - -In the following, we will cover some of the most common questions a user -switching from LaTeX will have when composing a document in Typst. If you prefer -a step-by-step introduction to Typst, check out our [tutorial]($tutorial). - -## How do I create a new, empty document? -That's easy. You just create a new, empty text file (the file extension is -`.typ`). No boilerplate is needed to get started. Simply start by writing your -text. It will be set on an empty A4-sized page. If you are using the web app, -click "+ Empty document" to create a new project with a file and enter the -editor. [Paragraph breaks]($func/parbreak) work just as they do in LaTeX, just -use a blank line. - -```example -Hey there! - -Here are two paragraphs. The -output is shown to the right. -``` - -## How do I create a section heading, emphasis, ...? -LaTeX uses the command `\section` to create a section heading. To nest deeper, -you can use `\subsection`, `\subsubsection`, etc. Depending on your document -class, there is also `\part` or `\chapter`. - -In Typst, [headings]($func/heading) are less verbose: You prefix the line with -the heading on it with an equals sign and a space to get a first-order heading: -`[= Introduction]`. If you need a second-order heading, you use two equals -signs: `[== In this paper]`. You can nest headings as deeply as you'd like by -adding more equals signs. - -Emphasis (usually rendered as italic text) is expressed by enclosing text in -`[_underscores_]` and strong emphasis (usually rendered in boldface) by using -`[*stars*]` instead. - -Below, there is a comparison between LaTeX commands and their Typst equivalents. -You can also check out the [full syntax cheat sheet]($syntax). - -| Element | LaTeX | Typst | See | -|:-----------------|:--------------------------|:-----------------------|:-------------------------| -| Strong emphasis | `\textbf{strong}` | `[*strong*]` | [`strong`]($func/strong) | -| Emphasis | `\emph{emphasis}` | `[_emphasis_]` | [`emph`]($func/emph) | -| Monospace / code | `\texttt{print(1)}` | ``[`print(1)`]`` | [`raw`]($func/raw) | -| Link | `\url{https://typst.app}` | `[https://typst.app/]` | [`link`]($func/link) | -| Label | `\label{intro}` | `[]` | [`label`]($func/label) | -| Reference | `\ref{intro}` | `[@intro]` | [`ref`]($func/ref) | -| Citation | `\cite{humphrey97}` | `[@humphrey97]` | [`cite`]($func/cite) | -| Bullet list | `itemize` environment | `[- List]` | [`list`]($func/list) | -| Numbered list | `enumerate` environment | `[+ List]` | [`enum`]($func/enum) | -| Term list | `description` environment | `[/ Term: List]` | [`terms`]($func/terms) | -| Figure | `figure` environment | `figure` function | [`figure`]($func/figure) | -| Table | `table` environment | `table` function | [`table`]($func/table) | -| Equation | `$x$`, `align` / `equation` environments | `[$x$]`, `[$ x = y $]` | [`equation`]($func/equation) | - -[Lists]($func/list) do not rely on environments in Typst. Instead, they have -lightweight syntax like headings. To create an unordered list (`itemize`), -prefix the line of the list item with a hyphen: - -````example -To write this list in Typst... - -```latex -\begin{itemize} - \item Fast - \item Flexible - \item Intuitive -\end{itemize} -``` - -...just type this: - -- Fast -- Flexible -- Intuitive - -```` - -By indenting them beyond the hyphen, you can also include multiple paragraphs or -nested lists in a single list item. If the list item's become longer, it's best -to put blank lines between the list items. This increases the spacing between -the list's items. - -To get a [numbered list]($func/enum) (`enumerate`) instead, use a `+` instead of -the hyphen. For a [term list]($func/terms) (`description`), write -`[/ Term: Description]` instead. - -## How do I use a command? -LaTeX heavily relies on commands (prefixed by backslashes). It uses these -_macros_ to affect the typesetting process and to insert and manipulate content. -Some commands accept arguments, most frequently they are enclosed in curly -braces: `\cite{rasmus}`. - -Typst differentiates between [markup mode and code mode]($scripting/#blocks). -Markup mode is the default and where you can write text and use syntactic -constructs like `[*stars for bold text*]`. Code mode is similar to other -programming languages like Python and allows you to write code like `{1 + 2 == -3}`. - -Within Typst's markup, you can switch to code mode for a single command (or -rather, _expression_) using a hashtag (`#`). This is how you call functions and -use features like [imports]($scripting/#modules) within markup. Within these -commands and function calls, code mode applies. To embed -[_content_]($type/content) as a value, you can go back to markup mode using -square brackets: - -```example -First, a rectangle: -#rect() - -Let me show how to do -#underline([_underlined_ text]) - -We can also do some maths: -#calc.max(3, 2 * 4) - -And finally a little loop: -#for x in range(3) [ - Hi #x. -] -``` - -A function call always involves the name of the function ([`rect`]($func/rect), -[`underline`]($func/underline), [`calc.max`]($category/calc/max), -[`range`]($func/range)) and then an argument list, even if it is empty. The -argument list is enclosed in parentheses. - -### Arguments -A function can have multiple arguments. Some arguments are positional, i.e. you -just provide the value: The function `[#lower("SCREAM")]` returns its argument -in all-lowercase. Many functions use named arguments instead of positional -arguments to increase legibility. For example, the dimensions and stroke of a -rectangle are defined with named arguments: - -```example -#rect( - width: 2cm, - height: 1cm, - stroke: red, -) -``` - -You specify a named argument by first entering its name (above, it's `width`, -`height`, and `stroke`), then a colon, followed by the value (`2cm`, `1cm`, -`red`). You can find the available named arguments in the [reference -page]($reference) for each function or in the autocomplete panel when typing. -Named arguments are similar to how some LaTeX environments are configured, for -example, you would type `\begin{enumerate}[label={\alph*)}]` to start a list -with the labels `a)`, `b)`, and so on. - -Often, you want to provide some [content]($type/content) to a function. For -example, the LaTeX command `\underline{Alternative A}` would translate to -`[#underline([Alternative A])]` in Typst. The square brackets indicate that a -value is content. Within these brackets, you can use normal markup. However, -that's a lot of parentheses for a pretty simple construct. This is why you can -also move trailing content arguments after the parentheses (and omit the -parentheses if they would end up empty). - -```example -Typst is an #underline[alternative] -to LaTeX. - -#rect(fill: aqua)[Get started here!] -``` - -### Data types -You likely already noticed that the arguments have distinctive data types. Typst -supports [many data types]($type). Below, there is a table with a few of the -most important ones and how to write them: - -| Data type | Example | -|:-------------------------------------|:----------------------------------| -| [Content]($type/content) | `{[*fast* typesetting]}` | -| [String]($type/string) | `{"Pietro S. Author"}` | -| [Integer]($type/integer) | `{23}` | -| [Floating point number]($type/float) | `{1.459}` | -| [Absolute length]($type/length) | `{12pt}`, `{5in}`, `{0.3cm}`, ... | -| [Relative length]($type/ratio) | `{65%}` | - -The difference between content and string is that content can contain markup, -including function calls, while a string really is just a sequence of -characters. You can use [operators]($scripting/#operators) like `+` for -summation and `==` for equality on these types like you would in a conventional -programming language instead of using `\addtocounter` or `\ifnum`. You can even -define [variables]($scripting/#bindings) and do computations with them. - -In order to specify values of any of these types, you have to be in code mode! - -### Commands to affect the remaining document -In LaTeX, some commands like `\textbf{bold text}` are passed their argument in curly -braces and only affect that argument whereas other commands like `\bfseries bold -text` act as switches and change the appearance of all following content in the -document or the current scope (denoted by a set of curly braces). - -In Typst, functions can be used in both ways: With effects applying until the -end of the document or block or just to its arguments. For example, -`[#text(weight: "bold")[bold text]]` will only embolden its argument, while -`[#set text(weight: "bold")]` will embolden any text until the end of the -current block, or, if there is none, document. The effects of a function are -immediately obvious depending on if it is used in a call or a -[set rule.]($styling/#set-rules) - -```example -I am starting out with small text. - -#set text(14pt) - -This is a bit #text(18pt)[larger,] -don't you think? -``` - -Set rules may appear anywhere in the document and can be though of as -pre-setting the arguments of their function: - -```example -#set enum(numbering: "I.") - -Good results can only be obtained by -+ following best practices -+ being aware of current results - of other researchers -+ checking the data for biases -``` - -The `+` is syntactic sugar (think of it as an abbreviation) for a call to the -[`{enum}`]($func/enum) function, to which we apply a set rule above. [Most -syntax is linked to a function in this way.]($syntax) If you need to style an -element beyond what its arguments enable, you can completely redefine its -appearance with a [show rule]($styling/#show-rules) (somewhat comparable to -`\renewcommand`). - -## How do I load a document class? -In LaTeX, you start your main `.tex` file with the `\documentclass{article}` -command to define how your document is supposed to look. In that command, you -may have replaced `article` with another value such as `report` and `amsart` to -select a different look. - -When using Typst, you style your documents with [functions]($type/function). -Typically, you use a template that provides a function that styles your whole -document. First, you import the function from a template file. Then, you apply -it to your whole document. This is accomplished with a -[show rule]($styling/#show-rules) that wraps the following document in a given -function. The following example illustrates how it works: - -```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: conf.with( - 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), -) - -Let's get started writing this -article by putting insightful -paragraphs right here! -``` - -The [`{import}`]($scripting/#modules) statement makes -[functions]($type/function) (and other definitions) from another file available. -In this example, it imports the `conf` function from the `conf.typ` file. This -function formats content as a conference article. We use the show rule to apply -it to the document and also configure some metadata about the article. Finally, -we can get started writing our article below! - -
- -Functions are Typst's "commands" and can transform their arguments to an output -value, including document _content._ Functions are "pure", which means that they -cannot have any effects beyond creating an output value / output content. This -is in stark contrast to LaTeX macros that can have arbitrary effects on your -document. - -To let a function style your whole document, the show rule processes everything -that comes after it and calls the function specified after the colon with the -result as an argument. The `.with` part is a _method_ that takes the `conf` -function and pre-configures some if its arguments before passing it on to the -show rule. -
- -In the web app, you can choose from predefined templates or even -create your own using the template wizard. You can also check out the -[`awesome-typst` repository](https://github.com/qjcg/awesome-typst) to find -templates made by the community. We plan to build a package manager to make -templates even easier to share in the future! - -You can also [create your own, custom templates.]($tutorial/making-a-template) -They are shorter and more readable than the corresponding LaTeX `.sty` files by -orders of magnitude, so give it a try! - -## How do I load packages? -Most things you load packages for in LaTeX are just included in Typst, no need -to load or install anything. Below, we compiled a table with frequently loaded -packages and their corresponding Typst functions. - -| LaTeX Package | Typst Alternative | -|:--------------------------------|:---------------------------------------------------------------------| -| graphicx, svg | [`image`]($func/image) function | -| tabularx | [`table`]($func/table), [`grid`]($func/grid) functions | -| fontenc, inputenc, unicode-math | Just start writing! | -| babel, polyglossia | [`text`]($func/text.lang) function: `[#set text(lang: "zh")]` | -| amsmath | [Math mode]($category/math) | -| amsfonts, amssymb | [`sym`]($category/symbols) module and [syntax]($syntax/#math) | -| geometry, fancyhdr | [`page`]($func/page) function | -| xcolor | [`text`]($func/text.fill) function: `[#set text(fill: rgb("#0178A4"))]` | -| hyperref | [`link`]($func/link) function | -| bibtex, biblatex, natbib | [`cite`]($func/cite), [`bibliography`]($func/bibliography) functions | -| lstlisting, minted | [`raw`]($func/raw) function and syntax | -| parskip | [`block`]($func/block.spacing) and [`par`]($func/par.first-line-indent) functions | -| csquotes | Type `["]` or `[']` and set the [`text`]($func/text.lang) language | -| caption | [`figure`]($func/figure) function | -| enumitem | [`list`]($func/list), [`enum`]($func/enum), [`terms`]($func/terms) functions | - -If you need to load functions and variables from another file, for example to -use a template, you can use an [`import`]($scripting/#modules) statement. If you -want to include the textual content of another file instead, you can use an -[`{include}`]($scripting/#modules) statement. It will yield the content of the -included file and put it in your document. - -Currently, there is no package manager for Typst, but we plan to build one so -that you can easily use packages with tools and templates from the community and -publish your own. - -## How do I input maths? -To enter math mode in Typst, just enclose your equation in dollar signs. You can -enter display mode by putting spaces or newlines between the opening and closing -dollar sign and the equation. - -```example -The sum of the numbers from -$1$ to $n$ is: - -$ sum_(k=1)^n k = (n(n+1))/2 $ -``` - -[Math mode]($category/math) works differently than regular markup or code mode. -Single characters and numbers with any amount of digits are displayed as -mathematical variables and values (of your equation), while multiple consecutive -non-number characters will be interpreted as Typst variables. - -As you can see in the example above, Typst pre-defines a lot of useful variables -in math mode. All Greek and some Hebrew letters are resolved by their name. -Refer to the [symbol page]($func/symbol) or use the autocomplete panel to check -which symbols are available. Alternate and related forms of symbols can often be -selected by [appending a modifier]($type/symbol) after a period. For example, -`arrow.l.squiggly` inserts a squiggly left-pointing arrow. If you want to insert -multiletter text in your expression instead, enclose it in double quotes: - -```example -$ delta "if" x <= 5 $ -``` - -You can type many symbols with shorthands like `<=`, `>=`, and `->`. Similarly, -delimiters will scale automatically for their expressions, just as if `\left` -and `\right` commands were implicitly inserted in LaTeX. You can customize -delimiter behavior using the [`lr` function]($func/lr). - -Typst will automatically set terms around a slash `/` as a fraction while -honoring operator precedence. All round parentheses not made redundant by the -fraction will appear in the output. - -```example -$ f(x) = (x + 1) / x $ -``` - -[Sub- and superscripts]($func/attach) work similarly in Typst and LaTeX. Typing -`{$x^2$}` will produce a superscript, `{$x_2$}` yields a subscript. If you want -to include more than one value in a sub- or superscript, enclose their contents -in parentheses: `{$x_(a -> epsilon)$}`. - -Just like you can insert variables without typing a `#` or `/`, you can also use -functions "naked": - -```example -$ f(x, y) := cases( - 1 "if" (x dot y)/2 <= 0, - 2 "if" x "is even", - 3 "if" x in NN, - 4 "else", -) $ -``` - -The above example uses the [`cases` function]($func/cases) to describe f. Within -the cases function, arguments are delimited using commas and the arguments are -also interpreted as math. If you would need to interpret arguments as Typst -values instead, prefix them with a `#`: - -```example -$ (a + b)^2 - = a^2 - + text(fill: #maroon, 2 a b) - + b^2 $ -``` - -You can use all Typst functions within math mode and insert any content. If you -want them to work normally, with code mode in the argument list, you can prefix -their call with a `#`. Nobody can stop you from using rectangles or emoji as -your variables anymore: - -```example -$ sum^10_(🥸=1) - #rect(width: 4mm, height: 2mm)/🥸 - = 🧠 maltese $ -``` - -If you'd like to enter your mathematical symbols directly as Unicode, that is -possible, too! - -Math calls can have two-dimensional argument lists using `;` as a delimiter. The -most common use for this is the [`mat` function]($func/mat) that creates -matrices: - -```example -$ mat( - 1, 2, ..., 10; - 2, 2, ..., 10; - dots.v, dots.v, dots.down, dots.v; - 10, 10, ..., 10; -) $ -``` - -## How do I get the "LaTeX look?" -Papers set in LaTeX have an unmistakeable look. This is mostly due to their -font, Computer Modern, justification, narrow line spacing, and wide margins. - -The example below -- sets wide [margins]($func/page.margin) -- enables [justification]($func/par.justify), [tighter lines]($func/par.leading) - and [first-line-indent]($func/par.first-line-indent) -- [sets the font]($func/text.font) to "New Computer Modern", an OpenType - derivate of Computer Modern for both text and [code blocks]($func/raw) -- disables paragraph [spacing]($func/block.spacing) -- increases [spacing]($func/block.spacing) around [headings]($func/heading) - -```typ -#set page(margin: 1.75in) -#set par(leading: 0.55em, first-line-indent: 1.8em, justify: true) -#set text(font: "New Computer Modern") -#show raw: set text(font: "New Computer Modern Mono") -#show par: set block(spacing: 0.55em) -#show heading: set block(above: 1.4em, below: 1em) -``` - -This should be a good starting point! If you want to go further, why not create -a reusable template? - -## What limitations does Typst currently have compared with LaTeX? -Although Typst can be a LaTeX replacement for many today, there are still -features that Typst does not (yet) support. Here is a list of them which, where -applicable, contains possible workarounds. - -- **Native charts and plots.** LaTeX users often create charts along with their - documents in PGF/TikZ. Typst does not yet include tools to draw diagrams, but - the community is stepping up with solutions such as - [`typst-canvas`](https://github.com/johannes-wolf/typst-canvas), - [`typst-plot`](https://github.com/johannes-wolf/typst-plot), and - [`circuitypst`](https://github.com/fenjalien/circuitypst). You can add those - to your document to get started with drawing diagrams. - -- **Change page margins without a pagebreak.** In LaTeX, margins can always be - adjusted, even without a pagebreak. To change margins in Typst, you use the - [`page` function]($func/page) which will force a page break. If you just want - a few paragraphs to stretch into the margins, then reverting to the old - margins, you can use the [`pad` function]($func/pad) with negative padding. - -- **Floating figures.** The figure command of LaTeX will smartly choose where to - place a figure, be it on the top or bottom of the page, or a dedicated figure - page. Typst's figure will always appear at the spot where they have been - inserted in the markup. While this behavior can save some headache, it is - often cumbersome to manually place figures. We will be adding this feature - soon! - -- **Include PDFs as images.** In LaTeX, it has become customary to insert vector - graphics as PDF or EPS files. Typst supports neither format as an image - format, but you can easily convert both into SVG files with [online - tools](https://cloudconvert.com/pdf-to-svg) or - [Inkscape](https://inkscape.org/). We plan to add automatic conversion for - these file formats to the Typst web app, too! - -- **Page break optimization.** LaTeX runs some smart algorithms to not only - optimize line but also page breaks. While Typst tries to avoid widows and - orphans, it uses less sophisticated algorithms to determine page breaks. You - can insert custom page breaks in Typst using `[#pagebreak(weak: true)]` before - submitting your document. The argument `weak` ensures that no double page - break will be created if this spot would be a natural page break - anyways. You can also use `[#v(1fr)]` to distribute space on your page. It - works quite similar to LaTeX's `\vfill`. - -- **Bibliographies are not customizable.** In LaTeX, the packages `bibtex`, - `biblatex`, and `natbib` provide a wide range of reference and bibliography - formats. You can also use custom `.bbx` files to define your own styles there. - Typst only supports a small set of citation styles at the moment, but we want - to build upon this by supporting [Citation Style Language - (CSL)](https://citationstyles.org), an XML-based format backed by Zotero that - allows you to describe your own bibliography styles. diff --git a/docs/src/guides/guide-for-latex-users.md b/docs/src/guides/guide-for-latex-users.md new file mode 100644 index 00000000..46559f6d --- /dev/null +++ b/docs/src/guides/guide-for-latex-users.md @@ -0,0 +1,592 @@ +--- +description: | + Are you a LaTeX user? This guide explains the differences and + similarities between Typst and LaTeX so you can get started quickly. +--- + +# Guide for LaTeX users +This page is a good starting point if you have used LaTeX before and want to try +Typst. We will explore the main differences between these two systems from a +user perspective. Although Typst is not built upon LaTeX and has a different +syntax, you will learn how to use your LaTeX skills to get a head start. + + + +Just like LaTeX, Typst is a markup-based typesetting system: You compose your +document in a text file and mark it up with commands and other syntax. Then, you +use a compiler to typeset the source file into a PDF. However, Typst also +differs from LaTeX in several aspects: For one, Typst uses more dedicated syntax +(like you may know from Markdown) for common tasks. Typst's commands are also +more principled: They all work the same, so unlike in LaTeX, you just need to +understand a few general concepts instead of learning different conventions for +each package. Moreover Typst compiles faster than LaTeX: Compilation usually +takes milliseconds, not seconds, so the web app and the compiler can both +provide instant previews. + +In the following, we will cover some of the most common questions a user +switching from LaTeX will have when composing a document in Typst. If you prefer +a step-by-step introduction to Typst, check out our [tutorial]($tutorial). + +## How do I create a new, empty document? { #getting-started } +That's easy. You just create a new, empty text file (the file extension is +`.typ`). No boilerplate is needed to get started. Simply start by writing your +text. It will be set on an empty A4-sized page. If you are using the web app, +click "+ Empty document" to create a new project with a file and enter the +editor. [Paragraph breaks]($func/parbreak) work just as they do in LaTeX, just +use a blank line. + +```example +Hey there! + +Here are two paragraphs. The +output is shown to the right. +``` + +## How do I create a section heading, emphasis, ...? { #elements } +LaTeX uses the command `\section` to create a section heading. To nest deeper, +you can use `\subsection`, `\subsubsection`, etc. Depending on your document +class, there is also `\part` or `\chapter`. + +In Typst, [headings]($func/heading) are less verbose: You prefix the line with +the heading on it with an equals sign and a space to get a first-order heading: +`[= Introduction]`. If you need a second-order heading, you use two equals +signs: `[== In this paper]`. You can nest headings as deeply as you'd like by +adding more equals signs. + +Emphasis (usually rendered as italic text) is expressed by enclosing text in +`[_underscores_]` and strong emphasis (usually rendered in boldface) by using +`[*stars*]` instead. + +Below, there is a comparison between LaTeX commands and their Typst equivalents. +You can also check out the [full syntax cheat sheet]($syntax). + +| Element | LaTeX | Typst | See | +|:-----------------|:--------------------------|:-----------------------|:-------------------------| +| Strong emphasis | `\textbf{strong}` | `[*strong*]` | [`strong`]($func/strong) | +| Emphasis | `\emph{emphasis}` | `[_emphasis_]` | [`emph`]($func/emph) | +| Monospace / code | `\texttt{print(1)}` | ``[`print(1)`]`` | [`raw`]($func/raw) | +| Link | `\url{https://typst.app}` | `[https://typst.app/]` | [`link`]($func/link) | +| Label | `\label{intro}` | `[]` | [`label`]($func/label) | +| Reference | `\ref{intro}` | `[@intro]` | [`ref`]($func/ref) | +| Citation | `\cite{humphrey97}` | `[@humphrey97]` | [`cite`]($func/cite) | +| Bullet list | `itemize` environment | `[- List]` | [`list`]($func/list) | +| Numbered list | `enumerate` environment | `[+ List]` | [`enum`]($func/enum) | +| Term list | `description` environment | `[/ Term: List]` | [`terms`]($func/terms) | +| Figure | `figure` environment | `figure` function | [`figure`]($func/figure) | +| Table | `table` environment | `table` function | [`table`]($func/table) | +| Equation | `$x$`, `align` / `equation` environments | `[$x$]`, `[$ x = y $]` | [`equation`]($func/equation) | + +[Lists]($func/list) do not rely on environments in Typst. Instead, they have +lightweight syntax like headings. To create an unordered list (`itemize`), +prefix the line of the list item with a hyphen: + +````example +To write this list in Typst... + +```latex +\begin{itemize} + \item Fast + \item Flexible + \item Intuitive +\end{itemize} +``` + +...just type this: + +- Fast +- Flexible +- Intuitive + +```` + +By indenting them beyond the hyphen, you can also include multiple paragraphs or +nested lists in a single list item. If the list item's become longer, it's best +to put blank lines between the list items. This increases the spacing between +the list's items. + +To get a [numbered list]($func/enum) (`enumerate`) instead, use a `+` instead of +the hyphen. For a [term list]($func/terms) (`description`), write +`[/ Term: Description]` instead. + +## How do I use a command? { #commands } +LaTeX heavily relies on commands (prefixed by backslashes). It uses these +_macros_ to affect the typesetting process and to insert and manipulate content. +Some commands accept arguments, most frequently they are enclosed in curly +braces: `\cite{rasmus}`. + +Typst differentiates between [markup mode and code mode]($scripting/#blocks). +Markup mode is the default and where you can write text and use syntactic +constructs like `[*stars for bold text*]`. Code mode is similar to other +programming languages like Python and allows you to write code like `{1 + 2 == +3}`. + +Within Typst's markup, you can switch to code mode for a single command (or +rather, _expression_) using a hashtag (`#`). This is how you call functions and +use features like [imports]($scripting/#modules) within markup. Within these +commands and function calls, code mode applies. To embed +[_content_]($type/content) as a value, you can go back to markup mode using +square brackets: + +```example +First, a rectangle: +#rect() + +Let me show how to do +#underline([_underlined_ text]) + +We can also do some maths: +#calc.max(3, 2 * 4) + +And finally a little loop: +#for x in range(3) [ + Hi #x. +] +``` + +A function call always involves the name of the function ([`rect`]($func/rect), +[`underline`]($func/underline), [`calc.max`]($category/calc/max), +[`range`]($func/range)) and then an argument list, even if it is empty. The +argument list is enclosed in parentheses. + +### Arguments { #arguments } +A function can have multiple arguments. Some arguments are positional, i.e. you +just provide the value: The function `[#lower("SCREAM")]` returns its argument +in all-lowercase. Many functions use named arguments instead of positional +arguments to increase legibility. For example, the dimensions and stroke of a +rectangle are defined with named arguments: + +```example +#rect( + width: 2cm, + height: 1cm, + stroke: red, +) +``` + +You specify a named argument by first entering its name (above, it's `width`, +`height`, and `stroke`), then a colon, followed by the value (`2cm`, `1cm`, +`red`). You can find the available named arguments in the [reference +page]($reference) for each function or in the autocomplete panel when typing. +Named arguments are similar to how some LaTeX environments are configured, for +example, you would type `\begin{enumerate}[label={\alph*)}]` to start a list +with the labels `a)`, `b)`, and so on. + +Often, you want to provide some [content]($type/content) to a function. For +example, the LaTeX command `\underline{Alternative A}` would translate to +`[#underline([Alternative A])]` in Typst. The square brackets indicate that a +value is content. Within these brackets, you can use normal markup. However, +that's a lot of parentheses for a pretty simple construct. This is why you can +also move trailing content arguments after the parentheses (and omit the +parentheses if they would end up empty). + +```example +Typst is an #underline[alternative] +to LaTeX. + +#rect(fill: aqua)[Get started here!] +``` + +### Data types { #data-types } +You likely already noticed that the arguments have distinctive data types. Typst +supports [many data types]($type). Below, there is a table with a few of the +most important ones and how to write them: + +| Data type | Example | +|:-------------------------------------|:----------------------------------| +| [Content]($type/content) | `{[*fast* typesetting]}` | +| [String]($type/string) | `{"Pietro S. Author"}` | +| [Integer]($type/integer) | `{23}` | +| [Floating point number]($type/float) | `{1.459}` | +| [Absolute length]($type/length) | `{12pt}`, `{5in}`, `{0.3cm}`, ... | +| [Relative length]($type/ratio) | `{65%}` | + +The difference between content and string is that content can contain markup, +including function calls, while a string really is just a sequence of +characters. You can use [operators]($scripting/#operators) like `+` for +summation and `==` for equality on these types like you would in a conventional +programming language instead of using `\addtocounter` or `\ifnum`. You can even +define [variables]($scripting/#bindings) and do computations with them. + +In order to specify values of any of these types, you have to be in code mode! + +### Commands to affect the remaining document { #rules } +In LaTeX, some commands like `\textbf{bold text}` are passed their argument in curly +braces and only affect that argument whereas other commands like `\bfseries bold +text` act as switches and change the appearance of all following content in the +document or the current scope (denoted by a set of curly braces). + +In Typst, functions can be used in both ways: With effects applying until the +end of the document or block or just to its arguments. For example, +`[#text(weight: "bold")[bold text]]` will only embolden its argument, while +`[#set text(weight: "bold")]` will embolden any text until the end of the +current block, or, if there is none, document. The effects of a function are +immediately obvious depending on if it is used in a call or a +[set rule.]($styling/#set-rules) + +```example +I am starting out with small text. + +#set text(14pt) + +This is a bit #text(18pt)[larger,] +don't you think? +``` + +Set rules may appear anywhere in the document and can be though of as +pre-setting the arguments of their function: + +```example +#set enum(numbering: "I.") + +Good results can only be obtained by ++ following best practices ++ being aware of current results + of other researchers ++ checking the data for biases +``` + +The `+` is syntactic sugar (think of it as an abbreviation) for a call to the +[`{enum}`]($func/enum) function, to which we apply a set rule above. [Most +syntax is linked to a function in this way.]($syntax) If you need to style an +element beyond what its arguments enable, you can completely redefine its +appearance with a [show rule]($styling/#show-rules) (somewhat comparable to +`\renewcommand`). + +## How do I load a document class? { #templates } +In LaTeX, you start your main `.tex` file with the `\documentclass{article}` +command to define how your document is supposed to look. In that command, you +may have replaced `article` with another value such as `report` and `amsart` to +select a different look. + +When using Typst, you style your documents with [functions]($type/function). +Typically, you use a template that provides a function that styles your whole +document. First, you import the function from a template file. Then, you apply +it to your whole document. This is accomplished with a +[show rule]($styling/#show-rules) that wraps the following document in a given +function. The following example illustrates how it works: + +```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: conf.with( + 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), +) + +Let's get started writing this +article by putting insightful +paragraphs right here! +``` + +The [`{import}`]($scripting/#modules) statement makes +[functions]($type/function) (and other definitions) from another file available. +In this example, it imports the `conf` function from the `conf.typ` file. This +function formats content as a conference article. We use the show rule to apply +it to the document and also configure some metadata about the article. Finally, +we can get started writing our article below! + +
+ +Functions are Typst's "commands" and can transform their arguments to an output +value, including document _content._ Functions are "pure", which means that they +cannot have any effects beyond creating an output value / output content. This +is in stark contrast to LaTeX macros that can have arbitrary effects on your +document. + +To let a function style your whole document, the show rule processes everything +that comes after it and calls the function specified after the colon with the +result as an argument. The `.with` part is a _method_ that takes the `conf` +function and pre-configures some if its arguments before passing it on to the +show rule. +
+ +In the web app, you can choose from predefined templates or even +create your own using the template wizard. You can also check out the +[`awesome-typst` repository](https://github.com/qjcg/awesome-typst) to find +templates made by the community. We plan to build a package manager to make +templates even easier to share in the future! + +You can also [create your own, custom templates.]($tutorial/making-a-template) +They are shorter and more readable than the corresponding LaTeX `.sty` files by +orders of magnitude, so give it a try! + +## How do I load packages? { #packages } +Most things you load packages for in LaTeX are just included in Typst, no need +to load or install anything. Below, we compiled a table with frequently loaded +packages and their corresponding Typst functions. + +| LaTeX Package | Typst Alternative | +|:--------------------------------|:---------------------------------------------------------------------| +| graphicx, svg | [`image`]($func/image) function | +| tabularx | [`table`]($func/table), [`grid`]($func/grid) functions | +| fontenc, inputenc, unicode-math | Just start writing! | +| babel, polyglossia | [`text`]($func/text.lang) function: `[#set text(lang: "zh")]` | +| amsmath | [Math mode]($category/math) | +| amsfonts, amssymb | [`sym`]($category/symbols) module and [syntax]($syntax/#math) | +| geometry, fancyhdr | [`page`]($func/page) function | +| xcolor | [`text`]($func/text.fill) function: `[#set text(fill: rgb("#0178A4"))]` | +| hyperref | [`link`]($func/link) function | +| bibtex, biblatex, natbib | [`cite`]($func/cite), [`bibliography`]($func/bibliography) functions | +| lstlisting, minted | [`raw`]($func/raw) function and syntax | +| parskip | [`block`]($func/block.spacing) and [`par`]($func/par.first-line-indent) functions | +| csquotes | Type `["]` or `[']` and set the [`text`]($func/text.lang) language | +| caption | [`figure`]($func/figure) function | +| enumitem | [`list`]($func/list), [`enum`]($func/enum), [`terms`]($func/terms) functions | + +If you need to load functions and variables from another file, for example to +use a template, you can use an [`import`]($scripting/#modules) statement. If you +want to include the textual content of another file instead, you can use an +[`{include}`]($scripting/#modules) statement. It will yield the content of the +included file and put it in your document. + +Currently, there is no package manager for Typst, but we plan to build one so +that you can easily use packages with tools and templates from the community and +publish your own. + +## How do I input maths? { #maths } +To enter math mode in Typst, just enclose your equation in dollar signs. You can +enter display mode by putting spaces or newlines between the opening and closing +dollar sign and the equation. + +```example +The sum of the numbers from +$1$ to $n$ is: + +$ sum_(k=1)^n k = (n(n+1))/2 $ +``` + +[Math mode]($category/math) works differently than regular markup or code mode. +Single characters and numbers with any amount of digits are displayed as +mathematical variables and values (of your equation), while multiple consecutive +non-number characters will be interpreted as Typst variables. + +As you can see in the example above, Typst pre-defines a lot of useful variables +in math mode. All Greek and some Hebrew letters are resolved by their name. +Refer to the [symbol page]($func/symbol) or use the autocomplete panel to check +which symbols are available. Alternate and related forms of symbols can often be +selected by [appending a modifier]($type/symbol) after a period. For example, +`arrow.l.squiggly` inserts a squiggly left-pointing arrow. If you want to insert +multiletter text in your expression instead, enclose it in double quotes: + +```example +$ delta "if" x <= 5 $ +``` + +You can type many symbols with shorthands like `<=`, `>=`, and `->`. Similarly, +delimiters will scale automatically for their expressions, just as if `\left` +and `\right` commands were implicitly inserted in LaTeX. You can customize +delimiter behavior using the [`lr` function]($func/lr). + +Typst will automatically set terms around a slash `/` as a fraction while +honoring operator precedence. All round parentheses not made redundant by the +fraction will appear in the output. + +```example +$ f(x) = (x + 1) / x $ +``` + +[Sub- and superscripts]($func/attach) work similarly in Typst and LaTeX. Typing +`{$x^2$}` will produce a superscript, `{$x_2$}` yields a subscript. If you want +to include more than one value in a sub- or superscript, enclose their contents +in parentheses: `{$x_(a -> epsilon)$}`. + +Just like you can insert variables without typing a `#` or `/`, you can also use +functions "naked": + +```example +$ f(x, y) := cases( + 1 "if" (x dot y)/2 <= 0, + 2 "if" x "is even", + 3 "if" x in NN, + 4 "else", +) $ +``` + +The above example uses the [`cases` function]($func/cases) to describe f. Within +the cases function, arguments are delimited using commas and the arguments are +also interpreted as math. If you would need to interpret arguments as Typst +values instead, prefix them with a `#`: + +```example +$ (a + b)^2 + = a^2 + + text(fill: #maroon, 2 a b) + + b^2 $ +``` + +You can use all Typst functions within math mode and insert any content. If you +want them to work normally, with code mode in the argument list, you can prefix +their call with a `#`. Nobody can stop you from using rectangles or emoji as +your variables anymore: + +```example +$ sum^10_(🥸=1) + #rect(width: 4mm, height: 2mm)/🥸 + = 🧠 maltese $ +``` + +If you'd like to enter your mathematical symbols directly as Unicode, that is +possible, too! + +Math calls can have two-dimensional argument lists using `;` as a delimiter. The +most common use for this is the [`mat` function]($func/mat) that creates +matrices: + +```example +$ mat( + 1, 2, ..., 10; + 2, 2, ..., 10; + dots.v, dots.v, dots.down, dots.v; + 10, 10, ..., 10; +) $ +``` + +## How do I get the "LaTeX look?" { #latex-look } +Papers set in LaTeX have an unmistakeable look. This is mostly due to their +font, Computer Modern, justification, narrow line spacing, and wide margins. + +The example below +- sets wide [margins]($func/page.margin) +- enables [justification]($func/par.justify), [tighter lines]($func/par.leading) + and [first-line-indent]($func/par.first-line-indent) +- [sets the font]($func/text.font) to "New Computer Modern", an OpenType + derivate of Computer Modern for both text and [code blocks]($func/raw) +- disables paragraph [spacing]($func/block.spacing) +- increases [spacing]($func/block.spacing) around [headings]($func/heading) + +```typ +#set page(margin: 1.75in) +#set par(leading: 0.55em, first-line-indent: 1.8em, justify: true) +#set text(font: "New Computer Modern") +#show raw: set text(font: "New Computer Modern Mono") +#show par: set block(spacing: 0.55em) +#show heading: set block(above: 1.4em, below: 1em) +``` + +This should be a good starting point! If you want to go further, why not create +a reusable template? + +## What limitations does Typst currently have compared with LaTeX? { #limitations } +Although Typst can be a LaTeX replacement for many today, there are still +features that Typst does not (yet) support. Here is a list of them which, where +applicable, contains possible workarounds. + +- **Native charts and plots.** LaTeX users often create charts along with their + documents in PGF/TikZ. Typst does not yet include tools to draw diagrams, but + the community is stepping up with solutions such as + [`typst-canvas`](https://github.com/johannes-wolf/typst-canvas), + [`typst-plot`](https://github.com/johannes-wolf/typst-plot), and + [`circuitypst`](https://github.com/fenjalien/circuitypst). You can add those + to your document to get started with drawing diagrams. + +- **Change page margins without a pagebreak.** In LaTeX, margins can always be + adjusted, even without a pagebreak. To change margins in Typst, you use the + [`page` function]($func/page) which will force a page break. If you just want + a few paragraphs to stretch into the margins, then reverting to the old + margins, you can use the [`pad` function]($func/pad) with negative padding. + +- **Floating figures.** The figure command of LaTeX will smartly choose where to + place a figure, be it on the top or bottom of the page, or a dedicated figure + page. Typst's figure will always appear at the spot where they have been + inserted in the markup. While this behavior can save some headache, it is + often cumbersome to manually place figures. We will be adding this feature + soon! + +- **Include PDFs as images.** In LaTeX, it has become customary to insert vector + graphics as PDF or EPS files. Typst supports neither format as an image + format, but you can easily convert both into SVG files with [online + tools](https://cloudconvert.com/pdf-to-svg) or + [Inkscape](https://inkscape.org/). We plan to add automatic conversion for + these file formats to the Typst web app, too! + +- **Page break optimization.** LaTeX runs some smart algorithms to not only + optimize line but also page breaks. While Typst tries to avoid widows and + orphans, it uses less sophisticated algorithms to determine page breaks. You + can insert custom page breaks in Typst using `[#pagebreak(weak: true)]` before + submitting your document. The argument `weak` ensures that no double page + break will be created if this spot would be a natural page break + anyways. You can also use `[#v(1fr)]` to distribute space on your page. It + works quite similar to LaTeX's `\vfill`. + +- **Bibliographies are not customizable.** In LaTeX, the packages `bibtex`, + `biblatex`, and `natbib` provide a wide range of reference and bibliography + formats. You can also use custom `.bbx` files to define your own styles there. + Typst only supports a small set of citation styles at the moment, but we want + to build upon this by supporting [Citation Style Language + (CSL)](https://citationstyles.org), an XML-based format backed by Zotero that + allows you to describe your own bibliography styles. diff --git a/docs/src/guides/welcome.md b/docs/src/guides/welcome.md new file mode 100644 index 00000000..43ecd181 --- /dev/null +++ b/docs/src/guides/welcome.md @@ -0,0 +1,11 @@ +--- +description: Guides for Typst. +--- + +# Guides +Welcome to the Guides section! Here, you'll find helpful material for specific +user groups or use cases. Currently, one guide is available: An introduction +to Typst for LaTeX users. Feel free to propose other topics for guides! + +## List of Guides { #list-of-guides } +- [Guide for LaTeX users]($guides/guide-for-latex-users) diff --git a/docs/src/html.rs b/docs/src/html.rs index cd47d75b..a9bbfb1c 100644 --- a/docs/src/html.rs +++ b/docs/src/html.rs @@ -3,6 +3,7 @@ use std::ops::Range; use comemo::Prehashed; use md::escape::escape_html; use pulldown_cmark as md; +use typed_arena::Arena; use typst::diag::FileResult; use typst::font::{Font, FontBook}; use typst::geom::{Point, Size}; @@ -22,17 +23,35 @@ pub struct Html { md: String, #[serde(skip)] description: Option, + #[serde(skip)] + outline: Vec, } impl Html { /// Create HTML from a raw string. pub fn new(raw: String) -> Self { - Self { md: String::new(), raw, description: None } + Self { + md: String::new(), + raw, + description: None, + outline: vec![], + } } /// Convert markdown to HTML. #[track_caller] pub fn markdown(resolver: &dyn Resolver, md: &str) -> Self { + Self::markdown_with_id_base(resolver, md, "") + } + + /// Convert markdown to HTML, preceding all fragment identifiers with the + /// `id_base`. + #[track_caller] + pub fn markdown_with_id_base( + resolver: &dyn Resolver, + md: &str, + id_base: &str, + ) -> Self { let mut text = md; let mut description = None; let document = YamlFrontMatter::parse::(md); @@ -43,7 +62,8 @@ impl Html { let options = md::Options::ENABLE_TABLES | md::Options::ENABLE_HEADING_ATTRIBUTES; - let mut handler = Handler::new(resolver); + let ids = Arena::new(); + let mut handler = Handler::new(resolver, id_base.into(), &ids); let iter = md::Parser::new_ext(text, options) .filter_map(|mut event| handler.handle(&mut event).then_some(event)); @@ -51,7 +71,12 @@ impl Html { md::html::push_html(&mut raw, iter); raw.truncate(raw.trim_end().len()); - Html { md: text.into(), raw, description } + Html { + md: text.into(), + raw, + description, + outline: handler.outline, + } } /// The raw HTML. @@ -72,6 +97,11 @@ impl Html { s.eat_if("

").then(|| s.eat_until("

")) } + /// The outline of the HTML. + pub fn outline(&self) -> Vec { + self.outline.clone() + } + /// The description from the front matter. pub fn description(&self) -> Option { self.description.clone() @@ -93,14 +123,23 @@ struct Metadata { struct Handler<'a> { resolver: &'a dyn Resolver, lang: Option, + outline: Vec, + id_base: String, + ids: &'a Arena, } impl<'a> Handler<'a> { - fn new(resolver: &'a dyn Resolver) -> Self { - Self { resolver, lang: None } + fn new(resolver: &'a dyn Resolver, id_base: String, ids: &'a Arena) -> Self { + Self { + resolver, + lang: None, + outline: vec![], + id_base, + ids, + } } - fn handle(&mut self, event: &mut md::Event) -> bool { + fn handle(&mut self, event: &mut md::Event<'a>) -> bool { let lang = self.lang.take(); match event { // Rewrite Markdown images. @@ -117,7 +156,19 @@ impl<'a> Handler<'a> { *html = buf.into(); } - // Rewrite contributor sectinos. + // Register HTML headings for the outline. + md::Event::Start(md::Tag::Heading(level, Some(id), _)) => { + self.handle_heading(id, level); + } + + // Also handle heading closings. + md::Event::End(md::Tag::Heading(level, Some(_), _)) => { + if *level > md::HeadingLevel::H1 && !self.id_base.is_empty() { + nest_heading(level); + } + } + + // Rewrite contributor sections. md::Event::Html(html) if html.starts_with(" { let from = html_attr(html, "from").unwrap(); let to = html_attr(html, "to").unwrap(); @@ -184,6 +235,36 @@ impl<'a> Handler<'a> { } } + fn handle_heading(&mut self, id: &mut &'a str, level: &mut md::HeadingLevel) { + if *level == md::HeadingLevel::H1 { + return; + } + + // Special case for things like "v0.3.0". + let name = if id.starts_with('v') && id.contains('.') { + id.to_string() + } else { + id.to_title_case() + }; + + let mut children = &mut self.outline; + let mut depth = *level as usize; + while depth > 2 { + if !children.is_empty() { + children = &mut children.last_mut().unwrap().children; + } + depth -= 1; + } + + // Put base before id. + if !self.id_base.is_empty() { + nest_heading(level); + *id = self.ids.alloc(format!("{}-{id}", self.id_base)).as_str(); + } + + children.push(OutlineItem { id: id.to_string(), name, children: vec![] }); + } + fn handle_link(&self, link: &str) -> Option { if link.starts_with('#') || link.starts_with("http") { return Some(link.into()); @@ -205,6 +286,7 @@ impl<'a> Handler<'a> { "$types" => "/docs/reference/types/", "$type" => "/docs/reference/types/", "$func" => "/docs/reference/", + "$guides" => "/docs/guides/", "$changelog" => "/docs/changelog/", "$community" => "/docs/community/", _ => panic!("unknown link root: {root}"), @@ -216,7 +298,7 @@ impl<'a> Handler<'a> { let ty = parts.next()?; let method = parts.next()?; route.push_str(ty); - route.push_str("/#methods--"); + route.push_str("/#methods-"); route.push_str(method); } else if root == "$func" { let mut parts = rest.split('.'); @@ -237,7 +319,7 @@ impl<'a> Handler<'a> { route.push_str("/#"); route.push_str(info.name); if let Some(param) = param { - route.push_str("-parameters--"); + route.push_str("-parameters-"); route.push_str(param); } else { route.push_str("-summary"); @@ -246,7 +328,7 @@ impl<'a> Handler<'a> { route.push_str(name); route.push('/'); if let Some(param) = param { - route.push_str("#parameters--"); + route.push_str("#parameters-"); route.push_str(param); } } @@ -347,6 +429,18 @@ fn html_attr_range(html: &str, attr: &str) -> Option> { Some(offset..offset + len) } +/// Increase the nesting level of a Markdown heading. +fn nest_heading(level: &mut md::HeadingLevel) { + *level = match &level { + md::HeadingLevel::H1 => md::HeadingLevel::H2, + md::HeadingLevel::H2 => md::HeadingLevel::H3, + md::HeadingLevel::H3 => md::HeadingLevel::H4, + md::HeadingLevel::H4 => md::HeadingLevel::H5, + md::HeadingLevel::H5 => md::HeadingLevel::H6, + v => **v, + }; +} + /// World for example compilations. struct DocWorld(Source); diff --git a/docs/src/lib.rs b/docs/src/lib.rs index fcf3610c..30501e22 100644 --- a/docs/src/lib.rs +++ b/docs/src/lib.rs @@ -54,9 +54,9 @@ static LIBRARY: Lazy> = Lazy::new(|| { pub fn provide(resolver: &dyn Resolver) -> Vec { vec![ markdown_page(resolver, "/docs/", "general/overview.md").with_route("/docs/"), - tutorial_page(resolver), - reference_page(resolver), - markdown_page(resolver, "/docs/", "general/guide-for-latex-users.md"), + tutorial_pages(resolver), + reference_pages(resolver), + guides_pages(resolver), markdown_page(resolver, "/docs/", "general/changelog.md"), markdown_page(resolver, "/docs/", "general/community.md"), ] @@ -99,6 +99,14 @@ impl PageModel { } } +/// An element in the "On This Page" outline. +#[derive(Debug, Clone, Serialize)] +pub struct OutlineItem { + id: String, + name: String, + children: Vec, +} + /// Details about the body of a documentation page. #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] @@ -113,7 +121,7 @@ pub enum BodyModel { } /// Build the tutorial. -fn tutorial_page(resolver: &dyn Resolver) -> PageModel { +fn tutorial_pages(resolver: &dyn Resolver) -> PageModel { let mut page = markdown_page(resolver, "/docs/", "tutorial/welcome.md"); page.children = SRC .get_dir("tutorial") @@ -125,8 +133,16 @@ fn tutorial_page(resolver: &dyn Resolver) -> PageModel { page } +/// Build the guides section. +fn guides_pages(resolver: &dyn Resolver) -> PageModel { + let mut page = markdown_page(resolver, "/docs/", "guides/welcome.md"); + page.children = + vec![markdown_page(resolver, "/docs/guides/", "guides/guide-for-latex-users.md")]; + page +} + /// Build the reference. -fn reference_page(resolver: &dyn Resolver) -> PageModel { +fn reference_pages(resolver: &dyn Resolver) -> PageModel { let mut page = markdown_page(resolver, "/docs/", "reference/welcome.md"); page.children = vec![ markdown_page(resolver, "/docs/reference/", "reference/syntax.md") @@ -164,6 +180,7 @@ fn markdown_page( title, description: html.description().unwrap(), part: None, + outline: html.outline(), body: BodyModel::Html(html), children: vec![], } @@ -200,6 +217,12 @@ fn category_page(resolver: &dyn Resolver, category: &str) -> PageModel { _ => &LIBRARY.global, }; + let parents: &[&str] = match category { + "math" => &[], + "calculate" => &["calc"], + _ => &[], + }; + let grouped = match category { "math" => GROUPS.as_slice(), _ => &[], @@ -222,7 +245,7 @@ fn category_page(resolver: &dyn Resolver, category: &str) -> PageModel { continue; } - let subpage = function_page(resolver, &route, func, info); + let subpage = function_page(resolver, &route, func, info, parents); items.push(CategoryItem { name: info.name.into(), route: subpage.route.clone(), @@ -235,11 +258,21 @@ fn category_page(resolver: &dyn Resolver, category: &str) -> PageModel { // Add grouped functions. for group in grouped { let mut functions = vec![]; + let mut outline = vec![OutlineItem { + id: "summary".into(), + name: "Summary".into(), + children: vec![], + }]; + for name in &group.functions { let value = focus.get(name).unwrap(); let Value::Func(func) = value else { panic!("not a function") }; let info = func.info().unwrap(); - functions.push(func_model(resolver, func, info)); + let func = func_model(resolver, func, info, &[], info.name); + let id = urlify(&func.path.join("-")); + let children = func_outline(&func, &id, false); + outline.push(OutlineItem { id, name: func.display.into(), children }); + functions.push(func); } let route = format!("{}{}/", route, group.name); @@ -249,13 +282,16 @@ fn category_page(resolver: &dyn Resolver, category: &str) -> PageModel { oneliner: oneliner(&group.description).into(), code: false, }); + children.push(PageModel { route, - title: group.title.clone(), + title: group.display.clone(), description: format!("Documentation for {} group of functions.", group.name), part: None, + outline, body: BodyModel::Funcs(FuncsModel { name: group.name.clone(), + display: group.display.clone(), details: Html::markdown(resolver, &group.description), functions, }), @@ -281,28 +317,47 @@ fn category_page(resolver: &dyn Resolver, category: &str) -> PageModel { } let name = category.to_title_case(); + let kind = match category { + "symbols" => "Modules", + _ => "Functions", + }; + PageModel { route, title: name.clone(), description: format!("Documentation for functions related to {name} in Typst."), part: None, + outline: category_outline(kind), body: BodyModel::Category(CategoryModel { name, details: Html::markdown(resolver, details(category)), - kind: match category { - "symbols" => "Modules", - _ => "Functions", - }, + kind, items, }), children, } } +/// Produce an outline for a category page. +fn category_outline(kind: &str) -> Vec { + vec![ + OutlineItem { + id: "summary".into(), + name: "Summary".into(), + children: vec![], + }, + OutlineItem { + id: urlify(kind), + name: kind.into(), + children: vec![], + }, + ] +} + /// Details about a function. #[derive(Debug, Serialize)] pub struct FuncModel { - pub name: &'static str, + pub path: Vec<&'static str>, pub display: &'static str, pub oneliner: &'static str, pub element: bool, @@ -310,12 +365,14 @@ pub struct FuncModel { pub params: Vec, pub returns: Vec<&'static str>, pub methods: Vec, + pub scope: Vec, } /// Details about a group of functions. #[derive(Debug, Serialize)] pub struct FuncsModel { pub name: String, + pub display: String, pub details: Html, pub functions: Vec, } @@ -326,33 +383,105 @@ fn function_page( parent: &str, func: &Func, info: &FuncInfo, + parents: &[&'static str], ) -> PageModel { + let model = func_model(resolver, func, info, parents, ""); PageModel { route: format!("{parent}{}/", urlify(info.name)), title: info.display.to_string(), description: format!("Documentation for the `{}` function.", info.name), part: None, - body: BodyModel::Func(func_model(resolver, func, info)), + outline: func_outline(&model, "", true), + body: BodyModel::Func(model), children: vec![], } } /// Produce a function's model. -fn func_model(resolver: &dyn Resolver, func: &Func, info: &FuncInfo) -> FuncModel { +fn func_model( + resolver: &dyn Resolver, + func: &Func, + info: &FuncInfo, + parents: &[&'static str], + id_base: &str, +) -> FuncModel { let mut s = unscanny::Scanner::new(info.docs); let docs = s.eat_until("\n## Methods").trim(); + + let mut path = parents.to_vec(); + let mut name = info.name; + for parent in parents.iter().rev() { + name = name + .strip_prefix(parent) + .or(name.strip_prefix(parent.strip_suffix('s').unwrap_or(parent))) + .unwrap_or(name); + } + path.push(name); + + let scope = info + .scope + .iter() + .filter_map(|(_, value)| { + let Value::Func(func) = value else { return None }; + let info = func.info().unwrap(); + Some(func_model(resolver, func, info, &path, id_base)) + }) + .collect(); + FuncModel { - name: info.name, + path, display: info.display, oneliner: oneliner(docs), element: func.element().is_some(), - details: Html::markdown(resolver, docs), + details: Html::markdown_with_id_base(resolver, docs, id_base), params: info.params.iter().map(|param| param_model(resolver, param)).collect(), returns: info.returns.clone(), methods: method_models(resolver, info.docs), + scope, } } +/// Produce an outline for a function page. +fn func_outline(model: &FuncModel, base: &str, summary: bool) -> Vec { + let mut outline = vec![]; + + if summary { + outline.push(OutlineItem { + id: "summary".into(), + name: "Summary".into(), + children: vec![], + }); + } + + outline.extend(model.details.outline()); + + if !model.params.is_empty() { + let join = if base.is_empty() { "" } else { "-" }; + outline.push(OutlineItem { + id: format!("{base}{join}parameters"), + name: "Parameters".into(), + children: model + .params + .iter() + .map(|param| OutlineItem { + id: format!("{base}{join}parameters-{}", urlify(param.name)), + name: param.name.into(), + children: vec![], + }) + .collect(), + }); + } + + for func in &model.scope { + let id = urlify(&func.path.join("-")); + let children = func_outline(func, &id, false); + outline.push(OutlineItem { id, name: func.display.into(), children }) + } + + outline.extend(methods_outline(&model.methods)); + outline +} + /// Details about a function parameter. #[derive(Debug, Serialize)] pub struct ParamModel { @@ -469,6 +598,7 @@ fn types_page(resolver: &dyn Resolver, parent: &str) -> PageModel { title: model.name.to_title_case(), description: format!("Documentation for the `{}` type.", model.name), part: None, + outline: type_outline(&model), body: BodyModel::Type(model), children: vec![], }); @@ -479,6 +609,7 @@ fn types_page(resolver: &dyn Resolver, parent: &str) -> PageModel { title: "Types".into(), description: "Documentation for Typst's built-in types.".into(), part: None, + outline: category_outline("Types"), body: BodyModel::Category(CategoryModel { name: "Types".into(), details: Html::markdown(resolver, details("types")), @@ -604,6 +735,48 @@ fn method_model(resolver: &dyn Resolver, part: &'static str) -> MethodModel { } } +/// Produce an outline for a type page. +fn type_outline(model: &TypeModel) -> Vec { + let mut outline = vec![OutlineItem { + id: "summary".into(), + name: "Summary".into(), + children: vec![], + }]; + + outline.extend(methods_outline(&model.methods)); + outline +} + +/// Produce an outline for a type's method. +fn methods_outline(methods: &[MethodModel]) -> Option { + (!methods.is_empty()).then(|| OutlineItem { + id: "methods".into(), + name: "Methods".into(), + children: methods.iter().map(method_outline).collect(), + }) +} + +/// Produce an outline for a type's method. +fn method_outline(model: &MethodModel) -> OutlineItem { + OutlineItem { + id: format!("methods-{}", urlify(model.name)), + name: model.name.into(), + children: model + .params + .iter() + .map(|param| OutlineItem { + id: format!( + "methods-{}-parameters-{}", + urlify(model.name), + urlify(param.name) + ), + name: param.name.into(), + children: vec![], + }) + .collect(), + } +} + /// A collection of symbols. #[derive(Debug, Serialize)] pub struct SymbolsModel { @@ -671,6 +844,7 @@ fn symbol_page(resolver: &dyn Resolver, parent: &str, name: &str) -> PageModel { title: title.into(), description: format!("Documentation for the `{name}` module."), part: None, + outline: vec![], body: BodyModel::Symbols(SymbolsModel { name: title, details: Html::markdown(resolver, details(name)), @@ -684,7 +858,7 @@ fn symbol_page(resolver: &dyn Resolver, parent: &str, name: &str) -> PageModel { #[derive(Debug, Deserialize)] struct GroupData { name: String, - title: String, + display: String, functions: Vec, description: String, } diff --git a/docs/src/reference/groups.yml b/docs/src/reference/groups.yml index 04eed2ee..5d8b330e 100644 --- a/docs/src/reference/groups.yml +++ b/docs/src/reference/groups.yml @@ -1,5 +1,5 @@ - name: variants - title: Variants + display: Variants functions: ["serif", "sans", "frak", "mono", "bb", "cal"] description: | Alternate typefaces within formulas. @@ -8,7 +8,7 @@ math fonts contain multiple variants of each letter. - name: styles - title: Styles + display: Styles functions: ["upright", "italic", "bold"] description: | Alternate letterforms within formulas. @@ -17,7 +17,7 @@ math fonts contain multiple variants of each letter. - name: underover - title: Under/Over + display: Under/Over functions: [ "underline", "overline", @@ -33,12 +33,12 @@ below or above themselves. - name: roots - title: Roots + display: Roots functions: ["root", "sqrt"] description: Square and non-square roots. - name: attach - title: Attach + display: Attach functions: ["attach", "scripts", "limits"] description: | Subscript, superscripts, and limits. @@ -50,7 +50,7 @@ the `scripts` and `limits` functions. - name: lr - title: Left/Right + display: Left/Right functions: ["lr", "abs", "norm", "floor", "ceil"] description: | Delimiter matching. diff --git a/docs/src/reference/welcome.md b/docs/src/reference/welcome.md index dc38663d..fc526f52 100644 --- a/docs/src/reference/welcome.md +++ b/docs/src/reference/welcome.md @@ -10,14 +10,14 @@ syntax, concepts, types, and functions. If you are completely new to Typst, we recommend starting with the [tutorial]($tutorial) and then coming back to the reference to learn more about Typst's features as you need them. -## Language +## Language { #language } The reference starts with a language part that gives an overview over [Typst's syntax]($syntax) and contains information about concepts involved in [styling documents,]($styling) using [Typst's scripting capabilities,]($scripting) and a detailed documentation of all [data types]($types) in Typst. -## Functions +## Functions { #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 diff --git a/docs/src/tutorial/1-writing.md b/docs/src/tutorial/1-writing.md index 21292d21..6bb6087e 100644 --- a/docs/src/tutorial/1-writing.md +++ b/docs/src/tutorial/1-writing.md @@ -67,7 +67,7 @@ the first item of the list above by indenting it. + The geology ``` -## Adding a figure +## 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 @@ -174,7 +174,7 @@ On the contrary, strings work wherever content is expected because text is a valid kind of content. -## Adding a bibliography +## 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 @@ -200,7 +200,7 @@ established in @glacier-melt. #bibliography("works.bib") ``` -## Maths +## 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 @@ -293,7 +293,7 @@ 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 { #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 diff --git a/docs/src/tutorial/2-formatting.md b/docs/src/tutorial/2-formatting.md index d5b810b2..c231b878 100644 --- a/docs/src/tutorial/2-formatting.md +++ b/docs/src/tutorial/2-formatting.md @@ -9,7 +9,7 @@ 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 { #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) @@ -70,7 +70,7 @@ for some of the parameters of a function for all future uses of that function. -## The autocomplete panel +## 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. @@ -84,7 +84,7 @@ what they do. ![Autocomplete panel](2-formatting-autocomplete.png) -## Set up the page +## 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: @@ -175,7 +175,7 @@ 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 +## 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. @@ -228,7 +228,7 @@ markup above. Other markup elements work similarly, they are only _syntax sugar_ for the corresponding function calls. -## Show rules +## 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. @@ -272,7 +272,7 @@ 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 { #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 diff --git a/docs/src/tutorial/3-advanced.md b/docs/src/tutorial/3-advanced.md index 4749c547..42a810fd 100644 --- a/docs/src/tutorial/3-advanced.md +++ b/docs/src/tutorial/3-advanced.md @@ -26,7 +26,7 @@ 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 conference guidelines { #guidelines } The layout guidelines are available on the conference website. Let's take a look at them: @@ -46,7 +46,7 @@ at them: 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 +## Writing the right set rules { #set-rules } Let's start by writing some set rules for the document. ```example @@ -84,7 +84,7 @@ setting into to `{"1"}`, Typst only displays the bare page number. Setting it to 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 +## 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*]`. @@ -246,7 +246,7 @@ 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 +## 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 @@ -493,7 +493,7 @@ the conference! The finished paper looks like this: style="box-shadow: 0 4px 12px rgb(89 85 101 / 20%); width: 500px; max-width: 100%; display: block; margin: 24px auto;" > -## Review +## 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. diff --git a/docs/src/tutorial/4-template.md b/docs/src/tutorial/4-template.md index 52557281..320f82b2 100644 --- a/docs/src/tutorial/4-template.md +++ b/docs/src/tutorial/4-template.md @@ -12,7 +12,7 @@ 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 +## 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? @@ -60,7 +60,7 @@ 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 +## 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. @@ -159,7 +159,7 @@ 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 +## 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 @@ -253,7 +253,7 @@ The resulting template function looks like this: } ``` -## A separate file +## 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 @@ -365,7 +365,7 @@ conference! Why not share it on [Typst's Discord server](https://discord.gg/2uDybryKPe) so that others can use it too? -## Review +## 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 diff --git a/docs/src/tutorial/welcome.md b/docs/src/tutorial/welcome.md index e2882561..530336cb 100644 --- a/docs/src/tutorial/welcome.md +++ b/docs/src/tutorial/welcome.md @@ -14,7 +14,7 @@ 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 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 @@ -27,7 +27,7 @@ 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 +## 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: -- cgit v1.2.3