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 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?

share|improve this question
    
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}}}} –  toussoc May 14 at 14:40
add comment

2 Answers

up vote 24 down vote accepted

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}}}
share|improve this answer
    
Great, exactly what I was looking for! –  cm2 Jan 4 '12 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. –  barbara beeton Jan 4 '12 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 Jan 4 '12 at 17:08
1  
You do not need tikz for this; just put in the "else" part of \IfFileExists 'File #1 is missing`. –  Boris Jan 4 '12 at 17:28
1  
You can have both text and image, for example,\newcommand{\includegraphicsmaybe}[1]{\IfFileExists{#1}{\includegraphic‌​s{#1}}{\makebox[0pt]{File #1 is missing}\includegraphics{dummy.pdf}}} –  Boris Jan 4 '12 at 17:47
show 1 more comment

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.

share|improve this answer
    
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 Jan 4 '12 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 Jan 4 '12 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 Jan 4 '12 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 Jan 4 '12 at 17:41
add comment

Your Answer

 
discard

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.