How write old fashioned factorial symbol in typst?

  • how i can write old style factorial symbol in math mode ??

  • and if we need to make manual function for this, then how make dynamic function so its vertical line take same height as content and similar for width

The content can be placed in a box which has lines on only two sides:

#let old-fact(body) = box(
  stroke: (left: 1pt, bottom: 1pt, rest: 0pt),
  inset: (left: .1em, rest: 0pt),//Affect horizontal spacing
  outset: (bottom: .1em, rest: 0pt),//Do not affect vertical spacing
  body
)

$ n! = #old-fact[$n$] $

$ sqrt( #old-fact($sqrt(x^n) + 1$) / (alpha + beta^gamma)) d x $

Issues:

  • The way I’m calling the function is annoying to type out, but I don’t know a simpler way
  • Vertical line doesn’t extend far enough for the second example

Nice solution. This is how I would suggest making it a math function. It works, but it doesn’t work transparently in script size unfortunately.

We give it a name without hyphen (math functions can’t have hyphen) and call it using oldfact(math content).

#let oldfact(body, script: false) = {
  set text(size: 0.6em) if script  // script size is awkward
  box(
    stroke: (left: 0.5pt, bottom: 0.5pt, rest: 0pt),
    inset: (left: .1em, rest: 0pt),
    outset: (bottom: .1em, rest: 0pt),
    math.equation({
      set text(size: 1em/0.6) if script
      if script { math.script(body) } else { body }
    })
  )
}

$ n! = oldfact(n) $
$ T^oldfact(n, script: #true) $
$ sqrt(oldfact(sqrt(x^n) + 1) / (alpha + beta^gamma)) d x $

oldfact(xyz) receives xyz as type content, and we can place it as it is into something that becomes an equation. But here inside the box - acting as a “math boundary” - we need to place it inside a math.equation again. This inner equation resets the math size, creating new problems so to speak - this includes any display, inline, script, sscript size context.


Another option is to use mannot. It’s used to draw annotations and boxes without changing math layout at all. It will work more transparently like any other math function (none of the problems with size mentioned above)

#import "@preview/mannot:0.3.1": core-mark
#let oldfact(body) = {
  core-mark(body, overlay: (width, height, color) => {
    let s = 0.5pt + color
    box(width: width, height: height,
      outset: (top: 0.1em, rest: 0.05em),
      stroke: (left: s, bottom: s))
  })
}
1 Like

I’m sorry for the second post here, but let’s call this a small breakthrough (thanks to @mkorje on discord) so that we can actually get the correct math script size from context - with an additional little smart function. This is an example of a place where 1em and text.size point to different sizes…

/// Return array like this: (func, float)
/// with math size function (math.inline, math.script or math.sscript)
/// and fraction (1, 0.7, or 0.5) of current font size in that context.
#let current-math-size() = {
  // display and inline produce the same size, so they can't be distinguished
  let script-size = 0.7
  let sscript-size = 0.5
  let emsize = 1em.to-absolute()
  let size-fraction = emsize/text.size
  
  let size-function = if size-fraction <= sscript-size + 0.01 { math.sscript }
    else if size-fraction <= script-size + 0.01 { math.script }
    else { math.inline }
  (size-function, size-fraction)
}

#let oldfact(body) = context {
  let (sizefunc, fracsize) = current-math-size()
  set text(size: fracsize * 1em) if sizefunc != math.inline // size the box correctly
  box(
    stroke: (left: 0.5pt, bottom: 0.5pt, rest: 0pt),
    inset: (left: .1em, rest: 0pt),
    outset: (bottom: .1em, rest: 0pt),
    math.equation({
      set text(size: 1/fracsize * 1em) if sizefunc != math.inline // reset the size change above
      sizefunc(body)
    })
  )
}

$ n! = oldfact(n) $
$ T^oldfact(n) $
$ sqrt(oldfact(sqrt(x^n) + 1) / (alpha + beta^gamma)) d x $


#let cont = context current-math-size()
$ display(cont) inline(cont) script(cont) sscript(cont) $

1 Like