summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rst_helpers.lua111
-rw-r--r--rst_parser.lua124
2 files changed, 119 insertions, 116 deletions
diff --git a/rst_helpers.lua b/rst_helpers.lua
index a635996..b30370a 100644
--- a/rst_helpers.lua
+++ b/rst_helpers.lua
@@ -590,5 +590,116 @@ function helpers.table.simple(raw)
return rows
end
+helpers.list = {}
+
+do
+ local c = {}
+ c.roman = S"ivxlcdm"^1
+ c.Roman = S"IVXLCDM"^1
+ c.alpha = R"az" - P"i"
+ c.Alpha = R"AZ" - P"I"
+ 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
+ helpers.list.conversion = con
+
+ local rnums = {
+ i = 1,
+ v = 5,
+ x = 10,
+ l = 50,
+ c = 100,
+ d = 500,
+ m = 1000,
+ }
+
+ local function roman_to_arab (str)
+ local n = 1
+ local curr, succ
+ local max_three = { }
+ local value = 0
+ while n <= #str do
+ if curr and curr == max_three[#max_three] then
+ if #max_three >= 3 then
+ return "Not a number"
+ else
+ max_three[#max_three+1] = curr
+ end
+ else
+ max_three = { curr }
+ end
+
+ curr = rnums[str:sub(n,n)]
+
+ n = n + 1
+ succ = str:sub(n,n)
+
+ if succ and succ ~= "" then
+ succ = rnums[succ]
+ if curr < succ then
+ --n = n + 1
+ --value = value + succ - curr
+ value = value - curr
+ else
+ value = value + curr
+ end
+ else
+ value = value + curr
+ end
+ end
+ return value
+ end
+ helpers.list.roman_to_arab = roman_to_arab
+
+ local suc = function (str, old)
+ str, old = itemstripper:match(str), itemstripper:match(old)
+ local n_str, n_old = tonumber(str), tonumber(old)
+ if n_str and n_old then -- arabic numeral
+ return n_str == n_old + 1
+ end
+
+ local con_str, con_old = con(str), con(old)
+ if con_str == "alpha" or
+ con_str == "Alpha" then
+ return str:byte() == old:byte() + 1
+ else -- “I'm a Roman!” - “A woman?” - “No, *Roman*! - Au!” - “So your father was a woman?”
+ if not (str:lower() == str or
+ str:upper() == str) then -- uneven cased --> fail
+ return false
+ end
+
+
+ local trc = state.roman_cache
+ n_str = trc[str] or nil
+ n_old = trc[old] or nil
+ if not n_str then
+ n_str = roman_to_arab(str:lower())
+ trc[str] = n_str
+ end
+ if not n_old then
+ n_old = roman_to_arab(old:lower())
+ trc[old] = n_old
+ end
+ --print(n_str, n_old, n_str == n_old + 1 )
+ return n_str == n_old + 1
+ end
+ end
+ helpers.list.successor = suc
+end
+
return helpers
diff --git a/rst_parser.lua b/rst_parser.lua
index b3e5f27..13f3a2d 100644
--- a/rst_parser.lua
+++ b/rst_parser.lua
@@ -88,115 +88,6 @@ 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" - P"i"
- c.Alpha = R"AZ" - P"I"
- 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
- state.conversion = con
-
- local rnums = {
- i = 1,
- v = 5,
- x = 10,
- l = 50,
- c = 100,
- d = 500,
- m = 1000,
- }
-
- local function roman_to_arab (str)
- local n = 1
- local curr, succ
- local max_three = { }
- local value = 0
- while n <= #str do
- if curr and curr == max_three[#max_three] then
- if #max_three >= 3 then
- return "Not a number"
- else
- max_three[#max_three+1] = curr
- end
- else
- max_three = { curr }
- end
-
- curr = rnums[str:sub(n,n)]
-
- n = n + 1
- succ = str:sub(n,n)
-
- if succ and succ ~= "" then
- succ = rnums[succ]
- if curr < succ then
- --n = n + 1
- --value = value + succ - curr
- value = value - curr
- else
- value = value + curr
- end
- else
- value = value + curr
- end
- end
- return value
- end
- state.roman_to_arab = roman_to_arab
-
- local suc = function (str, old)
- str, old = itemstripper:match(str), itemstripper:match(old)
- local n_str, n_old = tonumber(str), tonumber(old)
- if n_str and n_old then -- arabic numeral
- return n_str == n_old + 1
- end
-
- local con_str, con_old = con(str), con(old)
- if con_str == "alpha" or
- con_str == "Alpha" then
- return str:byte() == old:byte() + 1
- else -- “I'm a Roman!” - “A woman?” - “No, *Roman*! - Au!” - “So your father was a woman?”
- if not (str:lower() == str or
- str:upper() == str) then -- uneven cased --> fail
- return false
- end
-
-
- local trc = state.roman_cache
- n_str = trc[str] or nil
- n_old = trc[old] or nil
- if not n_str then
- n_str = roman_to_arab(str:lower())
- trc[str] = n_str
- end
- if not n_old then
- n_old = roman_to_arab(old:lower())
- trc[old] = n_old
- end
- --print(n_str, n_old, n_str == n_old + 1 )
- return n_str == n_old + 1
- end
-
- end
- state.successor = suc
-end
local parser = P{
[1] = V"document",
@@ -872,7 +763,7 @@ local parser = P{
(t.depth > 0 and n_spaces > 1),
bullet,
oldbullet,
- t.conversion(bullet))
+ helpers.list.conversion(bullet))
if t.depth == 0 and n_spaces == 1 then -- first level
t.depth = 1 -- “push”
@@ -898,23 +789,24 @@ local parser = P{
bullet_cont = Cmt(V"bullet_indent", function (s, i, bullet)
local t = state
+ local conversion = helpers.list.conversion
warn("conti",
t.depth,
bullet == t.bullets[t.depth],
bullet,
t.bullets[t.depth],
t.lastbullets[t.depth],
- t.conversion(t.lastbullet),
- t.conversion(bullet)
+ conversion(t.lastbullet),
+ conversion(bullet)
)
if utf.len(t.bullets[t.depth]) ~= utf.len(bullet) then
return false
- elseif not t.conversion(bullet) and t.bullets[t.depth] == bullet then
+ elseif not conversion(bullet) and t.bullets[t.depth] == bullet then
return true
- elseif t.conversion(t.lastbullet) == t.conversion(bullet) then -- same type
- local autoconv = t.conversion(bullet) == "auto"
- local successor = t.successor(bullet, t.lastbullet)
+ elseif conversion(t.lastbullet) == conversion(bullet) then -- same type
+ local autoconv = conversion(bullet) == "auto"
+ local successor = helpers.list.successor(bullet, t.lastbullet)
t.lastbullet = bullet
return autoconv or successor
end