Can I define a new kind of class with methods in the Typst scripting language? (I looked through the documentation but couldn’t find a way - apologies if I missed it.)
As of September 2024, this is not yet possible. However, there are plans to add them! To learn more (and shape development), you can read this blog post and visit the Types forge thread on Discord.
Overall, the plan for custom types is to serve two use cases:
- Aid in writing general programs.
- Use them with set and show rules, like built-in elements. To make this possible, there are plans to remove the content type and instead make each content element (e.g. heading, or list) its own type.
Until proper types are implemented, there are different workaround for these two use cases:
-
For general purpose programming, typically, you would use a dictionary and normal functions:
#let vec = ( x: 10pt, y: 15pt, ) #let vec-add(a, b) = ( x: a.x + b.x, y: a.y + b.y, )
Note that you can store functions in the dictionary, but I would not recommend emulating methods with this: You won’t get access to the members and calling them is cumbersome as you need extra parentheses (e.g.
(dict.func)(..)
).If you are dealing with various types and want to check which kind of type you have, you could add a tag field to your dictionary:
#let value = ( tag: "vec", x: 10pt, y: 10pt, ) #if value.tag == "vec" { .. }
-
To emulate custom set rules, the most common pattern is to use a state. While it doesn’t give the same nice scoping features, it allows you to make some piece of configuration globally available.
// A state to store the theme. #let my-theme = state("my-theme") // Stores a theme color in the theme. #let set-theme(value) = my-theme.update(value) // Displays text with the current theme color. #let themed(it) = context { set text(fill: my-theme.get()) it } // "Hello" will be red. #set-theme(red) #themed[Hello] // "World" will be green. #[ #set-theme(green) #themed[World] ] // ... but the usual scoping rules do not apply #themed[Still green :(]
For the time being you may be interested in this package