7

How to trim the end of line character for each line read from an external \jobname.list file below? Note that the real scenario does not use filecontents package to generate the list. I use a batch file to prepare the list. The following MWE is just for the sake of simplicity.

\documentclass{article}

\usepackage{filecontents}
\begin{filecontents*}{\jobname.list}
a.jpg
b.pdf
c.eps
d.png
\end{filecontents*}

\parindent=0pt
\usepackage{graphicx}
\newread\reader

\begin{document}
\makeatletter
\openin\reader=\jobname.list\relax
\advance\endlinechar \@M
\loop
    \read\reader to \x
    \unless\ifeof\reader
    \includegraphics[width=\textwidth,height=\textheight,keepaspectratio]{../../Images/\x}%
\repeat
\advance\endlinechar -\@M
\makeatother
\end{document}

The code above cannot be compiled because \includegraphics does not like the end of line charcter appended in the file path. I wasted much time to find the source of problem.

Edit:

If the image files a.jpg and b.pdf are put in ../../Images/ then the proposed solutions no longer work. How to solve it?

I mainly use xelatex to accommodate 4 image formats.

1
  • 2
    Add \begingroup\endlinechar=-1 before \loop and \endgroup after \repeat. Also put a space (or \par) after {\x}.
    – egreg
    Sep 25, 2012 at 9:39

3 Answers 3

6

An alternative approach to Herbert's is to remove the space at the end of the line, which is what TeX converts the end-line to (assuming no blank lines, of course)

\documentclass{article}

\usepackage{filecontents}
\begin{filecontents*}{\jobname.list}
example-image-a.pdf
example-grid-100x100pt.png
\end{filecontents*}

\parindent=0pt
\usepackage{graphicx}
\newread\reader

\begin{document}
\def\stripend#1 \stop{\unexpanded{#1}}
\openin\reader=\jobname.list\relax
\loop
    \read\reader to \x
    \unless\ifeof\reader
    \edef\x{%
      \unexpanded{%
        \includegraphics[width=\textwidth,height=\textheight,keepaspectratio]%
       }%
       {\expandafter\stripend\x \stop}%
     }%
     \x
\repeat
\closein\reader
\end{document}
1
  • @GarbageCollector I've edited to expand \x once before using \includegraphics. That should I hope solve any issues (which are nothing to do with the line end: it's the way \includegraphics does a file search that's important).
    – Joseph Wright
    Sep 25, 2012 at 12:04
6

without grouping:

\newread\reader
[...]
\begin{document}
\makeatletter
\advance\endlinechar \@M
\openin\reader=\jobname.list\relax
\loop
    \read\reader to \x
    \unless\ifeof\reader
    \includegraphics[width=\textwidth,height=\textheight,keepaspectratio]{\x}%
\repeat
\closein\reader
\advance\endlinechar -\@M
\makeatother
[...]

if the images are saved in another directory then use (example for images in /tmp/):

[...]
\edef\filename{/tmp/\x}
\unless\ifeof\reader
\includegraphics[width=\textwidth,height=\textheight,keepaspectratio]{\filename}%
[...]
5
  • What if XeTeX is used and \endlinechar equals 20000? Just joking. ;-)
    – egreg
    Sep 25, 2012 at 9:45
  • 1
    defined in latex.ltx the main source for LaTeX: \mathchardef\@M=10000
    – user2478
    Sep 25, 2012 at 9:47
  • see my edit, which works for me.
    – user2478
    Sep 25, 2012 at 11:44
  • It does not work with xelatex/latex when we import EPS file. Sep 25, 2012 at 11:55
  • LuaTeX throws an error "Invalid \endlinechar" if \endlinechar is set to a value greater than 127. Therefore it is more portable and safe to assign a negative value (-1) either in a group or with saving/restoring the previous value. Sep 25, 2012 at 12:43
3

The following approach works also when the file name in \includegraphics has some prefix (the problem mentioned in the question probably has to do with some setting made to \endlinechar in graphics.sty)

\documentclass{article}

\usepackage{filecontents}
\begin{filecontents*}{\jobname.list}
example-image-a.jpg
example-grid-100x100pt.png
\end{filecontents*}

\parindent=0pt
\usepackage{graphicx}
\newread\reader

\begin{document}

\openin\reader=\jobname.list\relax
\begingroup\endlinechar=-1
  \loop
    \read\reader to \x
    \unless\ifeof\reader
    \edef\x{../Images/\x}
    \includegraphics[width=\textwidth,height=\textheight,keepaspectratio]{\x}
\repeat
\endgroup
\closein\reader
\makeatother
\end{document}

Here is an expl3 implementation

\documentclass{article}

\usepackage{filecontents}
\begin{filecontents*}{\jobname.list}
example-image-a.jpg
example-grid-100x100pt.png
\end{filecontents*}

\usepackage{graphicx}

\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\includefromfile}{O{} m m}
 {
  \garbcoll_include:nnn { #1 } { #2 } { #3 }
 }
\ior_new:N \g__garbcoll_read_ior
\cs_new_protected:Npn \garbcoll_include:nnn #1 #2 #3
 {
  \ior_open:Nn \g__garbcoll_read_ior { #3 }
  \ior_map_inline:Nn \g__garbcoll_read_ior
   {
    \tl_set:Nx \l_tmpa_tl { #2 \tl_trim_spaces:n { ##1 } } 
    \includegraphics[ #1 ]{ \l_tmpa_tl } \par
   }
 }
\ExplSyntaxOff

\parindent=0pt

\begin{document}

\includefromfile
  [width=\textwidth,height=\textheight,keepaspectratio]
  {../Images/}{\jobname.list}

\end{document}
3
  • @GarbageCollector Yes, it does. Check the simplified version and also the expl3 one.
    – egreg
    Sep 25, 2012 at 13:34
  • It does not work with xelatex/latex when we import EPS file. Sep 25, 2012 at 15:32
  • @GarbageCollector It's a problem in xetex.def, I believe. The expl3 version works.
    – egreg
    Sep 25, 2012 at 15:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .