# Best way to loop over the value of a pgfkey key that is a csv list?

Using pgfkeys, suppose that I have a key whose value is a comma separated list:

\pgfkeys{/a list/.initial = {1,2,3}}


Question What is the correct way to iterate over this list using \foreach (from pgffor)?

The only way that I have found that works is to forcibly extract and expand the key value with something like:

\edef\alist{\pgfkeysvalueof{/a list}}
\foreach \a in \alist {A = \a\newline}% works!


This works but is ungainly as it shouldn't be necessary to extract the value of a key into a temporary variable in order to use it. My initial thought/hope was that something like

\foreach \a in \pgfkeysvalueof{/a list} {a = \a\newline}


would work, but this gives an error (! Argument of \pgfkeysvalueof has an extra }.)

Is there an "officially sanctioned" pgf approach for looping over a comma separated list that is the value of a pgf key? I initially got excited when I found the .list handler. It is not unlikely that .list does give a way of doing what I want but for the life of me I can't figure how to use it!

Bonus question Give an example showing what the .list handler does.

Here is full MWE:

\documentclass{article}
\usepackage{pgfkeys,pgffor}

\pgfkeys{/a list/.initial = {1,2,3}}

\begin{document}

\edef\alist{\pgfkeysvalueof{/a list}}
\foreach \a in \alist {A = \a\newline}% ugly, but works!

%\foreach \a in \pgfkeysvalueof{/a list} {a = \a}% does not work

\end{document}


Here are two solutions:

\documentclass{article}
\usepackage{pgfkeys}
\usepackage{pgffor}
\pgfkeys{
/list1/.initial = {1,2,3},
%
/list2/.store in=\mylisttwo,
/list2={1,2,3},
}

\begin{document}

\pgfkeys{body loop/.code={A = #1\par},body loop/.list/.expanded=\pgfkeysvalueof{/list1}}

\pgfkeys{/list1={a,b,c}}
\pgfkeys{body loop/.code={A = #1\par},body loop/.list/.expanded=\pgfkeysvalueof{/list1}}

\foreach \b in \mylisttwo {B = \b\par}
\pgfkeys{/list2={a,b,c}}
\foreach \b in \mylisttwo {B = \b\par}

\end{document}


To simplify usage, I define a generic style apply to key:

\documentclass{article}
\usepackage{pgfkeys}
\usepackage{pgffor}
\pgfkeys{
apply to key/.style n args={2}{@body loop/.code={#1},@body loop/.list/.expanded=\pgfkeysvalueof{#2}},
/list1/.initial = {1,2,3},
}
\begin{document}
\pgfkeys{apply to key={AA = #1\par}{/list1}}
\pgfkeys{/list1={a,b,c}}
\pgfkeys{apply to key={AA = #1\par}{/list1}}
\end{document}

• Thanks Paul! How does the list1 solution work when I change the value of list1? I tried \pgfkeys{/list1={a,b,c}}\pgfkeys{body loop} but this did not work . [Your list2 solution is similar to the \edef solution in the question and, like it, this approach suffers from the problem that it creates an external variable \mylisttwo outside of pgfkeys...I know that I am idiosyncratic, but I prefer to keep the data inside the pgfkeys...] – user30471 Feb 3 '17 at 7:59
• @Andrew I updated my code to add examples. – Paul Gaborit Feb 3 '17 at 9:49
• Thanks Paul. I'm afraid that this is less elegant than the solution that I posted. – user30471 Feb 5 '17 at 2:02
• @Andrew My apply to key solution is generic (you can apply it on any key, list of values or simple value) and does not suffer from the \foreach problem (the body of \foreach is an implicit group). – Paul Gaborit Feb 5 '17 at 10:59
• You're right, it is nice. Perhaps I didn't appreciate it enough. You also give a nice example of using .list. I am still surprised that there isn't a more direct way of doing this. – user30471 Feb 6 '17 at 2:57

Not sure if your application would permit a listofitems alternative solution.

\documentclass{article}
\usepackage{listofitems}
\begin{document}
\setsepchar{,}

\foreachitem\a\in\alist{A = \a\newline}
\end{document}


• Thanks Steven. I didn't know about thew listofitems package. With pgffor, it is possible to do what I want using\def\alist{1,2,3}\foreach \a in \alist {...} but I really want to do this using pgfkeys. – user30471 Feb 3 '17 at 3:07

Here is a pgf-style answer along the lines of what I am looking for but it places the \foreach loop inside the pgfkeys definition rather than having the loop outside of the key structure:

\documentclass{article}
\usepackage{pgfkeys,pgffor}

\pgfkeys{/mykeys/.is family,/mykeys}
\newcommand\MyKey[1]{\pgfkeys{/mykeys, #1}}
\MyKey{list/.style={llist/.code={\foreach \a in {#1}{A=\a\newline}}}}
\parindent=0pt

\begin{document}

\MyKey{list={1,2,3}}
\MyKey{llist}

\MyKey{list={a,b,c}}
\MyKey{llist}

\end{document}


I'd prefer a solution that allows me to loop over the key value outside of the pgfkeys definition and that does not require a "helper" key, like llist above.