我明白等的作用\@gobble
,\@gobbletwo
但我不明白为什么\@gobble
允许争论。
我认为宏的定义是\long\def\@gobble#1{}
。为什么需要这个参数?
在这答案例如 David Carlisle 定义\global\advance\rowc\@ne\@gobble{##}&&%
。这是否意味着只有##
被吞噬?
答案1
的定义\@gobble
等同于
\newcommand{\@gobble}[1]{}
因此,在使用时,它只会丢弃其参数。当你说类似这样的话时
\let\macro\@gobble
你告诉 TeX\macro
将要抛弃它的论点。相反
\@gobble{something}
{something}
一旦 TeX 找到它就丢弃它。
让我们看看您所指的代码:
\long\def\savedata#1{%
\setbox0\vbox\bgroup
\let\\\cr
\let\midrule\@empty
\let\multicolumn\@gobbletwo
\everyeof{\noexpand}%
\halign\bgroup
\global\colc\z@
\global\advance\rowc\@ne\@gobble{##}&&%
\global\advance\colc\@ne
\expandafter\xdef\csname data-#1(\the\rowc,\the\colc)\endcsname
{\zap@space## \@empty}\cr
\@@input #1
\crcr\egroup\egroup}
其目的是加载一个文件(的参数\savedata
),其中包含通常在\begin{tabular}{l...}
和之间传输的内容\end{tabular}
,以便从中收集数据。
表格排版在一个框内,之后将不再使用(\setbox0=\vbox\bgroup
),并且在这个形成组的框中,重新定义了一些宏:\let\\\cr
和\let\midrule\@empty
。第一个是将其设为\\
简单的表格行终止符,第二个是因为\midrule
对此目的毫无意义。也\multicolumn
重新定义了:
\let\multicolumn\@gobbletwo
这样,当 TeX 看到它时,\multicolumn{1}{c}{(1)}
它只会留{(1)}
在输入流中,因为\@gobbletwo
它会查找两个参数,但不对它们执行任何操作,所以它们会消失。可能
\let\multicolumn\@thirdofthree
理论上会更好,但最终结果是一样的。现在你明白为什么了吗?你的输入文件可能包含\multicolumn
,但在这种情况下,我们只对第三个参数感兴趣,因为我们实际上不是在排版表格,而只是将其内容(逐个单元格)存储在宏中。
发布了一份具有技术重要性的文件\everyeof{\noexpand}
(我不会讨论它),然后\halign
打开了一份。
原语的语法\halign
非常有趣;我不会深入讨论细节,但基本上它是
\halign{<template>\cr
<table row>\cr
...
<table row>\cr
}
其中<template>
是表单中每个表格列的规范集合<before>#<after>
,并以 分隔&
。#
表示单元格内容。&&
序列意味着以下规范将根据表格的需要重复多次。
在这种情况下,模板是
\global\colc\z@
\global\advance\rowc\@ne\@gobble{##}&&%
\global\advance\colc\@ne
\expandafter\xdef\csname data-#1(\the\rowc,\the\colc)\endcsname
{\zap@space## \@empty}\cr
它指定第一列,其中表示列的计数器设置为 0,表示行的计数器前进一。然后单元格内容被传递给\@gobble
,因此它将消失,因为我们不需要它。
表格的其余部分是一系列列,具有以下规范:列计数器是步进的,并且宏的形式为
\data-<argument>(i,j)
(<argument>
是 的参数\savedata
,括号中是行和列索引,以数字表示;宏名称不能用普通方式书写,但\csname...\endcsname
允许名称中出现那些奇怪的字符)。此宏的替换文本最终提供删除了前导和尾随空格的单元格内容(\zap@space## \@empty
)。\cr
模板结束。
正如艾哈迈德·穆萨所说,\zap@space
宏应该谨慎使用,因为它会所有空间;在这种情况下它并不重要,因为重要的条目不包含空格。
最后输入表内容,以便定义宏;\\
将其转换为原语以提供行终止(这里不需要在 LaTeX 环境中执行的\cr
更复杂的工作)并且只留下。\\
tabular
\multicol{1}{c}{(1)}
{(1)}
表格以 结束,\crcr
如果代码以 结尾,则不会添加行\\
。第一个\egroup
匹配\bgroup
之后\halign
,第二个匹配\bgroup
之后\vbox
。
请注意,这里的“单元格内容占位符”通常#
必须加倍,因为我们在定义内。