考虑一个简单的超级表格示例:
\documentclass{article}
\usepackage{supertabular}
\begin{document}
\begin{supertabular}
a & b \\
\end{supertabular}
\end{document}
假设我想创建一个使用稍微不寻常的方法动态输入表格数据的模板(而不仅仅是输入表格数据):
document.tex
\documentclass{article}
\usepackage{supertabular}
\begin{document}
\input{beforetable}
a & b \\
\input{aftertable}
\end{document}
与beforetable.tex
和aftertable.tex
是\begin{supertabular}{cc}\endinput
和\end{supertabular}\endinput
。
该操作失败并出现以下错误:
!放错 \noalign。\@tabletail ->\noalign {\global \let \@savcr =\ \global \let \=\org@tabula...
\input{aftertable}
如果我用其内容替换,该示例就可以工作。
\documentclass{article}
\usepackage{supertabular}
\begin{document}
\input{beforetable}
a & b \\
\end{supertabular}
\end{document}
“幕后”到底发生什么事?
答案1
所发生的情况取决于 TeX 的\halign
原语(用于实现任何类型的表格、数组等)的工作方式。要绘制水平线或任何其他不适合对齐的内容,必须使用原\noalign
语。这必须先于\cr
关闭上一行的。否则,当遇到时,TeX 已经开始排版新行的第一个单元格\noalign
。在典型的纯 TeX 情况下,我们会写
\halign{(#)&[#]\cr
a&b\cr
\noalign{\hrule}
c&d\cr}
\bye
第一行是“序言”,告诉 TeX 将有两列,并且每个单元格应该在前后排版时加上括号(该行的第一个单元格为圆形,第二个单元格为方形)。其中,#
表示单元格的内容。每次\cr
遇到 时,将排版前一个单元格的右方括号,并开始新的一行。如果下一个标记(扩展后)是\noalign
,则后面的内容将独立于任何序言进行设置(此处绘制一条水平线)。否则,与最后一行一样,将读取序言,并将其#
替换为单元格的内容。\bye
只是用来结束文件。
上面的关键字可能是“(扩展后)”:在 之后,TeX 首先完全扩展后面的内容,以尝试查看宏中\cr
是否可能存在。这在 LaTeX 中非常有用,因为它会扩展为。\noalign
\hline
\noalign{...}
在你的情况下,\cr
出现在 的末尾\\
。不幸的是,\input
是不可扩展的,并且阻止 TeX 找到\noalign
中的隐藏\end{supertabular}
,因此出现Misplaced \noalign
错误。我发现的一个解决方案是将最后一个放在\\
结尾文件中。(filecontents
这是一种非常有用的创建外部文件的方法,可用于示例。)
\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}