4

I am writing a Latex file that needs to include figures from a directory graphs.

graphs has several sub-directories say, one , two and three. These individually contain several graphics that should be included in the file.

One way is to include every graphic in the file manually. But, that is too cumbersome. Is there a better way to do this?

Martin Scharrer
  • 262,582
Ankit
  • 835
  • 5
    So you want to include all graphic files from certain directories automatically? In this case see How to iterate through the name of files in a folder, which looks like a duplicate. The adjustments to multiple directories should be easily done. – Martin Scharrer Dec 20 '11 at 10:00
  • @MartinScharrer: Ah. You beat me to the punch. – night owl Dec 20 '11 at 10:08
  • 1
    You question is not well-defined at the moment. Do you only want to reduce the amount of work, e.g. not have to write the full directory names all the time, or do you want to include all graphic files from a certain directory structure automatically? I personally think it is the later, but looking at the two answers so far other people think more about the former. In that case Automatically Locate Included Images looks like a duplicate. – Martin Scharrer Dec 20 '11 at 10:35
  • @Martin: Yea, I guess the question could be a tad bit more specific at what is the optimal goal here. Whether to reduce the typing or have it auto included. – night owl Dec 20 '11 at 10:49
  • @MartinScharrer. My main motive here is to reduce the amount of work as I have about 100 plots to include and including each of them one by one is a pain in the bottom – Ankit Dec 21 '11 at 03:29
  • http://tex.stackexchange.com/q/6547/9467 seems relevant. – kiss my armpit Dec 21 '11 at 03:36
  • You should edit your question to explain why the link that @MartinScharrer provided in the very first comment does not solve your issue, and provide an example directory structure along with sample file names. – Peter Grill Dec 21 '11 at 03:42

2 Answers2

8

Put into your preamble:

\graphicspath{{graphs}{graphs/one}{graphs/two}{graphs/three}}

makes sense if you do not have too many subdirectories. Every path is enclosed in braces.

  • Hi, But how do I include the files then as each one, two etc have the same file name like a.pdf and b.pdf – Ankit Dec 21 '11 at 03:26
  • @Ankit: you can use \graphicspath several times in your document to define other search rules. –  Dec 21 '11 at 08:08
  • When using \graphicspath some common file names are somehow reserved by the system (left.pdf, hand.png). The list of reserved names is moving such that you should always use ./file name instead of just file name in command arguments. – Jérôme LAURENS Nov 18 '21 at 09:28
3

Here is a solution. Comments will be added later.

