From 58042b5135ddf74bf5945c46eafd3828739e045c Mon Sep 17 00:00:00 2001
From: Jonas Smedegaard <dr@jones.dk>
Date: Mon, 24 Feb 2025 15:00:10 +0100
Subject: initial draft

---
 .../abstract-section/abstract-section.lua          | 85 ++++++++++++++++++++++
 1 file changed, 85 insertions(+)
 create mode 100644 _extensions/pandoc-ext/abstract-section/abstract-section.lua

(limited to '_extensions/pandoc-ext/abstract-section/abstract-section.lua')

diff --git a/_extensions/pandoc-ext/abstract-section/abstract-section.lua b/_extensions/pandoc-ext/abstract-section/abstract-section.lua
new file mode 100644
index 0000000..4badeb4
--- /dev/null
+++ b/_extensions/pandoc-ext/abstract-section/abstract-section.lua
@@ -0,0 +1,85 @@
+--[[
+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
-- 
cgit v1.2.3