# \ForEach fails with underscores

For the automatic generation of reports I'm using the \ForEach loop of the forarray package. This is just great as it saves me lots of time.

However, there is one issue: When the items I iterate through contain underscores I get lots of errors (even though LaTeX finishes compiling and creates the PDF).

Here's a minimum (not) working example:

\documentclass[a4paper]{article}
\usepackage{forarray}

\begin{document}
\ForEach
{,}
{
\section{\thislevelitem}
This section covers the topic of \thislevelitem.
} {test_one, test_two, test_three}
\end{document}


In case I replace the underscores with dashes all works fine.

Is there a way to deal with these underscores in the \ForEach loop?

Edit to be more specific: While using test_\one, etc. would work in the above minimal example it does not for my purpose because I usually use \thislevelitem to access figures (including underscores in their path). In case it is possible to replace \_ by _ in \thislevelitem fore generating the figure path it would be a solution.

• Underscores are used in math mode. When you are not in math mode, LaTeX complains. Oct 25, 2018 at 8:35
• Indeed the only problem in the MWE (besides the spurious brace in test_one},) is that you are not in math mode when you print the text test_one, test_two etc. LaTeX treats _ as a marker for subscripts in math mode, so _ requires math mode. If I say \section{$\thislevelitem$} This section covers the topic of $\thislevelitem$. to get into math mode there is no error, but of course the output is math-y. Oct 25, 2018 at 8:39
• test\_one and so on Oct 25, 2018 at 9:18
• test_one would work in my minimum working example, however I normally use \thislevelitem to include figures (which filenames including underscores). Using test_one would then not allow me to access to my figures anymore. except if there's a way of replacing the "_" with "_" before accessing to these figures?
– Fab
Oct 25, 2018 at 11:23

Within file-names you can use \string for turning special input-characters like _ into ordinary ones.

Be aware that LaTeX' Computer Modern Roman Font in the pdf-output-file doesn't deliver an underscore but a diacritic dot for the underscore-input-character.

In order to get in the output the underscore-character for the underscore-input-character, you need to switch, e.g., to Computer Modern Typewriter (cmr):

\documentclass[a4paper]{article}
\usepackage{forarray}

\begin{document}

\ForEach{,}%
{%
\section{\texttt{\thislevelitem}}%
This section covers the topic of \texttt{\thislevelitem}.%
}%
{%
test\string_one, test\string_two, test\string_three%
}%

\end{document}


By the way: With \input (La)TeX will keep expanding tokens while gathering the filename. Thus you can, e.g., implement an \if..-switch and a macro which either delivers \textunderscore or delivers \string_ depending on whether the thing is to be printed in the text or to be used within the system as part of a file-name:

\documentclass[a4paper]{article}

\begin{filecontents*}{test_one.tex}
This is test\textunderscore one
\end{filecontents*}
\begin{filecontents*}{test_two.tex}
This is test\textunderscore two
\end{filecontents*}
\begin{filecontents*}{test_three.tex}
This is test\textunderscore three
\end{filecontents*}

\usepackage{forarray}

\newif\iffilename
\global\filenamefalse
\makeatletter
\newcommand\myunderscore{%
\iffilename
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi{\string_}{\textunderscore}%
}%
\makeatother

\begin{document}

\ForEach{,}%
{%
\section{\thislevelitem}%
This section covers the topic of \thislevelitem.%
{% open up a local scope.
\filenametrue
\\This is the file-name with underscores: \texttt{\thislevelitem}%
\filenamefalse
\\This is the content of the file \textbf{\thislevelitem.tex}:
\filenametrue
\input{\thislevelitem.tex}%
}% close the local scope.
}%
{%
% Be aware that \ForEach does remove leading spaces but does not remove
% trailing spaces from comma-separated items and therefore the last item
% must be trailed by a comment-char neutralizing the space which comes
% into being due to \endlinechar:
test\myunderscore one, test\myunderscore two, test\myunderscore three%<-This comment must be!!!
}%

\end{document}


Even more general you can implement a macro which does select arguments depending on its current definition:

\documentclass[a4paper]{article}

\begin{filecontents*}{test_one.tex}
This is test\textunderscore one
\end{filecontents*}
\begin{filecontents*}{test_two.tex}
This is test\textunderscore two
\end{filecontents*}
\begin{filecontents*}{test_three.tex}
This is test\textunderscore three
\end{filecontents*}

\usepackage{forarray}

\newcommand\SelectMyThingie[3]{#3}%

\begin{document}

\ForEach{,}%
{%
{% open up a local scope:
\printdigits
\section{\thislevelitem}%
This section covers the topic of \thislevelitem.\\
\printtextphrases
This is the content of the file \textbf{\thislevelitem.tex}:
\createfilenames
\input{\thislevelitem.tex}%
}% close the local scope.
}%
{%
% Be aware that \ForEach does remove leading spaces but does not remove
% trailing spaces from comma-separated items and therefore the last item
% must be trailed by a comment-char neutralizing the space which comes
% into being due to \endlinechar:
test\SelectMyThingie{\string_one}{\textunderscore one}{~1},
test\SelectMyThingie{\string_two}{\textunderscore two}{~2},
test\SelectMyThingie{\string_three}{\textunderscore three}{~3}%<-this comment must be!
}%

\end{document}


• THANKS A LOT. That perfectly does the job!
– Fab
Oct 25, 2018 at 13:30
• using the first solution test\string_one, etc. in combination with \usepackage[T1]{fontenc} works like a charm without any other modifications.
– Fab
Oct 25, 2018 at 14:02