2

I'm trying to use \docsvlist from etoolbox to generate a table row. However, I've found a weird interaction when I try to use this trick to skip the first ampersand in the output. Here's an MWVE:

\documentclass{standalone}
\usepackage{etoolbox}

\begin{document}
\def\nextitem{\def\nextitem{&}}%
\renewcommand*{\do}[1]{\nextitem #1}%
\begin{tabular}{c|c|c|c|c}
  \docsvlist{a,b,c,d,e}
\end{tabular}
\end{document}

When I compile this file, the table it produces looks like this:

a|bc|de|

I'd expect it to look more like this:

a|b|c|d|e

Interestingly, if I modify the separator to be something other than &, like ,, it works as would be expected:

a,b,c,d,e|

And even more interestingly, if I change \def\nextitem{\def\nextitem{&}} to just \def\nextitem{&}, it works correctly, except that it has an extra blank cell at the beginning:

|a|b|c|d\ne|

To me this suggests that there is some very specific problem with redefining \nextitem to & while inside the tabular environment. How can I fix this issue?

3 Answers 3

3

Each cell within a tabular forms a group. So your redefinition of \nextitem within the cell doesn't survive to the next cell. If you make the redefinition global - via \gdef (say) - you achieve the desired output:

enter image description here

\documentclass{article}

\usepackage{etoolbox}

\begin{document}

% Local \nextitem redefinition
\def\nextitem{\def\nextitem{&}}% http://tex.stackexchange.com/a/89187/5764
\renewcommand*{\do}[1]{\nextitem #1}%
\begin{tabular}{c|c|c|c|c}
  \docsvlist{a,b,c,d,e}
\end{tabular}

% Global \nextitem redefinition
\def\nextitem{\gdef\nextitem{&}}% http://tex.stackexchange.com/a/89187/5764
\renewcommand*{\do}[1]{\nextitem #1}%
\begin{tabular}{c|c|c|c|c}
  \docsvlist{a,b,c,d,e}
\end{tabular}

\end{document}
0

Another way is to define the table contents with docsvlist first in a separate command outside of tabular and then insert it. Found that useful to assemble a table with contents from same-named variables read from multiple files

\newcommand*{\DataSetList}{DataFile1,DataFile2}

\renewcommand{\do}[1]{\input{DataSet.tex} Data1 & Data2 & Data3 \\} % for each item in docsvlist, read that data and ad a line to table
\renewcommand{\tableContents}{\expandafter\docsvlist\expandafter{\DataSetList}}

\begin{tabular}{c|c|c}
\tableContents
\end{tabular}

Note: data1,... defind in theDataFile*.inp using declarecommand per (using declarecommand How to define _or_ redefine a command (mixing \providecommand + \renewcommand)?)

0

You may be interested in a general solution to the problem, working in or outside tables.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\managecsvlist}
 {
  O{} % pre code
  m   % main code
  O{} % post code
  m % list
 }
 {
  #1
  \clist_set:Nn \l__kunkel_list_clist { #4 }
  \clist_use:Nn \l__kunkel_list_clist { #2 }
  #3
 }
\ExplSyntaxOff

\newcounter{rows}
\newcommand{\nr}{\stepcounter{rows}\therows &}

\begin{document}

\begin{tabular}{|l|c|c|c|c|c|}
\hline
\managecsvlist[\nr]{&}[\\\hline]{a,b,c,d,e}
\managecsvlist[\nr]{&}[\\\hline]{a,b,c,d,e}
\managecsvlist[\nr]{&}[\\\hline]{a,b,c,d,e}
\end{tabular}

\end{document}

The first argument (optional) is what is to be done before processing the list; the second argument(mandatory) specifies what has to go between items; the third argument is what should be done after processing the list. Finally comes the list.

enter image description here

Not that I condone caged tables. It's used here just by way of example.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .