The definition of \@gobble
is equivalent to
\newcommand{\@gobble}[1]{}
so, when used, it will simply throw away its argument. When you say something like
\let\macro\@gobble
you're telling TeX that \macro
will throw away its argument. Instead
\@gobble{something}
throws away {something}
as soon as TeX finds it.
Let's see the code you're referring to:
\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}
Its purpose is to load a file (the argument to \savedata
) which contains what usually would go between \begin{tabular}{l...}
and \end{tabular}
, in order to gather data from it.
The table is typeset inside a box, which will not be used afterwards (\setbox0=\vbox\bgroup
) and in this box, which forms a group, some macros are redefined: \let\\\cr
and \let\midrule\@empty
. The first is to make \\
into the simple table line terminator, the second is because \midrule
is meaningless for the purpose. Also \multicolumn
is redefined:
\let\multicolumn\@gobbletwo
so that, when TeX will see \multicolumn{1}{c}{(1)}
it will leave only {(1)}
in the input stream, because \@gobbletwo
looks for two arguments and doesn't do anything with them, so they simply disappear. Probably
\let\multicolumn\@thirdofthree
would be theoretically better, but in the end the result is just the same. Can you see now why? Your input file will possibly contain \multicolumn
, but in this context we are only interested in the third argument, because we are not really typesetting a table, but only storing its contents (cell by cell) in macros.
A technically important \everyeof{\noexpand}
is issued (I won't discuss it) and then a \halign
is opened.
The syntax for the primitive \halign
is quite interesting; I'm not going into the details, but basically it is
\halign{<template>\cr
<table row>\cr
...
<table row>\cr
}
where <template>
is a collection of specifications for each table column in the form <before>#<after>
and separated by &
. The #
represents the cell contents. A &&
sequence means that the following specifications are repeated as many times as the table needs.
In this case the template is
\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
which specifies a first column where the counter representing the columns is set to 0 and the one representing rows is advanced by one. Then the cell contents is passed to \@gobble
, so it will vanish, as we don't need it.
The rest of the table is a sequence of columns with the following specification: the column counter is stepped and macros of the form
\data-<argument>(i,j)
(<argument>
is the argument to \savedata
, in parentheses are the row and column indices, as numbers; the macro name can't be written with ordinary means, but \csname...\endcsname
allows for those strange characters in the name). The replacement text for this macro provides eventually the cell contents with leading and trailing spaces removed (\zap@space## \@empty
). The \cr
ends the template.
As Ahmed Musa remarks, the \zap@space
macro should be used with care, because it zaps all spaces; in this case it's unimportant, because the significant entries don't contain spaces.
Finally the table contents is input so that the macros will be defined; \\
will be translated into the primitive \cr
to provide line terminations (the more complex job that \\
does in LaTeX tabular
environments is not needed here) and \multicol{1}{c}{(1)}
will leave only {(1)}
.
The table is terminated by \crcr
which will not add a line if the code ends with \\
. The first \egroup
matches the \bgroup
after \halign
and the second one the \bgroup
after \vbox
.
Note that here the "cell contents placeholder", ordinarily #
, has to be doubled because we are inside a definition.
\@gobble
is precisely to gobble one argument.##
is strange, not the command\@gobble
.