# File name not handled correctly in /foreach loop

For some reason when I try to specify a file name for \includegraphics in a loop, either using \foreach or using \clist, I get a file not found error. The error displays a valid path for the file, and if I use function parameter instead of trying to loop through a list it works right. There seems to be some issue with using loops and specifying files. How do I get this to generate usable file paths?

\documentclass{article}

\usepackage{graphicx}
\usepackage{pgffor}

\newcommand{\lmrf}[3]
{
\begin{figure}
\centering
\foreach \f in {#1}
{
\includegraphics{./Figures/\f}
}
\caption{#2}
\label{fig:#3}
\end{figure}
}

\begin{document}

\lmrf{SURF1.png,SURF2.png}{(left) (right)}{rates}

\end{document}


This returns the error "! LaTeX Error: File ./Figures/SURF1.png' not found." ./Figures/SURF1.png is a file that is in that path. It works fine if I get rid of the loop.

This works:

\documentclass{article}

\usepackage{graphicx}

\newcommand{\lmrf}[3]
{
\begin{figure}
\centering
\includegraphics{./Figures/#1}
\caption{#2}
\label{fig:#3}
\end{figure}
}

\begin{document}

\lmrf{SURF1.png}{(left) (right)}{rates}

\end{document}


Update: Seems there's some underlying issue with resolving file names and loops. If I don't specify a path, it works. If I don't specify a file extension, it works. But, if a full path and file name including extension are specified it won't work.

Simply changing to:

\lmrf{SURF1,SURF2}{(left) (right) }{rates}


resulted in finding the files properly.

You're primary mistake is in the syntax of the \foreach group. It should be:

\foreach <var> in {<list>}
{<action>}


\documentclass{article}
\usepackage{amsmath}
\usepackage{pgffor}
\usepackage{float}
\usepackage{graphicx}
\usepackage{mwe}

\newcommand{\lmrf}[3]
{
\begin{figure}[H]
\centering
\foreach \f/\r in {#1}
{%%
\includegraphics[width=0.45\columnwidth,keepaspectratio=true,angle=\r]{\f}%%{./Figures/\f};
}%%
\caption{#2}
\label{fig:#3}
\end{figure}
}

\begin{document}

\lmrf{example-image-a/30,example-image-b}{Caption}{Figure}

\end{document}


 \foreach \f/\r in {#1}
{%%
\includegraphics[width=0.45\columnwidth,keepaspectratio=true,angle=\r]{./Figures/\f};%%
}%%


and called it successfully with

\lmrf{restaurant/30,oak_tree/-10}{Caption}{Figure}


But

\lmrf{restaurant.png/30,oak_tree.png/-10}{Caption}{Figure}


I would suggest removing the png suffix:

• That worked because the ./Figure/ part of the path was removed. It's not a compound statement being looped over, {} isn't needed. I'd like the figures in a static location.
– Eric
Sep 26 '18 at 20:15
• @Eric I created the same sort of directory structure as you have and I get a successful run. The difference I have is that I don't use the png suffix as it appears you do. Remove the png and all should be good. Sep 26 '18 at 20:46

The syntax

\foreach \f in {<list>} <code>;


only works in the context of a TikZ picture (and not even always).

The generally correct code is

\foreach \f in {<list>} {<code>}


On the other hand, I'm not sure that you gain that much with such code obfuscation. Typing

\begin{figure}[htp]
\centering

\includegraphics{./Figures/SURF1}%
\includegraphics{./Figures/SURF2}

\caption{(left) (right)}
\label{fig:rates}
\end{figure}


doesn't seem so burdensome. If you have several of these constructs, it *might be useful to have an abbreviation, but in that case the [H] option will most likely be of a hindrance, rather than help.

A reduced version:

\documentclass{article}

\usepackage{pgffor}

\newcommand{\insertfigures}[1]{%
\foreach \f in {#1}{\includegraphics{./Figures/\f}}%
}

\begin{document}

\begin{figure}[htp]
\centering
\insertfigures{SURF1,SURF2}

\caption{(left) (right)}\label{rates}
\end{figure}

\end{document}


This keeps \caption and \label searchable.

A more flexible implementation with key-value syntax.

\documentclass{article}
\usepackage{graphicx}
\usepackage{xparse}

\ExplSyntaxOn
\keys_define:nn { eric/lmrf }
{
pos     .tl_set:N = \l_eric_lmrf_pos_tl,
pos     .initial:n = htp,
caption .tl_set:N = \l_eric_lmrf_caption_tl,
label   .tl_set:N = \l_eric_lmrf_label_tl,
path    .tl_set:N = \l_eric_lmrf_path_tl,
o       .tl_set:N = \l_eric_lmrf_option_tl,
f       .code:n =
{
\seq_put_right:Nn \l_eric_lmrf_images_seq { #1 }
\seq_put_right:NV \l_eric_lmrf_options_seq \l_eric_lmrf_option_tl
},
}
\seq_new:N \l_eric_lmrf_images_seq
\seq_new:N \l_eric_lmrf_options_seq

\NewDocumentCommand{\lmrf}{m}
{
\use:x { \exp_not:N \begin{figure}[\l_eric_lmrf_pos_tl] }
\keys_set:nn { eric/lmrf } { #1 }
\centering
\int_step_inline:nn { \seq_count:N \l_eric_lmrf_images_seq }
{
\use:x
{
\exp_not:N \includegraphics
[ \seq_item:Nn \l_eric_lmrf_options_seq { ##1 } ]
{ \l_eric_lmrf_path_tl \seq_item:Nn \l_eric_lmrf_images_seq { ##1 } }
}
}
\caption{\tl_use:N \l_eric_lmrf_caption_tl}
\label{\tl_use:N \l_eric_lmrf_label_tl}
\end{figure}
}
\NewDocumentCommand{\lmrfsetup}{m}
{
\keys_set:nn { eric/lmrf } { #1 }
}
\ExplSyntaxOff

%\lmfrsetup{./Figures/}

\begin{document}

\lmrf{
caption={(left) (right)},
label=rates,
%  path=./Figures/
o = {width=3cm},
f = example-image,
f = example-image-a
}

\lmrf{
caption={(left) (center) (right)},
label=foo,
%  path=./Figures/
o = {width=3cm},
f = example-image,
f = example-image-a,
o = {width=2cm},
f = example-image-b
}

\end{document}


The defined keys are caption, label, pos, path,oandf. The first two should be self-explanatory;pos(default valuehtp) is for the positioning argument tofigure.

With o you can specify options to \includegraphics. Until countermanded by another o key, the option will be set for all the following images, as shown in the second example.

The path key is for specifying the path for the images. You can also specify it in the preamble with \lmfrsetup, say

\lmfrsetup{path=./Figures/}


as shown. In this case you don't need to specify the key in the \lmfr command. I commented out all calls just because I was lazy to make a directory structure.

• This looks like it could be a very useful response. I'm trying to standardize the way graphics are displayed in a collaborative document using submissions by multiple authors.
– Eric
Sep 27 '18 at 14:43