From d0ff66c9abe9d6abbca12fd811e0c3cb69c1033a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Fri, 22 Nov 2019 23:26:32 +0800 Subject: =?UTF-8?q?=E6=95=B4=E7=90=86=E4=B8=80=E4=B8=8B=E7=9B=AE=E5=BD=95?= =?UTF-8?q?=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script-beta/src/parser/calcline.lua | 93 +++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 script-beta/src/parser/calcline.lua (limited to 'script-beta/src/parser/calcline.lua') diff --git a/script-beta/src/parser/calcline.lua b/script-beta/src/parser/calcline.lua new file mode 100644 index 00000000..26f475d9 --- /dev/null +++ b/script-beta/src/parser/calcline.lua @@ -0,0 +1,93 @@ +local m = require 'lpeglabel' + +local row +local fl +local NL = (m.P'\r\n' + m.S'\r\n') * m.Cp() / function (pos) + row = row + 1 + fl = pos +end +local ROWCOL = (NL + m.P(1))^0 +local function rowcol(str, n) + row = 1 + fl = 1 + ROWCOL:match(str:sub(1, n)) + local col = n - fl + 1 + return row, col +end + +local function rowcol_utf8(str, n) + row = 1 + fl = 1 + ROWCOL:match(str:sub(1, n)) + return row, utf8.len(str, fl, n) +end + +local function position(str, _row, _col) + local cur = 1 + local row = 1 + while true do + if row == _row then + return cur + _col - 1 + elseif row > _row then + return cur - 1 + end + local pos = str:find('[\r\n]', cur) + if not pos then + return #str + end + row = row + 1 + if str:sub(pos, pos+1) == '\r\n' then + cur = pos + 2 + else + cur = pos + 1 + end + end +end + +local function position_utf8(str, _row, _col) + local cur = 1 + local row = 1 + while true do + if row == _row then + return utf8.offset(str, _col, cur) + elseif row > _row then + return cur - 1 + end + local pos = str:find('[\r\n]', cur) + if not pos then + return #str + end + row = row + 1 + if str:sub(pos, pos+1) == '\r\n' then + cur = pos + 2 + else + cur = pos + 1 + end + end +end + +local NL = m.P'\r\n' + m.S'\r\n' + +local function line(str, row) + local count = 0 + local res + local LINE = m.Cmt((1 - NL)^0, function (_, _, c) + count = count + 1 + if count == row then + res = c + return false + end + return true + end) + local MATCH = (LINE * NL)^0 * LINE + MATCH:match(str) + return res +end + +return { + rowcol = rowcol, + rowcol_utf8 = rowcol_utf8, + position = position, + position_utf8 = position_utf8, + line = line, +} -- cgit v1.2.3