Hi all,
I’m writing a simple slides template for my own usage. A couple of settings are different from project to project and are shared by some functions of the template. Let’s say a shared setting is bg
, used by functions f1
and f2
. AFAICS there are two approaches to achieve what I need:
-
A factory function in the template that creates closures for
f1
andf2
with the project-specific value forbg
. In this casebg
is inmutable, but I’m ok with that. -
Having a state object for
bg
in the template, as suggested in Write once variables · Issue #1913 · typst/typst · GitHub.
I’d like to implement the second alternative but I’m having some trouble getting the state:
#let config = (bg: state("slides.bg"))
#let slides(body, bg) = {
config.S.update(bg)
body
}
#let f1() = {
box(fill: config.bg.get(), "hello")
}
#let f2() = {
box(fill: config.bg.get(), "world")
}
At this point Typst complained about missing context
in the get expressions. Fine, I replaced them by:
box(fill: context config.bg.get(), ...)
but then I got expected color, gradient, tiling, or none, found content
. Ok, I assume context always build content, disregarding the type of the contextualized expression. I changed the expressions again to:
context box(fill: config.bg.get(), ...)
This works for this simple example, but in my real code I would like to assign the setting to a variable in order to use it in a number of expressions:
#let f1() = {
let bg = context config.bg.get()
box(fill: bg, "hello")
}
but now I’m obviously back at the expected something, found content
error. Maybe:
#let f1() = {
context let bg = config.bg.get()
box(fill: bg, "hello")
}
? Nope: unknown variable bg
, the scoping is wrong. Let’s try another one:
#let f1() = context {
let bg = config.bg.get()
box(fill: bg, "hello")
}
Ok, this works. But I’m not really comfortable with contextualizing the entire block just because of bg, at least because it makes difficult to spot where context is actually needed (not in this simplistic example, of course).
Do you have any better ideas? Some suggestion on how to structure the code for the described use case?
Thanks!