Why is the template function I wrote not working properly?

I am trying to put all my style and ctheorem customisations in a separate template file. I want to call a single #show all in my document. The code below works, except that I can’t seem to call two functions within #all() that both take and return #doc. As per my comments within the code, the theorems are formatting perfectly, but the styles are not applying. I am new and don’t (yet) properly understand how Typst is processing everything. Also, if I call styles first and then theorems, styles work but theorems get a bit messed up. So, I infer that you can’t do work on #doc twice like this. Is there another way to keep styles and theorems separate in the template and call them both together from a single function?

So, my document starts like this and then gets straight into the content. Nice.

#import "template.typ": *
#show: all

The template starts like this currently.

#import "@preview/ctheorems:1.1.2": *

#let styles(doc) = [
  #set page(margin: 2cm)
  #set par(justify: true)
  #set heading(numbering: "1.1")
  #doc
]

#let theorems(doc) = [
  #show: thmrules
  #doc
]

#let all(doc) = [
  //#show: thmrules // WHEN SET DIRECTLY HERE, THE STYLES() WORK
  #theorems(doc) // WHEN SET IN THIS FUNCTION, THE STYLES() DON'T WORK
  #styles(doc)
  #doc
]

#let theorem = thmbox(
  "theorem",
  "Theorem",
  base_level: 1,
  namefmt: name => strong(sym.paren.l + name + sym.paren.r),
  bodyfmt: body => emph(body),
  separator: strong("."),
  inset: 8pt,
  radius: 4pt,
  fill: rgb("#BBDEFB")
)
2 Likes

Basically, show will take everything below it and process it using the function you specify. For example:

#show: style
content

is equivalent to:

#style[content]

Based on this rule, let’s take a look at your code.

Firstly,

#let theorems(doc) = [
  #show: thmrules
  #doc
]

is equivalent to:

#let theorems(doc) = [
  #thmrules(doc)
]

So, in reality, thmrules and theorems are exactly the same.

Secondly, when you call show: all, your doc (which, in this case, refers to your entire document) is replaced by:

#theorems(doc)   // the document with theorem styles
#styles(doc)     // the document with other styles
#doc             // the original document

This means your document will be repeated three times, each with different styles.

If you want to apply both styles to your document simultaneously (i.e., you want the result to be):

#theorems(styles(doc))

you can simply define all as:

#let all(doc) = thmrules(styles(doc))

Or, if you prefer a more readable and neat approach:

#let all(doc) = [
  #show: thmrules
  #show: styles
  #doc
]
4 Likes

Hi, thank you for your question! I have changed your post’s title from “Trying to understand functions and templates” to “Why is the template function I wrote not working properly?” as the question guidelines recommend this:

Good titles are questions you would ask your friend about Typst.

I also added the templates and scripting tag, as it makes your question easier to find.

1 Like