summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/catch.lua108
-rw-r--r--test/references/init.lua2
2 files changed, 57 insertions, 53 deletions
diff --git a/test/catch.lua b/test/catch.lua
index 09b55929..849be09d 100644
--- a/test/catch.lua
+++ b/test/catch.lua
@@ -1,3 +1,5 @@
+local m = require 'lpeglabel'
+
local mt = {}
local function catchedTable()
@@ -18,63 +20,65 @@ function mt.__add(a, b)
return t
end
-local function getLine(offset, lns)
- for i = 0, #lns do
- if offset >= lns[i]
- and offset < lns[i+1] then
- return i
- end
- end
-end
-
-local function getPosition(offset, lns)
- for i = 0, #lns do
- if offset >= lns[i]
- and offset < lns[i+1] then
- return 10000 * i + offset - lns[i]
- end
- 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 sep string
-return function (script, sep)
- local pattern = ('()<(%s).-%s>()'):format(sep, sep)
- local lns = {}
- lns[0] = 0
- for pos in script:gmatch '()\n' do
- lns[#lns+1] = pos
- end
- lns[#lns+1] = math.maxinteger
- local codes = {}
- local pos = 1
- ---@type integer[]
- local list = {}
- local cuted = 0
- local lastLine = 0
- for a, char, b in script:gmatch(pattern) do
- codes[#codes+1] = script:sub(pos, a - 1)
- codes[#codes+1] = script:sub(a + 2, b - 3)
- pos = b
- local line1 = getLine(a + 1, lns)
- if line1 ~= lastLine then
- cuted = 0
- lastLine = line1
+---@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
- cuted = cuted + 2
- local left = getPosition(a + 1, lns) - cuted
- local line2 = getLine(b - 3, lns)
- if line2 ~= lastLine then
- cuted = 0
- lastLine = line2
+ if mode == 'NL' then
+ newBuf[#newBuf+1] = text
+ line = line + 1
+ lineOffset = offset + #text - skipOffset
end
- local right = getPosition(b - 3, lns) - cuted
- cuted = cuted + 2
- if not list[char] then
- list[char] = catchedTable()
+ 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
- list[char][#list[char]+1] = { left, right }
end
- codes[#codes+1] = script:sub(pos)
- return table.concat(codes), list
+
+ return table.concat(newBuf), result
end
diff --git a/test/references/init.lua b/test/references/init.lua
index a14f0a02..78e9aabf 100644
--- a/test/references/init.lua
+++ b/test/references/init.lua
@@ -20,7 +20,7 @@ end
function TEST(script)
files.removeAll()
- local newScript, catched = catch(script, '[!?~]')
+ local newScript, catched = catch(script, '!?~')
files.setText('', newScript)
local input = catched['?'] + catched['~']