I’m curious about using Typst to construct old-school sentence diagrams, as illustrated here. (I don’t know how many forum members are familiar with this practice, but it used to be part of grammar instruction in North America.) I’m happy to try to figure it out on my own, but I’m not even sure where to start. Would Fletcher be the appropriate vehicle for this? Is it even doable?
I’m having quite a lot of trouble parsing the diagram, but a priori I don’t see why this wouldn’t be feasible, but of course the answer of how easy developing such a package will depend a lot on the API of the package, e.g. the level of automation and how much parsing the package needs to do. Before trying to do this with fletcher I’d have a look at tdtr, which allows one to draw tree-style diagrams relatively painlessly and is quite customisable.
While this example (taken directly from the documentation) is much simpler than your diagram, hopefully it gives you some idea on the capabilities:
code
#import "@preview/tdtr:0.6.1" : *
#tidy-tree-graph(
draw-node: (
stroke: none,
defocus: 0 // set to 0 to force the edge to start exactly from south
),
draw-edge: (
tidy-tree-draws.south-north-draw-edge,
(marks: "-"),
),
)[
#let sink(n) = node-attr(sink: n)
- S
- NP
- Det
- The #sink(2)
- Adj
- big #sink(2)
- N
- dog #sink(2)
- VP
- V
- barked #sink(2)
- PP
- P
- at #sink(1)
- NP
- Det
- the
- N
- mailman
]
And since this seems relevant to your project, it is also possible to draw edges between different nodes in the tree
code
#tidy-tree-graph(
draw-edge: (
tidy-tree-draws.horizontal-vertical-draw-edge,
tidy-tree-draws.label-match-draw-edge.with(
to-matches: (
except: (marks: "1!-n!"),
),
default: (marks: "1!-n?"),
),
),
additional-draw: (
tidy-tree-draws.metadata-match-additional-draw.with(
matches: (
snap: (
tidy-tree-draws.side-label-draw-edge.with(label-sep: 0.25em),
(
stroke: teal,
label: text(teal)[snap],
label-side: left,
),
),
layout: (
tidy-tree-draws.side-label-draw-edge.with(label-sep: 0.25em),
(from-node, to-node, _) => (
vertices: (
(rel: (-10pt, 0pt), to: from-node.name),
to-node.name,
),
bend: 40deg,
stroke: orange,
label: text(orange)[layout],
label-angle: auto,
),
),
),
)
),
spacing: (4em, 3em),
node-stroke: luma(80%),
node-inset: .6em,
edge-corner-radius: 2.5pt,
)[
- *Diagram* #metadata("layout.end")
- *Node* <except> #metadata("snap.end") #metadata("layout.begin")
- *Edge* #metadata("snap.begin")
- *Mark*
]
Again feasibility will largely depend on how powerful you intend the package to be, and if your intention is to just draw just a couple of diagrams manually this is certainly feasible

