# Supertabular problem with \input

Consider a simple supertabular example:

\documentclass{article}
\usepackage{supertabular}
\begin{document}
\begin{supertabular}
a & b \\
\end{supertabular}
\end{document}


Suppose I wanted to create a template for dynamically inputting table data using a slightly unusual approach (instead of just inputting table data):

### document.tex

\documentclass{article}
\usepackage{supertabular}
\begin{document}
\input{beforetable}
a & b \\
\input{aftertable}
\end{document}


With beforetable.tex and aftertable.tex being \begin{supertabular}{cc}\endinput and \end{supertabular}\endinput.

That fails with the following error:

! Misplaced \noalign. \@tabletail ->\noalign {\global \let \@savcr =\ \global \let \=\org@tabula...

The example works if I replace \input{aftertable} with its contents.

\documentclass{article}
\usepackage{supertabular}
\begin{document}
\input{beforetable}
a & b \\
\end{supertabular}
\end{document}


What is going on "behind the scenes"?

-
The error Use of \@array doesn't match its definition. is caused by the missing argument to \begin{supertabular}; if you add {cc} in the example with \input{tabledata} LaTeX doesn't complain. – egreg May 27 '11 at 10:55
You are right. I must have missed that. – ipavlic May 27 '11 at 11:07

What happens comes from how TeX's \halign primitive (used to implement any kind of tabular, array, etc.) works. To draw horizontal lines, or anything else that does not fit in the alignment, one has to use the \noalign primitive. This must come first after the \cr which closes the previous line. Otherwise, TeX will already have started to typeset the first cell of a new line when meeting \noalign. In a typical plain TeX case, we would write

\halign{(#)&[#]\cr
a&b\cr
\noalign{\hrule}
c&d\cr}
\bye


The first line is the "preamble", telling TeX that there will be two columns, and each cell should be typeset with parentheses before and after (round for the first cell of the row, square for the second). There, # represents the contents of the cell. Each time \cr is met, the closing square bracket from the previous cell will be typeset, and a new line begins. If the next token (after expansion) is \noalign, then what follows is set independently of any preamble (here drawing a horizontal line). Otherwise, as in the last row, the preamble is read, and # is replaced by the content of the cell. \bye is just there to end the file.

In the above, the key is maybe "(after expansion)": after \cr, TeX first fully expands what follows to try and see if there might be a \noalign hidden in a macro. This is useful for instance in cases such as \hline in LaTeX, which expands to \noalign{...}.

In your case, \cr appears at the end of \\. Unfortunately, \input is not expandable, and stops TeX from finding a \noalign hidden within \end{supertabular}, hence the Misplaced \noalign error. One solution I found is to put the last \\ in the ending file. (filecontents is a very useful way of creating external files for the sake of examples.)

\documentclass{article}
\usepackage{filecontents}

\begin{filecontents}{beforetable}
\begin{supertabular}{cc}
\end{filecontents}

\begin{filecontents}{aftertable}
\\
\end{supertabular}
\end{filecontents}

\usepackage{supertabular}
\begin{document}
\input{beforetable}
a & b
\input{aftertable}
\end{document}

-
Great answer. Thank you. – ipavlic May 30 '11 at 8:59
Another solution is to replace \input by \@@input (in a context where @ is a letter). – Bruno Le Floch Nov 8 '11 at 16:15