数学模式中是否有针对不同风格的测试?我真的想要保存当前样式以便稍后重新调用它,但是\if
类似的方法\ifmmode
也同样有效。
在具体例子中,我想测量某个东西在数学模式下显示时会有多大,所以我这样做:
\settoheight{\mathheight}{some bit of maths}
但它会抱怨,因为它some bit of maths
被放进一个盒子里并被测量,而盒子不知道它是数学。所以我改用:
\settoheight{\mathheight}{\(some bit of maths\)}
但如果将其用于显示的数学,我会得到错误的答案。所以理想情况下,我想要:
\ifdisplaystyle
\let\currentstyle\displaystyle
\else
\iftextstyle
\let\currentstyle\textstyle
...
\fi
\fi
\settoheight{\mathheight}{\(\currentstyle some bit of maths\)}
那我就会很高兴。
有这样的测试吗?
好的,这\mathchoice
显然是可行的方法(感谢 Martin!),但它的行为有点奇怪,因为我想用它来根据我所处的模式定义宏,所以这个奇怪之处非常重要。以下是代码:
\newcommand{\mathtest}{%
\gdef\name{a}%
\mathchoice{%
\name
\gdef\name{b}%
}{%
\name
\gdef\name{c}%
}{%
\name
\gdef\name{d}%
}{%
\name
\gdef\name{e}%
}%
\name}
\[
\mathtest
\]
如果\mathchoice
表现得像\if
,这应该打印ab
。但它打印了ae
。 全部要处理的选项\mathchoice
(这让我有点好奇它是如何工作的,但那是顺便说一下)。
那么,有没有一种明显的方法可以让其\mathchoice
行为更像一点\if
?
答案1
我们将这样的宏称为 mathsettoheight。我将尽量简单,只定义 mathsettoheight(而不是 mathsettowidth 和 mathsettodepth)。
IIUC,你希望这个宏表现得像
\mathsettoheight{\dimen}{content}
首先,让我们考虑一下 \settoheight 的简化版本
\def\settoheight#1#2%
{\setbox\@tempboxa\hbox{{#2}}%
#1=\ht\@temboxa
\setbox\@temboxa\box\voidb@x}
我们在 \mathsettoheight 中需要做的唯一更改是正确设置框。而不是
\hbox{#2}
使用
\hbox{$\mathpalette{}{#2}$}
\mathpalette 是为了方便而使用的快捷方式,通常由所有宏包(纯 TeX、LaTeX、ConTeXt)定义为
\def\mathpalette#1#2{%
\mathchoice
{#1\displaystyle{#2}}%
{#1\textstyle{#2}}%
{#1\scriptstyle{#2}}%
{#1\scriptscriptstyle{#2}}}
一个小的改进是使用
\hbox{$\m@th\mathpalette{}{#2}$}
其中 \m@th 将数学环绕设置为零(如果您对内容的宽度感兴趣则很有用)。
就是这样。你举的例子的完整定义是
\documentclass{amsart}
\makeatletter
\def\mathsettoheight#1#2%
{\setbox\@tempboxa\hbox{{#2}}%
#1=\ht\@temboxa
\setbox\@temboxa\box\voidb@x}
\def\mathsettoheight#1#2%
{\setbox\@tempboxa\hbox{$\m@th\mathpalette{}{#2}$}%
#1=\ht\@tempboxa
\setbox\@tempboxa\box\voidb@x}
\makeatother
% Test case
\newlength\mathheight
\newcommand*\intheight{%
\mathsettoheight{\mathheight}{\int}
\the\mathheight
}
\begin{document}
$\intheight$
\begin{align}
\text{displaystyle}&={\displaystyle\text{\intheight}}\\
\text{textstyle}&={\textstyle\text{\intheight}} \\
\text{scriptstyle}&={\scriptstyle\text{\intheight}} \\
\text{scriptscriptstyle}&={\scriptscriptstyle\text{\intheight}}
\end{align}
{\obeylines
\text{displaystyle}= $\displaystyle\text{\intheight}$\\
\text{textstyle}=$\textstyle\text{\intheight}$ \\
\text{scriptstyle}=$\scriptstyle\text{\intheight}$ \\
\text{scriptscriptstyle}=$\scriptscriptstyle\text{\intheight}$
\endgraf}
\end{document}
答案2
这个答案只适用于 LuaTeX 和 LuaLaTeX,但您的问题很笼统,所以......
引擎luatex
定义了一个原语,允许您查询当前的数学样式。
这个原语被称为\mathstyle
,当查询值时(\ifnum
例如,在之后),它返回一个介于 -1(不在数学模式)、0(显示样式)和 7(狭窄的脚本样式)之间的数字。
Luatex 还定义了四个\cramped..
带前缀的新原语:\crampeddisplaystyle
,\crampedtextstyle
,\crampedscriptstyle
, 。它们与不带前缀的原语( ... )\crampedscriptscriptstyle
类似,只是它们明确地切换到其中一种“局促”的数学风格。\displaystyle
\scriptscriptstyle
最后,还有新的原语\Ustack
,它将用作\over..
和\atop..
构造的前缀(这是命令所喜欢\frac
并\binom
最终扩展为的),如下所示
\Ustack {a \over b}
如果不这样做,\mathstyle
将会在的初始部分返回错误的值{... \over ...}
,正如 Aditya 所解释的那样。
所有这些原语结合在一起,允许如下代码:
\ifnum\mathstyle=\textstyle
\message{normal text style}
\else \ifnum\mathstyle=\crampedtextstyle
\message{cramped text style}
\fi \fi
和这个:
\def\cramped#1% switch the argument to a cramped math style
{{\ifcase\mathstyle
\crampeddisplaystyle \or \or % 0 -> 1
\crampedtextstyle \or \or % 2 -> 3
\crampedscriptstyle \or \or % 4 -> 5
\crampedscriptscriptstyle \fi % 6 -> 7
#1}}
甚至允许您定义一个\mathchoice
不会将所有内容排版四次的版本:
\def\mathchoice#1#2#3#4%
{{\ifcase\mathstyle
#1\or #1\or
#2\or #2\or
#3\or #2\or
#4\or #4\else #2\fi}}
目前,只有当您的底层引擎是时才能使用所有这些luatex
,但希望最终也能支持此扩展xetex
。
答案3
是的,您有 \mathchoice
\documentclass{article}
\newcommand\mathtest{%
\mathchoice
{displaystyle}
{text style}
{scriptstyle}
{scriptscriptstyle}
}
\begin{document}
\[
\mathtest x^{\mathtest^{\mathtest}}
\]
\(
\mathtest
\)
\end{document}
答案4
这是一个迟来的解决方案,顺便说一句,它还没有经过彻底的测试,但是在 OP 想要做的事情的情况下是有效的。
它是半可扩展的,即宏\def\mathcase{\getmsty\mstycase}
有两个部分\getmsty
,一个不可扩展,\mstycase
另一个确实可扩展。类似于\pgfmathparse{..}
和\pgfmathresult
。例如,如果您想在 csname 中放入某些内容,则需要\getmsty\csname\mstycase{cdot}{times}{div}{cdots}\endcsname
。
欢迎任何评论,因为这可能不会按预期工作,至少不像我预期的那样。
\documentclass{scrartcl}
\usepackage{mathtools}
\usepackage{zref-savepos}
\newcount\mmstynum
\newcount\tmpnum
\protected\def\getmsty
{\global\advance\mmstynum1 %
\expandafter\getstyA\expandafter{\number\mmstynum}}
\protected\def\getstyA#1%
{\zsaveposx{mmsty-#1-a}%
\mathchoice{\kern4sp}{\kern3sp}{\kern2sp}{\kern1sp}%
\zsaveposx{mmsty-#1-b}
\tmpnum=\numexpr
\zposx{mmsty-#1-b} - \zposx{mmsty-#1-a}
\relax
\ifcase\tmpnum\or\kern-1sp \or\kern-2sp \or\kern-3sp \or\kern-4sp \fi}
\protected\def\mstycase
{\ifcase\tmpnum\expandafter\gobblefour\or\expandafter\usefourth\or
\expandafter\usethird\or\expandafter\usesecond\or
\expandafter\usefirst\else\expandafter\gobblefour\fi}
\protected\def\mathcase{\getmsty\mstycase}
\long\def\gobblefour#1#2#3#4{}
\long\def\usefourth#1#2#3#4{#4}
\long\def\usethird#1#2#3#4{#3}
\long\def\usesecond#1#2#3#4{#2}
\long\def\usefirst#1#2#3#4{#1}
\def\tmpa{If this prints it means it doesn't work}
\newcommand*\foo
{\mathcase % compare with \mathchoice
{\def\tmpa{displaystyle}}
{\def\tmpa{textstyle}}
{\def\tmpa{scriptstyle}}
{\def\tmpa{scriptscriptstyle}}
\text\tmpa}
\begin{document}
\begin{align}
\text{displaystyle} &= {\displaystyle\foo}\\
\text{textstyle} &= {\textstyle\foo} \\
\text{scriptstyle} &= {\scriptstyle\foo} \\
\text{scriptscriptstyle} &= {\scriptscriptstyle\foo}
\end{align}
\end{document}
或者......可能是这个解决方案不起作用,因为它计算当前样式的方式,它可能不够健壮(这是通过添加一个小空间,然后检查\pdfsavepos
已插入的空间来完成的)。