全局定义的宏改变数值

全局定义的宏改变数值

在实验过程中\ThisStyle,我发现了以下非常奇怪的行为:

\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}

结果是这样的:

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

实际上,全局\edefed 宏(仅设置一次)在设置和访问之间会改变其值,并且数值恰好对应于所需值的一半。这是为什么呢?

答案1

只要你在当前范围内回忆它 \ThisStyle,它会记住高度(但在退出时会丢失对它的有效记忆\ThisStyle)。在这里,我移动了\ThisStyle 调用\textrm

正如 Gustavo 所评论的,\ThisStyle调用标准 LaTeX \mathchoice,它会构建 4 种样式的框,并在最后一刻确定要设置哪一种。这意味着,一旦退出范围,最后构建的框将是\scriptscriptstyle框,并且来自的残差测量和全局定义\mathchoice将仅与该框相关联。\ThisStyle

\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}

在此处输入图片描述

然而,这是一种可以做到的最好的\mathchoice方法...它可以在不同的宏中全局保存所有 4 个高度,但它不会记住当时在内部应用的特定样式\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}

在此处输入图片描述

答案2

您可以使用mathstylescalerel

\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}

在此处输入图片描述

答案3

\ThisStyle通过 实现\mathchoice;实际上,这意味着它的参数被处理了四次,每种可能的数学风格各处理一次,并且将得到的四个数学列表存储起来并在稍后将数学列表转换为其水平等效项的过程中使用,此时实际要使用的数学风格已知。这意味着参数中包含的每个赋值也执行了四次,因此,如果它是全局赋值,则只有最后一个赋值的效果会保留下来。由于执行顺序是\displaystyle-> \textstyle-> \scriptstyle-> \scriptscriptstyle

相关内容