How does one avoid caligraphic font difference between Typst and LaTeX?

In LaTeX, the calligraphic font by amsmath creates the following:

\documentclass[margin=10mm]{standalone}
\usepackage{amsmath}

\begin{document}
$\mathcal{ABCDEFGHIJKLMANOPQRSTUVWXYZ}$
\end{document}

gives

However, the calligraphic font in Typst:

#set page(margin: 10pt, width: auto, height: auto, background: none)
$cal(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)$

gives


Can someone point me to a solution to get LaTeX’s version of calligraphic font (if it is possible)? Perhaps a font feature option? I don’t know where to start if I were to try and search it myself. :see_no_evil:

Many thanks!

The documentation for cal shows how to enable a font option (stylistic set) to get a different style, but I don’t think this will help you.

I think this is just New Computer Modern Math (used by Typst) being different from the default Latex font. If you do \usepackage{fontsetup} (the more recent way to setup fonts in Latex) it will also use New Computer Modern and you’ll get the same style as Typst.

To answer directly your question: you’d need to find a Truetype/OpenType font with this style for calligraphic letters. I don’t know if there’s one.

One possible font with this style of calligraphic letters would be this Garamond Math with stylistic set 3. To only use this font for those letters, you can define a custom function like this (using some weird hacks to circumvent a current limitation of Typst) :

#let cal(it) = math.class("normal", box({
  show math.equation: set text(font: "Garamond-Math", stylistic-set: 3)
  $#math.cal(it)$
}) + h(0pt))

The \mathcal font is not provided by amsmath. In User’s Guide for the amsmath Package:

The basic set of math font commands in LaTeX includes \mathbf, \mathrm, \mathcal, \mathsf, \mathtt, \mathit. Additional math alphabet commands such as \mathbb for blackboard bold, \mathfrak for Fraktur, and \mathscr for Euler script are available through the packages amsfonts and euscript (distributed separately).

The font you are using is the TFM font Computer Modern.

This solution doesn’t work when the caligraphic fonts are used in subscripts, for instance

$
  sum_(i in cal(I)) x_i = 0.
$

This renders with the cal(I) full size, as though it weren’t a part of the subscript.

Would you happen to have a solution that works in this case too?

Right, there were some changes in 0.13 regarding how nested equations are sized in subscripts. There is an open issue about that here. Since this also came with a change in how 1em is resolved, we can use that to our advantage and calculate the ratio by which the text size changes in subscripts. Based on that ratio, we can then decide whether to wrap the equation in a script or sscript call. I choose a boundary of 60% in the hope that it works with most math fonts, but that can be adjusted.

#let cal(it) = math.class("normal", context {
  show math.equation: set text(font: "Garamond-Math", stylistic-set: 3)

  let scaling = 100% * (1em.to-absolute() / text.size)
  let wrapper = if scaling < 60% { math.sscript }
                else if scaling < 100% { math.script }
                else { it => it }
  
  box(text(top-edge: "bounds", $wrapper(math.cal(it))$))
})

The top-edge: "bounds" is necessary as otherwise, the box get the regular (i.e. unscaled) height leading to a misplaced subscript.

1 Like