aboutsummaryrefslogtreecommitdiff
path: root/_extensions
diff options
context:
space:
mode:
authorJonas Smedegaard <dr@jones.dk>2025-05-11 14:53:26 +0200
committerJonas Smedegaard <dr@jones.dk>2025-05-11 14:53:26 +0200
commit39098b25a005f934c081cec017a19cbee670c797 (patch)
tree4c5fd0fe6d47894ec6b31eb5195c4062b9d03f5a /_extensions
parent902ee44c241d2b6ba991f9e8f8800b6918fd1d7e (diff)
collect unenclosed and bracketed stacks separately
Diffstat (limited to '_extensions')
-rw-r--r--_extensions/ruc-play/semantic-markdown/semantic-markdown.lua73
1 files changed, 61 insertions, 12 deletions
diff --git a/_extensions/ruc-play/semantic-markdown/semantic-markdown.lua b/_extensions/ruc-play/semantic-markdown/semantic-markdown.lua
index d41acce..378681e 100644
--- a/_extensions/ruc-play/semantic-markdown/semantic-markdown.lua
+++ b/_extensions/ruc-play/semantic-markdown/semantic-markdown.lua
@@ -228,29 +228,43 @@ local function Statements (block)
-- amount of detected statements in this block
local statement_count = 0
+ -- stacks of qualified and pending unenclosed/enclosed elements
local elems = pandoc.List()
+ local elems_none = pandoc.List()
+ local elems_bracketed = pandoc.List()
for _, el in ipairs(block.content) do
local pos = 1
- local chars = ""
+
+ -- strings of pending unenclosed/enclosed chars
+ local chars_none = ""
+ local chars_bracketed = ""
-- non-string element, highest state first to support fall-through
if el.t ~= 'Str' then
+ elems_none:insert(el)
- -- collect element, except in braced enclosure
- -- TODO: support mixed-use braced enclosure
- if encl ~= Enclosure.BRACED then
- elems:insert(el)
+ if encl == Enclosure.BRACED then
+ goto continue
end
+ elems_bracketed:insert(el)
+
if encl == Enclosure.BRACKETED_DONE then
-- disqualify bracketing not directly followed by brace
+ elems:extend(elems_none)
+ elems_none = pandoc.List()
+ elems_bracketed = pandoc.List()
encl = Enclosure.NONE
-- fall through to parse element as unenclosed
end
+ if encl == Enclosure.BRACKETED then
+ goto continue
+ end
+
if encl == Enclosure.NONE then
-- specific elements represent content enclosure
@@ -267,11 +281,14 @@ local function Statements (block)
if encl == Enclosure.NONE then
local _, x, s = el.text:find("^([^%[\\]*)")
pos = x and x + 1 or pos + 1
- chars = chars..s
+ chars_none = chars_none..s
+ chars_bracketed = chars_none
-- entering bracketed enclosure
if el.text:sub(pos, pos) == "[" then
pos = pos + 1
+ chars_bracketed = chars_none
+ chars_none = chars_none.."["
encl = Enclosure.BRACKETED
end
end
@@ -282,11 +299,13 @@ local function Statements (block)
if encl == Enclosure.BRACKETED then
local _, x, s = el.text:find("^([^%[%]}\\]*)", pos)
pos = x and x + 1 or pos + 1
- chars = chars..s
+ chars_none = chars_none..s
+ chars_bracketed = chars_bracketed..s
-- exiting bracketed enclosure
if el.text:sub(pos, pos) == "]" then
pos = pos + 1
+ chars_none = chars_none.."]"
encl = Enclosure.BRACKETED_DONE
end
end
@@ -297,13 +316,23 @@ local function Statements (block)
-- entering braced enclosure
if el.text:sub(pos, pos) == "{" then
pos = pos + 1
+ chars_none = chars_none.."{"
encl = Enclosure.BRACED
-- leaving non-annotation enclosure
else
+
+ -- disqualify bracketing not directly followed by brace
+ elems:extend(elems_none)
+ elems_none = pandoc.List()
+ elems_bracketed = pandoc.List()
+ if chars_none:len() > 0 then
+ elems:insert(pandoc.Str(chars_none))
+ chars_none = ""
+ end
+ chars_bracketed = ""
encl = Enclosure.NONE
- -- TODO: parse remains of Str
end
end
@@ -320,21 +349,41 @@ local function Statements (block)
pos = d + 1
-- TODO: instead recursively call Statements() on remains of Str
- chars = chars..el.text:sub(pos)
+ chars_bracketed = chars_bracketed..el.text:sub(pos)
+ -- qualify completed bracketed enclosure
+ elems:extend(elems_bracketed)
+ elems_bracketed = pandoc.List()
+ elems_none = pandoc.List()
+ if chars_bracketed:len() > 0 then
+ elems:insert(pandoc.Str(chars_bracketed))
+ chars_bracketed = ""
+ end
+ chars_none = ""
encl = Enclosure.NONE
end
end
- -- push any string collected from above parsing to stack
- if chars:len() > 0 then
- elems:insert(pandoc.Str(chars))
+ -- push strings to stacks
+ if chars_bracketed:len() > 0 then
+ elems_bracketed:insert(pandoc.Str(chars_bracketed))
+ end
+ if chars_none:len() > 0 then
+ elems_none:insert(pandoc.Str(chars_none))
end
-- done parsing current Inline element
::continue::
end
+
+ -- return altered stack if it contains complete enclosures
if statement_count > 0 then
+
+ -- disqualify incomplete enclosure
+ if encl ~= Enclosure.NONE then
+ elems:extend(elems_none)
+ end
+
block.content = elems
return block
end