# How do I process a comma separated list passed through a command

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}

-
minimal must not be used forever. – kiss my armpit Oct 16 '13 at 17:59
\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expand‌​after\PROCESS\expandafter\expandafter\expandafter\expandafter\expandafter\expanda‌​fter\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.) – Qrrbrbirlbel 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
@DonKreher This is probably meant: Why should the minimal class be avoided? – Qrrbrbirlbel Oct 16 '13 at 18:48

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}


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}

-
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

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


-