Created
June 23, 2024 15:22
-
-
Save CodeSandwich/35cd06d3925ca8c48ce950fb4b8be2ca to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local function length(elem) | |
return pandoc.text.len(pandoc.utils.stringify(elem)) | |
end | |
function insert(doc, inserted, idx, before) | |
idx = idx or -1 | |
local total_length = length(doc) | |
if(idx < 0) then | |
idx = idx + 1 + total_length | |
end | |
if(idx < 1 or idx > total_length) then | |
error("Index out of bounds") | |
end | |
local function insert_string(string, inserted, idx, before) | |
if(before) then idx = idx - 1 end | |
local prefix = pandoc.text.sub(string, 1, idx) | |
local suffix = pandoc.text.sub(string, idx + 1) | |
return prefix..inserted..suffix | |
end | |
local function insert_inlines(elem, inserted, before) | |
elem = pandoc.Inlines(elem) | |
inserted = pandoc.Inlines(inserted) | |
if(before) then | |
return inserted..elem | |
else | |
return elem..inserted | |
end | |
end | |
local function inline(elem) | |
if(idx == 0) then | |
return nil, false | |
end | |
local elem_length = length(elem) | |
if(elem_length < idx) then | |
idx = idx - elem_length | |
return nil, false | |
end | |
if(elem.t == "Str") then | |
elem = insert_string(elem.text, inserted, idx, before) | |
elseif(elem.t == "Code" or elem.t == "Math") then | |
elem.text = insert_string(elem.text, inserted, idx, before) | |
elseif(elem.t == "Space" or elem.t == "LineBreak" or elem.t == "SoftBreak") | |
or (elem.t == "RawInline" and elem.format == "html" and string.find(elem.text, "^<br")) then | |
elem = insert_inlines(elem, inserted, before) | |
elseif(elem.t == "Quoted" and (elem.quotetype == "SingleQuote" or elem.quotetype == "DoubleQuote")) then | |
if((idx == 1 and before) or (idx == length and not before)) then | |
elem = insert_inlines(elem, inserted, before) | |
elseif(idx == 1 or idx == length) then | |
elem.content = insert_inlines(elem.content, inserted, not before) | |
else | |
idx = idx - 1 | |
return nil, true | |
end | |
else | |
return nil, true | |
end | |
idx = 0 | |
return elem, false | |
end | |
return doc:walk({traverse = 'topdown', Inline = inline}) | |
end | |
function testInsert(markup, inserted, idx, before, expected) | |
local doc = pandoc.read(markup, "markdown") | |
doc = insert(doc, inserted, idx, before) | |
local actual = pandoc.write(doc, "markdown") | |
actual = string.gsub(actual, "\n$", "") | |
if(actual == expected) then | |
print("Test successful") | |
else | |
print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>") | |
print("Test failed!") | |
print("Invalid result of inserting '"..inserted.."' " | |
..(before and "before" or "after").." index "..idx.." into:") | |
print(markup) | |
print("Actual:") | |
print(actual) | |
print("Expected:") | |
print(expected) | |
print(pandoc.json.encode(doc)) | |
print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<") | |
end | |
end | |
-- Str | |
testInsert("abc", "X", 2, true, "aXbc") | |
testInsert("abc", "X", 2, false, "abXc") | |
-- Code | |
testInsert("`abc`", "X", 2, true, "`aXbc`") | |
testInsert("`abc`", "X", 2, false, "`abXc`") | |
-- Math | |
testInsert("$abc$", "X", 2, true, "$aXbc$") | |
testInsert("$abc$", "X", 2, false, "$abXc$") | |
-- Space | |
testInsert("*a* *b*", "X", 2, true, "*a*X *b*") | |
testInsert("*a* *b*", "X", 2, false, "*a* X*b*") | |
-- LineBreak | |
testInsert("*a*\\\n*b*", "X", 2, true, "*a*X\\\n*b*") | |
testInsert("*a*\\\n*b*", "X", 2, false, "*a*\\\nX*b*") | |
-- SoftBreak | |
testInsert("*a*\n*b*", "X", 2, true, "*a*X *b*") | |
testInsert("*a*\n*b*", "X", 2, false, "*a* X*b*") | |
-- RawInline | |
testInsert("*a*`<br>`{=html}*b*", "X", 2, true, "*a*X`<br>`{=html}*b*") | |
testInsert("*a*`<br>`{=html}*b*", "X", 2, false, "*a*`<br>`{=html}X*b*") | |
-- SingleQuote | |
testInsert("*a*'*b*'*c*", "X", 2, true, "*a*X'*b*'*c*") | |
testInsert("*a*'*b*'*c*", "X", 2, false, "*a*'X*b*'*c*") | |
testInsert("*a*'*b*'*c*", "X", 3, true, "*a*'*Xb*'*c*") | |
testInsert("*a*'*b*'*c*", "X", 3, false, "*a*'*bX*'*c*") | |
testInsert("*a*'*b*'*c*", "X", 4, true, "*a*'*b*X'*c*") | |
testInsert("*a*'*b*'*c*", "X", 4, false, "*a*'*b*'X*c*") | |
-- DoubleQuote | |
testInsert('*a*"*b*"*c*', "X", 2, true, '*a*X"*b*"*c*') | |
testInsert('*a*"*b*"*c*', "X", 2, false, '*a*"X*b*"*c*') | |
testInsert('*a*"*b*"*c*', "X", 3, true, '*a*"*Xb*"*c*') | |
testInsert('*a*"*b*"*c*', "X", 3, false, '*a*"*bX*"*c*') | |
testInsert('*a*"*b*"*c*', "X", 4, true, '*a*"*b*X"*c*') | |
testInsert('*a*"*b*"*c*', "X", 4, false, '*a*"*b*"X*c*') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment