local word_count = 0 local function count_words_in_string(str) local _, count = string.gsub(str, "%S+", "") return count end local function count_words_in_inlines(inlines) for _, inline in ipairs(inlines) do if inline.t == "Str" then if inline.text:match("%P") then word_count = word_count + 1 end end if inline.t == "Code" or inline.t == "CodeBlock" then word_count = word_count + count_words_in_string(inline.text) end if inline.t == "Cite" then word_count = word_count + 1 end if inline.t == "Span" or inline.t == "Emph" or inline.t == "Strong" or inline.t == "Link" or inline.t == "Quoted" or inline.t == "Para" or inline.t == "Strikeout" then count_words_in_inlines(inline.content) end end end local function processblocks(b) for _, block in ipairs(b) do if block.t == "Para" or block.t == "Plain" or block.t == "Header" or block.t == "BlockQuote" then count_words_in_inlines(block.content) end if block.t == "Div" then processblocks(block.content) end end end function Note(el) processblocks(el.content) end function Math(el) word_count = word_count + count_words_in_string(el.text) end function CodeBlock(el) word_count = word_count + count_words_in_string(el.text) end function BulletList(el) for _, block in ipairs(el.content) do processblocks(block) end end function OrderedList(el) for _, block in ipairs(el.content) do processblocks(block) end end function DefinitionList(el) for _, block in ipairs(el.content) do processblocks(block) end end function Pandoc(doc) processblocks(doc.blocks) doc.meta.wordn = word_count return doc end