Add semantic block parser and PDF export
Some checks are pending
Build / build (push) Waiting to run

This commit is contained in:
Neeldhara Misra 2026-06-25 12:35:40 +05:30
parent 632543db4d
commit 58310e1944
47 changed files with 3078 additions and 0 deletions

View file

@ -0,0 +1,131 @@
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