summaryrefslogtreecommitdiff
path: root/rst_parser.lua
diff options
context:
space:
mode:
authorPhilipp Gesang <pgesang@ix.urz.uni-heidelberg.de>2010-09-03 12:20:43 +0200
committerPhilipp Gesang <pgesang@ix.urz.uni-heidelberg.de>2010-09-03 12:20:43 +0200
commit93838985e29fdfb11937db920f08b87435c83c2d (patch)
tree2418be3d5e25d681d88250f0a8e8b77c8d64a110 /rst_parser.lua
parenta5bbf034b6264780bd5144c48fdd9be61ec9030a (diff)
downloadcontext-rst-93838985e29fdfb11937db920f08b87435c83c2d.tar.gz
fixed a serious bug in list nesting
Diffstat (limited to 'rst_parser.lua')
-rw-r--r--rst_parser.lua88
1 files changed, 66 insertions, 22 deletions
diff --git a/rst_parser.lua b/rst_parser.lua
index eb5e6b8..14d23ff 100644
--- a/rst_parser.lua
+++ b/rst_parser.lua
@@ -23,6 +23,7 @@ local eol = P"\n"
local tracklists = {}
tracklists.depth = 0
tracklists.bullets = {} -- mapping bullet forms to depth
+tracklists.bullets.max = 0
tracklists.lastbullet = ""
n = 0
@@ -47,6 +48,32 @@ local utfchar = P{ -- from l-lpeg.lua, modified to use as grammar
}
+do
+ local c = {}
+ c.roman = S"ivxlcdm"^1
+ c.Roman = S"IVXLCDM"^1
+ c.alpha = R"az"
+ c.Alpha = R"AZ"
+ c.digit = R"09"^1
+ c.auto = P"#"
+
+ local stripme = S" ()."
+ local dontstrip = 1 - stripme
+ local itemstripper = stripme^0 * C(dontstrip^1) * stripme^0
+
+ local con = function (str)
+ print("This is it: >"..str.."<")
+ str = itemstripper:match(str)
+ for conv, pat in next, c do
+ if pat:match(str) then
+ return conv
+ end
+ end
+ return false
+ end
+ tracklists.conversion = con
+end
+
local parser = P{
[1] = V"document",
@@ -83,23 +110,22 @@ local parser = P{
-- the next rule handles enumerations as well
bullet_list = V"bullet_init"
- * (V"bullet_list"
- + V"bullet_continue")^0
+ --* (V"bullet_list"
+ --+ V"bullet_continue")^0
+ * (V"bullet_continue"
+ + V"bullet_list")^0
* V"bullet_stop"
* Cmt(Cc(nil), function (s, i)
local t = tracklists
print("[close]>", t.depth)
+ t.bullets[t.depth] = nil -- “pop”
t.depth = t.depth - 1
return true
end),
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_init = V"eol"^0 * V"bullet_first" * V"bullet_itemrest",
bullet_first = #Cmt(V"bullet_indent", function (s, i, bullet)
local t = tracklists
@@ -108,18 +134,21 @@ local parser = P{
print("[first]>",
t.depth,
(t.depth == 0 and n_spaces == 1) or
- (t.depth > 0 and n_spaces > 1), bullet, oldbullet)
+ (t.depth > 0 and n_spaces > 1), bullet, oldbullet,
+ t.conversion(bullet))
if t.depth == 0 and n_spaces == 1 then -- first level
- t.depth = 1
+ t.depth = 1 -- “push”
t.bullets[1] = bullet
t.lastbullet = bullet
+ t.bullets.max = t.bullets.max < t.depth and t.depth or t.bullets.max
return true
- elseif t.depth > 0 and n_spaces > 1 then -- sublist (of sublist)^0
+ 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
+ t.bullets.max = t.bullets.max < t.depth and t.depth or t.bullets.max
return true
end
end
@@ -128,37 +157,50 @@ local parser = P{
--* V"bullet_indent" / rst.startitemize,
* Cs(V"bullet_indent") / rst.startitemize,
+ bullet_indent = V"space"^0 * V"bullet_expr" * V"space"^1,
+
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])
- return t.bullets[t.depth] == bullet
+ t.bullets[t.depth],
+ t.conversion(t.lastbullet),
+ t.conversion(bullet)
+ )
+
+ if utf.len(t.bullets[t.depth]) ~= utf.len(bullet) then
+ return false
+ elseif t.bullets[t.depth] == bullet then
+ return true
+ elseif t.conversion(t.lastbullet) == t.conversion(bullet) then -- same type
+ return true
+ end
+ return true
+ --return t.bullets[t.depth] == bullet
end) / "",
-- ^^^^^
-- otherwise returns the value of V"bullet_indent", not sure why …
- bullet_continue = V"eol"^0
+ bullet_continue = V"eol"^0 -- ^-1
* V"bullet_cont"
* 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_expr"))^1)^0))
+ * (V"bullet_match" * (V"bullet_rest" - V"bullet_indent"))^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"⁃",
+ + (V"number_char" * P")")
+ + (V"number_char" * V"dot") * #V"space"
+ + (V"number_char" * #V"space")
+ ,
number_char = V"roman_numeral"
+ V"Roman_numeral"
@@ -169,8 +211,8 @@ local parser = 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)
+ bullet_next = V"space"^1,
+ bullet_match = #Cmt(V"bullet_next", function (s, i, this)
local t = tracklists
print("[match]>>>",
t.depth,
@@ -411,6 +453,8 @@ local parser = P{
adornment_char = S[[!"#$%&'()*+,-./:;<=>?@[]^_`{|}~]] + P[[\\]],
+ bullet_char = S"*+-" + P"•" + P"‣" + P"⁃",
+
digit = R"09",
roman_numeral = S"ivxlcdm"^1,
Roman_numeral = S"IVXLCDM"^1,
@@ -426,7 +470,7 @@ f:close()
print(parser:match(testdata))
print(">>>Last used char>: " ..tracklists.lastbullet.." <<<<")
-print(">>>Max list nestin>: "..#tracklists.bullets .." <<<<")
+print(">>>Max list nestin>: "..tracklists.bullets.max .." <<<<")
--for i,j in next, rst.collected_references do
--print (string.format("== %7s => %s <=", i,j))