不确定我该如何发布我的问题,但这里是:我已经看到在纯 TeX 中,\newcount
在宏\def
初始化中是非法的。有没有办法在宏内分配寄存器?此外,如果我知道我只会使用寄存器一两次,我可以在之后释放它并为将来留下空间\newcount
吗?
答案1
在 Plain TeX 中,\newcount
被定义为\outer
,因此它不能出现在宏的替换文本中。这个想法是,宏永远不应该定义新的计数器,尽管这并非在所有情况下都是正确的,但我稍后会举一个例子。
主要原因是你不能在分配寄存器后“释放”它。我可以是可能的,但其他可能已定义访问它的宏怎么办?最好的策略是使用符号名称(什么\newcount
做的)并且永远不关心实际的寄存器号。
如果您需要一个计数器来临时存储,只需使用\count255
(别名为\count@
)或组中的任何其他计数寄存器。在更复杂的情况下,您可以自己分配一个临时计数器并根据需要多次使用它。
\newcount
以下是定义中“合法”调用的示例。假设您想要为不同的逻辑结构定义不同的计数器(就像 LaTeX 对 所做的那样\newtheorem
)。因此,您想要定义一个命令
\newtheorem{<name>}{<label>}
因此\<name>
定义了并分配了一个计数器。
\def\newtheorem#1#2{%
\outer\expandafter\def\csname #1\endcsname{%
\par\medskip\noindent
\global\advance\csname thmcnt#1\endcsname by 1
{\bf\number\csname thmcnt#1\endcsname\ #2}%
\enspace\begingroup\it \ignorespaces}
\outer\expandafter\def\csname end#1\endcsname{\endgroup\par\medskip}
\csname newcount\expandafter\endcsname\csname thmcnt#1\endcsname
}
\newtheorem{thm}{Theorem}
\newtheorem{lem}{Lemma}
\lem
Something preliminary.
\endlem
\thm
The big result.
\endthm
\thm
Another big result.
\endthm
\bye
当然,这只是一个例子;定理的编号应该与标签无关。如果你仔细观察,你就会明白如何欺骗 TeX,以便\outer
在替换文本中使用宏。
答案2
这并不违法,并且可以无错误地运行:
\newcommand\foo{\newcounter{zz}}
\foo
\setcounter{zz}{2}
\stop
然而,最好不要这样做,而是分配一次计数器,然后在每个宏中使用它。
我假设您指的是 LaTeX(正如您使用的\newcounter
)。另一方面,如果您指的是普通的 TeX,\newcount
那就不同了,因为它是一个\outer
宏,可以阻止您使用它。可以解决这个问题,但同样适用的是,最好不要这样做。
plain 和 latex 中使用的标准分配系统不允许释放未使用的分配。这是一个简单的增量。在经典 TeX 中只有 256 个计数寄存器,因此很容易用完,而 etex 允许几千个,因此问题不大。