Slash fractions here!

Many may have noticed that inline equations show fractions in a vertical format, which might not be very elegant when the fraction becomes longer. For example:

- $1 / 2$

- $(1 / 2) / (3 + 1)$

- $(A / (m omega^2))^2 / sqrt(B / (A + C))$

- $a + b / c$

- $(a + b) / c$

Result-before

To improve this, I created a function to convert the fractions into slash style which is more readable for large fractions.

Code
let slash-frac(eq) = {
  let modify(f) = {
    let num = if f.num.func() == [].func() {
      math.lr([\(] + f.num + [\)])
    } else {
      f.num
    }
    let denom = if f.denom.func() == [].func() {
      math.lr([\(] + f.denom + [\)])
    } else {
      f.denom
    }
    return math.lr([#num #math.mid(math.class("fence", "/")) #denom])
  }

  // Empty
  if eq.body == [] {
    return eq
  }

  // Single Frac
  if eq.body.func() == math.frac {
    let args = eq.fields()
    args.remove("body")
    let new_eq = math.equation(
      ..args,
      modify(eq.body),
    )
    return new_eq
  }

  // Sequence
  if eq.body.func() == [].func() {
    if eq.body.children.find(c => c.func() == math.frac) == none {
      return eq
    }
    let children = eq.body.children.map(c => if c.func() == math.frac {
      modify(c)
    } else {
      c
    })
    let args = eq.fields()
    args.remove("body")
    let new_eq = math.equation(
      ..args,
      children.join(),
    )
    return new_eq
  }
  return eq
}

After adding

#show math.equation.where(block: false): slash-frac

the former equations would be like this

Result-after

It only converts the outermost fraction and add parentheses smartly.


Update: I have created a package here

I found a bug about lr matching, and fixed it.

Feel free to report bugs & issues!

17 Likes

v0.1.1 has been released! Please feel free to share feedback or submit issues!

2 Likes

Doesn’t typst have built-in support for slash division?

It now has support for skewed and horizontal styles in math.frac, since 0.14, but that didn’t exist when this thread was first posted.

(The result is also not exactly the same as the examples from this package.)

1 Like