4

Consider a table (regular tabular environment) with a fixed number of columns. I want to create a command that accepts a comma-separated list of strings, where the number of strings may differ between zero and the number of columns.

\begin{tabular}{llll}
  \outputrow{ab cd,foo,3,5}\\ %all columns used
  \outputrow{}\\ %no column used
  \outputrow{1,2}\\ %two columns used
\end{tabular} 

\outputrow{cvs-input} should, in all cases, generate all columns (4 in this example). The actual column value should be generated by two additional commands: \emptycol just outputs the content of an empty column, whereas \usercol{content} generates the corresponding output of the provided user input. So the result of the above example should be

\begin{tabular}{llll}
  \usercol{ab cd} & \usercol{foo} & \usercol{3} & \usercol{5} \\
  \emptycol & \emptycol & \emptycol & \emptycol \\
  \usercol{1} & \usercol{2} & \emptycol & \emptycol \\
\end{tabular} 

The number of columns is static for a single table, but I need this solution for different cases with a different number of columns.

I first thought of using a package like etoolbox, but I'm not sure how I can emit a single column using a loop or something like this.

Do you have any advice how this can be achieved?

  • Is \emptycol really necessary? For example, row 2 might just as well have been \\. – Werner Dec 6 '14 at 18:45
  • One of your macros is named \emptycol, which at first glance would seem to indicate that it's supposed to generate an entire column. However, the code snippets you provide suggest that it's supposed to generate empty cells, not columns. Please clarify the purpose of this macro. Same goes for the name of \usercol. – Mico Dec 6 '14 at 18:47
  • @Werner yes, as it should generate a tikz picture – muffel Dec 6 '14 at 18:49
  • @Mico you are right, they don't generate a column but just a tikz picture that contains the user input string – muffel Dec 6 '14 at 18:50
  • You may want to rename the macros (col -> cell) – Mico Dec 6 '14 at 18:52
2

This can be done by using some advanced TeX features, i.e. \def with a scantext instead of \newcommand. This way you can extract all text between the commas.

One way to do this would be:

\documentclass{article}

\makeatletter
\newcommand\outputrow[1]{%
    \@outputrow#1,,,,,\@nil
}
\def\@outputrow#1,#2,#3,#4,#5\@nil{%
    \@usercol{#1} & \@usercol{#2} & \@usercol{#3} & \@usercol{#4} \\%
}
\def\@usercol#1{%
    \expandafter\ifx\expandafter\@nnil\unexpanded{#1}\@nnil
        \emptycol
    \else
        \usercol{#1}%
    \fi
}
\makeatother

\newcommand\usercol[1]{\fbox{#1}}
\newcommand\emptycol{(empty)}


\begin{document}

\begin{tabular}{llll}
  \outputrow{ab cd,foo,3,5}\\ %all columns used
  \outputrow{}\\ %no column used
  \outputrow{1,2}\\ %two columns used
\end{tabular} 
\end{document}

The \outputrow calls an internal macro \@outputrow and places the argument behind it without { } but with several commas and an endmarker (\@nil). Then \@outputrow scans for the four arguments and consumes the remaining commas as fives argument which is then discarded. The four arguments as used with \@usercol which checks if the argument is empty and then uses \emptycol or \usercol{#1}.

Note that this can be improved as well, e.g. with a loop so it works with an large number of columns.

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.