Kerning is off in MathJax4 + Asana + \mathit + "f"
Steps to Reproduce:
I have the following expression in an inline math expression:
\mathit{leftChild}
Technical details:
- MathJax Version: 4.0
- Client OS: Windows 11
- Browser: Firefox 145 and Edge 142
I am using the following MathJax configuration:
MathJax = {
tex: { inlineMath: [ ["$","$"], ["\\(","\\)"] ] },
output: {
font: 'mathjax-asana',
scale: 1, // also tried this at > 1 scales
},
loader: { load: ['[tex]/noerrors'] }
};
and loading MathJax via
<script defer src="https://cdn.jsdelivr.net/npm/mathjax@4/tex-mml-chtml.js"></script>
Supporting information:
- A complete sample file is
<!doctype HTML>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script>
window.MathJax = {
tex: { inlineMath: [ ["$","$"], ["\\(","\\)"] ] },
output: { font: 'mathjax-asana' },
loader: { load: ['[tex]/noerrors'] }
};
</script>
<script defer src="https://cdn.jsdelivr.net/npm/mathjax@4/tex-mml-chtml.js"></script>
<style>
body { font-size: 1.18rem; }
</style>
</head>
<body>
<p>
<ul>
<li><p>\(leftChild(idx) = \mathit{leftChild}(idx) = 2 * idx + 1\)</p></li>
<li><p>\(rightChild(idx) = \mathit{rightChild}(idx) = 2 * idx + 2\)</p></li>
<li><p>\(parent(idx) = \mathit{parent}(idx) = \mathit{floor}((idx - 1) / 2)\)</p></li>
</ul>
</p>
</body>
</html>
- I rendered this four times:
Using \mathit{...} |
Omitting \mathit{...} |
|
|---|---|---|
| Asana | ||
| NewCM |
Things I noticed:
- The two Asana renderings are basically identical, but the two NewCM renderings clearly show the difference that
mathitmakes - If you look at the full example above, the other words look much more consistent in their kerning; only the
fis really wrong.
Yes, you are correct. Here's the deal:
The MathJax fonts are created from a variety of separate fonts, usually a math font, and text fonts for regular, italic, bold, and bold italic. The Math font will give the math symbols, the stretchy characters, and the Math Alphabetic Unicode characters, which includes the italic characters with the spacing used in math, along with Fraktur, Script, Double-struck characters, etc. The text fonts are used to fill in characters that aren't in the math font, and in particular, the text italic is used for \mathit characters.
For example, the mathjax-newcm font uses NewCMMath-Book.otf, NewCM10-Regular.otf, NewCM10-Italic.otf, NewCM10-Bold.otf, and NewCM10-BoldItalic.otf (along with some others, like NewCMMono10-Book.otf and NewCMSans10-Bold.otf). Similarly for STIX2 and the other fonts.
It seems, however, that Asana only has a math font, and none of the other text fonts. In particular, no text italic font to use for \mathit. That means MathJax must fall back on the math italic as the only italic characters available. That is why the two version in your table are the same.
As a work-around, you could use something like
\style{font-family:Times; font-style:italic}{\text{leftChild}}(idx)
to get
and you could redefine \mathit to be \style{font-family:Times; font-style:italic}{\text{#1}} in order to be able to use \mathit{leftChild}(idx) as you do now. You can, of course, substitute another font for Times, if you want something with a different look. Note, however, that even in actual LaTeX, with setmathfont{Asana-Math.otf}, the font used for \mathit is not Asana.
Thanks. For now, since I do want to keep "whichever font it is that mathjax-asana is picking" (since it renders most nicely relative to the surrounding text of my actual document; I'm curious which font it actually picks!), my workaround for now is to render \mathit{le\mkern-2muf\mkern-2mutChild}, which is admittedly a pain to type, but renders as
which looks reasonably well-kerned, and will suffice until Asana one day has correct text metrics for the f used in math mode.
If this is a #wontfix bug because it's actually in the underlying font rather than in MathJax, that's fine; I'll manage with my workaround. (And if there's an appropriate other repo for Asana that this bug should transfer to, that's cool too!) But if there's a way to fix this more broadly for MathJax users, that would be the nicest outcome :)
"whichever font it is that mathjax-asana is picking" (... I'm curious which font it actually picks!)
It is still the Asana font, but it is the math italic letters, which have different metrics from what is needed for text italics, as your example shows. There are no text italic characters in the Asana-Math font (as there are none in any math font), and since there are no Asana text fonts, there is no place for MathJax to get the italic letters needed for \mathit (which is badly named, because it actually produces text italics, not math italics).
This isn't a bug in either MathJax or the Asana fonts. It is just that there are no text italic letters to use, and so the math italic letters are used as the only alternative. That's a limitation, but not a bug.
One future solution would be to make one or more MathJax font extensions that would fill in the text italic characters using glyphs from one of the other fonts, like those from mathjax-newcm. But that isn't likely to happen until we get the font tools released and can start making more specialized font extensions like that.
Got it -- thanks for the explanations!
Last night, I thought of an alternative work-around. Since the "f" is the main culprit, we can define that one character in MathJax's -tex-mathit variant and use some CSS to adjust the spacing around it. Here is a configuration that does that.
MathJax = {
loader: {
'[mathjax-asana]/chtml': {
ready() {
const ASANA = MathJax._.output.fonts['mathjax-asana'].chtml_ts.MathJaxAsanaFont;
ASANA.defaultChars['-tex-mathit'] = {0x66: [.733, .276, .55, {c: '\u{1D453}', f: 'MI'}]};
ASANA.defaultStyles['.mjx-c66.ASNA-MI'] = {margin: '0 -.111em'};
}
}
},
output: {
font: 'mathjax-asana',
}
};
This configuration defines the math italic "f" to have the usual height, depth and width of the regular math "f", using the Math Alphanumerics italic "f" at U+1D453, but assigns it a class ASNA-MI, and we use CSS to remove the 2mu spacing on the right and left. That way, you don't have to modify your LaTeX code.
If the user switches to SVG output, however, this won't work, as the SVG output doesn't use fonts (it uses paths instead), and it won't respond to this kind of CSS manipulation. If you need an SVG solution, let me know.
Oh that's great, that's a much more robust solution than me remembering to add mskips everywhere :) In my actual use case (of writing lecture notes), I've disabled SVG output and the MathJax context menu (so that students don't get sidetracked fussing with MathJax instead of reading the lecture notes!), so I don't personally need to worry about an SVG solution.
Thanks again!