Is it possible to query the final value of a state from the CLI?

I’ve found that it’s possible to query the final state using a label like so:

#let s = state("test", 0)
#context [
  #s.final()
  <test>
]
#s.update(2)

Running typst query test.typ "<test>" gives:

[
  {
    "func": "text",
    "text": "2",
    "label": "<test>"
  }
]

This works, but I wonder, is there a more direct way to query this information?

1 Like

There is no more direct way

To add a bit more detail: getting the final value using a context and labelling it is the only way, but the way you did it, you’re robbing yourself of a bit of detail: you’re creating a text element and thus the number is converted to a string. The way that is probably a bit more common is using metadata:

#let s = state("test", 0)
#context [#metadata(s.final()) <test>]
#s.update(2)

This way, the same query results in

[
  {
    "func": "metadata",
    "value": 2,
    "label": "<test>"
  }
]

The query itself can be improved a bit, as usually you only want the value field and your use case suggests that there’s only one <test>:

typst query experiment/test.typ --field value --one "<test>"

Which simply results in the number (and valid JSON) 2.

2 Likes

What hasn’t been pointed out yet is that 2 approaches give a different in-document output:

#let c = counter("test")
|#context [#c.final().first()<test>]|
|#context [#metadata(c.final().first())<test>]|
#c.update(2)

image

So depending on your goal, you might want to use one or the other variant. Or if you want to get number type + print it:

#let c = counter("test")
|#context { let n = c.final().first(); [#n#metadata(n)<test>] }|
#c.update(2)

BTW, for natural number counting you should use counter instead.

2 Likes