1

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?

5
  • 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
  • 2
    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

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)

1

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.

11
  • 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
  • 1
    Compile with \newcommand in the latest version of pdflatex and see if it still works. – Manuel Jun 15 '18 at 7:45
  • 2
    @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
0

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}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.