\documentclass[a4paper,10pt]{article}
\usepackage{graphicx,ifpdf}
\usepackage{ltxkeys}[2011/12/10]
\makeatletter
\ltxkeys@declarekeys*[KV]{importfiles}[fim@]{
  cmd/setorlaunch/set;
  cmd/processor/\includegraphics/
    \ifltxkeys@dec\else
      \ifescapedTF{#1}{}{
        \edef\fim@processor{\noexpandcsn\fim@processor}
      }
      \def\reserved@a##1{
        \def\reserved@a####1##1####2####3\@nil{
          \def\fim@procnr{####2}
          \ifx\fim@procnr\@nnil
            \@latex@error{Unknown processor \unexpanded{##1}}\@ehc
          \fi
        }%
        \reserved@a\includegraphics{0}\input{1}\include{2}##1{\@nil}\@nil
      }%
      \s@expandarg\reserved@a\fim@processor
    \fi;
  cmd/stuffbefore//;
  cmd/stuffafter//;
  cmd/fileext/tex/
    \ifpdf
      \ifinsetTF{#1}{,pdf,png,jpeg,jpg,mps,}
        {
          \edef\fim@graphicsext{#1}
        }{
          \def\fim@graphicsext{pdf}
        }
    \else
      \def\fim@graphicsext{eps}
    \fi;
  cmd/inputpaths/./
    \ifltxkeys@dec\else
      \def\fim@inputpaths{}
      \edef\fim@tempa{#1}
      \fim@stripbraces\fim@tempa
      % \openin will not take spaces in path or filename:
      \edef\fim@tempa{\s@expandarg\cptzapspaces\fim@tempa}
      \docommalist*\fim@tempa{
        \xifinsetTF{/\relax}{##1\relax}{
          \edef\fim@inputpaths{\fim@inputpaths\ifbracedTF{##1}{##1}{{##1}}}
        }{
          \@latex@error{Inputpath '##1' not ended with slash (/)}\@ehc
        }
      }
    \fi;
  cmd/inputpath/./\setaliaskey{inputpaths};
  cmd/scale/1;
  cmd/\needvalue{width}//;
  cmd/\needvalue{height}//;
  cmd/\needvalue{viewport}/0 0 100 100;
  bool/clip/true;
  choice/align.{
    center/\def\fim@align{center},
    left/\def\fim@align{flushleft},
    right/\def\fim@align{flushright},
    justified/\def\fim@align{fim@phantomenv}
  }/center;
}
% Why didn't I want to say \let\fim@phantomenv\relax?
\new@def*\fim@phantomenv{\relax}
\robust@def*\fim@stripbraces#1{%
  \cptstripallbrincs#1\despacecontent#1\cptstripallbrincs#1%
}
\robust@def*\importfiles{\cpt@testopt\fim@importfiles{}}
\robust@def*\fim@importfiles[#1]#2{%
  \usename{ltxkeys@\fim@setorlaunch keys}[KV]{importfiles}{#1}%
  % Some paths might have been suggested via \input@path
  % and/or \graphicspath. So we heed them here.
  \edef\fim@currpaths{%
    \ifdefTF\input@path\input@path{}%
    \ifdefTF\Ginput@path\Ginput@path{}%
    \fim@inputpaths
  }%
  \edef\fim@tempa{\ifmacroTF{#2}\expandcsonce\unexpanded{#2}}%
  \docommalist*\fim@tempa{%
    \def\currfile{##1}%
    \fim@stripbraces\currfile
    \def\siso@do####1{%
      \def\currpath{####1}%
      \fim@stripbraces\currpath
      \ifnum\fim@procnr=\z@pt
        \let\currfileext\fim@graphicsext
      \else
        \let\currfileext\fim@fileext
      \fi
      \edef\fileonpath{\currpath\currfile.\currfileext}%
      % Hmm, why don't I want to use \IfFileExists?
      \openin\@inputcheck\fileonpath\relax
      \ifcondTF\ifeof\@inputcheck\fi{}{%
        \typeout{File '\fileonpath' found}%
        \closein\@inputcheck
        \fim@doimport
      }%
    }%
    \s@expandarg\siso@@loop\fim@currpaths
  }%
}
\robust@def*\fim@doimport{%
  \fim@stuffbefore
  \begintoksgroup
  \ifcase\fim@procnr
    \toks@{%
      \begin{\fim@align}%
      \cptexpanded{%
        \noexpand\includegraphics
        [viewport=\fim@viewport,scale=\fim@scale,
        \ifcsemptyTF\fim@height{}{height=\fim@height,}%
        \ifcsemptyTF\fim@width{}{width=\fim@width,}%
        \iffim@clip,clip\fi]{\fileonpath}%
      }%
      \end{\fim@align}%
    }%
  \or
    \toks@{\input\fileonpath}%
  \or
    \toks@{%
      \let\fim@savpath\input@path
      \edef\input@path{{\currpath}}%
      \fiminclude\currfile
      \let\input@path\fim@savpath
    }%
  \fi
  \endtoksgroup
  \fim@stuffafter
}
\robust@def*\fiminclude#1{%
  \relax
  \ifnumcmpTF\@auxout=\@partaux{%
    \@latex@error{Command \noexpand\fiminclude cannot be nested}\@ehc
  }{%
    \edef\reserved@a{\cptzapspaces{#1}}%
    \s@expandarg\fim@include\reserved@a
  }%
}
\robust@def*\fim@include#1{%
  \xifinsetTF{.tex\relax}{#1\relax}{%
    \def\reserved@a##1.tex\@nil{%
      \def\fim@filename{##1}%
    }%
    \reserved@a#1\@nil
  }{%
    \def\fim@filename{#1}%
  }%
  \clearpage\relax
  \if@partsw
    % I don't know why LaTeX chose to do a loop here. We don't need it here:
    \xifinsetTF{,\fim@filename,}{,\fim@partlist,}%
      \@tempswatrue\@tempswafalse
  \else
    \@tempswatrue
  \fi
  \ifboolTF{@tempswa}{%
    \if@filesw
      \immediate\write\@mainaux{\string\@input{\fim@filename.aux}}%
    \fi
    \let\@auxout\@partaux
    \if@filesw
      \immediate\openout\@partaux\fim@filename.aux
      \immediate\write\@partaux{\relax}%
    \fi
    \@input@{\fim@filename.tex}%
    \clearpage\relax
    \@writeckpt{\fim@filename}%
    \if@filesw
      \immediate\closeout\@partaux
    \fi
  }{%
    \deadcycles\z@pt
    \@nameuse{cp@\fim@filename}%
  }%
  \let\@auxout\@mainaux
}
\robust@def*\fimincludeonly#1{%
  \@partswtrue
  \cptexpandarg{\cptfiltermergecsv\fim@partlist}
    {\cptzapspaces{#1}}\nofilter
}
\cptonlypreamble\fimincludeonly
\makeatother

\fimincludeonly{subfile1a}
\begin{document}
\section{Test section}

\importfiles[
  processor   =includegraphics,
  viewport    =20 21 590 400,
  scale       =.25,
  inputpaths  ={D:/MyTempDoc/Path1/,D:/MyTempDoc/Path2/},
  stuffbefore =\bigskip\centering Importing \currfile\space from path \currpath\endgraf,
  stuffafter  =\endgraf\centering File import succeeded (\currfile).\endgraf
]{
  comet1
}

\importfiles[
  processor   =include,
  inputpaths  ={D:/MyTempDoc/Path1/,D:/MyTempDoc/Path2/}
]{
  subfile1a,subfile1b,subfile1c
}

\importfiles[
  processor   =\input,
  inputpaths  ={D:/MyTempDoc/Path1/,D:/MyTempDoc/Path2/}
]{
  subfile1a,subfile1b,subfile1c
}
\end{document}

This is only a partial listing of the code. The full version can handle stand-alone documents in the manner of docmute and standalone packages. I will release it as a package.

enter image description here enter image description here

Ahmed Musa
  • 11,742