6

In experimenting with \ThisStyle, I have come across the following very weird behavior:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{scalerel}
\def\foo{%
    \ThisStyle{%
        \setbox0=\hbox{$\SavedStyle o$}%
        \global\edef\myheight{\the\dimexpr\ht0+\dp0\relax}%
        \textrm{Written \string\myheight\space as \meaning\myheight;~}%
    }%
    \textrm{reading \string\myheight\space as \meaning\myheight}%
}
\begin{document}
    $\foo$
\end{document}

The results is this:

Written \myheight as macro:->4.30554pt; reading \myheight as macro:->2.15277pt

Effectively, the globally \edefed macro (set only a single time) changes its value between setting and accessing, and the numerical value corresponds to exactly half the desired value. Why is that?

1
  • 3
    It’s because \ThisStyle invokes \mathchoice, which executes the code for all the four possible styles, in the order \displaystyle/\textstyle/\scriptstyle/\scriptscriptstyle; so, \box0 is set equal to the four variants in turn, and only the last assignment remains in effect. Maybe I’ll find the time, later on, to write a complete answer, if nobody has done it yet.
    – GuM
    Jun 14, 2017 at 14:59

3 Answers 3

4

As long as you recall it within the scope of the current \ThisStyle, it will remember the height (but will lose valid memory of it upon exit from \ThisStyle). Here, I moved the closing brace of the \ThisStyle after the \textrm invocation.

As Gustavo commented, \ThisStyle invokes the standard LaTeX \mathchoice, which builds 4 styles of boxes and figures out which one to set at the last moment. This means that the last box built will be the \scriptscriptstyle box, and residual measurements and global definitions from the \mathchoice will be associated with that one only, once the \ThisStyle scope has been exited.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{scalerel}
\def\foo{%
    \ThisStyle{%
        \setbox0=\hbox{$\SavedStyle o$}%
        \global\edef\myheight{\the\dimexpr\ht0+\dp0\relax}%
        \textrm{Written \string\myheight\space as \meaning\myheight;~}%
    %
    \textrm{reading \string\myheight\space as \meaning\myheight}}%
}
\begin{document}
    $\foo$
\end{document}

enter image description here

However, here is the best that a \mathchoice approach can do...it can save all 4 heights globally in different macros, but it will not remember the particular style that applied at the time, inside the \mathchoice.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{scalerel}
\makeatletter
\def\foo{%
 \ThisStyle{\setbox0=\hbox{$\SavedStyle o$}%
   \expandafter\xdef\csname myheight\m@switch\endcsname{\the\dimexpr\ht0+\dp0\relax}%
   \textrm{Written \string\myheight\space as %
     \expandafter\meaning\csname myheight\m@switch\endcsname;~}%
}}
\makeatother
\begin{document}
$\foo $

$\scriptstyle\foo$

But here are the 4 sizes globally saved:\\
Display style: \myheightD\\
Text style: \myheightT\\
Script style: \myheightS\\
Script-Script style: \myheights
\end{document}

enter image description here

2
  • This does not solve the problem, because after that \myheight will expand to 2.15277pt nonetheless. The OP's aim is to have it defined to the height plus depth of the actually typeset material and that's the reason for having the second \textrm outside of \ThisStyle.
    – egreg
    Jun 14, 2017 at 15:29
  • @egreg It will not solve a global definition issue, nor did I say it would. I only indicated that one could reliably employ the value only within the scope of the \ThisStyle. Jun 14, 2017 at 15:30
6

You can use mathstyle instead of scalerel:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{amsmath}
\usepackage{mathstyle}

\newcommand\foo[1]{%
  \sbox0{$\currentmathstyle o$}%
  \xdef#1{\the\dimexpr\ht0+\dp0\relax}%
  \texttt{\footnotesize\meaning#1}%
}

\begin{document}

$\foo\myheightT$ has value \myheightT

$_{\foo\myheightS}$ has value \myheightS

\end{document}

enter image description here

1
3

\ThisStyle is implemented through \mathchoice; in practice, this means that its argument is processed four times, one for each of the four possible math styles, and the resulting four math lists are stored away and used later, during the process of converting a math list into its horizontal equivalent, when the actual math style to use becomes known. This entails that each assignment contained in the argument is executed four times too, so that, if it is a global assignment, only the effects of the last one will survive. And since the order of execution is \displaystyle -> \textstyle -> \scriptstyle -> \scriptscriptstyle

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .