diff --git a/md.lua b/md.lua index 295fecf..1deb3c1 100644 --- a/md.lua +++ b/md.lua @@ -80,7 +80,7 @@ end local function externalLinkEscape(str, t) local nomatches = true - for m1, m2, m3 in gmatch(str, '(.*)%[(.*)%](.*)') do + for m1, m2, m3 in gmatch(str, '(.*)%[%w(.*)%](.*)') do if nomatches then t[#t + 1] = match(m1, '^(.-)!?$'); nomatches = false end if byte(m1, #m1) == byte '!' then t[#t + 1] = {type = 'img', attributes = {alt = m2}} @@ -197,10 +197,12 @@ local PATTERN_RULE1 = "^%s?%s?%s?(-%s*-%s*-[%s-]*)$" local PATTERN_RULE2 = "^%s?%s?%s?(*%s**%s**[%s*]*)$" local PATTERN_RULE3 = "^%s?%s?%s?(_%s*_%s*_[%s_]*)$" local PATTERN_CODEBLOCK = "^%s*%`%`%`(.*)" +local PATTERN_BLOCKALERT = "^%s*> %[!(.*)%]" local PATTERN_BLOCKQUOTE = "^%s*> (.*)$" local PATTERN_ULIST = "^%s*[%*%-] (.+)$" local PATTERN_OLIST = "^%s*%d+%. (.+)$" local PATTERN_LINKDEF = "^%s*%[(.*)%]%s*%:%s*(.*)" +local PATTERN_TABLE = "^%s*|(.*)|%s*$" -- List of patterns local PATTERNS = { @@ -211,10 +213,12 @@ local PATTERNS = { PATTERN_RULE2, PATTERN_RULE3, PATTERN_CODEBLOCK, + PATTERN_BLOCKALERT, PATTERN_BLOCKQUOTE, PATTERN_ULIST, PATTERN_OLIST, - PATTERN_LINKDEF + PATTERN_LINKDEF, + PATTERN_TABLE } local function isSpecialLine(line) @@ -349,6 +353,101 @@ local function readBlockQuote(pop, peek, tree, links) end end +local function readBlockAlert(pop, peek, tree, links) + local line = peek() + local type_alert, txt = match(line, PATTERN_BLOCKALERT) + if type_alert then + local ba = { + type = "div", + attributes = { class = format('markdown-alert markdown-alert-%s', lower(type_alert)) } + } + + tree[#tree + 1] = ba + if match(pop(), PATTERN_BLOCKQUOTE) then + local bqh = { + type = "p", + attributes = { class = 'markdown-alert-icon' } + } + ba[#ba + 1] = bqh + + local bqv = readFragment(pop, peek, links, function(l) + local tp = isSpecialLine(l) + return tp and tp ~= PATTERN_BLOCKQUOTE + end) + + ba[#ba + 1] = bqv + ba[#ba + 1] = '\r\n' + end + + return peek() + end +end + +local function readTable(pop, peek, tree, links) + local line = peek() + local row1, txt = match(line, PATTERN_TABLE) + if row1 then + local t = { + type = "table", + attributes = { class = 'table table-markdown' } + } + + tree[#tree + 1] = t + local thead = { type = "thead" } + t[#t + 1] = thead + local tbody = { type = "tbody" } + t[#t + 1] = tbody + + local thead_ok = false + while true do + line = pop() + if not line then break end + -- add header + if thead_ok == false then + thead_ok = true + if match(line, "^%s*|%s*%-%-%-") then + local tr = { type = "tr" } + thead[#thead + 1] = tr + for col in row1:gmatch("[^|]+") do + local th = { col, type = "th" } + tr[#tr + 1] = th + end + line = pop() + else + local tr = { + type = "tr", + attributes = { class = '' } + } + tbody[#tbody + 1] = tr + for col in row1:gmatch("[^|]+") do + local td = { col, type = "td" } + tr[#tr + 1] = td + end + end + end + + local row, txt = match(line, PATTERN_TABLE) + if row then + local tr = { + type = "tr", + attributes = { class = '' } + } + tbody[#tbody + 1] = tr + + for col in row:gmatch("[^|]+") do + local td = { col, type = "td" } + tr[#tr + 1] = td + end + + else + break + end + end + + return peek() + end +end + local function readList(pop, peek, tree, links, expectedIndent) if not peek() then return end if expectedIndent and getIndentLevel(peek()) ~= expectedIndent then return end @@ -398,9 +497,13 @@ function readLineStream(stream, tree, links) tree = tree or {} links = links or {} while peek() do - if not readBlockQuote(pop, peek, tree, links) then - if not readList(pop, peek, tree, links) then - readSimple(pop, peek, tree, links) + if not readBlockAlert(pop, peek, tree, links) then + if not readBlockQuote(pop, peek, tree, links) then + if not readTable(pop, peek, tree, links) then + if not readList(pop, peek, tree, links) then + readSimple(pop, peek, tree, links) + end + end end end end