7

When passing a comma-separated list the commas are ignored, i.e. the list becomes a single item and I can't seem to find a way to prevent this. What should I do so that TEST C in the attached code will achieve the expected result of "extratcting" the itmes in the list?.

\documentclass{article}
\usepackage{pgffor}
\newcommand{\setstr}[2]{\expandafter\def\csname#1\endcsname{#2}}
\newcommand{\getstr}[1]{\csname#1\endcsname}
\newcommand{\PROCESS}[1]
{
The list items are:
 \foreach \i in {#1}
 {
   (\i)
 }
}
\newcommand{\SETC}[2]{\setstr{C#1}{#2}}
\newcommand{\RUN}[1]{
\expandafter\PROCESS\expandafter{\getstr{C#1}}
}
\begin{document}
%
% The following works
%
\noindent{TEST A:}
\PROCESS{a,b,c,d}
\newline
%
% and the following also works
%
\noindent{TEST B:}
\newcommand{\A}{a,b,c,d}
\expandafter\PROCESS\expandafter{\A}
\newline
%
% but this  does not work
%
\noindent{TEST C:}
\SETC{1}{a,b,c,d}%
\RUN{1}%
\newline
\end{document}
4
  • 1
    minimal must not be used forever. Oct 16 '13 at 17:59
  • 1
    \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\PROCESS\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{\getstr{C#1}} for \RUN will work. (This is an expansion issue.) But it might be easier to create a slightly different macro that handle a list stored in a macro. (Just like pgffor itself: \foreach \i in {<list>} vs \foreach \i in \listMacro.) Oct 16 '13 at 18:26
  • @Marienplatz: I don't understand the comment on "minimal" please explain. This is my first attempt at posting here and I thought that is what you did.
    – Don Kreher
    Oct 16 '13 at 18:47
  • 1
    @DonKreher This is probably meant: Why should the minimal class be avoided? Oct 16 '13 at 18:48
8

As Qrrbrbirlbel says in a comment, it's an expansion issue; \getstr requires three expansion steps, not just one.

\documentclass{article}
\usepackage{pgffor}
\newcommand{\setstr}[2]{\expandafter\def\csname#1\endcsname{#2}}
\newcommand{\getstr}[1]{\csname#1\endcsname}
\newcommand{\PROCESS}[1]{%
The list items are:
 \foreach \i in {#1}
 {%
   (\i)
 }%
}
\newcommand{\SETC}[2]{\setstr{C#1}{#2}}
\makeatletter
\newcommand{\RUN}[1]{%
  \begingroup\protected@edef\x{\endgroup\protect\PROCESS{\getstr{C#1}}}\x
}
\makeatother

\begin{document}
%
% The following works
%
\noindent{TEST A:}
\PROCESS{a,b,c,d}

%
% and the following also works
%
\newcommand{\A}{a,b,c,d}

\noindent{TEST B:}
\expandafter\PROCESS\expandafter{\A}

%
% also this works
%
\SETC{1}{a,b,c,d}

\noindent{TEST C:}
\RUN{1}

\end{document}

enter image description here

A slightly different approach, that better preserves the structure of the comma separated list.

\documentclass{article}
\usepackage{pgffor}
\newcommand{\setstr}[2]{\expandafter\def\csname#1\endcsname{\unexpanded{#2}}}
\newcommand{\getstr}[1]{\csname#1\endcsname}
\newcommand{\PROCESS}[1]{%
The list items are:
 \foreach \i in {#1}
 {%
   (\i)
 }%
}
\newcommand{\SETC}[2]{\setstr{C#1}{#2}}
\newcommand{\RUN}[1]{%
  \begingroup\edef\x{\endgroup
  \noexpand\PROCESS{\getstr{C#1}}}\x
}
\begin{document}
%
% The following works
%
\noindent{TEST A:}
\PROCESS{a,b,c,d}

%
% and the following also works
%
\newcommand{\A}{a,b,c,d}

\noindent{TEST B:}
\expandafter\PROCESS\expandafter{\A}

%
% also this works
%
\SETC{1}{a,b,c,\textbf{d}}

\noindent{TEST C:}
\RUN{1}

\getstr{C1}

\end{document}
1
  • This works perfect and now I am finished with the project and can get back to Mathematics ..... I hope.
    – Don Kreher
    Oct 17 '13 at 16:27
5

Although the OP is probably only interested in LaTeX solutions, here I'll present a ConTeXt solution.

The command \processcommacommand takes two arguments. The first one being the comma separated list, which can be a macro, and a second argument which is the macro to be used to process the list items. Example:

\define[1]\doprocess
  {(#1)}

\define\somelist
  {foo, bar, baz}

\starttext
  \processcommacommand
    [alpha, \math{\beta}, gamma]
    \doprocess

  \processcommacommand
    [\somelist]
    \doprocess

  \expandafter\processcommacommand\expandafter
    [\somelist]
    \doprocess
\stoptext

screenshot

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.