Typst currently doesn’t have reflection natively (using typst code to look at other typst code in a structured way).
But, Typst supports plugins compiled to WebAssembly. And Typst itself is written in Rust, a language that can compile to WebAssembly.
“So,” the devil whispers in your ear, “why not compile a part of typst itself to a plugin and run it inside typst?” [The Inception soundtrack plays…]
Yes, it is very inefficient. Wasteful, even. But it works, and that is what counts.
API
This package exposes two functions:
parse(str, flat: bool)
: Produce a representation of typst syntax (markup mode).- The output with
flat: false
(the default) is more structured and thus probably more useful. - The output with
flat: true
is simpler, but also more direct, including e.g. comments.
- The output with
operator-info(str)
: Get arity, precedence and associativity information for an operator.
I haven’t taken the effort to explicitly document the output format of parse
, but you can use the following information:
- For
flat: true
, it’s a really simple tree and all nodes have the same form:(kind: str, span: (start: int, end: int), text: str, children: array[node])
. - For
flat: false
, whenever fields of a node are only sometimes present, there will also be akind
(orlet-kind
) field, indicating an enum. Otherwise, every field is always there for that type of node (abscence will be indicated by anone
value). If you need more info than that, you can try around and see what outputs you can get, or, if you really want to be sure, readrust-plugin/src/lib.rs
.