131 lines
3 KiB
Lua
131 lines
3 KiB
Lua
local env_types = {
|
|
theorem = true,
|
|
lemma = true,
|
|
proposition = true,
|
|
corollary = true,
|
|
definition = true,
|
|
example = true,
|
|
remark = true,
|
|
proof = true,
|
|
}
|
|
|
|
local function has_class(el, class_name)
|
|
for _, value in ipairs(el.classes) do
|
|
if value == class_name then
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function first_env_class(el)
|
|
for _, value in ipairs(el.classes) do
|
|
if env_types[value] then
|
|
return value
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
local function latex_escape(value)
|
|
value = tostring(value or "")
|
|
value = value:gsub("\\", "\\textbackslash{}")
|
|
value = value:gsub("([{}%%$&#_])", "\\%1")
|
|
value = value:gsub("%^", "\\textasciicircum{}")
|
|
value = value:gsub("~", "\\textasciitilde{}")
|
|
return value
|
|
end
|
|
|
|
local function internal_link_to_cref(el)
|
|
if FORMAT:match("latex") and el.target:sub(1, 1) == "#" then
|
|
local label = el.target:sub(2)
|
|
if label ~= "" then
|
|
return pandoc.RawInline("latex", "\\cref{" .. label .. "}")
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
local function markdown_to_latex(markdown)
|
|
local doc = pandoc.read(
|
|
markdown or "",
|
|
"markdown+fenced_code_attributes+tex_math_dollars+tex_math_single_backslash+footnotes+raw_html"
|
|
)
|
|
doc = doc:walk({ Link = internal_link_to_cref })
|
|
return pandoc.write(doc, "latex")
|
|
end
|
|
|
|
local function label_line(label)
|
|
if label and label ~= "" then
|
|
return "\\label{" .. label .. "}\n"
|
|
end
|
|
return ""
|
|
end
|
|
|
|
local function interactive_to_latex(el)
|
|
local label = el.identifier
|
|
local caption = el.attributes.caption or el.attributes.title or ""
|
|
local fallback = el.attributes.pdf or el.attributes.fallback or el.text
|
|
local fallback_latex = markdown_to_latex(fallback)
|
|
local caption_line = ""
|
|
|
|
if caption ~= "" then
|
|
caption_line = "\\caption{" .. latex_escape(caption) .. "}\n"
|
|
end
|
|
|
|
return pandoc.RawBlock(
|
|
"latex",
|
|
table.concat({
|
|
"\\begin{figure}[htbp]\n",
|
|
"\\centering\n",
|
|
"\\fbox{\\begin{minipage}{0.86\\linewidth}\n",
|
|
fallback_latex,
|
|
"\n\\end{minipage}}\n",
|
|
caption_line,
|
|
label_line(label),
|
|
"\\end{figure}",
|
|
})
|
|
)
|
|
end
|
|
|
|
local function env_to_latex(el)
|
|
local env_type = el.attributes.type or first_env_class(el)
|
|
if not env_type or not env_types[env_type] then
|
|
return nil
|
|
end
|
|
|
|
local title = el.attributes.title or el.attributes.name or ""
|
|
local begin_env = "\\begin{" .. env_type .. "}"
|
|
if title ~= "" then
|
|
begin_env = begin_env .. "[" .. latex_escape(title) .. "]"
|
|
end
|
|
|
|
return pandoc.RawBlock(
|
|
"latex",
|
|
table.concat({
|
|
begin_env,
|
|
"\n",
|
|
label_line(el.identifier),
|
|
markdown_to_latex(el.text),
|
|
"\n\\end{",
|
|
env_type,
|
|
"}",
|
|
})
|
|
)
|
|
end
|
|
|
|
function CodeBlock(el)
|
|
if FORMAT:match("latex") and has_class(el, "interactive") then
|
|
return interactive_to_latex(el)
|
|
end
|
|
|
|
if FORMAT:match("latex") and (has_class(el, "env") or has_class(el, "latex-env") or first_env_class(el)) then
|
|
return env_to_latex(el)
|
|
end
|
|
|
|
return nil
|
|
end
|
|
|
|
function Link(el)
|
|
return internal_link_to_cref(el)
|
|
end
|