我们刚才讨论的是一个可能有点不切实际的想法。是否有可能将 URL 支持修补到其中,graphicx.sty
或者是否有一个软件包可以在更大范围内支持这一点(我可以想象它对 和类似产品都会很有用pdfpages
)listings
?
显然,它需要\write18
支持,但至少graphicx.sty
某些操作已经需要它,所以这应该不是问题。我假设在一般情况下,需要定义一个宏。可以通过定义一个具有/ /? 规则的扩展graphicx
来作弊。.url
curl
wget
理想情况下\includegraphics{http://domain/file.png}
是可行的,但我不明白graphicx
如果不进行大规模修补,这将如何适应当前环境。或者我可以看到\includegraphics{\grab{http://domain/file.png}}
或\includegraphics{http://domain/file.png.url}
。
有人做过这个吗?想分享一下吗?这样做合理吗?
答案1
我不太确定您设想的工作原理,也不相信有此必要。我认为更合理的做法是先将图像下载到本地文件夹(而不是每次运行时都重新下载),并使用您选择的文件名,而不是根据 URL 自动得出文件名,然后仅包含该文件名。
以下是一个概念证明,假设curl
可用且\write18
已启用:
\documentclass{article}
\usepackage{graphicx}
\newcommand*{\grabto}[2]{\IfFileExists{#2}{}{\immediate\write18{curl \detokenize{#1 -o #2}}}}
\grabto{https://i.stack.imgur.com/Bil0Q.png}{test.png}
\begin{document}
\includegraphics{test.png}
\end{document}
(图片来自你另一个问题的回答。)
答案2
好的,受到 Joseph Wright 使用 lua 的想法的启发,我尝试使用纯 lua 来实现这一点。
\newcommand{\grabto}[2]{#2\ifluatex%
\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
io.close(file)
else
% 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)")
else
require("ltn12")
local outputsink = ltn12.sink.file(file)
require("socket.url")
local parsed = socket.url.parse(uri, {scheme = 'file'})
if parsed.scheme == 'http' then
require("socket.http")
socket.http.request { url = uri, sink = outputsink, }
elseif parsed.scheme == 'ftp' then
require("socket.ftp")
socket.ftp.get { url = uri, sink = outputsink, }
else
% 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
end
end
end}%
\else%
% fallback
\fi}
这是我接触的第一个 lua,因此非常感谢改进。我相信它适用于我能想到的所有情况。正如评论中提到的,如果 luatex 不是编译器,我试图想出一个合理的后备方案,但很快就变得很糟糕。
我也改变了界面,所以它返回了#2
,因为然后我可以写
\includegraphics{\luagrabto{https://i.stack.imgur.com/Bil0Q.png}{test.png}}
这对于 lua 部分和基本的后备来说工作得很好,但\includegraphic
在某些部分确实很挑剔,而且绝对不喜欢我摆弄它\hyper@normalize
以确保这不会因为奇怪的 url 而崩溃。