1

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.

1 Answer 1

2

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)
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @egor-skriptunoff I had not thought of returning a function within a function. I guess this is a key feature of Lua that I need to master.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.