# How to make persistent changes to math parameters

I find that inline fractions with the Stix Two fonts are a bit too tall, pushing the baselines apart. So I want to shrink them down a little. In principle, I know how; see below.

The problem is that the parameters get reset after a change in font size, even if the size change is local to a group. MWE:

\documentclass{minimal}
\usepackage{fontspec,unicode-math}
\setmathfont{STIX2Math.otf}
\begin{document}
$\frac12$\quad
\Umathfractionnumup\textstyle=5pt
\Umathfractiondenomdown\textstyle=5pt
$\frac12$\quad
{\fontsize{8pt}{9pt}\selectfont$\frac12$}\quad
$\frac12$
\end{document}


The output is as follows.

The second fraction is what I wanted (more or less). But as you can see from the fourth one, parameters are back to standard after the smaller fraction has been typeset. So it seems that I need to hook into something to repeat the relevant settings somehow. I can set these parameters from lua as well, but I have been unable to find a suitable hook. In particular, setting this in luaotfload.patch_font does not cure the problem.

Yes, I could try to use \everymath, but that is prone to being overwritten by other stuff. Or maybe not. I'll try it if desperate, but it does not seem like a sufficiently robust solution.

Also, I wonder if this behaviour is the expected one? It does seem to make life difficult.

• It occured to me that the simplest solution might be to patch \frac itself. But it seems inelegant. Aug 10 '17 at 13:12
• patching the mathconstants table with patch_font should imho work. What did you try there? Aug 10 '17 at 14:49
• @UlrikeFischer Thanks for the hint! I used it to find an answer, which I posted. Aug 10 '17 at 17:05

This seems to work:

\documentclass{minimal}
\usepackage{fontspec,unicode-math,luacode}
\begin{luacode}
local patch_stix = function (fontdata)
if fontdata.psname == "STIXTwoMath" then
local mc=fontdata.MathConstants
local mp=fontdata.mathparameters
mc.FractionNumeratorShiftUp = 0.85 * mc.FractionNumeratorShiftUp
mp.FractionNumeratorShiftUp = 0.85 * mp.FractionNumeratorShiftUp
mc.FractionDenominatorShiftDown = 0.8 * mc.FractionDenominatorShiftDown
mp.FractionDenominatorShiftDown = 0.8 * mp.FractionDenominatorShiftDown
end
end
"my_private_callbacks.patch_stix")
\end{luacode}
\setmathfont{STIX2Math.otf}
\begin{document}
$\frac12$
\end{document}


It produces a fraction as follows:

How I found out:

After being gently prodded by Ulrike Fischer in a comment, I discovered luaotfload.pdf in the standard distribution. I ran the TeX code shown in Section 9.1 there, and looked at the structure of STIX2Math.otf. A little guesswork (wasn't that hard), I ended up with this solution. This answer was also tremendously helpful, of course.

Oddly, the fraction shifts are listed in both the MathhConstants section and the mathparamters section (with identical data), and you have to change both of them.

• After the latest update of luaotfload I get the error 'directlua: attempt to index a nil value (local 'mc')' when running this. Anyone know a fix? Nov 13 '20 at 17:44
• @Michael I have noticed the same thing. But I haven't had the time to try to figure out what happened, other than noting that the fontdata looks quite different now. I'll keep looking, but don't hold your breath. Nov 13 '20 at 20:22

# 2021 update

Improving on the answer of Harald Hanche-Olsen, I've updated the code slightly to work with a current TeXLive 2021 release of the STIX2Math font as well as the current lauaotfload library:

\documentclass{standalone}
\usepackage{fontspec,unicode-math,luacode}
\begin{luacode}
local patch_stix = function (tfmdata)
if tfmdata.psname == "STIXTwoMath" then

-- Some of the loaded files do not appear to contain these MathConstants
-- but I don't know why
if not (tfmdata.MathConstants and next(tfmdata.MathConstants)) then
-- In those cases we simply do nothing
return
end

local mc=tfmdata.MathConstants

mc.FractionNumeratorShiftUp     = 0.85 * mc.FractionNumeratorShiftUp
mc.FractionDenominatorShiftDown = 0.85 * mc.FractionDenominatorShiftDown
end
end

"my_private_callbacks.patch_stix")
\end{luacode}

\setmathfont{STIXTwoMath}

\begin{document}
$\frac{a}{b}$
\end{document}


The central difference seems to be that the names have slightly changed. Maybe some more experiecend OTF expert could comment on why the font gets loaded multiple times (I still get that there are different variants), where sometimes the parameter is not available. But there is a very simply construct to catch these cases.

This is an example of how this looks without and with the patch applied:

# Background

Apart from the answer by Harald Hanche-Olsen I used this dumping script, which was taken from page 31 of the luaotfloat.pdf (version 2021-01-08 v3.17)

\begin{luacode}
local dumpfile = "fontdump.lua"
local dump_stix = function (fontdata)
if fontdata.psname == "STIXTwoMath" then
local data = table.serialize(fontdata)
io.savedata(dumpfile, data)
end
end