How to control the math superscripts element?

I am writing a math test paper with lots of fractional superscripts, but it is illegible in small font sizes. How to increase the height of the superscript element or how to increase the gap between the numerator, the fraction line and the denominator?

This is how it looks at the moment:

2 Likes

There are some fraction related packages available. Maybe one of them will be suitable for your use case.

#import "@preview/fractus:0.1.0" as frac
#let fr = frac.display.with(style: "inline")
$ lr((9 / 26) ^ #fr("-1/2")) $

#import "@preview/frackable:0.2.0": frackable as fr
$ lr((9 / 26) ^ #fr(-1, 2)) $

#import "@preview/slashion:0.1.1": slash-frac as fr
$ lr((9 / 26) ^ fr(-1/2)) $

One thing that may be a drawback is that they all require calling a function to take affect. The package slashion demonstrates using a show rule to apply the function to all fractions in an equation, but I’m not sure that is what you want either.

Regular superscripts use the script style in math (and superscripts on superscripts use sscript).

The first question is - what’s a more legible alternative to the default superscript, and maybe it could be something like this:

#let bigsuper(x) = math.inline(text(size: 0.85em, x))

$(343/216)^(2/3)$

$(343/216)^bigsuper(2/3)$

Applying this style automatically to all scripts in math is not obvious to me how to do (it could be done by replacing math.attach objects, but it’s not a so satisfying solution because of how complicated the code gets)

Maybe targeting math.frac is a good call, those are a little bit easier to target.

1 Like

Attempting to do it the long and proper way if there is one.

  • Establish possibility of styling math scripts with show/set in a template/style function
  • Implement the desired style

Philosophy: I want Typst documents to be like the “document” part here. It’s great that we can implement the nitty gritty details like in the template here; that kind of code belongs in Typst itself or in a package.

Template / Style
// Template/Style starts here
#set enum(number-align: horizon, numbering: "A.")
#show enum: it => {
  show math.equation.where(block: true): set align(start)
  it
}

/// Label for script level n = 1, 2 and so on
#let scriptlevel(n) = label("math-script:" + str(n))
// Template style for controlling math scripts (sub/superscripts)
#let math-script-style(body) = {
  // State: current script level
  let scriptlevel-state = state("math-scriptlevel", 0)

  // increase script level in attachments (scripts)
  show math.attach: it => {
    if it.at("label", default: none) == <processed> {
      return it
    }
    context {
      let scriptlabel-n = scriptlevel(scriptlevel-state.get() + 1)
      let fields = it.fields()
      let base = fields.remove("base")
      let previous-label = fields.remove("label", default: none)
      // transform all the attachments
      let fields = fields.pairs().map(((key, script)) => {
        if script != none {
          script = scriptlevel-state.update(x => x + 1) + [#script#scriptlabel-n] + scriptlevel-state.update(x => x - 1)
        }
        (key, script)
      }).to-dict()
      // XXX: Apply #previous-label to the result or not? Seems best to not do
      [#{[#math.attach(base, ..fields)<processed>]; [ ]}]
    }
  }

  body
}
Document
#show: math-script-style

// Set style for scripts (by level, if needed)
#show math.equation: eq => {
  show scriptlevel(1): math.inline
  show scriptlevel(1): text.with(size: 0.85em)
  eq
}

+ $ (1/4)^(-2) - 3 times 8^(2/3) times 5^0 + (9/26)^(-1/2) $
+ $ sqrt(1/4) + (0.01)^(-1/2) - (27)^(2/3) times 3^0 $
+ $ (343/216)^(2/3) $
+ $ sum_(x^i) "scripts on scripts below" $


What does the style code do

  • Transform all math.attach; they have a base and several attachments. Increment scriptlevel state in all attachments. Label all attachments with their current script level.
  • Mark the transformed math.attach so that we terminate recursion, otherwise we would repeat the same show rule ad infinitum.

There is/was a bug about #previous-label in the code - applying the label again makes some styles apply multiple times to scripts that have scripts, which is not intended. Shows why this should be in a package, to shake out details and bugs.

3 Likes

Thanks to everyone who replied. I think @bluss’s answer makes it easier to implement for a one time thing.

1 Like