--[[ abstract-section – move an "abstract" section into document metadata Copyright: © 2017–2023 Albert Krewinkel License: MIT – see LICENSE file for details ]] local stringify = (require 'pandoc.utils').stringify local section_identifiers = { abstract = true, } local collected = {} --- The level of the highest heading that was seen so far. Abstracts --- must be at or above this level to prevent nested sections from being --- treated as metadata. Only top-level sections should become metadata. local toplevel = 6 --- Extract abstract from a list of blocks. local function abstract_from_blocklist (blocks) local body_blocks = {} local looking_at_section = false for _, block in ipairs(blocks) do if block.t == 'Header' and block.level <= toplevel then toplevel = block.level if section_identifiers[block.identifier] then looking_at_section = block.identifier collected[looking_at_section] = {} else looking_at_section = false body_blocks[#body_blocks + 1] = block end elseif looking_at_section then if block.t == 'HorizontalRule' then looking_at_section = false else local collect = collected[looking_at_section] collect[#collect + 1] = block end else body_blocks[#body_blocks + 1] = block end end return body_blocks end Pandoc = function (doc) local meta = doc.meta -- configure section_identifiers_list = (doc.meta['abstract-section'] or {})['section-identifiers'] if section_identifiers_list and #section_identifiers_list > 0 then section_identifiers = {} for i, ident in ipairs(section_identifiers_list) do section_identifiers[stringify(ident)] = true end end -- unset config in meta doc.meta['abstract-section'] = nil local blocks = {} if PANDOC_VERSION >= {2,17} then -- Walk all block lists by default blocks = doc.blocks:walk{Blocks = abstract_from_blocklist} elseif PANDOC_VERSION >= {2,9,2} then -- Do the same with pandoc versions that don't have walk methods but the -- `walk_block` function. blocks = pandoc.utils.walk_block( pandoc.Div(doc.blocks), {Blocks = abstract_from_blocklist} ).content else -- otherwise, just check the top-level block-list blocks = abstract_from_blocklist(doc.blocks) end for metakey in pairs(section_identifiers) do metakey = stringify(metakey) local abstract = collected[metakey] if not meta[metakey] and abstract and #abstract > 0 then meta[metakey] = pandoc.MetaBlocks(abstract) end end return pandoc.Pandoc(blocks, meta) end