4

I am collaborating on a project that started off with images stored on a server. Since everyone had a different path to get to this server I took advantage of a \graphicspath declaration in the main tex file so that everyone could access the files. Recently, people have started working offline, but still expect the document to compile.

There are several good questions around that demonstrate how to do a IfFileExists check and replace with an alternative. Unfortunately I haven't yet found a version that successfully iterates through the specified graphics paths. Both file paths and names contain underscores and spaces. I am not a fan of this but I am stuck with this.

I was reading here: https://tex.stackexchange.com/a/3132/69378 a very clear answer that when \includegraphics{<thegraphic>} is called it actually iterates through each \graphicspath and checks it with \IfFileExists{<thepath><thegraphic>.pdf}.

The function is in the MWE below, and it will only return the missing figures even if a file exists (but in a graphicspath specified base), because I accidentally overlooked the fact that just because the path passed to to the function works for \includegraphics doesn't mean the same iteration will apply to IfFileExists.

I tried to go to the sty files for graphicx and graphicsbut I didn't see any looping syntax I recognized.

Is it difficult to add a loop to check each path in graphics path to this new command that contains the IfFileExists request?

Note: I am going the newcommand approach because I couldn't get the patch proposed here: https://tex.stackexchange.com/a/39987/69378 working with file extensions and spaces. But it's possible that time would be better spent getting the proposed patch working because it patches an already iterated command.

\documentclass{article}
\usepackage{todonotes}
\usepackage{graphicx}
\usepackage{xparse}
\usepackage{caption}
\usepackage[format=hang,singlelinecheck=0,font={sf,small},labelfont=bf]{subfig}

