带有 \input 的超表问题

带有 \input 的超表问题

考虑一个简单的超级表格示例:

\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.texaftertable.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}

相关内容