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.

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

share|improve this question

5 Answers 5

up vote 73 down vote accepted

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}}}
share|improve this answer
    
Nice and simple solution, thanks! –  fuenfundachtzig Feb 18 '11 at 18:50
2  
@uenfundachtzig: I find grffile easier as it provides other features too (like spaces in filenames). –  Martin Schröder Dec 31 '11 at 11:46

You can use package grffile with option multidot.

http://www.tex.ac.uk/cgi-bin/texfaq2html?label=grffilenames

share|improve this answer
4  
Specifying options doesn't seem to be necessary; \usepackage{grffile} was sufficient when I tried it. –  Mechanical snail Apr 26 '13 at 20:22

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.

share|improve this answer
1  
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 2 '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 2 '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 2 '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 2 '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 2 '12 at 16:33

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

share|improve this answer
    
So many lines for something \usepackage[multidot]{grffile} does automatically... –  Martin Schröder Dec 31 '11 at 11:45
6  
Just an exercise for a bored student on Christmas break. –  Ahmed Musa Dec 31 '11 at 11:53

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.

share|improve this answer

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.