How to create special math macros which preserve the current style?

The mathtools package provides a number of commands like \mathmbox which preserve the current math style. The process seems to involve a lot of \expandafters, \mathpalette and \m@th. The following MWE compiles, but the superscript should not be visible and is. Also, how would I create a two argument macro (like \savebox) where only the second argument is in math mode?

\documentclass{amsart}

\makeatletter
\newcommand{\mathsbox}{\expandafter\mathpalette\expandafter\math@sbox}
\newcommand{\math@sbox}[1]{\sbox0{$\m@th #1$}}
\makeatother

\begin{document}
\begin{equation*}
x^{\mathsbox{2}} = a
\end{equation*}

\end{document}

• I am confident the \ThisStyle macro of the scalerel pacakge can help you, but I don't understand your quesiton fully. What is \mathsbox supposed to accomplish? – Steven B. Segletes Jan 13 '17 at 17:11
• With the modified code you get the exponent in scriptscript style, not in script style. Try adding {}^2 after a^{\usebox{\mybox}} to see it. – egreg Jan 14 '17 at 0:10
• @JohnKormylo Exactly. – egreg Jan 14 '17 at 15:39
• Isn't it what I say in my answer? – egreg Jan 14 '17 at 16:41
• @StevenB.Segletes - Actually, I'm not really trying to accomplish anything except master the process. – John Kormylo Jan 14 '17 at 16:41

\mathpalette needs two arguments, the first of which should be a two argument macro. With your code, the call

\mathsbox{2}


expands to

\expandafter\mathpalette\expandafter\math@sbox{2}


and \expandafter does nothing at all, so you get

\mathpalette\math@sbox{2}


Now, \math@sbox is defined with a single argument, which is bad. According to the definition of \mathpalette

% latex.ltx, line 4289:
\def\mathpalette#1#2{%
\mathchoice
{#1\displaystyle{#2}}%
{#1\textstyle{#2}}%
{#1\scriptstyle{#2}}%
{#1\scriptscriptstyle{#2}}}


you now get

  \mathchoice
{\math@sbox\displaystyle{2}}%
{\math@sbox\textstyle{2}}%
{\math@sbox\scriptstyle{2}}%
{\math@sbox\scriptscriptstyle{2}}}


This typesets four math subformulas expanding each argument; the first becomes

\sbox0{$\m@th\displaystyle$}{2}


and similarly for the other three. So \box0 is set to a box containing an empty formula.

Even if you define \math@sbox with two arguments, you get nothing really useful, because \box0 will turn out to be void.

If you want to properly save the box in the style current at the time of the definition, you can use the mathstyle package (but it has some quirks, beware).

\documentclass{amsart}
\usepackage{mathstyle}

\makeatletter
\newcommand{\mathsavebox}[2]{%
\global\setbox#1=\hbox{$\m@th\currentmathstyle#2$}%
}
\makeatother

\newsavebox{\mybox}

\begin{document}
\begin{equation*}
x^{\mathsavebox{\mybox}{2}} = a^{\usebox{\mybox}}{}^2
\end{equation*}

\end{document}


The {}^2 is meant to show that the exponent is in the correct style (with your code it isn't).

You need to pass two arguments to \math@sbox, the first will be the math style to be used.

\documentclass{amsart}

\makeatletter
\newcommand{\mathsbox}{\expandafter\mathpalette\expandafter\math@sbox}
\newcommand{\math@sbox}[2]{\sbox0{$\m@th #1#2$}}
\makeatother

\begin{document}

\begin{equation*}
x^{\mathsbox{2}} = a
\end{equation*}

\end{document}


Adding \tracingmacros=1 will show you in the log file what arguments are being passed to each macro. See https://tex.stackexchange.com/a/34412/15925 for a good description of the working of \mathpalette.

• @JohnKormylo Indeed - you didn't say what you wanted to use it for though. Box 0 is mostly for local use. – Andrew Swann Jan 14 '17 at 11:12

The \ThisStyle{...\SavedStyle...} feature of the scalerel package can extend the current math style into places where it is normally lost, such as boxes. However, to transport that saved data outside of the \ThisStyle group, an \xdef must be employed.

\documentclass{amsart}
\usepackage{scalerel,amsmath}
\newcommand{\mathsbox}[1]{\ThisStyle{\xdef\xyz{\fbox{$\SavedStyle#1$}}}}
\begin{document}
\begin{equation*}
x^{\mathsbox{2}} = a \quad\text{What was saved and boxed earlier?} \xyz
\end{equation*}
\end{document}


If you want to save something in the current mathstyle in a box, you have to use LuaTeX. It offers the \mathstyle primitive which can be used to query the current math style.

% arara: lualatex
\documentclass{amsart}

\makeatletter
\DeclareRobustCommand\getmathstyle[1]{%
\ifcase \mathstyle
\let#1=\displaystyle
\or
\let#1=\crampeddisplaystyle
\or
\let#1=\textstyle
\or
\let#1=\crampedtextstyle
\or
\let#1=\scriptstyle
\or
\let#1=\crampedscriptstyle
\or
\let#1=\scriptscriptstyle
\or
\let#1=\crampedscriptscriptstyle
\fi
}

\DeclareRobustCommand\mathsbox[1]{%
\getmathstyle\currentmathstyle
\global\setbox0=\hbox{$\m@th\currentmathstyle#1$}%
}
\makeatother

\begin{document}

$\mathsbox{\int}$ \box0

$\mathsbox{\int}$ \box0

\end{document}