8

Consider the following table:

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

I would like to define commands \addtableline{...}{...} and \printtable in order to build this table dynamically, i.e. I want to be able to write

% 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

I played around with \edef and \noexpand, trying to recursively generate a command \tablecontent storing the table content, but I failed miserably. I guess the problem lies in the fact that the & is interpreted too early, outside the table environment. What brings me to this assumption is the fact that I was able to solve the problem if the result should be not a table, but rather simple text.

How can I solve the problem?

My try (might be complete nonsense):

\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}}
  • I've asked this question to be a general answer to such questions tex.stackexchange.com/questions/227084/… – percusse Oct 17 '15 at 12:49
  • 1
    Off-topic: There are answers to some of your questions -- please consider to accept one of them, thereby showing you respect the works and efforts of users here in order to answer them! – user31729 Oct 17 '15 at 12:52
7

There isn't any special trick to this, putting this under your "whatever" category.

You can append content to macro without expansions issues using the kernel-provided \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}

Similar options are provided by etoolbox.

5

More dynamic! The row cells are separated by commas (or another character settable in the optional argument). The command \printtable has an optional argument to specify column configurations different from the default 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}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.