markdown
markdown copied to clipboard
Implement the `witiko/graphicx/http` LaTeX user theme in Lua
Since version 2.10.0, the Markdown package has supported the witiko/graphicx/http
theme. Currently, the witiko/graphicx/http
LaTeX user theme requires shell access and either GNU Wget or cURL to download images, which reduces security and portability. At BachoTeX 2017, Hans Hagen suggested to use the Luasocket library, which would solve both problems. An example implementation is as follows:
\ProvidesPackage{markdownthemewitiko_graphicx_http}[2021/03/22]%
\RequirePackage{catchfile}
\let\markdown@witiko@graphicx@http@oldRendererImagePrototype
\markdownRendererImagePrototype
\newcount\markdown@witiko@graphicx@http@counter
\markdown@witiko@graphicx@http@counter=0
\newcommand\markdown@witiko@graphicx@http@filename{%
\markdownOptionCacheDir/witiko_graphicx_http%
.\the\markdown@witiko@graphicx@http@counter}%
\begingroup
\catcode`\%=12
\catcode`\^^A=14
\global\def\markdownRendererImagePrototype#1#2#3#4{^^A
\begingroup
\edef\filename{\markdown@witiko@graphicx@http@filename}^^A
\markdownIfOption{FrozenCache}{}{^^A
\directlua{
local url = "#3"
local filename = "\filename"
if string.match(url, "^https?:") then
local md5 = require("md5")
local output_prefix = "\markdownOptionCacheDir"
local output_body = md5.sumhexa(url)
local output_suffix = string.match(url, "%.[^.]*$")
local output = output_prefix .. "/"
.. output_body .. output_suffix
local output_file = io.open(output, "r")
if output_file == nil then
local http = require("socket.http")
local result, status, headers = http.request(url)
if result == nil then
os.remove(filename)
else
output_file = assert(io.open(output, "w"))
assert(output_file:write(result))
assert(output_file:close())
file = assert(io.open(filename, "w"))
assert(file:write(output))
assert(file:close())
end
end
else
file = assert(io.open(filename, "w"))
assert(file:write(url))
assert(file:close())
end
}}^^A
\CatchFileDef{\filename}{\filename}{}^^A
\markdown@witiko@graphicx@http@oldRendererImagePrototype^^A
{#1}{#2}{\filename}{#4}^^A
\endgroup
\global\advance\markdown@witiko@graphicx@http@counter by 1\relax}^^A
\endgroup
\endinput
%%
%% End of file `markdownthemewitiko_graphicx_http.sty'.
Here are the issues with the implementation:
- The
http.request
function does not handle redirects well. For example, it is unable to resolve the URL https://github.com/witiko/markdown/raw/master/banner.png and will always return the 301 HTTP code. Both GNU Wget and cURL can correctly resolve redirects. - The
\directlua
command is unavailable outside LuaTeX. We would like to use an equivalent of the\markdownLuaExecute
command that would not produce any output. Instead, it would just run the Lua code, either using\directlua
, or by executingtexlua
in shell. We can easily solve this one.