--- Title: Typesetting with Typst Date: 2024-10-19 18:00 Modified: 2024-10-19 21:00 Lang: en Author: Fabrice Category: software Tags: vim, neovim, typst Slug: typst-intro table-of-contents: true Summary: An overview of Typst for simple usage. Header_Cover: ../images/covers/printing-press.jpg --- For about ten years now, I’ve been using _LaTeX_ to typeset any document which aims to be printed. The main reason is that I’m quite familiar with the syntax to adjust the page setting to what I imagine. Other solutions exist to ease this workflow, such as [Pandoc](https://pandoc.org/) to convert easier to write syntax to other formats. However, this solution was not palatable to me as the universal aspect of Pandoc, makes it a pain to specify pagination properties. And, to produce a PDF in the end, Pandoc calls _LaTeX_, and for the sake of simplicity I prefer to directly write in _LaTeX_ (see the conclusion for clarification). However, for some kind of documents that I don’t write very often, such as letters, it’s sometimes a pain to find the syntax of the [LaTeX class for letters](https://texlive.mycozy.space/macros/latex/contrib/lettre/lettre.pdf)(fr) I use. Recently, I had to write small documents (approx 3 pages), with a bibliography, and that just needed to have a nice and neat presentation. Before going farther, I decided to give a try to [typst](https://typst.app/). It is an open-source typesetting engine that is written in [rust](https://rust-lang.org/), that promotes modern features such as _incremental compilation_, and a scripting language that is actually readable by humans. Moreover, the markup language is clean, and as in [markdown] or [asciidoc], it can be read from the source (without a [concealer](https://alok.github.io/2018/04/26/using-vim-s-conceal-to-make-languages-more-tolerable/)) to have an idea of the typeset text before compiling it. The project is still in development and some features may break before the first major version is out. However, to quickly generate a document, it can be a good idea to consider. Also, please note that there is no native output from Typst to HTML. However, Pandoc can read and write `.typ` files, so it’s an alternative worth considering given that native LaTeX is **not** easy to write for that purpose. In the following, it will be a quick overview of the features that I find nice in Typst. Please don’t expect an in-depth review, I only used it for a couple of opportunities. # Syntax To illustrate Typst, here follows a simple document, with its corresponding [compiled version]({static}/examples/typst-example.pdf). ```typst /* Set some variables for the authors and the title */ #let title = [How to type in Typst] #let authors = ("Fabrice Mouhartem", ) /* Set some document properties: * - Numbering of sections (default: none) * - PDF properties (it does not print anything) */ #set heading(numbering: "I.") #set document(title: title, author: authors) /* Now we can print the title and the authors */ #align(center, text(size: 17pt, strong(title))) #for author in authors { // TODO: would be better in a grid align(center, text(author)) } /* Table of contents */ #outline() /* To define a section */ = Introduction /* And to write the content: */ To _type_ in Typst, you just have to… *type*. = Conclusion See, it was #strike[hard] easy. ``` Besides the programmatic part at the start, we can see that the syntax is close to what we may know in other simple markup languages such as [markdown] or [asciidoc]. However, it is its own and Typst [doesn’t plan](https://github.com/typst/typst/discussions/2498) to converge toward another markup language, especially knowing that the markdown syntax is [ambiguous](https://roopc.net/posts/2014/markdown-cfg/). For the preamble of the file, it can be deferred to another file to accentuate the separation between content and typesetting. We won’t go into details, but it was mostly there to illustrate some parts of the language, such as variable declaration (`#let …`) or loops over arrays (`#for … in …`). We also set some values about the document using either static values (for the numbering) or the defined variables (authors and title options). Let us now check that these options are indeed well set: ```bash ❯ pdfinfo "typst-example.pdf" | head -n 3 Title: How to type in Typst Author: Fabrice Mouhartem Creator: Typst 0.12.0 ``` The generated document is a bit bare, but we can easily change it, and as easily create a template to automate this work for us. # Example: a letter (the French way) For a simple example, I’ll take the letter one, for which I wrote a simple template to generate them. The template is available in [this repository](https://git.epheme.re/fmouhart/typst-lettre). The main issue I had is that the French way of doing letters revert the order of the addresses of the sender and recipient are… reverted compared to the English style. Let us dig in what it does by looking at the example file. First thing first, the file is loading the template from `lettre.typ`. This file defines the typesetting and the paginations properties, and provide an initialisation function to define the different headers, which you can look into if you feel curious. If you find it a bit unbearable, you can create a new file `preamble.typ` to hide everything, and include it with `#include "preamble.typ"` at the outset of the file. ```typst #import "lettre.typ": * #show: doc => lettre( de: [ Sender\ Address ], pour: [ Recipient\ Address ], objet: "subject of the letter", // optional date: "date of sending", // optional lieu: "location", introduction: "opening", cloture: "closing", signature: "signature", post: [ post-letter (e.g., post-scriptum) ], doc ) ``` This will generate the template with the elements where they should be, in a very simple fashion. Now, we just have to write the content of the letter and have a `pdf` file pretty easily with `typst compile` without all the files that _LaTeX_ generates for us. As a bonus, it also set some PDFs metadata from the input variables. # Bibliography Another nice feature is that Typst embeds a bibliography engine, that is compatible with the bibtex format. Meaning that I don’t have to change the way I manage my bibliography or directly use [community-managed bibliography](https://cryptobib.di.ens.fr/). For that you simply have to call the bibliography function where you want it to be generated: ```typst #bibliography("bibliography.bib", title: "References", style: "springer-basic") ``` And cite the references you want with the `@bibkey` syntax (note that it’s the same syntax for cross-referencing) or the `#cite` function. Note that if you have a `+` in your bibliography key, the label won’t be recognized. It is my case as my bibkeys are in the _alpha_ style with the initials of the authors + year up to 3 names, and a `+` afterward… To be able to cite the reference anyway, just do `#cite(label("bib+key"))`. The full list of natively available style is given in the [Typst documentation](https://typst.app/docs/reference/model/bibliography/#parameters-style), however you can define your own in the [Citation Style Language](https://citationstyles.org/). Meaning that you can pick the best one for your usage in the [CSL repository](https://github.com/citation-style-language/styles). To put multiple citations (as in `\cite{ref1, ref2}` in _LaTeX_), you just have to concatenate them, like `@ref1 @ref2`. If the citation style supports it, it would automatically merge them under the same bracket (however, it’s not the case for all citation styles). # Tooling Unlike my [blogpost about using nvim for LaTeX]({filename}./nvim-latex.md), it’s pretty much easier here. I just added the [`typst.vim`](https://github.com/kaarmu/typst.vim) plugin to _neovim_, added a binding for the `:TypstWatch` command and that’s basically all. It is possible to set the `g:typst_pdf_viewer` (`vim.g.typst_pdf_viewer` in Lua) global variable as well if you want to have a different default PDF viewer for your system and for edition. Now, each time I save, the document is incrementally compiled (I think) and updated in my PDF viewer. I tried using typst language servers as well, but they don’t seem mature enough yet. In the end, the `typst.vim` plugin suffices to my needs without being too nosy. Hopefully, the tooling will get better with time. # Conclusion For simple document typesetting, even with features such as bibliography, cross-referencing, and table of contents, Typst seems to be a good choice. However, for long-term support documents, such as documentation, I would wait to see it being more stable. Even while writing this blog post, the _lettre_ template I made was done in Typst 0.11, and preparing it in a repository raised some warnings about [breaking changes from 0.12](https://typst.app/docs/changelog/0.12.0/) which has been published… [yesterday](https://typst.app/blog/2024/typst-0.12/) (at the time of writing): > Added > [`par.spacing`](https://typst.app/docs/reference/model/par/#parameters-spacing > "Typst Documentation: paragraph spacing") property for configuring paragraph > spacing. This should now be used instead of `show par: set block(spacing: ..)` > **(Breaking change)** Which also leads me to say that one other advantage of Typst is… the readability of error messages. They are way much cleaner than the ones from _LaTeX_. Leading to easier debugging as well. I, however, can’t say for sure as I didn’t typeset big documents using Typst yet (which is unlikely to happen given my stance so far, but who knows…). Finally, to complete the note about compiling in _LaTeX_ from Pandoc in the introduction of this blogpost… I’m apparently not up to date. For the sake of transparency, it is possible to use different PDF engines with Pandoc according to the [documentation](https://pandoc.org/MANUAL.html#option--pdf-engine). I didn’t try them yet, so I can’t provide feedbacks about them. Note that Typst is part of the PDF generators, as well as other nice typesetting projects such as [pagedjs](https://pagedjs.org/) that aims at paginating HTML sources to have great web page and print-ready PDFs. However, the argument about avoiding intermediate steps if possible still holds (moreover when the syntax of Typst is already clean enough). ## See Also - [Awesome Typst](https://github.com/qjcg/awesome-typst): a repository listing useful links for typst users. - [Typst for _LaTeX_ users](https://typst.app/docs/guides/guide-for-latex-users/ "Typst documentation: guide for LaTeX users"): a comprehensive guide for typst for _LaTeX_ users. [markdown]: https://daringfireball.net/projects/markdown/ [asciidoc]: https://asciidoc.org/