# compose an array of strings as a macro

I can use the \foreach loop to iterate over an array of strings:

\documentclass{article}
\usepackage{tikz}
\begin{document}
\foreach \v in {A, B}{
\input{the\v file.txt}
}
\end{document}


Now, I would like to compose a string as a macro as in:

\documentclass{article}
\usepackage{tikz}
\begin{document}
\newcommand\var{A, B} % <<< macro
\foreach \v in \var{
\input{the\v file.txt}
}
\end{document}


Then I get a problem:

! LaTeX Error: File theA, Bfile.txt' not found.


Using \def instead of \newcommand creates the same problem using Latex version pdfTeXk, Version 3.141592-1.40.3 (Web2C 7.5.6).

How to solve?

• Have you tried \def instead of \newcommand? – Foitn Jun 12 '18 at 14:34
• I do not get your error for the 2nd case. I get the proper errors: ! LaTeX Error: File 'theAfile.txt' not found. and ! LaTeX Error: File 'theBfile.txt' not found. which would not occur if those files existed on my system. – Steven B. Segletes Jun 12 '18 at 14:42
• You get theA, Bfile.txt if you call \foreach \v in {\var}{...}; not with your code. – egreg Jun 15 '18 at 8:08
• @egreg, in pdfTeXk, Version 3.141592-1.40.3 (Web2C 7.5.6) I have the problem without the braces {. In pdfTeX, Version 3.14159265-2.6-1.40.16 (TeX Live 2015/Debian) I need to add the braces to generate the problem. – Viesturs Jun 15 '18 at 8:49
• Probably the relevant information is the version of TikZ. Using newer code in a very old release of TeX is hopeless; anyway, try \expandafter\foreach\expandafter i\expandafter n\expandafter{\var}{...} – egreg Jun 15 '18 at 8:57

## 3 Answers

I can reproduce the problem with TikZ/PGF version 1.7 (2006/10/11, twelve years ago), but not with later versions.

I guess that, starting with version 2.0, the syntax of \foreach has been extended to cope with the cases

\foreach \v in {<list>}{...}
\foreach \v in \cs{...}


but the latter case was not possible in previous versions.

Solution: update your TeX system.

For the old system you can do, which will also work in newer releases, as follows.

\documentclass{article}
\usepackage[pdftex]{graphicx}
\usepackage{tikz}
\begin{document}
\newcommand\var{A, B} % <<< macro
\expandafter\foreach\expandafter\v\expandafter i\expandafter n\expandafter{\var}{
\input{the\v file.txt}
}
\end{document}


I had to go back to TeX Live 2007, the earliest release I have on one of my machines, to reproduce the issue: This is pdfTeXk, Version 3.1415926-1.40.9 (Web2C 7.5.7)

Your \newcommand defines one string, so when called it produces that string. For more about the differences, see https://tex.stackexchange.com/a/658/114249. What you should use is the \def command:

\documentclass{article}
\usepackage{tikz}
\begin{document}
\def\var{A, B} % <<< macro
\foreach \v in \var{
\input{the\v file.txt}
}
\end{document}


This tries to open theAfile.txt and theBfile.txt as requested.

• I compiled your code and got exactly the same problem. – Viesturs Jun 12 '18 at 14:40
• You still get the theA, Bfile.txt not found, so for that exact string? – Foitn Jun 12 '18 at 14:41
• I use your code exactly. – Viesturs Jun 12 '18 at 14:42
• Compile with \newcommand in the latest version of pdflatex and see if it still works. – Manuel Jun 15 '18 at 7:45
• @Foitn There is no difference at all between \newcommand{\var}{A, B} and \def\var{A, B} (apart from the check done by the former and the fact that the macro it generates is \long, which is inessential here). – egreg Jun 15 '18 at 8:05

Maybe you use some package releases where \foreach's list-argument must not come from a macro but must be delivered fully expanded.

If so, then something like the following might help:

\documentclass{article}
\usepackage{tikz}
\newcommand\PassFirstToSecond[2]{#2{#1}}%
\newcommand\OneLevelExpandedSecond[2]{%
\expandafter\PassFirstToSecond\expandafter{#2}{#1}%
}%
\begin{document}
\newcommand\var{A, B} % <<< macro
\OneLevelExpandedSecond{\foreach \v in }{\var}{% <- We don't want unneeded spaces due to \endlinechar!
\input{the\v file.txt}%  <- We don't want unneeded spaces due to \endlinechar!
}% <- We don't want unneeded spaces due to \endlinechar!
\end{document}
`