TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

We were just talking about an idea that may be a little further out there. Would it be possible to patch URL support into graphicx.sty or is there a package that would support this on a wider scale (I could imagine it would be useful for pdfpages, listings and similar as well)?

It would need \write18 support obviously, but at least graphicx.sty needs it already for some operations so that shouldn't be a problem. I assume for the general case one would need to define a macro. For graphicx one could cheat a little by defining a .url extension that would have a curl/wget/? rule.

Ideally \includegraphics{http://domain/file.png} would work but I don't see how this would fit into graphicx current context without patching it massively. Alternatively I could see \includegraphics{\grab{http://domain/file.png}} or \includegraphics{http://domain/file.png.url}.

Has someone done this before and wants to share? Is this sane?

share|improve this question
It would probably be possible. The questions is, would it be desirable? – You Dec 28 '12 at 19:03
LuaTeX can do the remote operation itself, and ConTeXt Mark IV certainly can include remote content as a result. Would a LuaTeX-only solution be acceptable? – Joseph Wright Dec 28 '12 at 20:47
I though about having this feature several times, apparently context can handle this very easily (see comments in tex.stackexchange.com/questions/5433/…). Also, a local cache would be desirable, otherwise it will be too slow. @You, I bet you that this is one of those things that once this is implemented everybody will be using it. – alfC Dec 28 '12 at 20:56
I don't know. I just see end-users being surprised that they need an internet connection to typeset a document, that the original URL has 404ed, etc. I don't see the advantage over just wgetting and saving the file in the first place—why should TeX do that for you? – You Dec 28 '12 at 21:00
Hacked together something that may be of interest: the download package. – You Dec 31 '12 at 22:19

I am not really sure how you envision things to work, nor am I convinced that there is a need for this. It seems (to me) more reasonable to first download the image to the local folder (rather than re-downloading for every run), with a filename of your choice rather being automatically derived based on the URL, and then just to include that.

Here's a proof of concept for that, assuming curl is available and \write18 enabled:

\newcommand*{\grabto}[2]{\IfFileExists{#2}{}{\immediate\write18{curl \detokenize{#1 -o #2}}}}



(Image is from an answer to another question of yours.)

share|improve this answer
Thanks, i really like it. I also combined it with parts of tex.stackexchange.com/questions/13226/test-success-of-write18 and it works quite nicely. – Max Dec 29 '12 at 18:35
@Max: Good idea. Feel free to provide a competing answer if you think it is worth sharing. – cyberSingularity Dec 29 '12 at 22:31
up vote 5 down vote accepted

OK Inspired by Joseph Wright's idea of using lua for this i threw together an attempt at this in pure lua.

\directlua 0 {
local uri   = "\luatexluaescapestring{#1}"
local fname = "\luatexluaescapestring{#2}"
local job   = "\luatexluaescapestring{\jobname}"
local file  = io.open(fname, 'r')
if file \string~= nil then 
  % This detection isn't foolproof because this will happily write to a 0200 
  % file for example but latex can't read it and confusingly won't barf, but 
  % this case is pathologic and depending on posix is somewhat unpreferable
  file = io.open(fname, 'w')
  if file == nil then 
    print("(" .. job .. " file " .. fname .. " does exist already but cannot be read)")
    local outputsink = ltn12.sink.file(file)
    local parsed = socket.url.parse(uri, {scheme = 'file'})
    if parsed.scheme ==  'http' then
      socket.http.request { url = uri, sink = outputsink, } 
    elseif parsed.scheme == 'ftp' then
      socket.ftp.get { url = uri, sink = outputsink, } 
      % file scheme doesn't make sense because this branch indicates we 
      % at least couldn't read the file.
      tex.error("Don't know how to download this sorry")
      % This situation is a little annoying because we may have 
      % accidentally created a file and can't delete it in case our heuristics
      % failed
% fallback

This is the first lua I ever touched, so improvements are greatly appreciated. I believe it works for all cases i could come up with. As mentioned in the comment, I tried to come up with a resonable fallback if luatex isn't the compiler, but it get's nasty quick.

I also changed the interface, so it returns #2, because then I can write \includegraphics{\luagrabto{http://i.stack.imgur.com/Bil0Q.png}{test.png}} That works fine for the lua part and for the rudimentary fallback, but \includegraphic really is fussy in some parts and absolutely disliked me playing around with \hyper@normalize to make sure this doesn't blow up for weird urls.

share|improve this answer

Your Answer


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.