Skip to content

typst eval subcommand #7344

@laurmaedje

Description

@laurmaedje

Description

A typst eval subcommand that evaluates a piece of Typst code and outputs the serialized results. Can be done in the context of a document to introspect said document.

The CLI design is to be determined, but one possible argument surface I could imagine is the following:

  • A string of Typst code (required).
  • --in file.typ: A file in whose context the code should be executed. This generalizes the typst query subcommand as it allows using the introspection functions to observe the document.
  • --mode=code|markup|math: While not extremely useful, it nicely mirrors the argument on the eval function and it might come in handy.
  • --scope x=hello: Also mirrors the argument on the eval function. Could be used for safe argument interpolation.
  • --format=json|yaml: The serialization format for the output (like for the existing typst query).
  • --pretty: Whether to pretty-print the serialized output.
  • Flags that affect the compilation itself (like for typst query).

Benefits over typst query:

  • Much more general: Many things that the current query subcommand does not support are trivial with the eval subcommand (e.g. running a transformation over the query).
  • Knowledge about Typst scripting directly translates to typst eval. No need to look up special flags like --field and --one.
  • Extends to use cases beyond querying.

I think these benefits are sufficiently strong to warrant deprecating typst query in favor of typst eval.

Use Case

Query-like use cases:

# Basic case
typst query main.typ raw
typst eval --in main.typ query(raw)
# => [{"func":"raw","lang":"typc", ...}]

# Extracting a field
typst query main.typ raw --one --field lang
typst eval --in main.typ query(raw).first().lang
# => "typ"

Query-like use cases that the current typst query is not capable of:

# Extracting the page number of the bibliography
typst eval --in main.typ locate(bibliography).page()
# => 27

# Extracting the page/x/y positions of all raw blocks
typst eval --in main.typ "query(raw).map(it => it.location().position())"
# => [{"page":1,"x":"10pt","y":"10pt"},{"page":2,"x":"10pt","y":"80pt"}]

Other fun examples:

# Calculations
typst eval 1+2
# => 3

# Testing how some Typst code behaves from the command line
typst eval '"âbc".clusters()'
# => ["â", "b", "c"]

# Taking input from stdin
echo "1+2" | typst eval -
# => 3

# Using a scope
typst eval "x+2" --scope x=$(echo 1)

Notes

Would resolve #7008

Metadata

Metadata

Assignees

No one assigned

    Labels

    change requestA proposal for changes to an existing featurecliAbout Typst's command line interface.feature requestNew feature or requestscriptingAbout Typst's coding capabilities

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions