Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I have a particular problem which I am trying to solve using etoolbox, but I can't figure out how. What I'm trying to do is to auto-generate a table based on information from a previous table. This is best explained with an example:

\newcounter{numc}
\setcounter{numc}{0}
\newcolumntype{n}{>{\thenumc.}r<{\addtocounter{numc}{1}}}
% This is simply a column displaying the row number.

\newrobustcmd{\push}[1]{\listadd{\numcount}{\thenumc} \listadd{\ncom}{#1}}
% This command may have to be defined differently, depending on the missing code below.

\begin{xtabular}{ n l l }
  & row1,col2    & row1,col3 \\
  & row2,col2    & row2,col3 \\ \push{Comment for row 2.}
  & row3,col2    & row3,col3 \\ 
  & row4,col2    & row4,col3 \\ \push{Comment for row 4.}
  & row5,col2    & row5,col3 \\ \push{Comment for row 5.}
\end{xtabular}

\begin{xtabular}{ r l }
% The code for auto-generating the second table goes here.
% The first column is supposed to be the values in the numcount list, minus 1.
% The second column is supposed to be the text in the ncom list.
\end{xtabular}

So the output is intended to be as follows:

Table 1:

1.   row1,col2   row1,col3
2.   row2,col2   row2,col3
3.   row3,col2   row3,col3
4.   row4,col2   row4,col3
5.   row5,col2   row5,col3

Table 2:

2.   Comment for row 2.
4.   Comment for row 4.
5.   Comment for row 5.

However, I can't find a good solution for the missing code in the second table. The code should generate the first column from the first list (numcount), and the second column from the second list (ncom).

Do you have any suggestions to how I can solve this?

share|improve this question

2 Answers 2

As already commented, \listadd won't work because the tabular environment is a local scope, so the lists are only defined inside your table. Therefore, we need the global version \listgadd. And then you add \thenumc to a list, but \thenumc doesn't get expanded until the list itself is used, which is the reason we will ned \listxadd here (\listeadd is not global).
(The same applies for the \appto macro I actually use.)

I did not used etoolbox' lists but a primitive macro. Furthermore, I defined only one macro where the actual contents are separated by /, I need only to loop over one list now.

The counter intXI is used to detect the first \push and the last line for the \mytable macro.

I also pushed the \push command before the \\ macro, because

  • no confusion about \thenumc (the \push macro falls in the n column of the next line)
  • no otherwise empty line at the end of the table.

Mini Solution

In this simple case we could use

\ifnum\value{intXI}=1\relax%
  \xappto\mytable{\thenumc & #1}%
\else%
  \xappto\mytable{\noexpand\\\thenumc & #1}%
\fi%

in the \push macro without the use of a loop.

Code

\documentclass{article}
\usepackage{etoolbox}
\usepackage{array}
\usepackage{pgffor}

\newcounter{numc}\newcounter{intXI}
\newcolumntype{n}{>{\stepcounter{numc}\thenumc.}r}

\newrobustcmd{\push}[1]{%
    \stepcounter{intXI}%
    \ifnum\value{intXI}=1\relax%
      \xappto\mylist{\thenumc/{#1}}%
    \else%
      \xappto\mylist{,\thenumc/{#1}}%
    \fi%
}

\begin{document}
\begin{tabular}{ n l l }
  & row1,col2    & row1,col3 \\
  & row2,col2    & row2,col3 \push{Comment for row 2.} \\
  & row3,col2    & row3,col3 \\
  & row4,col2    & row4,col3 \push{Comment for row 4.} \\
  & row5,col2    & row5,col3 \push{Comment for row 5.} \\
\end{tabular}
\foreach \contentn/\contentt in \mylist {%
    \addtocounter{intXI}{-1}%
    \ifnum0=\value{intXI}\relax
      \xappto\mytable{%
          \contentn & \contentt%
      }%
    \else
      \xappto\mytable{%
          \contentn & \contentt\noexpand\\%
      }%
    \fi%
}%

\begin{tabular}{ r l }
    \mytable
\end{tabular}
\end{document}

Output

enter image description here

share|improve this answer

If you are interested in an alternative solution that doesn't use etoolbox but xparse and the LaTeX3 environment, here it is:

\documentclass{article}
\usepackage{array,xparse}
\newcounter{numc}

\newcolumntype{n}{>{\stepcounter{numc}\thenumc.}r}

\ExplSyntaxOn
\NewDocumentEnvironment{xtabular}{ m }
 {
  \seq_gclear:N \g_eiterorm_pushes_seq
  \setcounter{numc}{0}
  \begin{tabular}{n #1}
 }
 {
  \end{tabular}
 }

\NewDocumentCommand{\push}{ m }
 {
  \eiterorm_push:n { #1 }
 }

\NewDocumentCommand{\printcomments} { }
 {
  \begin{tabular}{rl}
  \seq_use:Nnnn \g_eiterorm_pushes_seq { \\ } { \\ } { \\ }
  \end{tabular}
 }
\seq_new:N \g_eiterorm_pushes_seq
\cs_new_protected:Npn \eiterorm_push:n #1
 {
  \seq_gput_right:Nx \g_eiterorm_pushes_seq { \thenumc. \exp_not:n { & #1 } }
 }
\ExplSyntaxOff

\begin{document}

\begin{xtabular}{ l l }
  & row1,col2    & row1,col3 \\
  & row2,col2    & row2,col3 \push{Comment for row 2.} \\
  & row3,col2    & row3,col3 \\ 
  & row4,col2    & row4,col3 \push{Comment for row 4.} \\
  & row5,col2    & row5,col3 \push{Comment for row 5.} 
\end{xtabular}

\bigskip

\printcomments

\end{document}

Note that \push should go before the terminal \\ because otherwise the last row will initiate a new row which would have the initial number and empty contents and no final \\ should appear.

The idea is that \push adds to a sequence that is later used by \printcomments.

enter image description here

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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