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
f1andf2with the project-specific value forbg. In this casebgis inmutable, but I’m ok with that. -
Having a state object for
bgin 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!