diff options
-rw-r--r-- | rst_context.lua | 72 | ||||
-rw-r--r-- | rst_parser.lua | 80 |
2 files changed, 124 insertions, 28 deletions
diff --git a/rst_context.lua b/rst_context.lua index 8b4c8d6..8131505 100644 --- a/rst_context.lua +++ b/rst_context.lua @@ -195,12 +195,76 @@ function rst_context.transition (str) return "\n\\hrule\n" end -function rst_context.bullet_list (str) - return [[ +function rst_context.bullet_marker(str) + return "marker" +end + +do + local space = lpeg.S(" \t\v\n") + local nospace = 1 - space + local stripper = space^0 * lpeg.C((space^0 * nospace^1)^0) + function string.strip(str) + return match(stripper,str) or "" + end +end + +local enumeration_types = { + ["*"] = "*", -- unordered bulleted + ["+"] = "*", + ["-"] = "*", + ["•"] = "*", + ["‣"] = "*", + ["⁃"] = "*", + + ["#"] = "1", -- numbered lists and conversion + ["A"] = "A", + ["a"] = "a", + ["I"] = "R", + ["i"] = "r", +} + +-- \setupitemize[left=(, right=), margin=4em, stopper=] + +local stripme = S"()." +local dontstrip = 1 - stripme +local itemstripper = stripme^0 * C(dontstrip) * stripme^0 +local function parse_itemstring(str) + local setup = [[\setupitemize[]] + -- string.match is slightly faster than string.find + if str:match("^%(") then + setup = setup .. [[left=(,]] + end + if str:match("%)$") then + setup = setup .. [[right=)]] + end + if str:match("%.$") then + setup = setup .. [[stopper=.]] + end + setup = setup .. "]\n" + + str = itemstripper:match(str) + return {setup = setup, str=str} +end -\\startitemize -]] .. str .. [[ +function rst_context.startitemize(str) + local setup = "" + str = string.strip(str) + + local listtype = enumeration_types[str] or parse_itemstring(str) + + if type(listtype) == "table" then + print(type(listtype), listtype[2]) + setup = listtype.setup + listtype = listtype.str + end + + return setup .. [[ +\\startitemize[]] .. listtype .. [[] +]] +end +function rst_context.stopitemize(str) + return str .. [[ \\stopitemize ]] end diff --git a/rst_parser.lua b/rst_parser.lua index 826d79c..eb5e6b8 100644 --- a/rst_parser.lua +++ b/rst_parser.lua @@ -78,17 +78,14 @@ local parser = P{ list = V"bullet_list", -------------------------------------------------------------------------------- --- Bullet lists +-- Bullet lists and enumerations -------------------------------------------------------------------------------- - --bullet_list = Cs(V"bullet_init" - --* (V"bullet_continue" - --+ V"bullet_list")^0) - --/ rst.bullet_list, - - bullet_list = Cs(V"bullet_init" + -- the next rule handles enumerations as well + bullet_list = V"bullet_init" * (V"bullet_list" - + V"bullet_continue")^0) / rst.bullet_list + + V"bullet_continue")^0 + * V"bullet_stop" * Cmt(Cc(nil), function (s, i) local t = tracklists print("[close]>", t.depth) @@ -96,11 +93,22 @@ local parser = P{ return true end), - bullet_first = Cmt(C(V"space"^0 * V"bullet_char" * V"space"^1), function (s, i, bullet) + bullet_stop = Cs(Cc("")) / rst.stopitemize, + + bullet_init = V"eol"^0 + * V"bullet_first" + * V"bullet_itemrest", + + bullet_indent = V"space"^0 * V"bullet_expr" * V"space"^1, + + bullet_first = #Cmt(V"bullet_indent", function (s, i, bullet) local t = tracklists local oldbullet = t.bullets[t.depth] local n_spaces = match(P" "^0, bullet) - print("[first]>", t.depth, n_spaces, bullet, oldbullet) + print("[first]>", + t.depth, + (t.depth == 0 and n_spaces == 1) or + (t.depth > 0 and n_spaces > 1), bullet, oldbullet) if t.depth == 0 and n_spaces == 1 then -- first level t.depth = 1 @@ -116,39 +124,58 @@ local parser = P{ end end return false - end), + end) + --* V"bullet_indent" / rst.startitemize, + * Cs(V"bullet_indent") / rst.startitemize, - bullet_cont = Cmt(C(V"space"^0 * V"bullet_char" * V"space"^1), function (s, i, bullet) + bullet_cont = Cmt(V"bullet_indent", function (s, i, bullet) local t = tracklists - print("[contin]>>", t.depth, bullet, t.bullets[t.depth], bullet == t.bullets[t.depth]) + print("[contin]>>", + t.depth, + bullet == t.bullets[t.depth], + bullet, + t.bullets[t.depth]) return t.bullets[t.depth] == bullet - end), - - bullet_init = V"eol"^0 - * V"bullet_first" - * Cs(V"bullet_itemrest") - / rst.bullet_item, + end) / "", + -- ^^^^^ + -- otherwise returns the value of V"bullet_indent", not sure why … bullet_continue = V"eol"^0 * V"bullet_cont" - * Cs(V"bullet_itemrest") - / rst.bullet_item, + * V"bullet_itemrest", bullet_itemrest = Cs(V"bullet_rest" -- first line * ((V"bullet_match" * V"bullet_rest")^0 -- any successive lines * (V"eol" - * (V"bullet_match" * (V"bullet_rest" - V"bullet_char"))^1)^0)), + * (V"bullet_match" * (V"bullet_rest" - V"bullet_expr"))^1)^0)) + / rst.bullet_item, -- ^^^^^^^^^^^^^ -- otherwise matches bullet_first + bullet_expr = V"bullet_char" + + (V"number_char" * V"dot") + + (P"(" * V"number_char" * P")") + + V"number_char" * P")" + + V"number_char" * #V"space", + bullet_char = S"*+-" + P"•" + P"‣" + P"⁃", + number_char = V"roman_numeral" + + V"Roman_numeral" + + P"#" + + V"digit"^1 + + R"AZ" + + R"az", + bullet_rest = Cs((1 - V"eol")^1 * V"eol"), -- rest of one line bullet_next = C(V"space"^1), bullet_match = Cmt(V"bullet_next", function (s, i, this) local t = tracklists - print("[match]>>>", t.depth, utf.len(t.bullets[t.depth]), string.len(this) ) + print("[match]>>>", + t.depth, + string.len(this) == utf.len(t.bullets[t.depth]), + utf.len(t.bullets[t.depth]), string.len(this) ) return string.len(this) == utf.len(t.bullets[t.depth]) end), @@ -232,7 +259,7 @@ local parser = P{ -- Paragraphs * Inline Markup -------------------------------------------------------------------------------- - paragraph = -(V"doubledot" + V"double_underscore" + V"bullet_char") + paragraph = -(V"doubledot" + V"double_underscore" + V"bullet_indent") * Cs((V"enclosed_inline" + V"inline_elements" + V"word" @@ -381,8 +408,13 @@ local parser = P{ endpar = V"eol" * (V"eol"^1 + V"eof"), delimiters = P"‐" + P"‑" + P"‒" + P"–" + P"—" + V"space", + adornment_char = S[[!"#$%&'()*+,-./:;<=>?@[]^_`{|}~]] + P[[\\]], + digit = R"09", + roman_numeral = S"ivxlcdm"^1, + Roman_numeral = S"IVXLCDM"^1, + inline_delimiter = P"**" + P"``" + S"*`", enclosed_open = S[['"([{<]], enclosed_close = S[['")]}>]], |