Scoped `state()`?

Hi all,

I’m new to Typst—it’s a great typesetting language!

I’ve been using it to write my resume and learning along the way. I’m using the minimal-cv template, which is excellent, but it produces a warning about “content labelled multiple times.” I tried to fix it myself, and during this journey, I thought I had found a bug in Typst (#7692), but it turns out this is intended behavior.

Anyway, the template triggers the warning because it uses an “ellipse hack” to pass the theme parameter into functions. Specifically, it:

  1. Marks function bodies with label() in functions like section(), with the optional theme stored in ellipse.inset or ellipse.outset attributes
  2. Uses show label("cv-label") rules to process the content and extract the theme from the ellipse attributes

Contributors advised me to use state() instead of this approach. So I dove into learning state() and quickly ran into a question: It seems state() doesn’t follow scoping rules. What I mean is, I cannot temporarily set a state value within a block scope and have it automatically restore to its previous value after exiting the scope—the way set ellipse.inset works with style properties.

Is there any way to achieve scoped state behavior, or is this on Typst’s roadmap? Is there an existing issue tracking this feature?

Thanks for any guidance!

1 Like

This sounds like you’re looking for custom types—here’s one relevant thread from the forum: (How) can I define a new type in the Typst scripting language? (I also recommend the linked blog post; so yes, it’s on the roadmap).

For now, there is the Elembic package which does something (probably) similar to your ellipse hack, but may be better tested and more featureful, meaning you may be able to fix your issues using it. You should note though that fundamentally, Elembic is meant to be superseded by a built-in Typst feature, so using it is somewhat experimental. That said, lilaq, a pretty big graphics package, uses it too, so using elembic in a production-grade package is also not unheard of.