diff options
Diffstat (limited to 'test/catch.lua')
-rw-r--r-- | test/catch.lua | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/test/catch.lua b/test/catch.lua new file mode 100644 index 00000000..849be09d --- /dev/null +++ b/test/catch.lua @@ -0,0 +1,84 @@ +local m = require 'lpeglabel' + +local mt = {} + +local function catchedTable() + return setmetatable({}, mt) +end + +function mt.__add(a, b) + if not a or not b then + return a or b + end + local t = catchedTable() + for _, v in ipairs(a) do + t[#t+1] = v + end + for _, v in ipairs(b) do + t[#t+1] = v + end + return t +end + +local function parseTokens(script, seps) + local parser = m.P { + m.Ct(m.V 'Token'^0), + Token = m.Cp() * (m.V 'Mark' + m.V 'Nl' + m.V 'Text'), + Mark = m.Cc 'ML' * m.P '<' * m.C(m.S(seps)) + + m.Cc 'MR' * m.C(m.S(seps)) * m.P '>', + Nl = m.Cc 'NL' * m.C(m.P '\r\n' + m.S '\r\n'), + Text = m.Cc 'TX' * m.C((1 - m.V 'Nl' - m.V 'Mark')^1), + } + local results = parser:match(script) + return results +end + +---@param script string +---@param seps string +return function (script, seps) + local tokens = parseTokens(script, seps) + local newBuf = {} + local result = {} + local marks = {} + + local lineOffset = 1 + local line = 0 + local skipOffset = 0 + for i = 1, #tokens, 3 do + local offset = tokens[i + 0] + local mode = tokens[i + 1] + local text = tokens[i + 2] + if mode == 'TX' then + newBuf[#newBuf+1] = text + end + if mode == 'NL' then + newBuf[#newBuf+1] = text + line = line + 1 + lineOffset = offset + #text - skipOffset + end + if mode == 'ML' then + marks[#marks+1] = { + char = text, + position = line * 10000 + offset - skipOffset - lineOffset, + } + skipOffset = skipOffset + 1 + #text + end + if mode == 'MR' then + for j = #marks, 1, -1 do + local mark = marks[j] + if mark.char == text then + local position = line * 10000 + offset - skipOffset - lineOffset + if not result[text] then + result[text] = catchedTable() + end + result[text][#result[text]+1] = { mark.position, position } + table.remove(marks, j) + break + end + end + skipOffset = skipOffset + 1 + #text + end + end + + return table.concat(newBuf), result +end |