Universe

syntree is a Typst package for rendering syntax trees / parse trees (the kind linguists use).

Add #import "@preview/syntree:0.3.0: * somewhere in the preamble. This will add both the latest version of the package, and import the tree, syntree, and listtree functions from the library.

The name and default syntax are inspired by Miles Shang’s syntree. Here’s an example to get started:

#import "@preview/syntree:0.3.0": syntree

#syntree(
  nonterminal: (style: "italic"),
  terminal: (fill: blue),
  child-spacing: 3em, // default: 1em
  layer-spacing: 2em, // default: 2.3em
)[
  [S [NP This] [VP [V is] [^NP a wug]]]
]

Output tree for "This is a wug"

There’s full support for formulas inside nodes; for example, #syntree[[DP$zws_i$ this]] or #syntree[[C $diameter$]]. For more flexible tree-drawing, tree can be used directly:

#import "@preview/syntree:0.3.0": tree

#let bx(col) = box(fill: col, width: 1em, height: 1em)
#tree("colors",
  tree("warm", bx(red), bx(orange)),
  tree("cool", bx(blue), bx(teal)))

Output tree of colors

In addition to standard syntree bracket syntax, a list-based syntax is also provided:

#import "@preview/syntree:0.3.0": listtree

#figure(gap: 2em,
  caption: "Example of a syntax tree.")[
  #listtree(
    nonterminal: (style: "italic"),
    terminal: (fill: blue),
  )[
    - S
      - NP
        - Det
          - the
        - Nom
          - Adj
            - little
          - N
            - bear
      - VP
        - VP
          - V
            - saw
          - NP
            - Det
              - the
            - Nom
              - Adj
                - fine
              - Adj
                - fat
              - N
                - trout
        - PP
          - P
            - in
          - ^NP
            - the brook
  ]
]

Output tree for "The little bear saw the fine fat trout in the brook"

And tree, syntree, and listtree all can compose with each other.

#import "@preview/syntree:0.3.0": listtree

#figure(gap: 2em,
  caption: "Example of a syntax tree.")[
  #listtree(
    nonterminal: (style: "italic"),
    terminal: (fill: blue),
  )[
    - S
      #syntree[
        [NP
          [Det the]
          [Nom
            [Adj little]
            [N bear]
          ]
        ]
      ]
      - VP
        - VP
          - V
            - saw
          - NP
            - Det
              - the
            #tree("Nom",
              tree("Adj", "fine"),
              tree("Adj", "fat"),
              tree("N", "trout"))
        - PP
          - P
            - in
          - ^NP
            - the brook
  ]
]

Output tree for "The little bear saw the fine fat trout in the brook"