59 lines
2.0 KiB
Lua
59 lines
2.0 KiB
Lua
local babycode = {}
|
|
|
|
---renders babycode to html
|
|
---@param s string input babycode
|
|
---@param escape_html fun(s: string): string function that escapes html
|
|
function babycode.to_html(s, escape_html)
|
|
if not s or s == "" then return "" end
|
|
-- extract code blocks first and store them as placeholders
|
|
-- don't want to process bbcode embedded into a code block
|
|
local code_blocks = {}
|
|
s = escape_html(s)
|
|
local text = s:gsub("%[code%](.-)%[/code%]", function(code)
|
|
-- strip leading and trailing newlines, preserve others
|
|
local m, _ = code:gsub("^%s*(.-)%s*$", "%1")
|
|
table.insert(code_blocks, m)
|
|
return "\1CODE:"..#code_blocks.."\1"
|
|
end)
|
|
|
|
-- replace `[url=https://example.com]Example[/url] tags
|
|
text = text:gsub("%[url=([^%]]+)%](.-)%[/url%]", function(url, label)
|
|
return '<a href="'..url..'">'..label..'</a>'
|
|
end)
|
|
|
|
-- replace `[url]https://example.com[/url] tags
|
|
text = text:gsub("%[url%]([^%]]+)%[/url%]", function(url)
|
|
return '<a href="'..url..'">'..url..'</a>'
|
|
end)
|
|
|
|
-- bold, italics, strikethrough
|
|
text = text:gsub("%[b%](.-)%[/b%]", "<strong>%1</strong>")
|
|
text = text:gsub("%[i%](.-)%[/i%]", "<em>%1</em>")
|
|
text = text:gsub("%[s%](.-)%[/s%]", "<del>%1</del>")
|
|
|
|
-- replace loose links
|
|
text = text:gsub("(https?://[%w-_%.%?%.:/%+=&~%@#%%]+[%w-/])", function(url)
|
|
if not text:find('<a[^>]*>'..url..'</a>') then
|
|
return '<a href="'..url..'">'..url..'</a>'
|
|
end
|
|
return url
|
|
end)
|
|
|
|
-- rule
|
|
text = text:gsub("\n+%-%-%-", "<hr>")
|
|
|
|
-- normalize newlines, replace them with <br>
|
|
text = text:gsub("\r?\n\r?\n+", "<br>")--:gsub("\r?\n", "<br>")
|
|
|
|
-- replace code block placeholders back with their original contents
|
|
text = text:gsub("\1CODE:(%d+)\1", function(n)
|
|
local code = code_blocks[tonumber(n)]
|
|
local button = ("<button type=button class=\"copy-code\" value=\"%s\">Copy</button>"):format(code)
|
|
return "<pre><span class=\"copy-code-container\">" .. button .. "</span><code>"..code.."</code></pre>"
|
|
end)
|
|
|
|
return text
|
|
end
|
|
|
|
return babycode
|