使用 \@for 命令生成表格

使用 \@for 命令生成表格

我正在制作一个报告模板,需要以几种不同的方式呈现作者列表,其中一种方式是列出每个作者的表格,并为他们提供一个空间来签署文档的打印版本。

我有一个作者列表定义为

\newcommand{\reportAuthors}{Bob Jones,Sally Smith,Humpty Dumpty}

并尝试生成如下表格:

\begin{tabular}{|b{4cm}|b{6cm}|b{4cm}|}
    \hline
    \multicolumn{3}{l}{\begin{Large}\textbf{Signatures}\end{Large}} \\ \hline
    Approved by: & & Bob Jones \\ \hline
    Approved by: & & Sally Smith \\ \hline
    Approved by: & & Humpty Dumpty \\ \hline
\end{tabular}

我尝试使用\@for以下命令执行此操作:

\begin{tabular}{|b{4cm}|b{6cm}|b{4cm}|}
    \hline
    \multicolumn{3}{l}{\begin{Large}\textbf{Signatures}\end{Large}} \\
    \hline
    \makeatletter
    \@for\authname:=\reportAuthors\do{%
        Approved by: & & \authname \\
    }
    \makeatother
\end{tabular}

但这会产生一个错误,即\authname未定义的控制序列。如果我删除,& &这样就没有列了,错误就会消失,它会正确地迭代并插入每个名称……但当然,这让我没有按要求在正确的列中找到名称。

如果我把放在\authname第一列(这不是模板应该有的,而只是为了测试一些东西),那么我得到的不是未定义的控制序列,而是“不完整\ifx”。

那么,首先,\authname如果我插入字符,是什么原因导致未定义的&?其次,我该如何解决这个问题?


更新:我尝试结合一些发现的信息别处尝试按照马丁的建议尝试收集tabular环境之外的行:

\newcommand{\tablecontent}{}
\makeatletter
\@for\signame:=\reportAuthors\do{%
    \g@addto@macro\tablecontent{Approved by: & & \signame \\ \hline }%
}
\makeatother

\begin{tabular}{|b{4cm}|b{6cm}|b{4cm}|}
    \hline
    \multicolumn{3}{l}{\begin{Large}\textbf{Signatures}\end{Large}} \\
    \hline
    \tablecontent
\end{tabular}

这修复了错误,但导致第三列(应该\signame是)单元格为空。我怀疑这是由于我对扩展缺乏了解,当它扩展时,定义\signame超出了范围。\edef到目前为止,摆弄它并没有真正起到作用,但也许有人可以指出一些缺陷……?

答案1

错误可能是由于&在表格中处理的特殊方式(实际上是在内部使用\halign)而导致的。\@for循环可能在与不同的列(读取组)中执行\authname

如果您将行收集到第一个宏之外的宏中,则将节省空间。使用能够循环逗号分隔列表的包,tabular这非常容易。您还可以使用它的列表生成宏。有关更多详细信息,请参阅其手册。etoolbox\reportAuthors

\documentclass{article}

\newcommand{\reportAuthors}{Bob Jones,Sally Smith,Humpty Dumpty}

\usepackage{array}
\usepackage{etoolbox}

\begin{document}

\begingroup
\newcommand\tablecontent{}
\def\do#1{\appto\tablecontent{Approved by: & & #1 \\}}%
\expandafter\docsvlist\expandafter{\reportAuthors}

\begin{tabular}{|b{4cm}|b{6cm}|b{4cm}|}
    \hline
    \multicolumn{3}{l}{\begin{Large}\textbf{Signatures}\end{Large}} \\
    \hline
    \tablecontent
\end{tabular}
\endgroup

\end{document}

答案2

没有必要构造\tablecontent第一个然后打印它。相反,你可以\docvslist直接在环境内添加行tabular

\documentclass{article}

\usepackage{array}
\usepackage{etoolbox}
\usepackage{booktabs}
\newcommand\AuthorList[1]{%
  \renewcommand*\do[1]{Approved by &&##1\\}
  \begin{tabular}{|b{4cm}|b{6cm}|b{4cm}|}
      \toprule
      \multicolumn{3}{l}{\begin{Large}\textbf{Signatures}\end{Large}} \\
      \midrule
      \docsvlist{#1}
      \bottomrule
  \end{tabular}
}

\begin{document}

    \AuthorList{Bob Jones,Sally Smith,Humpty Dumpty}

\end{document}

\reportAuthors如果你想使用问题中的预定义列表,那么你需要

\expandafter\AuthorList\expandafter{\reportAuthors}

或用于\expandafter\docsvlist\expandafter{#1}的定义\AuthorList

相关内容