\newsavebox 的奇妙效果

\newsavebox 的奇妙效果

以下代码失败并出现错误

! 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 中分配寄存器......

相关内容