-- center-v.lua -- Pandoc Lua filter for converting ~V~ section break symbols -- into properly centered paragraphs in EPUB/DOCX/HTML output. -- -- Handles multiple input patterns that Obsidian might produce: -- 1.
\n~V~\n
(HTML blocks wrapping subscript) -- 2. Raw ~V~ as a paragraph -- 3. The tilde-based subscript interpretation (~V~ → subscript V) local function make_centered() if FORMAT == "epub" or FORMAT == "epub3" or FORMAT == "html" or FORMAT == "html5" then return pandoc.RawBlock("html", '

~V~

') elseif FORMAT == "docx" or FORMAT == "openxml" then return pandoc.RawBlock("openxml", [[ ~V~ ]]) else return pandoc.Para({pandoc.Str("~V~")}) end end function Pandoc(doc) local newblocks = {} local i = 1 while i <= #doc.blocks do local b1 = doc.blocks[i] local b2 = doc.blocks[i+1] local b3 = doc.blocks[i+2] -- Pattern 1:
block + subscript V +
block if b1 and b2 and b3 and b1.t == "RawBlock" and b1.format == "html" and b1.text:match("^
%s*$") and b2.t == "Plain" and #b2.content == 1 and b2.content[1].t == "Subscript" and #b2.content[1].content == 1 and b2.content[1].content[1].t == "Str" and b2.content[1].content[1].text == "V" and b3.t == "RawBlock" and b3.format == "html" and b3.text:match("^
%s*$") then table.insert(newblocks, make_centered()) i = i + 3 -- Pattern 2: Single paragraph containing just "~V~" elseif b1 and b1.t == "Para" and #b1.content == 1 and b1.content[1].t == "Str" and b1.content[1].text == "~V~" then table.insert(newblocks, make_centered()) i = i + 1 -- Pattern 3: Plain block with subscript V (standalone, no center tags) elseif b1 and b1.t == "Plain" and #b1.content == 1 and b1.content[1].t == "Subscript" and #b1.content[1].content == 1 and b1.content[1].content[1].t == "Str" and b1.content[1].content[1].text == "V" then table.insert(newblocks, make_centered()) i = i + 1 -- Pattern 4: Para with Str "~" + Subscript "V" + Str "~" (tilde interpreted separately) elseif b1 and b1.t == "Para" and #b1.content == 3 and b1.content[1].t == "Str" and b1.content[1].text == "~" and b1.content[2].t == "Subscript" and #b1.content[2].content == 1 and b1.content[2].content[1].t == "Str" and b1.content[2].content[1].text == "V" and b1.content[3].t == "Str" and b1.content[3].text == "~" then table.insert(newblocks, make_centered()) i = i + 1 else table.insert(newblocks, b1) i = i + 1 end end doc.blocks = newblocks return doc end