2

While trying to give a foreach loop a macro to loop into, I found on Macro not working in foreach loop that I can use \pgfplotsforeachungrouped and it was indeed able to loop through my macro.

However, macro: it returns my list twice. Here is a MWE of what I am talking about:

\documentclass{article}

\usepackage{pgfplots} \newcommand{\xlabelsol}{0/0,1/1,2/2} \pgfplotsset{compat=1.18} \begin{document} \pgfplotsforeachungrouped \x/\label in {\xlabelsol}{% \x/\label \ } \end{document}

And the outcome of the MWE:

Doubled list

Ireally need to use a macro for the list in the loop because I am trying to automate the creation of pdf files with a template for the project I am working on. Also, a solution would need to be compatible with XeLaTeX

I have tried to look up how to fix this issue but I can't seem to find a solution.

2 Answers2

5

The command \xlabelsol needs to be expanded before the loop starts. So you could do something like this:

\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.18}

\newcommand{\xlabelsol}{0/0, 1/1, 2/2} \begin{document} \edef\myloop{% \noexpand\pgfplotsforeachungrouped \noexpand\x/\noexpand\label in {\xlabelsol}{% \noexpand\x/\noexpand\label \space }% }\myloop \end{document}

Which would ouput:

enter image description here

  • 2
    \expanded{\unexpanded{\pgfplotsforeachungrouped \x/\label} in {\xlabelsol}}{\x/\label \space} works too (sorry for wrapping it on only one input line) – user691586 Jun 06 '23 at 15:31
  • @user691586 Thanks, this is a nice idea since it simplifies the code and makes it more readable. – Jasper Habicht Jun 06 '23 at 15:49
3

First, for the original \foreach provided by pgffor (sub)package, its syntax is either

\foreach \x/\label in {0/0,1/1,2/2} {<loop body>}
% or
\foreach \x/\label in \xlabelsol {<loop body>}

but never

\foreach \x/\label in {\xlabelsol} {<loop body>} % wrong syntax

Again, in the easiest case, <list> is either a comma-separated list of values surrounded by curly braces or it is the name of a macro that contain such a list of values.

https://tikz.dev/pgffor#\foreach

Then, \pgfplotsforeachungrouped from pgfplots is simpler than \foreach, such that it can't handle list stored in a macro, like

% not supported in pgfplots v1.18.1
\pgfplotsforeachungrouped  \x/\label in \xlabelsol {<loop body>}

Finally, here's a patch to \pgfplotsforeachungrouped:

\documentclass{article}

\usepackage{pgfplots} \pgfplotsset{compat=1.18}

\makeatletter \long\def\pgfplotsforeachungrouped@#1/#2in{% \pgfutil@ifnextchar\bgroup{% \pgfplotsforeachungrouped@@{#1}{#2}% }{% % \pgfplots@error{Found unexpected characters: expected 'in '.}% \pgfplotsforeachungrouped@@@{#1}{#2}% }% }

\long\def\pgfplotsforeachungrouped@@@#1#2#3{% \expanded{\unexpanded{\pgfplotsforeachungrouped@@{#1}{#2}}{\unexpanded\expandafter{#3}}}% } \makeatother

\begin{document} \setlength\parindent{0pt} \newcommand{\xlabelsol}{0/0,1/1,2/2}

\foreach \x/\y in \xlabelsol {% (\x)(\y) \ }

\pgfplotsforeachungrouped \x/\y in \xlabelsol {% (\x)(\y) \ } \end{document}

Output is two copies of

(0)(0)
(1)(1)
(2)(2)
muzimuzhi Z
  • 26,474