203

\includegraphics cannot handle filenames that contain more than the one dot, separating the filename from the extension. Apparently it uses everything after the first dot as extension and then, of course, complains about an unknown graphics extension.

This is annoying as I very often have filenames that contain parameter values, e.g. plot_a0.4_b0.6.pdf.

Is there a way to teach LaTeX to interpret only the string behind the last dot as extension?

lockstep
  • 250,273

5 Answers5

233

You can hide the other dots by masking them from TeX's token scanner with { }, i.e.:

\includegraphics{{plot_a0.4_b0.6}.pdf}

works fine.

Note that the extension can also be dropped, then a list of default extensions is used. See the graphicx manual for more information. If you want to do this, you need to double group the filename, which makes three together with the one for the arguments:

\includegraphics{{{plot_a0.4_b0.6}}}
lockstep
  • 250,273
Martin Scharrer
  • 262,582
  • 4
    @uenfundachtzig: I find grffile easier as it provides other features too (like spaces in filenames). – Martin Schröder Dec 31 '11 at 11:46
  • 1
    @MartinSchröder Definitely easier .. when it is supported by your other packages. – kando Jun 10 '16 at 15:52
  • Does this work with any other characters which are typically bounced back? (Spaces, etcetera?) – kando Jun 10 '16 at 15:59
  • 2
    @kando: The dots are special here because the macros looks for a file extension. But it should work with spaces as well, as they are also handles special by the underlying TeX macros. Other, normally problematic characters like underscores should work fine out of the box. – Martin Scharrer Jun 14 '16 at 19:31
  • 2
    Apparently this is no longer the preferred way to do this in 2020. It can lead to problems in newer versions of LaTeX, although it can still be used if the brackets are put around the whole expression. (Before it would also work if we put for example/dir/{name.with.dots}.pdf, but that is no longer the case in recent versions of latex. – Marten Dec 09 '20 at 22:49
  • @Kvothe Someone reading in 2021 might arrive at this post if you do not provide extensions (.png or .pdf) in the argument and the base filename has dots (as in trajectoryAtg=9.8). I generally export my graphics in two extensions .png and .pdf for quick viewing in file explorer and for publication respectively. To avoid errors, declare the extensions apriorily in the preamble \DeclareGraphicsExtensions{.pdf, .png, .jpg}. For more informaton, please refer Section 4.5 of graphics package user manual – baalkikhaal Mar 03 '21 at 13:01
  • I can testify that \includegraphics{/dir/{name.with.dots}.pdf} indeed solves the compilation error with on Debian buster (texlive 2018.20190227-2), while the curly brackets are not necessary anymore on Debian bullseye (texlive 2020.20210202-3). I've not yet made the reverse test (do the addition of {...} breaks the compilation on more recent texlive?) – Pierre H. Oct 07 '21 at 12:47
50

You can use package grffile with option multidot.

https://texfaq.org/FAQ-grffilenames

David Carlisle
  • 757,742
Ulrike Fischer
  • 327,261
  • 8
    Specifying options doesn't seem to be necessary; \usepackage{grffile} was sufficient when I tried it. – Mechanical snail Apr 26 '13 at 20:22
  • 1
    Even works for \includepdf from the pdfpages Package. Excellent! – jakob-r Mar 14 '15 at 23:24
  • grffile is the best. I had to drop it due to compatibility issues with another package I could not part with a couple years ago. It was so sad. I think the perpetrator was KOMA. For me, despite the warnings, KOMA works in harmony with geometry .. why not grffile too. : / – kando Jun 10 '16 at 15:38
6

Actually supporting such file names was part of the initial design spec for graphicx. The filetype is defaulted from the extension but for cases like this there is a type key so you can go type=eps or type=bmp or whatever is needed.


(copying an answer from a question marked as duplicate of this one)

For example, to tell latex it is eps type and the extension to use for the file itself and to find the bounding box, you can use:

\documentclass{article}

\usepackage{graphicx}

\begin{document}


\includegraphics[width=5cm,type=eps,ext=.1.eps,read=.1.eps]{example}

\end{document}

this includes example.1.eps using xelatex, or latex/dvips etc.

David Carlisle
  • 757,742
  • 3
    That doesn't work for me (at least for type=pdf and type=png): either LaTeX complains wrongly that it cannot find image size, or (after giving size as parameters) fails with division by zero error. – Jakub Narębski Aug 02 '12 at 15:53
  • latex can't read the image size so you need to give it in the arguments or in a matching .bb file with a postscript style bounding box comment. I would guess you used the arguments and went height=1cm that gives div by zero as that is a scale option to resize the figure so it divides the requested height by the natural size (which is still set to 0). You need to use the bb key or natheight=1cm, natwidth=1cm to set the natural height. – David Carlisle Aug 02 '12 at 15:57
  • I have used bb (and ext=.pdf) and it didn't work -- still "ERROR: LaTeX Error: Cannot determine size of graphic in CUDA_4.0_Math_Libraries_Performance_6_14.p4-crop.pdf (no size specifed).". I didn't know about the difference between height and natheight and that I should have used the latter. – Jakub Narębski Aug 02 '12 at 16:07
  • FYI: The command was: \includegraphics[type=pdf,ext=.pdf,bb=0 0 595 842]{CUDA_4.0_Math_Libraries_Performance_6_14.p4-crop} and the file was CUDA_4.0_Math_Libraries_Performance_6_14.p4-crop.pdf (the bounding box was taken from converted to PostScript). – Jakub Narębski Aug 02 '12 at 16:10
  • hmm cuda math libraries, too close to the day job:-) I think those arguments should work (if it doesn't, it's possible my former self did something wrong I may test later...) – David Carlisle Aug 02 '12 at 16:33
  • Actually pdflatex says that bb doesn't make sense ( "Package pdftex.def Warning: Option bb does not make sense" ), and it doesn't help; the natheight and natwidth doesn't help either (BoudingBox is in pt, isn't it?) -- still "Cannot determine size of graphic", and width + height result in division by 0. – Jakub Narębski Aug 03 '12 at 14:00
  • bounding box comments is bp (postscript points) or I seem to remember that if you use the bb key I allowed optional units. But it shouldn't be needed anyway as (unlike classic tex and eps files) pdftex reading pdf can read the included pdf to determine its natural size. Can't look now. – David Carlisle Aug 03 '12 at 14:09
