2

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 enter image description here

Mico
  • 506,678
majkrzak
  • 143
  • It is not about what https://tex.stackexchange.com/questions/283274/reading-the-data-to-iterate-over-with-foreach-from-a-file is about. This question refers to macro expansion in foreach environment – majkrzak Nov 13 '20 at 08:49

3 Answers3

3

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}

Skillmon
  • 60,462
  • I thought so, but applied \expanded in wrong place. thx – majkrzak 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. – Skillmon Nov 12 '20 at 16:05
2

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}
\newcommand\loaddata[1]{\CatchFileDef\loadeddata{#1}{\endlinechar=-1}}
\begin{document}
    \loaddata{mylist.txt}
    \foreach \one/\two in \loadeddata {\one--\two\par}
\end{document}

enter image description here

Rmano
  • 40,848
  • 3
  • 64
  • 125
2

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}

Henri Menke
  • 109,596
  • thx! Is this change going to be included in upcoming release of pgf? Will it woek with \input or its primitive \@@input? – majkrzak 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. – Henri Menke Nov 13 '20 at 20:30