summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rst_context.lua16
-rw-r--r--rst_parser.lua107
2 files changed, 115 insertions, 8 deletions
diff --git a/rst_context.lua b/rst_context.lua
index 6363dfe..8b4c8d6 100644
--- a/rst_context.lua
+++ b/rst_context.lua
@@ -195,6 +195,22 @@ function rst_context.transition (str)
return "\n\\hrule\n"
end
+function rst_context.bullet_list (str)
+ return [[
+\\startitemize
+]] .. str .. [[
+
+\\stopitemize
+]]
+end
+
+function rst_context.bullet_item (str)
+ return [[
+
+\\item ]] .. str .. [[
+
+]]
+end
return rst_context
diff --git a/rst_parser.lua b/rst_parser.lua
index 1bef9e3..826d79c 100644
--- a/rst_parser.lua
+++ b/rst_parser.lua
@@ -16,12 +16,15 @@ rst = require "rst_context"
local C, Cb, Cc, Cg, Cmt, Cp, Cs, Ct, P, R, S, V, match = lpeg.C, lpeg.Cb, lpeg.Cc, lpeg.Cg, lpeg.Cmt, lpeg.Cp, lpeg.Cs, lpeg.Ct, lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.match
-test = [[
-]]
-
+local utf = unicode.utf8
local eol = P"\n"
+local tracklists = {}
+tracklists.depth = 0
+tracklists.bullets = {} -- mapping bullet forms to depth
+tracklists.lastbullet = ""
+
n = 0
local enclosed_mapping = {
@@ -64,12 +67,90 @@ local parser = P{
block = V"target_block"
+ Cs(V"section") / rst.escape
+ Cs(V"transition") --/ rst.escape
+ + Cs(V"list") / rst.escape
+ Cs(V"paragraph") / rst.escape
+ V"comment",
- comment = Cs(V"doubledot"
- * (1 - V"eol")^0
- * V"eol") / ">>comment<<",
+--------------------------------------------------------------------------------
+-- Lists
+--------------------------------------------------------------------------------
+
+ list = V"bullet_list",
+
+--------------------------------------------------------------------------------
+-- Bullet lists
+--------------------------------------------------------------------------------
+
+ --bullet_list = Cs(V"bullet_init"
+ --* (V"bullet_continue"
+ --+ V"bullet_list")^0)
+ --/ rst.bullet_list,
+
+ bullet_list = Cs(V"bullet_init"
+ * (V"bullet_list"
+ + V"bullet_continue")^0) / rst.bullet_list
+ * Cmt(Cc(nil), function (s, i)
+ local t = tracklists
+ print("[close]>", t.depth)
+ t.depth = t.depth - 1
+ return true
+ end),
+
+ bullet_first = Cmt(C(V"space"^0 * V"bullet_char" * V"space"^1), 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)
+
+ if t.depth == 0 and n_spaces == 1 then -- first level
+ t.depth = 1
+ t.bullets[1] = bullet
+ t.lastbullet = bullet
+ return true
+ elseif t.depth > 0 and n_spaces > 1 then -- sublist (of sublist)^0
+ if n_spaces >= utf.len(oldbullet) then
+ t.depth = t.depth + 1
+ t.bullets[t.depth] = bullet
+ t.lastbullet = bullet
+ return true
+ end
+ end
+ return false
+ end),
+
+ bullet_cont = Cmt(C(V"space"^0 * V"bullet_char" * V"space"^1), function (s, i, bullet)
+ local t = tracklists
+ 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,
+
+ bullet_continue = V"eol"^0
+ * V"bullet_cont"
+ * Cs(V"bullet_itemrest")
+ / rst.bullet_item,
+
+ 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)),
+ -- ^^^^^^^^^^^^^
+ -- otherwise matches bullet_first
+
+ bullet_char = S"*+-" + P"•" + P"‣" + P"⁃",
+
+ 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) )
+ return string.len(this) == utf.len(t.bullets[t.depth])
+ end),
--------------------------------------------------------------------------------
-- Transitions
@@ -151,7 +232,7 @@ local parser = P{
-- Paragraphs * Inline Markup
--------------------------------------------------------------------------------
- paragraph = -(V"doubledot" + V"double_underscore")
+ paragraph = -(V"doubledot" + V"double_underscore" + V"bullet_char")
* Cs((V"enclosed_inline"
+ V"inline_elements"
+ V"word"
@@ -234,6 +315,14 @@ local parser = P{
_reference = (1 - V"underscore" - V"spacing" - V"eol" - V"punctuation" - V"groupchars")^1 * V"underscore",
--------------------------------------------------------------------------------
+-- Comments
+--------------------------------------------------------------------------------
+
+ comment = Cs(V"doubledot"
+ * (1 - V"eol")^0
+ * V"eol") / ">>comment<<",
+
+--------------------------------------------------------------------------------
-- Urls
--------------------------------------------------------------------------------
uri = V"url_protocol" * V"url_domain" * (V"slash" * V"url_path")^0,
@@ -299,11 +388,13 @@ local parser = P{
enclosed_close = S[['")]}>]],
}
-f = io.open("testfile.rst", "r")
+f = io.open("list.rst", "r")
testdata = f:read("*all")
f:close()
print(parser:match(testdata))
+print(">>>Last used char>: " ..tracklists.lastbullet.." <<<<")
+print(">>>Max list nestin>: "..#tracklists.bullets .." <<<<")
--for i,j in next, rst.collected_references do
--print (string.format("== %7s => %s <=", i,j))