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, 2013 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, 2013 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, 2013 at 18:47
  • 1
    @DonKreher This is probably meant: Why should the minimal class be avoided? Oct 16, 2013 at 18:48

2 Answers 2

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, 2013 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

You must log in to answer this question.

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