How to add arrows between equation lines, like latex `witharrows`, in Typst?

Here is a semi-automated version using mannot:

#import "@preview/mannot:0.3.0": annot-cetz, mark
#import "@preview/cetz:0.4.1"

#let bent-arrow(from, to, body, bend: 0.1, shrink: 0.04) = {
  import cetz.draw: arc-through, content, set-style
  let mid = (rel: (bend, 0), to: (from, 50%, to))
  set-style(mark: (end: ">", fill: black, scale: 0.5))
  arc-through((rel: (0, -shrink), to: from), mid, (rel: (0, shrink), to: to))
  content(mid, anchor: "west", pad(0.5em, body))
}

#let mark-line(tag) = mark(tag: tag)[]

#let arrow(from, to, body) = bent-arrow(from, to, body)

#let arrow-coords(ctx, ..coords) = {
  let (_, ..coords) = cetz.coordinate.resolve(ctx, ..coords)
  let right-most = calc.max(..coords.map(v => v.first())) + 0.2
  coords.map(v => (right-most, v.at(1)))
}

$
   x^2 + 5x & = 2x^2 #mark-line(<a>) \
  -x^2 + 5x & = 0 #mark-line(<b>) \
    x_(1,2) & = (-5 plus.minus sqrt(25)) / (-2) #mark-line(<c>) \
    x_(1,2) & = 0, 5 #mark-line(<d>) \
  #annot-cetz((<a>, <b>, <c>, <d>), cetz, cetz.draw.get-ctx(ctx => {
    let (a, b, c, d) = arrow-coords(ctx, "a", "b", "c", "d")
    arrow(a, b)[$-2x^2$]
    arrow(b, c)[Quadratic Formula]
    arrow(c, d)[Simplify]
  }))
$

A fully automated version would require more code, and less verbose syntax — even more code. Latex witharrows in typst - #4 by bluss does give a somewhat 1 to 1 solution.

2 Likes