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'm not sure about the question, since I do not really understand why it fails.

I tend to use commands to generate my tables, and when I use the #1 style of accessing the arguments it works. But now I have a wider dataset, and need to use this trick: How to make define a command that takes more than 9 arguments to get all the arguments together in one command.

Minimal example:

\documentclass[]{article}
\begin{document}

\newcommand\rowdata[2]{%
    \def\firstPoint{#1}%
    \def\secondPoint{#2}%
    \createRow
    % #1 & #2 \\ would work.
}
\newcommand\createRow{ %
    \wlog{\firstPoint \secondPoint} % it appears in the log 
    \firstPoint & \secondPoint \\ % this fails
}

\begin{table}
    \begin{tabular}{l l}
        \rowdata{a}{b}
        \rowdata{d}{b}
        \rowdata{a}{c}
    \end{tabular}
\end{table}
\end{document}

And this gives the following error:

! Undefined control sequence.
\createRow ...dPoint } \firstPoint & \secondPoint 
                                                  \\ 
l.16        \rowdata{a}{b}

If I remove the & it does work, but then I cannot create a table anymore.

So what is happening here?

share|improve this question
5  
Alignment cells form groups, so the definition of \secondPoint is forgotten as soon as & is digested. –  egreg Feb 21 '13 at 15:50

2 Answers 2

up vote 5 down vote accepted

In comments, the reason is pointed out: & besides other things ends and begins a group so the definition of \secondPoint is forgotten. Solution: use \gdef :

\documentclass[]{article}
\begin{document}

\newcommand\rowdata[2]{%
    \gdef\firstPoint{#1}%
    \gdef\secondPoint{#2}%
    \createRow
    % #1 & #2 \\ would work.
}
\newcommand\createRow{ %
    \wlog{\firstPoint \secondPoint} % it appears in the log 
    \firstPoint & \secondPoint \\ % this fails
}

\begin{table}
    \begin{tabular}{l l}
        \rowdata{a}{b}
        \rowdata{d}{b}
        \rowdata{a}{c}
    \end{tabular}
\end{table}
\end{document}
share|improve this answer

The stringstrings package has a \getargs command that works like Unix. It will parse a single argument into \argi, \argii, etc. The total number of arguments is in \narg.

\documentclass{article}
\usepackage{stringstrings}
\begin{document}
\getargs{1 2 3 4 5 6 7 8 9 10 11 12 FinalArgument}
There are \narg~arguments.  The thirteenth is \argxiii
\end{document}

The result to this example is:

There are 13 arguments. The thirteenth is FinalArgument

======

In answer to a request for a MWE, I note that stringstrings did suffer the same problem the user noticed above, which is that the getargs results were not global. However, I remedy that here with a \makeatletter redefinition of \getargs.

Then I redefined \rowdata to take one big space-separated argument. So here is how one prints a 12 column table with a command that generates the rows. Furthermore, the argument is merely space-separated data, not separate {} blocks.

AFTERTHOUGHT: The \rowdata command can take more than just typed data as its content. For example, you could have \today as part of the data, and it would take up three arguments (i.e., columns) of the table

Here is the code

\documentclass[]{article}
\usepackage{stringstrings}
\makeatletter
\renewcommand\getargs[2][q]{\+%
  \if v#1\def\@mode{q}\else\def\@mode{#1}\fi
  \edef\@argv{#2}%
  \@getstringlength{\@argv}{@stringsize}%
  \setcounter{@iargc}{0}%
  \whiledo{\value{@stringsize} > 0}{%
    \addtocounter{@iargc}{1}%
    \getaword[\@mode]{\@argv}{1}%
    \expandafter\global\expandafter\edef\csname arg\roman{@iargc}\endcsname{\thestring}%
    \removeword[e]{\@argv}%
    \edef\@argv{\thestring}%
    \@getstringlength{\@argv}{@stringsize}%
  }
  \edef\narg{\arabic{@iargc}}%
\?}
\makeatother
\newcommand\rowdata[1]{%
  \getargs{#1}
  \argi & \argii & \argiii & \argiv & \argv & \argvi & \argvii & 
  \argviii & \argix & \argx & \argxi & \argxii \\
}
\begin{document}
\begin{table}
    \begin{tabular}{l l l l l l l l l l l l}
        \rowdata{a b 3 4 5 6 7 8 9 10 11 12}
        \rowdata{d b blah 3 45 89 s rt 343 \today}
        \rowdata{a c 45 dfgf 454 454 fd 7 sds ssd s s}
    \end{tabular}
\end{table}
\end{document}

enter image description here

share|improve this answer
2  
I cannot see how this answers the question. Could you please embed it into the example provided in the question? –  yo' Feb 21 '13 at 15:55
1  
Remark: You can use \expandafter\xdef instead of \expandafter\global\expandafter\edef ;) –  yo' Feb 22 '13 at 18:03
    
Thanks for that tip. –  Steven B. Segletes Feb 22 '13 at 18:08
1  
@StevenB.Segletes And \global\expandafter\edef would suffice anyway, because \global wants to find a "def" command after it, so it starts expansion. –  egreg Feb 22 '13 at 18:19
    
Thanks. And note I edited the example to show how a command can be used as part of the \rowdata input. –  Steven B. Segletes Feb 22 '13 at 18:23

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.