123 lines
3.0 KiB
Lua
123 lines
3.0 KiB
Lua
local md = {}
|
|
|
|
function md.parse(md)
|
|
local it = {}
|
|
it.l = {}
|
|
it[#it+1] = {["content"]="",["bold"]=false,["italic"]=false}
|
|
local lc,llc = "",""
|
|
local function newpart()
|
|
it[#it+1] = {["content"]="",["bold"]=it[#it].bold,["italic"]=it[#it].italic}
|
|
end
|
|
newpart()
|
|
local lm = false
|
|
local cc = 0
|
|
for c in md:gmatch(".") do
|
|
cc = cc + 1
|
|
if c == "[" then
|
|
newpart()
|
|
elseif c == "(" and lc == "]" then
|
|
lm = true
|
|
it[#it].content = it[#it].content:sub(1,-2)
|
|
it[#it].address = ""
|
|
elseif c == ")" and lm then
|
|
lm = false
|
|
it.l[#it.l+1] = it[#it].address
|
|
it[#it].addrid = #it.l
|
|
newpart()
|
|
elseif c == "*" then
|
|
if lc == "*" then
|
|
it[#it].italic = false
|
|
it[#it].italic = it[#it-1].italic
|
|
it[#it].bold = not it[#it].bold
|
|
else
|
|
newpart()
|
|
it[#it].italic = not it[#it].italic
|
|
end
|
|
elseif c == "\n" and lc == "\n" then
|
|
if it[#it-1].content == "\n" then
|
|
table.remove(it,#it-1)
|
|
end
|
|
newpart()
|
|
it[#it].content = "\n\n"
|
|
newpart()
|
|
elseif c == "\n" then
|
|
local line = md:sub(1,cc):match(".+\n(.+)") or it[#it].content
|
|
if line:sub(line:find("%S")) == "-" then
|
|
newpart()
|
|
it[#it].content = "\n"
|
|
newpart()
|
|
elseif line:sub(line:find("%S")) == "#" then
|
|
newpart()
|
|
it[#it].content = "\n"
|
|
newpart()
|
|
elseif line:find("%s-%d+%.") == 1 then
|
|
newpart()
|
|
it[#it].content = "\n"
|
|
newpart()
|
|
else
|
|
it[#it].content = it[#it].content .. c
|
|
end
|
|
else
|
|
if not lm then
|
|
it[#it].content = it[#it].content .. c
|
|
else
|
|
it[#it].address = it[#it].address .. c
|
|
end
|
|
end
|
|
llc = lc
|
|
lc = c
|
|
end
|
|
return it
|
|
end
|
|
|
|
function md.reflow(text,len)
|
|
local words, lines, links, lastitalic, lastbold = {}, {""}, {}, false, false
|
|
for k,v in ipairs(md.parse(text)) do
|
|
if v.content == "\n\n" or v.content == "\n" then
|
|
words[#words+1] = {v.content}
|
|
elseif not v.address then
|
|
for word in v.content:gmatch("%S+") do
|
|
words[#words+1] = {word}
|
|
if v.italic and not lastitalic then
|
|
words[#words][1] = "\27[30;47m"..words[#words][1]
|
|
lastitalic = not lastitalic
|
|
elseif not v.italic and lastitalic then
|
|
words[#words-1][1] = words[#words-1][1].."\27[0m"
|
|
lastitalic = not lastitalic
|
|
end
|
|
if v.bold and not lastbold then
|
|
words[#words][1] = "\27[31m"..words[#words][1]
|
|
lastbold = not lastbold
|
|
elseif not v.bold and lastbold then
|
|
words[#words-1][1] = words[#words-1][1].."\27[0m"
|
|
lastbold = not lastbold
|
|
end
|
|
end
|
|
else
|
|
words[#words+1] = {v.content,v.address}
|
|
end
|
|
end
|
|
for k,v in pairs(words) do
|
|
if v[2] then
|
|
if lines[#lines]:len()+v[1]:len()+2 > len then
|
|
lines[#lines+1] = ""
|
|
end
|
|
links[#links+1] = {#lines, lines[#lines]:len()+1, v[1], v[2]}
|
|
lines[#lines] = lines[#lines] .. "<"..v[1].."> "
|
|
elseif v[1] == "\n" then
|
|
lines[#lines+1] = ""
|
|
elseif v[1] == "\n\n" then
|
|
lines[#lines+1] = ""
|
|
lines[#lines+1] = ""
|
|
else
|
|
if lines[#lines]:len()+v[1]:len() > len then
|
|
lines[#lines+1] = ""
|
|
end
|
|
lines[#lines] = lines[#lines] .. v[1].." "
|
|
end
|
|
end
|
|
return lines, links
|
|
end
|
|
|
|
return md
|