以下代码失败并出现错误
! LaTeX Error: Command \mybox already defined.
Or name \end... illegal, see p.192 of the manual.
尽管事实上\mybox
已经放松。
\documentclass{minimal}
%
\newcommand{\repeatstuff}[1]{%
\newsavebox\mybox
\sbox\mybox{\ensuremath{\displaystyle #1}}
\usebox{\mybox}\usebox{\mybox}
\let\mybox\relax
}
%
\begin{document}
\[
\repeatstuff{\gamma} \repeatstuff{\alpha}
\]
\[
\repeatstuff{\gamma} \repeatstuff{\alpha}
\]
\end{document}
尽管第一个方程包含两个 ,但问题只出现在第二个方程中\repeatstuff
。有人能解释一下这种现象吗?
答案1
编辑:抱歉,我考虑过了。正如其他人指出的那样,正确的解决方法是在 的定义之外声明该框\repeatstuff
。
可以通过\let\mybox\relax
用替换 来解决这个\global\let\mybox\relax
问题。TeX 中的赋值可以是“局部的”,即限制在当前组(例如 LaTeX 中的当前环境,或在方程式中等),也可以是“全局的”,即甚至在当前组之外的任何位置应用。
当在组内本地进行分配时,组结束时将恢复组开始前的旧值。在您的例子中,\newsavebox
执行全局分配,因为盒子是一种稀缺资源,不应浪费,但它\let\mybox\relax
是本地的。因此,第一个全局\newsavebox
定义\mybox
,然后本地设置为\relax
,这允许第二个定义。当等式结束时,它回到前一个(全局分配的)值,即盒子寄存器。\newsavebox
因此,第三个遇到已定义的命令并发出抱怨。再次,\let\mybox\relax
在本地执行其工作,允许下一个\newsavebox
,等等。
以下任务是本地的:
\def
,\edef
\let
,\futurelet
\chardef
,,,,,\boxdef
\dimendef
\countdef
\toksdef
\setbox
\count123=...
或\mycount=...
,其中使用(或,这是对该 的包装器,或在 LaTeX 中)\mycount
定义\countdef
\newcount
\newcounter
- 其他类似的作业,包括
\toks
、 或\dimen
等。 - ETC。
所有这些赋值都可以通过在它们前面加上 来使其成为全局的\global
。为方便起见,TeX 还分别为\gdef
和提供了和。\xdef
\global\def
\global\edef
解释为什么全局\newsavebox
定义\mybox
需要讨论如何在纯 TeX 和 LaTeX 中分配寄存器......