summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rst_context.lua72
-rw-r--r--rst_parser.lua80
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[['")]}>]],