4

It is possible to automate Martin Scharrer's routine:

\documentclass{article}
\usepackage{catoptions}
\usepackage{graphicx}
\makeatletter
\def\parsegraphicsfilename#1{%
  \begingroup
  \def\flname{}\def\flext{}%
  \def\updateflname##1{%
    \edef\flname{\ifcsnullTF\flname{}{\flname.}##1}%
  }%
  \ifinsetTF{.}{#1}{%
    \def\reserved@a##1.##2\@nil{%
      \ifinsetTF{.}{##2}{%
        \updateflname{##1}%
        \reserved@a##2\@nil
      }{%
        \updateflname{##1}%
        \ifinsetTF{,##2,}{,eps,pdf,png,jpeg,jpg,mps,}{%
          \def\flext{##2}%
        }{%
          \updateflname{##2}%
        }%
      }%
    }%
    \reserved@a#1\@nil
    \ifcsnullTF\flname{%
      \@latex@error{Filename is empty;
        \ifcsnullTF\flext{}{ extension '\flext'}}\@ehc
    }{%
      \edef\flname{\ifcsnullTF\flext{{{\flname}}}{{\flname}.\flext}}%
    }%
  }{%
    \def\flname{#1}%
  }%
  \postgroupdef\flname\endgroup
}
\robust@def*\newincludegraphics{%
  \cpt@testopt\new@includegraphics{}%
}
\def\new@includegraphics[#1]#2{%
  \parsegraphicsfilename{#2}%
  \includegraphics[#1]{\flname}%
}
\makeatother 

Examples

\begin{document}
\def\result{{\tt\detokenize\expandafter{\flname}}\endgraf}
\parsegraphicsfilename{xx}
\result
\parsegraphicsfilename{xx.yy}
\result
\parsegraphicsfilename{xx.yy.pdf}
\result
\parsegraphicsfilename{xx.yy.zz.}
\result
\parsegraphicsfilename{plot_a0.4_b0.6.pdf}
\result
% The next one gives error because there is no filename:
%  \parsegraphicsfilename{.pdf}
\end{document}

Real-life application:

\newincludegraphics[scale=1.2,clip]{my..image.file.with..many.dots.ex.pdf}

Sample output

Ahmed Musa
  • 11,742
3

While the question is answered for the generic case - I often have a case, where I have files with constant (unchanging), yet unstandard extensions; and where I'd like to use these files as input "as is" to pdflatex in a batch script context (meaning, I wouldn't want to code any parsing logic in respect to filenames, either in the Latex code, or the batch code).

For instance, the usual \includegraphics{mydir/file01.csv_.pdf} would fail with:

! LaTeX Error: Unknown graphics extension: .csv_.pdf.

One thing that works, is as per the answer by @DavidCarlisle:

\includegraphics[ext=.csv_.pdf,type=pdf,read=*]{mydir/file01}

... but this requires me to strip the extension from the filename, so I'd have to introduce filename parsing logic somewhere.

However, what really works for me is using \DeclareGraphicsRule{ext}{type}{read-file}{command} (see grfguide.pdf: Packages in the 'graphics' bundle):

% preamble:
\DeclareGraphicsRule{.csv_.pdf}{pdf}{*}{}

% ...

\begin{document}

% ...

\includegraphics{mydir/file01.csv_.pdf}

... and this seems to work fine, without any changes to the filename argument of \includegraphics. Note that command argument can be left empty (it's for a system conversion otherwise), and read-file is where do we read the size/bounding box information from: since the .csv_.pdf is a .pdf file proper, with * we simply say - read the size from the same file that has matched the declared extension.

sdaau
  • 17,079