Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I have a set of pictures in my working directory and I want to make a PDF report using these images. I want to include all of them, but the number of the pictures changes in each case. I would like to make a "for" loop to insert each picture one after the other sequentially. Can anyone can help me? At the moment the code I have is the following:

\caption[Sèries temporals de vent i direccions]{Sèries temporals velocitat de vent i     direccions. filtratge de pics i glaçades de velocitat.}


I would like to do it for every .png image in the directory. Thanks for your questions: I'm using Windows 7 and the files names follow the pattern Figura1.png, Figura2.png and so forth. So which of these possibilities would fit best?

share|improve this question

migrated from stackoverflow.com Apr 26 '12 at 16:30

This question came from our site for professional and enthusiast programmers.

I don't know of an (easy) way that can traverse a directory from within LaTeX and apply a certain command for each file. There is PerlTeX, wich might be the easiest-to-use candidate for this job within LaTeX. However, PerlTeX is as far as I know not installed by default (in common LaTeX distros such as TexLive or MikTeX), and if you use PerlTex, you have to invoke LaTeX with some special flags. If you, however, do it "outside" from LaTeX, i.e. you set up a script that generates that very part of your document automatically, than you have to run this script and afterwards you can call LaTeX. –  phimuemue Apr 26 '12 at 10:59
Are you on Windows, or Unix (Mac/Linux)? Are the files named in a systematic format? If the files have a controlled naming format you could consider using How to iterate through the name of files in a folder –  Peter Grill Apr 26 '12 at 16:37

5 Answers 5

Using the wonderful python.sty package (see github) and some embedded python code, this is very easy:




import os
directory = "."
extension = ".png"
files = [file for file in os.listdir(directory) if file.lower().endswith(extension)]

for file in files:
   print r"\begin{figure}[!ht]"
   print r"\centering"
   print r"\includegraphics[width=10cm,height=10cm]{%s}" % file
   print r"\caption{File %s}" % file
   print r"\label{Serie}"
   print r"\end{figure}"


Notice that you need to compile with the --enable-write18 option in order to run the python code.

share|improve this answer
It might be simpler to generate the code with python (or whatever softaware or language you used to generate the figures) using a similar syntax and copy and paste it. I often do it with R and MATLAB. –  Alfred M. Apr 26 '12 at 19:05
Does it runs under Windows 7 too? Could you explain me this sentence please? files = [file for file in os.listdir(directory) if file.lower().endswith(extension)] –  Jonel_R Apr 28 '12 at 9:23
@Jonel_R: the line files = [file for file in os.listdir(directory) if file.lower().endswith(extension)] first constructs the list os.listdir(directory) and then filters it by the condition file.lower().endswith(extension). –  Yori Apr 28 '12 at 19:02
@Jonel_R: Yes, from now on, the github version of python.sty should work on Windows too. –  Yori Apr 29 '12 at 3:16
I am haviong real problems using python. See stackoverflow.com/questions/10385232/python-in-latex pleae. –  Jonel_R Apr 30 '12 at 15:17

If your system is a Unix one, the following set of macros will do, but they require that the file is compiled with pdflatex -shell-escape:

  \etex_everyeof:D { \exp_not:N }
  \tex_endlinechar:D \c_minus_one
  \seq_gset_split:Nnx \g_figloop_names_seq { , }
    { \tex_input:D |"ls ~ -m ~ #1*.png" ~}
  \seq_map_inline:Nn \g_figloop_names_seq { \dofigureloop { ##1 } }
\cs_generate_variant:Nn \seq_gset_split:Nnn {Nnx}
\seq_new:N \g_figloop_names_seq

\NewDocumentCommand \dofigureloop {m}
  \caption[Sèries temporals de vent i direccions]
          {Sèries temporals velocitat de vent i direccions. Filtratge de pics i glaçades de velocitat.}




The argument to \figureloop is the common part in the names of your figures. It might be generalized to different extensions.

The \tex_input:D |"ls~-m~#1*.png"~ bit loads the output of the ls command sent via shell-escape to the operating system. This output is stored in a sequence that is then split. Then a mapping function is called on the sequence, its argument is exactly a file name and the macro called just typesets the necessary figure environment. A label in the form Serie-<filename> is also generated.

With a different shell command this may be adapted also to Windows systems.

share|improve this answer

Suppose your pictures are all following certain naming convention (here I used pic1.png up to pic4.png), the lipsumpackage is just for the dummy text:



\foreach \x in {1,2,3,4}
{ \lipsum[\x]


Alternatively, you can specify tuples of variable to iterate over. The following does the same:

\foreach \x/\picname in {4/pic1.png,8/pic2.png,15/pic3.png,16/pic4.png}
{ \lipsum[\x]
        \caption{The very nice picture \x}

And the output being:

enter image description here

share|improve this answer
Just another solution with the same constraint. –  stalking is prohibited Apr 28 '12 at 12:00


I want to expand my first answer with an easy to understand approach based on LaTeX3 (pdflatex). Because it follows the same principle like the LuaLaTeX answer I gave (see for explanation), I don't want to separate it from my original answer. So one can compare the two solutions and see how easy it is to use some basics of LaTeX3. As in the LuaLaTeX solution one is independent from external scripting languages, shell commands and specific operating systems.



% new bool for the loop condition
\bool_new:N \runWhileLoop    
% new integer for the filename counter
\int_new:N \counter

% create a new latex command
% #1 filename base
% #2 file extension
    % set the condition to 'true'
    \bool_set_true:N \runWhileLoop        
    % set the counter to '0'
    \int_zero:N \counter

    % run the loop until '\runWhileLoop' is set to 'false' 
    \bool_while_do:Nn {\runWhileLoop}
        % increment the counter   
        \int_incr:N \counter            
        % merge the given arguments to a filename

        % check if the file exists
        \file_if_exist:nTF {\fileName}
            % file exists
            % there is no file with the given name
            % break the loop
            \bool_set_false:N \runWhileLoop




I think this is a good job for LuaLaTeX. You are independent of the operating system and any external scripts. In this example there is a lua function which concatenates a filename, checks if the file exists and put the picture to the 'figure' environment. You don't have to know how many files are in the folder and you can reuse the given function with different (base)filenames and extensions.

It is good practice to write the lua functions in a separate file with the extension .lua. For this MWE I use the filecontents environment to do so.


%create a lua script file
function PrintImages(name, extension)

    local i = 1
    local filename = ""

    while true do    
        --concatenate the filename
        filename = name..i..extension
        i = i + 1

        if FileExists(filename) then

            tex.print(string.format("\\includegraphics[width=15cm, height=10cm]{"..filename.."}"))

            --if the file doesn't exists break the while loop

--checks if a file exists
function FileExists(fileName)
    -- try to open the file
    local file = io.open(fileName, "r")

    -- if the file exists close the file and return true
    if file ~= nil then
        return true
        return false

% read the external lua file to declare the functions,
% but without execute the Lua commands and functions

% latex commands to execute the lua functions
\def\printImages#1#2{\directlua{PrintImages("#1", "#2")}}

%choose what type of images you want to print
share|improve this answer

Compile the following with pdflatex -shell-escape filename.tex. Only for Windows users.

% filename.tex

\edef\subdir{"Sub Dir/"}

\immediate\write18{cmd /c dir /b \subdir\space *.png > imagelist.txt}

    \readline\reader to \data


  • It can accept spaces in the file name or path.
  • It can import images from any sub directory.
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.