I have previously found a solution that allows me to have two things:
Chapter headings on the next, odd page, and
To remove all page decorations (e.g. page numbers) on any skipped page
The code I have for this is:
#show heading.where(depth: 1): it => {
{
set page(background: none)
pagebreak(to: "odd")
}
it
}
What I don’t understand is what the extra set of braces is doing to this function. What I do know is that they are clearly necessary, as the following does not work:
#show heading.where(depth: 1): it => {
set page(background: none)
pagebreak(to: "odd")
it
}
In this case, the heading ends up being on its own, isolated page, and the chapter text doesn’t start until the next page.
As someone coming from a programming background, these braces suggest to me ideas like scope, and in the context of Typst, signal the beginning of a code section. But neither of these seem to account for this difference.
The first thing to keep in mind is that #set page(...) will always trigger an implicit page break. This new page will be created whenever a new #set page(...) rule comes into effect, which includes when a short-lived page configuration reverts back to the default configuration.
Secondly, the inner curly braces signal a new scope, and specifically in this case, signal a limited scope for the #set page(...) command.
So what’s happening in the second example, without the inner braces is:
The scope of #set page(...) includes the entire block of code, including the heading.
When this block returns, the page settings revert to the parent scope, which in turn triggers a new page.
This causes the heading and its ensuing body text to be set on separate pages.
When the inner curly braces are added:
The scope of #set page(...) is in effect only during the page break.
When the scope ends, the parent scope’s page settings come back into effect.
And since this page configuration change occurs at the same point as an explicit page break, the implicit page break is forgone.
Since set page already triggers a pagebreak, it can be useful to use pagebreak(weak: true, to: "odd") here, where weak means that it will skip the pagebreak if we already are at the start of a new page.