Various examples online define a flex-caption function to generate long vs short captions for “List of Figures” outlines. I cannot get it to work properly when doing #import.
I have two files: lib_mwe.typ
#let in-outline = state("in-outline", false)
#show outline: it => {
in-outline.update(true)
it
in-outline.update(false)
}
#let flex-caption(short: none, long: none) = context if state("in-outline", false).get() {
short
} else { long }
#let custom-outline(..args) = {
show outline: set heading(outlined: true)
outline(..args)
}
Compiling main.typ gives me the “long” caption" in the “List of figures” instead of the “short caption”.
Copy-pasting the contents of lib_mwe.typ into main.typ yields the desired behavior. I suspect state-related issues are at play, but they are beyond me at this point.
The reason is actually not about state, but about styles and templates. import just imports the functions and definitions from lib_mwe.typ. The style you applied in the lib file with show has no effect outside its own file.
#show outline: it => {
in-outline.update(true)
it
in-outline.update(false)
}
So that you can import a function for that and apply it to your actual document in main.typ.
As an alternative to turning it into a template, the style would need to be applied inside a function like for example the custom-outline function. Then it would have effect there.
That’s not quite equivalent, this is the style you want to apply:
#show outline: it => {
in-outline.update(true)
it
in-outline.update(false)
}
And now we write a function that applies this style to a document:
#let template(doc) = {
show outline: it => {
in-outline.update(true)
it
in-outline.update(false)
}
doc
}
As an alternative to turning it into a template, the style would need to be applied inside a function like for example the custom-outline function. Then it would have effect there.
So this did indeed work, thanks. But I’m unclear what it does differently than my template-outline suggestion. When using your template function, I still needed to do #show template in main.typ. Is this expected? If so, why would typst require (seemingly, from my naive perspective) duplicated show calls (within template and in main.typ) ? At the risk of derailing this question, I guess I also don’t understand how to use the doc argument to template.
In this code, when you call #show: template-outline then it is the document. But originally, it was just the outline. That’s why the translation was not equivalent. It could have been made equivalent by applying it as #show outline: template-outline but I wanted to show you how to make a proper template instead.
Yes
They shouldn’t really be duplicated. The original one you had moves into a function, where it’s not used, only defined. Then you use show in main.typ to invoke that template. Maybe that makes sense?