typst
typst copied to clipboard
`figure.caption` `separator` field only exists if set manually
Description
Take a look at the following Typst code.
// Replaces any figure by its caption separator.
#show figure: it => {
it.caption.separator
}
#figure(
caption: figure.caption(separator: [separator])[caption]
)[figure]
This renders as the word "separator", as expected.
Now, consider the following piece of code:
// Replaces any figure by its caption separator.
#show figure: it => {
it.caption.separator
}
#figure(
caption: figure.caption[caption]
)[figure]
This time, no separator is explicitly declared, and the compiler emits the following error message:
content does not contain field "separator"
The same error message is produced with figure(caption: [caption])[figure]
.
Instead, I would expect the separator
field to contain whatever the default separator is where the figure.caption
is displayed.
Code analysis
I would have expected this to set the separator before the execution of the show rule:
https://github.com/typst/typst/blob/0f274f8edbbb93d65cb11713f4bdf912b3286800/crates/typst-library/src/meta/figure.rs#L534-L540
This is likely due to the fact that synthesize
is not called for the figure.caption
when executing the show rule for a figure
, because the following Typst code works as I would expect, rendering as a colon:
// Replaces any figure by its caption separator.
#show figure: it => {
show figure.caption: it => {
it.separator
}
it.caption
}
#figure(
caption: figure.caption[caption]
)[figure]
Adding the following line in FigureElem::synthesize
seems to fix the issue, although I'm not sure this is the right way to do it.
caption.synthesize(vt, styles)?;
Reproduction URL
No response
Operating system
No response
Typst version
- [X] I am using the latest version of Typst
To handle this for the caption, it would need to be preprocessed during figure synthesis. This pre-processing would need to include basically the whole preparation stage (so that show-set styles are properly materialized), but without actually marking the implement as prepared (because we can't apply show-set styles beyond materializing the fields: for show figure.caption: set text(blue)
there is no place to store the blue style before the caption itself is prepared & shown).
While possible, I'm not sure in how far supporting this now would restrict future design possibilities. There are also other elements like enum.item
which would need similar manual pre-processing.
For this reason, I'll leave this out of #3311 for now. I'm not even sure whether I consider it a bug or just behaviour that may or may not be desirable.