46

I was recently in charge of organizing all of the references and labels in a very large scientific proposal document. My workflow typically involved compiling the document, seeing a "There were undefined references." statement, and then searching the resultant PDF file for the usual "?" or "??."

Sometimes those missing references were in regard to labels for figures that were used throughout the text and not something in our bibliography. It got me wondering:

Is it possible to have a "dummy" or "default" figure to use in \includegraphics statements if the requested file is missing?

Perhaps a use case would be if in the LaTeX document there were a command such as \includegraphics{scaling.pdf}, but scaling.pdf doesn't exist in the current directory, so we use the existing dummy.pdf automatically. I assume this involves renewcommand'ing the includegraphics command, but how should one go about doing it for this scenario?

1
  • Just to say that it can be useful, to avoid error due to filename with underscore, to add \detokenize in the message box for missing file : \newcommand{\includegraphicsmaybe}[1]{\IfFileExists{#1}{\includegraphics{#1}} {\makebox[0pt]{\detokenize{File #1 is missing}}}}
    – user51717
    Commented May 14, 2014 at 14:40

3 Answers 3

56

Try the standard command \IfFileExists. It has three arguments: the file name, what to do if it exists, and what to do if it does not:

\IfFileExists{scaling.pdf}{\includegraphics{scaling.pdf}}{\includegraphics{dummy.pdf}}

Of course, you can add syntactic sugar to this:

\newcommand{\includegraphicsmaybe}[1]{\IfFileExists{#1}{\includegraphics{#1}}{\includegraphics{dummy.pdf}}}
6
  • Great, exactly what I was looking for!
    – cm2
    Commented Jan 4, 2012 at 1:50
  • 3
    instead of (or in addition to) using a dummy figure, it would be informative to show the name of the missing figure in the output. Commented Jan 4, 2012 at 13:41
  • @barbarabeeton: Indeed! My next step was going to write a tikz code that would write the filename overtop of the image.
    – cm2
    Commented Jan 4, 2012 at 17:08
  • 1
    You do not need tikz for this; just put in the "else" part of \IfFileExists 'File #1 is missing`.
    – Boris
    Commented Jan 4, 2012 at 17:28
  • 4
    You can have both text and image, for example,\newcommand{\includegraphicsmaybe}[1]{\IfFileExists{#1}{\includegraphics{#1}}{\makebox[0pt]{File #1 is missing}\includegraphics{dummy.pdf}}}
    – Boris
    Commented Jan 4, 2012 at 17:47
20

The last macro called within graphicx) before including the image is \Gin@ii. Due to the structure of \Gin@ii, it is possible to patch this command and temporarily remove LaTeX error-producing capability. Here's a minimal example:

enter image description here

\documentclass{article}
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\usepackage{graphicx}% http://ctan.org/pkg/graphicx
\newcommand{\noimage}{%
  \setlength{\fboxsep}{-\fboxrule}%
  \fbox{\phantom{\rule{150pt}{100pt}}}% Framed box
}

\makeatletter
\patchcmd{\Gin@ii}
  {\begingroup}% <search>
  {\begingroup\renewcommand{\@latex@error}[2]{\noimage}}% <replace>
  {}% <success>
  {}% <failure>
\makeatother

\begin{document}
\includegraphics[width=150pt]{tiger} \par
\includegraphics[width=150pt]{tigers}
\end{document}

In the above example, the command \noimage is used to represent the output that is generated when no image exists. You could, for example, define \noimage using

\newcommand{\noimage}{\includegraphics{dummy}}

if you wish to include dummy instead of my 150pt x 100pt empty rectangle. The redefinition of \@latex@error (which takes 2 arguments that is gobbles and replaces with \noimage) occurs inside a group, making it local and is therefore reverted back after \Gin@ii finishes.

Here is the final macro called within \Gin@ii called \Ginclude@graphics; I've highlighted the part that is indirectly affected by the redefinition of \@latex@error:

\def\Ginclude@graphics#1{%
  \begingroup
  \let\input@path\Ginput@path
  \filename@parse{#1}%
  \ifx\filename@ext\relax
    \@for\Gin@temp:=\Gin@extensions\do{%
      \ifx\Gin@ext\relax
        \Gin@getbase\Gin@temp
      \fi}%
  \else
    \Gin@getbase{\Gin@sepdefault\filename@ext}%
    \ifx\Gin@ext\relax
       \@warning{File `#1' not found}%
       \def\Gin@base{\filename@area\filename@base}%
       \edef\Gin@ext{\Gin@sepdefault\filename@ext}%
    \fi
  \fi
    \ifx\Gin@ext\relax
         \@latex@error{File `#1' not found}% <----------------------------- MODIFIED
         {I could not locate the file with any of these extensions:^^J% <-- MODIFIED
          \Gin@extensions^^J\@ehc}% <-------------------------------------- MODIFIED
    \else
       \@ifundefined{Gin@rule@\Gin@ext}%
         {\ifx\Gin@rule@*\@undefined
            \@latex@error{Unknown graphics extension: \Gin@ext}\@ehc
          \else
            \expandafter\Gin@setfile\Gin@rule@*{\Gin@base\Gin@ext}%
           \fi}%
         {\expandafter\expandafter\expandafter\Gin@setfile
             \csname Gin@rule@\Gin@ext\endcsname{\Gin@base\Gin@ext}}%
    \fi
  \endgroup}

The advantage with this approach is that you don't have to modify any of your existing macro definitions, like \includegraphics. It would be possible to extend this to indicate the offending (missing) file as well.

6
  • Actually it is better to patch \Gin@getbase command. In one of my (yet unpublished) packages I patched it to select print version of a graphics for print version, web version of graphics for web version and the default version if the special version did not exist.
    – Boris
    Commented Jan 4, 2012 at 15:55
  • @Werner: Thanks for this alternative approach. Although it is more involved, I do like that fact that I don't have to modify the \includegraphics macro.
    – cm2
    Commented Jan 4, 2012 at 17:10
  • 1
    @cm2: Remember, the only code required to do this is everything between \makeatletter and \makeatother. Showing \Ginclude@graphics at the end of my answer was just an illustration of what \patchcmd modifies within the command. I don't think it's that much more involved...
    – Werner
    Commented Jan 4, 2012 at 17:20
  • @Werner: Indeed, you are correct. I guess by "more involved," I simply meant that you had to modify some internal functionality. The amount of work involved is similar.
    – cm2
    Commented Jan 4, 2012 at 17:41
  • it seems not to work with beamer. I get \end{frame} error.
    – luchonacho
    Commented Feb 5, 2018 at 14:58
3

Based on the other answers, I have come up with the following code to ignore missing image files in a latex document.

The advantage of this answer over the others is that it deals with the optional arguments of \includegraphics, it doesn't require a dummy.pdf file and it doesn't require changing any of the \includegraphics commands in the body of the document.

% deal with missing images which are not directly included in the repository
\newcommand{\noimage}{%
  \setlength{\fboxsep}{-\fboxrule}%
  \fbox{\phantom{\rule{10pt}{10pt}}File missing\phantom{\rule{10pt}{10pt}}}% Framed box
}
\let\includegraphicsoriginal\includegraphics
\renewcommand{\includegraphics}[2][width=\textwidth]{\IfFileExists{#2}{\includegraphicsoriginal[#1]{#2}}{\noimage}}
6
  • 2
    I think it should be \renewcommand{\includegraphics}[2][width=\textwidth]..., otherwise it'll raise an error. Commented Sep 4, 2018 at 11:41
  • It doesn't raise an error for me and I cannot find any source which says the (default) arguments to a (re)newcommand should be named in that way. Commented Sep 6, 2018 at 8:26
  • 1
    It's not about how the default arguments to \renewcommand should be named (they could be named \HappyPotatoes for that matter). It's about how \includegraphicsoriginal will understand these arguments. \textwidth is not a valid option for \includegraphics. Commented Sep 6, 2018 at 10:33
  • What do you mean by named? \includegraphics expects a specific format for optional arguments and in the best case your pass-through will yield something unexpected.
    – TeXnician
    Commented Sep 6, 2018 at 10:34
  • I'm sorry, my head was in the wrong place. I've edited the answer and fixed the mistake you pointed out. Commented Sep 6, 2018 at 13:28

You must log in to answer this question.

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