TL;DR: in my experience it is difficult or impossible to “tweak” Typst templates to change some layout policies without copying and modifying its source code. Is it just that we are collectively bad at writing templates, or a fundamental design flaw or missing feature in the Typst language?
Context
I’ve been using Typst for various documents for a few months now (free-form documents, talk slides, more structured document looking like math research papers). My experience is that “packages” work as I expect (I import them, use them, I can find documentation online etc.) but that “templates” (packages that define the layout of the document, corresponding to LaTeX document classes) never work in the way I would expect, which comes from my experience with LaTeX templates.
In LaTeX-land the usual experience is to use a document class, and then tweak it (in the preamble of my document) to get the desired result. Maybe I want to have larger margins, change the styling of sections (but not subsections), whatever. It is very easy to do. In Typst, my experience is that this is often unpleasant, sometimes impossible, and I always end up copying the template in my local repository and modifying its implementation.
This observation is coherent with the fact that there are tons of templates online: people don’t seem to reuse each other templates, they copy-paste, modify, and then releasr their own.
Concrete example
I wanted to write a math document so I decided to start from an existing math template. I randomly picked the unequivocal-ams template, which is maintained by the Typst authors (so: presumably it embodies best practices in writing templates), and described as
An AMS-style paper template to publish at conferences and journals for mathematicians […] It also is a nice starting point for a classy tech report or thesis.
I import the package and notice that level-1 headings are in smallcaps, which may be what the AMS does but I don’t like it. Here is a simple repro case:
#import "@preview/unequivocal-ams:0.1.2": ams-article, theorem, proof
#show: ams-article.with(
title: [A simple math document],
paper-size: "a4",
)
= My first section
Some content.
How can I, from the document, tweak the package to change the level-1 headings to not be smallcaps anymore? This should be easy with #set
or #show
rules, right? (Or maybe an option of the ams-article.with
function?)
Wrong! Or at least I don’t know how to do this. The problem is that unequivocal-ams
has no parameter to toggle this, and defines all its heading style choices in a single show heading: it => { ... }
block (see the current source code). The only way I found to override this show is to repeat show heading: it => { ... }
myself, but this removes all the styling choices for all headings, not just the styling of level-1 heading. If the package defined this heading-style function as an exported variable, I could call it again from my own document and also do some overrides. But it does not.
The only solution I found is to re-implement all heading styles in my document, by copying the template definition and then simplifying it away.
The question
How can we make it easy to use a template and let users tweak aspects of it? I currently see the difficulty of doing this as a major flaw of Typst compared to LaTeX.
- Maybe I’m just unlucky in my package choices or missing something obvious, and there is no problem?
- Is this just a question of social convention, there is a way to write template packages in easy-to-override style (which one? are there best-practices described somewhere?) and we should ask people to follow it? For example, maybe all style choices should be controlled by mutable variables that users can change, or pass as package config parameters? Or maybe all layout functions in the template should be named explicitly, to allow a user-defined callback to use a form of “inheritance” by calling them?
- Or is this a fundamental missing piece in Typst the language? Do we need a first-class construct for tweakability, similar to the existing research on Aspect-Oriented Programming? Emacs has a
defcustom
mechanism for variables anddefadvice
for functions (and generous use of dynamic binding) to support similar forms of configurability.