I am in the process of writing a Lua filter for Pandoc specifically targeting Pandoc generated LaTeX documents.
Here is a small code snippet from my filter:
LATEX_CODES_FOR_TAGS = {
Span = {
sans = '\\sffamily ',
serif = '\\rmfamily ',
},
Div = {
-- Font Styles
sans = '\\begin{sffamily}',
serif = '\\begin{rmfamily}',
}
}
function Span(span)
for tag, code_for_class in pairs(LATEX_CODES_FOR_TAGS) do
for class, code in pairs(code_for_class) do
if tag == "Span" then
if span.classes:includes(class) then
table.insert(span.content, 1, pandoc.RawInline('latex', code))
end
end
end
end
return span
end
function Div(div)
for tag, code_for_class in pairs(LATEX_CODES_FOR_TAGS) do
for class, code in pairs(code_for_class) do
if tag == "Div" then
if div.classes:includes(class) then
local code_end = code:gsub('begin', 'end')
table.insert(div.content, 1, pandoc.RawBlock('latex', code))
table.insert(div.content, pandoc.RawBlock('latex', code_end))
end
end
end
end
return div
end
As you can see the code for the Div()
and Span()
functions are almost exactly the same, and therefore want to refactor the code.
I have hitherto been unable to come up with a solution that makes the filter without the repeating code.
I am still very new to Lua and wrapping my head around the concepts.
Thanks in advance.
Define the body of the loop as a separate function:
local function create_handler(tag_str, handler_func)
return
function (obj)
for tag, code_for_class in pairs(LATEX_CODES_FOR_TAGS) do
for class, code in pairs(code_for_class) do
if tag == tag_str then
if obj.classes:includes(class) then
handler_func(obj, code)
end
end
end
end
return obj
end
end
Span = create_handler("Span",
function(span, code)
table.insert(span.content, 1, pandoc.RawInline('latex', code))
end)
Div = create_handler("Div",
function(div, code)
local code_end = code:gsub('begin', 'end')
table.insert(div.content, 1, pandoc.RawBlock('latex', code))
table.insert(div.content, pandoc.RawBlock('latex', code_end))
end)