\graphicspath{%
    {S://}
    {../../../}
}

%S:\latex\MWE_Tex-StackExchange\2016-04-25 missing figures

%https://tex.stackexchange.com/questions/75014/is-it-possible-to-make-a-reference-to-a-subfigure-to-appear-figure-2a-with-cle
\captionsetup[subfigure]{subrefformat=simple,labelformat=simple,listofformat=subsimple}
\renewcommand\thesubfigure{\Alph{subfigure}}
\DeclareDocumentCommand{\MyIncludeGraphics}{ O{} +m }
{%
    \IfFileExists{"#2"}
    {%
        \includegraphics[#1]{"#2"}%
    }{%
        \missingfigure[figwidth=7.0cm]{Missing "#2"}%
    }%
}
\makeatletter

\renewcommand{\missingfigure}[2][]{% modified from todonotes.sty
  \setkeys{todonotes}{#1}%
  \addcontentsline{tdo}{todo}{\@todonotes@MissingFigureText: \protect\detokenize{"#2"}}%
  \par
  \noindent
  \begin{tikzpicture}
    \draw[fill=\@todonotes@currentfigcolor, draw = black!40, line width=2pt]
    (-2, -2.5) rectangle +(\@todonotes@currentfigwidth, \@todonotes@currentfigheight);
    \draw (2, -0.3) node[right, text width=\@todonotes@currentfigwidth-4.5cm] {\detokenize{#2}};
    \draw[red, fill=white, rounded corners = 5pt, line width=10pt]
    (30:2cm) -- (150:2cm) -- (270:2cm) -- cycle;
    \draw (0, 0.3) node {\@todonotes@MissingFigureUp};
    \draw (0, -0.3) node {\@todonotes@MissingFigureDown};
  \end{tikzpicture}\hfill
}
\makeatother
\begin{document}
\begingroup
    \begin{figure}[ht!]
    \subfloat{\label{fig:A}\MyIncludeGraphics[width=0.5\textwidth]{figure_A_On_S.jpg}}%
    \subfloat{\label{fig:B}\MyIncludeGraphics{example_image_b.jpg}}%
    \caption[CAPTION UNDER DEVELOPMENT Grin lens design and performance]{%
        FIGURE NOT FINAL - CAPTION UNDER DEVELOPMENT \\
    }
\end{figure}
\endgroup
\listoftodos
\end{document}

Update

The solution below works very well for every instance except file names with spaces.

I think I have tried every possible permutation I could find of \detokenize and " around variables etc, with no avail. Adding the quotes seem to be read literaly when checking if a file exists.

I have loaded \usepackage[space]{grffile}, but if I understand how it works, this won't help unless I am using \includegraphics. The modification to allow spaces wont work unless I can find a way to maybe duplicate this code with my new imagetest function, thanks to Ulrike Fischer in the answer below.

let\grffile@org@Ginclude@graphics\Ginclude@graphics
\renewcommand*{\Ginclude@graphics}{%
  \ifx\grffile@filenameencoding\@empty
  \else
    \ifx\grffile@inputencoding\@empty
      \expandafter\ifx\csname inputencodingname\endcsname\relax
        \expandafter\ifx\csname
            CurrentInputEncodingOption\endcsname\relax
        \else
          \let\grffile@inputencoding\CurrentInputEncodingOption
        \fi
      \else
        \let\grffile@inputencoding\inputencodingname
      \fi
    \fi
    \ifx\grffile@inputencoding\@empty
    \else
      \grffile@extendedcharstrue
    \fi
  \fi
  \ifnum0\ifgrffile@babel 1\fi\ifgrffile@extendedchars 1\fi>\z@
    \begingroup
      \ifgrffile@babel
        \csname @safe@activestrue\endcsname
        \edef~{\string~}%
      \fi
      \ifgrffile@extendedchars
        \grffile@inputenc@loop\^^A\^^H%
        \grffile@inputenc@loop\^^K\^^K%
        \grffile@inputenc@loop\^^N\^^_%
        \grffile@inputenc@loop\^^?\^^ff%
      \fi
      \expandafter\grffile@extchar@Ginclude@graphics
  \else
    \expandafter\grffile@Ginclude@graphics
  \fi
}
  • Hm, isn't this the loop in graphics.sty???: \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}% – user31729 Apr 28 '16 at 14:18
  • @ChristianHupfer Thanks! I really didn't recognize that. I will update my question later with my efforts in including the for loop. Hopefully successfully, I haven't worked much with TeX in this style before so I look forward to diving in this afternoon. – EngBIRD Apr 28 '16 at 16:11
  • The LaTeX core provides some nice features, sometimes they are a little bit hard to use – user31729 Apr 28 '16 at 16:33
5

You are really trying to make your questions difficult to read. Why are you adding all these unnecessary details? If you want to test if an graphics exists you can try this: (from Check for a valid file before using \includegraphics)

\documentclass[]{article}
\usepackage{graphicx,todonotes}

\makeatletter
\newif\ifgraphicexist

\catcode`\*=11
\newcommand\imagetest[1]{%
 \begingroup
 \global\graphicexisttrue
   \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
       \global\graphicexistfalse
       \def\Gin@base{\filename@area\filename@base}%
       \edef\Gin@ext{\Gin@sepdefault\filename@ext}%
    \fi
  \fi
  \ifx\Gin@ext\relax
         \global\graphicexistfalse
    \else
       \@ifundefined{Gin@rule@\Gin@ext}%
         {\global\graphicexistfalse}%
         {}%
    \fi
  \ifx\Gin@ext\relax
   \gdef\imageextension{unknown}%
  \else
   \xdef\imageextension{\Gin@ext}%
  \fi
 \endgroup
 \ifgraphicexist
  \expandafter \@firstoftwo
 \else
  \expandafter \@secondoftwo
 \fi
 }
\catcode`\*=12

\newcommand\myincludegraphics[2][]{%
 \imagetest{#2}{\includegraphics[#1]{#2}}{\missingfigure{\detokenize{#2}}}}

\makeatother
\graphicspath{{test/}}

\begin{document}

\myincludegraphics{blub}

\myincludegraphics{test-convert}

\myincludegraphics{example-image-A.pdf}

\end{document}
  • I am really sorry my question is hard to read. I haven't done a good job balancing the MWE with my previous efforts (probably because I haven't selected a good approach), and requirements. Thanks for your answer, it's well above my level so I working now to annotate it so that I can post back with a followup as at the moment it works, but only for the sample figures in your MWE. Still troubleshooting, but I think it's not handling spaces and underscores. I am also experimenting to see if the \@for\Gin@temp:=\Gin@extensions\do part can be wrapped around the function I allready wrote. – EngBIRD Apr 28 '16 at 16:20
  • I added a \detokenize for the missing figures text. This should handle underscores. Regarding the spaces: I'm a quite hard core "don't use spaces in filenames". So if you need them you will have to find out where to add quotes yourself (you could try the grffile package). – Ulrike Fischer Apr 28 '16 at 16:42
  • Thanks, I spent a couple days non-stop trying to address the space issue, but with no success. Thanks for this cool looping version of the graphics code, eventually I may know enough to allow this to work with spaces. – EngBIRD May 2 '16 at 17:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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