4

I would like to write something like:

\foreach \myline in {\input{filehandle}}
{\dosomethingwith\myline}

If I have an outside_file.tex:

this,
is,
the content, of, a
file

and then try to pass it to a \foreach loop as follows

\documentclass{article}
\usepackage{pgffor}
\newcommand\dosomethingwith[1]{\textbf{#1}\par}

\begin{document}

Output as expected:\par
\foreach \myitem in {this,is,the content, of, a file}
{\dosomethingwith\myitem}

Output not as expected:\par
\foreach \myitem in {\input{outside_file}}
{\dosomethingwith\myitem}

\end{document}

I do not get the result I expect.

Here's an image of the result:

enter image description here

I once saw some package for loading and storing the content of a file in a macro. But I can no longer find that package. If you know the package I am referring to, I would accept since that will solve the problem I'm having here.

A.Ellett
  • 50,533

3 Answers3

2

If I understand your question, you need to load the whole contents of the file and use it as a parameter of the \foreach macro. Then you can replace the line

\foreach \myitem in {\input{outside_file}}

in your example by two lines:

{\everyeof={\noexpand}\xdef\filecontent{\csname @@input\endcsname outside_file }}%
\foreach \myitem in \filecontent

I suppose that the file doesn't include the TeX sensitive material (macros, TeX special characters like % etc.) and whole file contents can be processed by \edef.

wipet
  • 74,238
1

You could use a CSV processing package for reading the lines of the input file. The following solution uses csvsimple but I guess you can get similar solutions with datatool and pgfplotstable also:

\documentclass{article}

\usepackage{csvsimple}

\usepackage{filecontents}
\begin{filecontents*}{outside_file.txt}
this,
is,
the content, of, a
file
\end{filecontents*}

\newcommand\dosomethingwith[1]{\textbf{#1}\par}

\begin{document}

Read from file:\par
\csvloop{
  file=outside_file.txt,
  no head,
  check column count=false,
  command=\dosomethingwith\csvline,
}

\end{document}

enter image description here

0

You can assign the output of cat to a macro:

enter image description here

Notes:

Code:

\documentclass{article}

\usepackage{filecontents} \begin{filecontents}{OutsideFile.tex} this, is, the content, of, a file \end{filecontents}

\usepackage{pgffor} \newcommand\dosomethingwith[1]{\textbf{#1}\par}

\makeatletter %% Adapted from https://tex.stackexchange.com/questions/102365/specify-file-name-shell-access-via-input \newcommand\SetMacroToShellOutput[2]{%
\begingroup\endlinechar=\m@ne\everyeof{\noexpand}% \edef\TempResult{\endgroup \expandafter\def\noexpand#1{% @@input|"#2" }}% \TempResult} \makeatother

\begin{document}

Output as expected:\par \foreach \myitem in {this,is,the content, of, a file} {\dosomethingwith\myitem}

\SetMacroToShellOutput{\MyFileContent}{cat OutsideFile.tex} Output also as expected:\par \foreach \myitem in \MyFileContent {\dosomethingwith{\myitem}}

\end{document}

Peter Grill
  • 223,288