如何定义一个宏来向尚未打印的表中添加一行?

如何定义一个宏来向尚未打印的表中添加一行?

我想生成我使用的技术缩写和首字母缩略词列表。目前,我正在使用我设计的宏定义所有首字母缩略词。现在,我希望该宏\addtototaa每次调用时都调用另一个宏,名为 ,该宏将缩写添加到表中。这个宏定义为

\newrobustcmd{\addtototaa}[2]{\let\OldContent\TableoftaaBody%
    \renewrobustcmd{\TableoftaaBody}{\OldContent #1 & #2 \\}}

然后我还有两个额外的宏

\newrobustcmd{\TableoftaaBody}{}
\newrobustcmd{\tableoftaa}[0]{\begin{longtabu}{l X}\TableoftaaBody\end{longtabu}}

其中\TableoftaaBody充当表格内容的存储容器并\tableoftaa打印表格。但是当我尝试编译文档时,我得到了

TeX capacity exceeded, sorry [input stack size=5000] \tableoftaa

如果我调用\tableoftaa(否则不会)。为什么我会收到此错误?我继续阅读这篇博文如果您有无限递归循环,则会出现此消息(我猜函数调用放在堆栈上,这就是它被吃掉的原因)。我在这里的某个地方定义了递归函数吗?顺便说一句,在调用\addtototaa之前调用了 31 次\tableoftaa,因为这就是我定义的首字母缩略词和缩写的数量,并且我发送给的两个参数\addtototaa始终只是文字,没有额外的宏。

答案1

您可以使用etoolbox包裹\gappto使用(与 类似)将内容附加到现有宏\g@addto@macro。我简化了您的代码片段,以便我可以制作 MWE,但很可能很容易扩展到您的用法:

在此处输入图片描述

\documentclass{article}
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\usepackage{tabularx}% http://ctan.org/pkg/tabularx
\usepackage{lipsum}% http://ctan.org/pkg/lipsum
\let\TableoftaaBody\relax
\newcommand{\tableoftaa}{\begin{tabularx}{\textwidth}{l X}\TableoftaaBody\end{tabularx}}

\newcommand{\addtototaa}[2]{%
  \gappto\TableoftaaBody{#1 & #2 \\}%
}
\begin{document}
\addtototaa{1}{\lipsum*[1]}
\addtototaa{2}{\lipsum*[2]}
\addtototaa{3}{\lipsum*[3]}
\noindent\tableoftaa
\end{document}

答案2

@Werner 已经展示了如何做你想做的事情,所以我将回答另一个问题:是的,你已经定义了一个无限递归循环。

\newrobustcmd{\TableoftaaBody}{}

\newrobustcmd{\addtototaa}[2]{\let\OldContent\TableoftaaBody%
\renewrobustcmd{\TableoftaaBody}{\OldContent #1 & #2 \\}}

那么 \TableoftaaBodyeempty 就是你做的

 \addtototaa{1}{2}

所以\OldContent\let所以\TableoftaaBody 被定义为空并且\TableoftaaBody 定义为

\OldContent 1 & 2 \\

然后你走

 \addtototaa{3}{4}

所以\OldContent\let所以\TableoftaaBody 被定义为\OldContent 1 & 2 \\ (oooops!!!!)并且\TableoftaaBody 定义为

\OldContent 3 & 4 \\

因此,此时如果您扩展\TableoftaaBody第一个标记,您会看到 ,\OldContent因此会扩展,但该扩展的第一个标记\OldContent又是 ,因此您处于无限循环中。每次扩展时, \OldContent您都会再次看到 \OldContent,但之后会将更多标记推送到输入流,因此最终您会填满所有可用内存。

相关内容