使用 `\edef`、`\noexpand` 或其他方式动态构建表格

使用 `\edef`、`\noexpand` 或其他方式动态构建表格

请考虑下表:

\begin{tabular}{ll}
a & A\\
b & B\\
c & C\\
\end{tabular}

我想定义命令\addtableline{...}{...}\printtable以便动态地构建这个表,即我希望能够编写

% no tabular environment here
...
\addtableline{a}{A} % remembers line
...
\addtableline{b}{B} % remembers line
...
\addtableline{c}{C} % remembers line
...
\printtable % now generates table and typesets it

我尝试了\edef\noexpand,试图递归生成一个\tablecontent存储表格内容的命令,但失败了。我猜问题在于&解释得太早了,超出了表格环境。让我产生这种假设的原因是,如果结果不是表格,而是简单的文本,我就能解决这个问题。

我该如何解决这个问题?

我的尝试(可能完全是胡说八道):

\def\generatetableline#1#2{#1 & #2\\}
\gdef\tablecontent{}
\def\addtableline#1#2{\xdef\tablecontent{\tablecontent\noexpand\generatetableline{#1}{#2}}}
\def\printtable{\begin{tabular}\tablecontent\end{tabular}}

答案1

对此没有什么特殊的技巧,将其归入“任何”类别即可。

您可以使用内核提供的方法将内容附加到宏而不会出现扩展问题\g@addto@macro

\documentclass{article}

\makeatletter
\newcommand\tablecontent{}
\newcommand\addtableline[2]{\g@addto@macro\tablecontent{#1 & #2 \\}}
\newcommand\printtable{%
  \begin{tabular}{ll}\tablecontent\end{tabular}%
  \renewcommand{\tablecontent}{}}% Clear \tablecontent
\makeatother

\begin{document}

% no tabular environment here
\addtableline{a}{A} % remembers line
\addtableline{b}{B} % remembers line
\addtableline{c}{C} % remembers line

\printtable % now generates table and typesets it

\end{document}

类似的选项由etoolbox

答案2

更加动态!行单元格以逗号(或可选参数中可设置的其他字符)分隔。该命令\printtable有一个可选参数,用于指定不同于默认的列配置ll

\documentclass{article}
\usepackage{xparse,booktabs}

\ExplSyntaxOn

\NewDocumentCommand{\addtableline}{O{,}m}
 {
  \seq_set_split:Nnn \l_johnb_addtable_row_seq { #1 } { #2 }
  \tl_gput_right:Nx \g_johnb_addtable_body_tl
   {
    \seq_use:Nn \l_johnb_addtable_row_seq { & }
    \exp_not:N \\
   }
 }

\NewDocumentCommand{\printtable}{O{ll}}
 {
  \begin{tabular}{#1}
  \tl_use:N \g_johnb_addtable_body_tl
  \end{tabular}
  \tl_gclear:N \g_johnb_addtable_body_tl
 }

\seq_new:N \g_johnb_addtable_row_seq
\tl_new:N \g_johnb_addtable_body_tl

\ExplSyntaxOff

\begin{document}

\addtableline{a,A} % remembers line
\addtableline{b,B} % remembers line
\addtableline{c,C} % remembers line

\printtable % now generates table and typesets it

\bigskip

\addtableline{a,A,.} % remembers line
\addtableline[|]{b|B|,} % remembers line
\addtableline{c,C,;} % remembers line

\printtable[llc]

\end{document}

在此处输入图片描述

相关内容