简体   繁体   中英

How to refactor repeating code in Pandoc lua filter

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM