blog/content/software/typst.md

254 lines
11 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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, Ive been using _LaTeX_ to typeset any document which
aims to be printed. The main reason is that Im 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 dont write very often, such as
letters, its sometimes a pain to find the syntax of the [LaTeX class for
letters](https://texlive.mycozy.space/macros/latex/contrib/lettre/lettre.pdf)<sup>(fr)</sup>
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 its 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 dont 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 [doesnt
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 wont 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, Ill 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 dont 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 its the
same syntax for cross-referencing) or the `#cite` function. Note that if you
have a `+` in your bibliography key, the label wont 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, its not the case for all citation
styles).
# Tooling
Unlike my [blogpost about using nvim for LaTeX]({filename}./nvim-latex.md),
its 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 thats 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 dont 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/) that has been published 3 days
ago (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, cant say for sure as I didnt 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… Im 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
didnt try them yet, so I cant 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/