I would like to use an if-condition in a template function to trigger dark mode. The template function has a boolean value dark
that defaults to false
. The following code works:
set page(fill: rgb("333333")) if dark
set text(fill: rgb("fdfdfd")) if dark
set text(font: "Source Sans Pro") if dark
However, when I try to wrap all three lines into an if-condition, I get a blank page (set in dark mode) and then the rest of the document in light mode instead. What am I doing wrong here?
if dark {
set page(fill: rgb("333333"))
set text(fill: rgb("fdfdfd"))
set text(font: "Source Sans Pro")
}
set
rules only work in their scope and child scopes. The if
statement creates a new scope, meaning set
rules are only active at that level:
if dark {
set page(fill: rgb("333333"))
// "set" rule is active from here
....
} // to here, where the scope ends
You can get around this using set-if
rules:
set page(fill: rgb("333333")) if dark
set text(fill: rgb("fdfdfd"), font: "Source Sans Pro") if dark
But it is inconvenient to do this for multiple rules in a row or when you rely on nested conditions. For more complicated scenarios, I use the following approach:
// Define non-dark mode variables in an outer scope
let (page-fill, text-fill, font) = (none, black, "New Computer Modern")
if dark {
// Reuse variables from an outer scope, so changes persist
(page-fill, text-fill, font) = (rgb("333333"), rgb("fdfdfd"), "Source Sans Pro")
}
// Apply set rules in parent scope
set page(fill: page-fill)
set text(fill: text-fill, font: font)