Introduction
A good way to ensure reproducability of Typst source code would make it easier for publishers in academia to adopt Typst. That’s why this discussion began in the thread : “Discussion: Lobbying for Typst adoption by publishers”,
with this remark :
Regarding the question of having a Typst distribution: an alternative would be to have a small script to make a Typst document self-contained. The typst would fetch all external packages that the document relies on, possibly font files as well, and return a version of the document that builds from these local assets in a self-contained way, along with a metadata file describing where the packages are coming from and which Typst version is known to work for this self-contained document. The result would be highly reproducible.
from this thread :
And this one from the same thread :
Reproducability
The goal is to be as confident as posssible that Typst source can be shared and recompiled when having access to the right version of the Typst compiler. Different problem comes into mind :
- system fonts that have to be installed to be used
- online packages with the right version
- common build system to build the same way every time
I will now discuss counter measure that permits to be confident that you can share Typst source code between people on the same project or to publishers.
Fonts
This is solved by using the --ignore-system-fonts and --font-path parameter of the typst compiler command. Other option is to only used embed fonts of the Typst compiler but this is not ideal.
In a given project I usually put fonts in a fonts/ directory (I am not very knowledgable in potential Licensing issue with dowloading random fonts on the internet).
This command to compile file is good to ensure that multiple authors have no problem to compile on their system :
typst compile main.typ --ignore-system-fonts --font-path fonts/
Online Packages
Packages are right now imported this way : #import "@preview/package_name:version".This is pretty flexible however this forces internet access multiple times. For this to be reproducible we have to assume multiple things :
- version has to be specified : this is already the case and mandatory so this is good
- the github typst packages repository has to be always available : in my experience this has been the case but cannot be garanteed in long term (especially for publishers)
Downloading once and for all the package you use is one of the solution to allow to distribute things in a reproductible way. You can this in multiple ways :
- downloading all the packages repository (maybe a bit too much however this is the Latex approach)
- use the
--depsarguments of thetypst compilecommand to get all dependancy however I found this to be too precise as it gets you files that you have used however this may change if you modify a bit your source file. For this to be effective packages should have in theirtypst.tomltheir exact depedancy written somewhere for easier import of indirect depedancy.
Build tool
I usually use a Makefile even if I prefer justfile. But I don’t want to make people install something they don’t have on their system. As with Rust or other language, it is very appreciated to not have to use an external tool to build something. Or at least to use a well polished tool maintained by the community/fondations.
Proposal
Use typst.toml the optional entry point for typst compilation.
I wish we could do :
typst compile
this would look at a typst.toml (if present) or a config file that describe the command line arguments of the command. typst.toml already exists for packages and should be configures a bit differently for document project. In Rust there is the same dichotomy between binary project or library projects that bot use the Cargo.toml file. Here a “binary” project would produce a pdf (or other format) while a “library” project would give access to library function just as packages do today in Typst.
- Package should indicate their dependancy before compiling to be able to downloading all the code needed when using a given package. To do that we could extend the
typst.tomlwith a “dependancies” field.
[dependancies]
cetz = "2.3.4"
fletcher = "5.2.3"
- we should be able to define a “binary” compilation to pdf or other format in the
typst.tomlwith “bin” field. Every single argument of the Typst CLI would be accessible in thetypst.tomlwith the exact same name and parameter.
Here is a typst.toml that would be the result of everything I just said :
[dependencies]
cetz = "2.3.4"
fletcher = "5.2.3"
[[bin]]
entry-point = "main.typ"
output = "main.pdf"
# Reproducible fonts
ignore-system-fonts = true
font-path = "fonts/"
# Reproducible packages
package-path = "packages/"
ignore-online-package = true
The ignore-online-package does not exists yet but could be useful in the same vain as ignore-system-fonts.
Of course I don’t want to reinvent the wheel and this is proposal is of course inspired by the way Rust do it with Cargo.toml.
One major thing that the compiler should also make possible it to not have to patch existing Typst code. For example #import "@preview/cetz:2.3.4 should be able to point to a local package without changing the source code.
Conclusion
This is one way to do it. Please share your setup for making it easier to work in group on Typst project. The web app also have been a solution for me because a lot is being taken care of for you. Especially Typst version is very well handled on the web app. However the web app does not solve the publisher problem that won’t want to use the web app to compile a document.
Another possibility would be to define all of this in the Typst language directly. Maybe this is the direction that would be choosen especially because the document function has already been enriched in previous version of Typst to be able to write a “build” file that compiles multiple document for a web page for example. This is handy but it might be too heavy to put allll the CLI arguments inside the document function API.