请考虑下表:
\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}