为什么 \@gobble 需要一个参数

为什么 \@gobble 需要一个参数

我明白等的作用\@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

请注意,这里的“单元格内容占位符”通常#必须加倍,因为我们在定义内。

相关内容