basic-book-builder/filters/callouts.lua

67 lines
2.4 KiB
Lua

-- Map callout types to LaTeX environments
local callout_env_map = {
idea = "ideabox",
proposed = "proposedbox",
established = "establishedbox",
speculative = "speculativebox",
caution = "cautionbox",
warning = "warningbox",
danger = "dangerbox"
}
function BlockQuote(el)
if #el.content > 0 and el.content[1].t == "Para" then
local firstPara = el.content[1]
if #firstPara.content > 0 and firstPara.content[1].t == "Str" then
local firstWord = firstPara.content[1].text
local calloutType = firstWord:match("^%[%!(%w+)%]$")
if calloutType and callout_env_map[calloutType] then
-- 1. Remove the [!type] marker
table.remove(firstPara.content, 1)
-- 2. Remove one following space if present
if #firstPara.content > 0 and firstPara.content[1].t == "Space" then
table.remove(firstPara.content, 1)
end
-- 3. Gather optional custom title
local titleInlines = {}
while #firstPara.content > 0 do
local t = firstPara.content[1].t
if t == "SoftBreak" then
table.remove(firstPara.content, 1)
break
elseif t == "Space" or t == "Str" or t == "Emph" or t == "Strong" or t == "Code" then
table.insert(titleInlines, table.remove(firstPara.content, 1))
else
break
end
end
local customTitle = pandoc.utils.stringify(pandoc.Span(titleInlines))
customTitle = customTitle:gsub("^%s+", ""):gsub("%s+$", "")
if customTitle == "" then customTitle = nil end
-- 4. Map to LaTeX environment
local env = callout_env_map[calloutType]
local titleOption = customTitle and ("[" .. customTitle .. "]") or "[]"
-- 5. Handle the Margin Issue
-- We add \par and \medskip specifically for 'established'
local prefix = ""
if calloutType == "established" then
prefix = "\\par\\medskip\\noindent\n"
end
-- 6. Construct the LaTeX block
local latex = prefix .. "\\begin{" .. env .. "}" .. titleOption .. "\n"
.. pandoc.write(pandoc.Pandoc(el.content), "latex")
.. "\n\\end{" .. env .. "}"
return pandoc.RawBlock("latex", latex)
end
end
end
end