显然,\DHLhksqrt
下面 MWE 中的宏对其内容进行了 20 次测量:
问题:
\measuring@true
我到底该把and放在哪里\measuring@false
才能得到 1 的计数?如果取消注释这些\measuring
行,计数将下降到 16,因此在两行注释之间将进行 4 次测量。奖金:这 20 个测量值来自哪里?
参考:
代码:
\documentclass{article}
\usepackage{mathtools}
\usepackage{xparse}
\usepackage{letltxmacro}
\LetLtxMacro{\oldsqrt}{\sqrt}
\makeatletter
\newcommand{\ClosedSqrt}[1][]{\def\DHLindex{#1}\mathpalette\DHLhksqrt}%
\def\DHLhksqrt#1#2{%
%\measuring@true
\setbox0=\hbox{$#1\oldsqrt{#2\,}$}\dimen0=\ht0\relax%
\advance\dimen0-0.25\ht0\relax%
\setbox2=\hbox{\kern-0.375pt\vrule height\ht0 depth -\dimen0}%
%\measuring@false
{%
\hbox{$#1\expandafter\oldsqrt\expandafter[\DHLindex]{#2\,}$}%
\lower\ifx\math@version\[email protected]\else0.4pt\fi\box2%
}%
}%
\RenewDocumentCommand{\sqrt}{O{\hphantom{3}} O{0} O{0} m}{\ClosedSqrt[\leftroot{#2}\uproot{#3}#1]{#4}}%
\newcounter{NumberOfInstances}
\setcounter{NumberOfInstances}{0}
\newcommand*{\MyValue}{%
\ifmeasuring@\else%
\stepcounter{NumberOfInstances}%
\fi
x%
}%
\makeatother
\begin{document}\noindent
NumberOfInstances=\arabic{NumberOfInstances}.
\[ \sqrt{\MyValue} \]
NumberOfInstances=\arabic{NumberOfInstances}.
\end{document}
答案1
当文本被多次处理时,当然会发生这种情况\mathpalette
。
如果你试试
\documentclass{article}
\usepackage{amsmath}
\newcounter{noi}
\newcommand{\doit}{\stepcounter{noi}x}
\begin{document}
$\sqrt[3]{\doit}$
Number of instances: \thenoi
\end{document}
(注意可选参数)您将获得 4 个实例数。使用 您将只获得 1 个\sqrt{\doit}
。
对于闭平方根符号,可选参数是总是假设,所以该例程被调用四次因为\mathpalette
进入行动。
amsmath
您可以通过加载(嗯,amstext
)并重新定义\mathpalette
为设置来大大减少步进量\iffirstchoice@
。包重新定义\stepcounter
和在返回false\addtocounter
时不执行任何操作\iffirstchoice@
。这用于\text
避免步进计数器四次。但是,\mathpalette
没有重新定义,所以我们需要。此外,\firstchoice@false
当可能包含计数器步进的参数需要进行试排版时,必须发出。
请注意,这只是关闭多余的步进,而不是关闭框排版的次数(确实是 20)。
\documentclass{article}
\usepackage{mathtools}
\usepackage{xparse}
\usepackage{letltxmacro}
\makeatletter
\def\mathpalette#1#2{%
\mathchoice
{#1\displaystyle{#2}}%
{\firstchoice@false#1\textstyle{#2}}%
{\firstchoice@false#1\scriptstyle{#2}}%
{\firstchoice@false#1\scriptscriptstyle{#2}}}
\makeatother
\LetLtxMacro{\oldsqrt}{\sqrt}
\makeatletter
\newcommand{\ClosedSqrt}[1][]{\def\DHLindex{#1}\mathpalette\DHLhksqrt}%
\def\DHLhksqrt#1#2{%
\sbox0{\firstchoice@false$#1\oldsqrt{#2\,}$}\dimen0=\ht0\relax
\advance\dimen0-0.25\ht0\relax
\sbox2{\kern-0.375pt\vrule height\ht0 depth -\dimen0}%
{%
\hbox{$#1\expandafter\oldsqrt\expandafter[\DHLindex]{#2\,}$}%
\lower\ifx\math@version\[email protected]\else0.4pt\fi\box2
}%
}%
\RenewDocumentCommand{\sqrt}{O{\hphantom{3}} O{0} O{0} m}{\ClosedSqrt[\leftroot{#2}\uproot{#3}#1]{#4}}%
\newcounter{NumberOfInstances}
\setcounter{NumberOfInstances}{0}
\newcommand*{\MyValue}{%
\stepcounter{NumberOfInstances}%
x%
}%
\makeatother
\begin{document}\noindent
NumberOfInstances=\arabic{NumberOfInstances}.
\[ \sqrt{\MyValue} \]
NumberOfInstances=\arabic{NumberOfInstances}.
\[ \oldsqrt[3]{\MyValue} \]
NumberOfInstances=\arabic{NumberOfInstances}.
\end{document}
为了将步进减少到 1,您还需要修改 的定义\r@@t
。
\documentclass{article}
\usepackage{mathtools}
\usepackage{xparse}
\usepackage{letltxmacro}
\makeatletter
\def\mathpalette#1#2{%
\mathchoice
{#1\displaystyle{#2}}%
{\firstchoice@false#1\textstyle{#2}}%
{\firstchoice@false#1\scriptstyle{#2}}%
{\firstchoice@false#1\scriptscriptstyle{#2}}}
\def\r@@t#1#2{%
\ifx#1\displaystyle\else\firstchoice@false\fi
\setbox\z@\hbox{$\m@th#1\sqrtsign{#2}$}%
\dimen@\ht\z@ \advance\dimen@-\dp\z@
\mkern5mu\raise.6\dimen@\copy\rootbox
\mkern-10mu\box\z@}
\makeatother
\LetLtxMacro{\oldsqrt}{\sqrt}
\makeatletter
\newcommand{\ClosedSqrt}[1][]{\def\DHLindex{#1}\mathpalette\DHLhksqrt}%
\def\DHLhksqrt#1#2{%
\sbox4{\firstchoice@false$#1\oldsqrt{#2\,}$}\dimen0=\ht4\relax
\advance\dimen0-0.25\ht0\relax
\sbox2{\kern-0.375pt\vrule height\ht0 depth -\dimen0}%
{%
\hbox{$#1\expandafter\oldsqrt\expandafter[\DHLindex]{#2\,}$}%
\lower\ifx\math@version\[email protected]\else0.4pt\fi\box2
}%
}%
\RenewDocumentCommand{\sqrt}{O{\hphantom{3}} O{0} O{0} m}{\ClosedSqrt[\leftroot{#2}\uproot{#3}#1]{#4}}%
\newcounter{NumberOfInstances}
\setcounter{NumberOfInstances}{0}
\newcommand*{\MyValue}{%
\stepcounter{NumberOfInstances}%
x%
}%
\makeatother
\begin{document}\noindent
NumberOfInstances=\arabic{NumberOfInstances}.
\[ \sqrt{\MyValue} \]
NumberOfInstances=\arabic{NumberOfInstances}.
\[ \oldsqrt[3]{\MyValue} \]
NumberOfInstances=\arabic{NumberOfInstances}.
\end{document}
答案2
更详细的计数。没有使用 amsmath 进行澄清,因为\ifmeasuring@
它仅用于查询和设置,除了意外之外不会产生任何效果。
\documentclass{article}
%\usepackage{mathtools}
\usepackage{xparse}
\usepackage{letltxmacro}
\LetLtxMacro{\oldsqrt}{\sqrt}
\makeatletter
\newcommand{\ClosedSqrt}[1][]{\def\DHLindex{#1}\mathpalette\DHLhksqrt}%
\def\DHLhksqrt#1#2{%
%\measuring@true
\typeout{Processing DHLhksqrt (#1, start): \the\value{NumberOfInstances}}%
\setbox0=\hbox{$#1\oldsqrt{#2\,}$}\dimen0=\ht0\relax%
\typeout{Processing DHLhksqrt (#1, after first oldsqrt): \the\value{NumberOfInstances}}%
\advance\dimen0-0.25\ht0\relax%
\setbox2=\hbox{\kern-0.375pt\vrule height\ht0 depth -\dimen0}%
%\measuring@false
{%
\hbox{$#1\expandafter\oldsqrt\expandafter[\DHLindex]{#2\,}$}%
\lower\ifx\math@version\[email protected]\else0.4pt\fi\box2%
}%
\typeout{Processing DHLhksqrt (#1, after second oldsqrt): \the\value{NumberOfInstances}}%
}%
%\RenewDocumentCommand{\sqrt}{O{\hphantom{3}} O{0} O{0} m}{\ClosedSqrt[\leftroot{#2}\uproot{#3}#1]{#4}}%
\RenewDocumentCommand{\sqrt}{O{\hphantom{3}} O{0} O{0} m}{\ClosedSqrt[#2#3#1]{#4}}%
\newcounter{NumberOfInstances}
\setcounter{NumberOfInstances}{0}
\newcommand*{\MyValue}{%
% \ifmeasuring@%\else%
\stepcounter{NumberOfInstances}%
% \fi
x%
}%
\makeatother
\begin{document}\noindent
NumberOfInstances=\arabic{NumberOfInstances}.
\[ \sqrt{\MyValue} \]
NumberOfInstances=\arabic{NumberOfInstances}.
\end{document}
以下是日志:
Processing DHLhksqrt (\displaystyle , start): 0
Processing DHLhksqrt (\displaystyle , after first oldsqrt): 1
Processing DHLhksqrt (\displaystyle , after second oldsqrt): 5
Processing DHLhksqrt (\textstyle , start): 5
Processing DHLhksqrt (\textstyle , after first oldsqrt): 6
Processing DHLhksqrt (\textstyle , after second oldsqrt): 10
Processing DHLhksqrt (\scriptstyle , start): 10
Processing DHLhksqrt (\scriptstyle , after first oldsqrt): 11
Processing DHLhksqrt (\scriptstyle , after second oldsqrt): 15
Processing DHLhksqrt (\scriptscriptstyle , start): 15
Processing DHLhksqrt (\scriptscriptstyle , after first oldsqrt): 16
Processing DHLhksqrt (\scriptscriptstyle , after second oldsqrt): 20
结论:使用\sqrt
可选参数会导致4
通过。并且20 = 4x(1+4)
。