# Tikz foreach does not work with \input or \directlua

When I'm trying to load data for tikz's \foreach using \input, or later with \directlua I noticed that it is not splited.

    \foreach \a / \n in {\directlua{tex.sprint("a/b")}}
{\a}


Can I (and how) force it to be parsed correctly?

results in

You have to expand \directlua before \foreach scans the argument. This could be done with the \expanded primitive:

\documentclass[]{article}

\usepackage[]{tikz}

\begin{document}
\expanded{\unexpanded{\foreach \a / \n in }{\directlua{tex.sprint("a/b")}}}
{\a\ and \n}

\end{document}

• I thought so, but applied \expanded in wrong place. thx Nov 12 '20 at 16:03
• @majkrzak note that this won't work with \input. LaTeX's \input isn't expandable, and while the primitive is (which one can access with \@@input), I couldn't make this work with \foreach. Nov 12 '20 at 16:05

This is what I use for when I want to foreach over a file content (not sure, but probably copied from Reading the data to iterate over with \foreach from a file):

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{pgffor}
\begin{filecontents}[overwrite]{mylist.txt}
a/b, 1/2,
c/d
\end{filecontents}
\usepackage{catchfile}
\begin{document}
\end{document}


You can use the patch provided below to provide an expand list option to fully expand the list before use.

\documentclass{article}
\usepackage{pgffor}
\begin{document}
\foreach [expand list=true] \a / \n in {\directlua{tex.sprint("a/b")}} {
\a
}
\end{document}

diff --git a/tex/generic/pgf/utilities/pgffor.code.tex b/tex/generic/pgf/utilities/pgffor.code.tex
index cdb77b31..65b62b8c 100644
--- a/tex/generic/pgf/utilities/pgffor.code.tex
+++ b/tex/generic/pgf/utilities/pgffor.code.tex
@@ -79,10 +79,13 @@
\fi%
}

+\def\pgffor@expand@list@true{\let\pgffor@expand@list\edef}
+\def\pgffor@expand@list@false{\let\pgffor@expand@list\def}
\def\pgffor@macro@list#1{%
\expandafter\pgffor@normal@list\expandafter{#1}}
\def\pgffor@normal@list#1{%
-  \def\pgffor@values{#1, \pgffor@stop,}%
+  \pgffor@expand@list\pgffor@values{#1}%
+  \expandafter\def\expandafter\pgffor@values\expandafter{\pgffor@values, \pgffor@stop,}%
\ifx\pgffor@values\pgffor@emptyvalues
\def\pgffor@values{\pgffor@stop,}%
\fi%
@@ -619,6 +622,9 @@
count/.code=\pgffor@count@parse#1\pgffor@stop,
parse/.is if=pgffor@assign@parse,
parse/.default=false,
+    expand list/.is if=pgffor@expand@list@,
+    expand list/.default=true,
+    expand list=false,
}

\def\pgffor@assign@parse#1{%


Instead of patching your PGF installation (which will be overriden by the next update anyway), you can also include the necessary definitions in your document directly.

\documentclass{article}
\usepackage{pgffor}

\makeatletter
\def\pgffor@expand@list@true{\let\pgffor@expand@list\edef}
\def\pgffor@expand@list@false{\let\pgffor@expand@list\def}
\def\pgffor@normal@list#1{%
\pgffor@expand@list\pgffor@values{#1}%
\expandafter\def\expandafter\pgffor@values\expandafter{\pgffor@values, \pgffor@stop,}%
\ifx\pgffor@values\pgffor@emptyvalues
\def\pgffor@values{\pgffor@stop,}%
\fi%
\let\pgffor@body=\pgfutil@empty%
\global\pgffor@continuetrue%
\pgffor@collectbody}
\makeatother

\pgfqkeys{/pgf/foreach}{
expand list/.is if=pgffor@expand@list@,
expand list/.default=true,
expand list=false,
}

\begin{document}
\foreach [expand list=true] \a / \n in {\directlua{tex.sprint("a/b")}} {
\a
}
\end{document}

• thx! Is this change going to be included in upcoming release of pgf? Will it woek with \input or its primitive \@@input? Nov 13 '20 at 20:24
• @majkrzak The patch would have to be applied to your PGF installation. I've added another section to the answer on how to backport the feature to your document without patching. Nov 13 '20 at 20:30