mirror of
https://github.com/linux-man/LoveFrames.git
synced 2024-12-03 18:24:21 +00:00
129 lines
2.9 KiB
Lua
129 lines
2.9 KiB
Lua
return function(utf8)
|
|
|
|
local byte = utf8.byte
|
|
local unpack = utf8.config.unpack
|
|
|
|
local builder = {}
|
|
local mt = {__index = builder}
|
|
|
|
utf8.regex.compiletime.charclass.builder = builder
|
|
|
|
function builder.new()
|
|
return setmetatable({}, mt)
|
|
end
|
|
|
|
function builder:invert()
|
|
self.inverted = true
|
|
return self
|
|
end
|
|
|
|
function builder:internal() -- is it enclosed in []
|
|
self.internal = true
|
|
return self
|
|
end
|
|
|
|
function builder:with_codes(...)
|
|
local codes = {...}
|
|
self.codes = self.codes or {}
|
|
|
|
for _, v in ipairs(codes) do
|
|
table.insert(self.codes, type(v) == "number" and v or byte(v))
|
|
end
|
|
|
|
table.sort(self.codes)
|
|
return self
|
|
end
|
|
|
|
function builder:with_ranges(...)
|
|
local ranges = {...}
|
|
self.ranges = self.ranges or {}
|
|
|
|
for _, v in ipairs(ranges) do
|
|
table.insert(self.ranges, v)
|
|
end
|
|
|
|
return self
|
|
end
|
|
|
|
function builder:with_classes(...)
|
|
local classes = {...}
|
|
self.classes = self.classes or {}
|
|
|
|
for _, v in ipairs(classes) do
|
|
table.insert(self.classes, v)
|
|
end
|
|
|
|
return self
|
|
end
|
|
|
|
function builder:without_classes(...)
|
|
local not_classes = {...}
|
|
self.not_classes = self.not_classes or {}
|
|
|
|
for _, v in ipairs(not_classes) do
|
|
table.insert(self.not_classes, v)
|
|
end
|
|
|
|
return self
|
|
end
|
|
|
|
function builder:include(b)
|
|
if not b.inverted then
|
|
if b.codes then
|
|
self:with_codes(unpack(b.codes))
|
|
end
|
|
if b.ranges then
|
|
self:with_ranges(unpack(b.ranges))
|
|
end
|
|
if b.classes then
|
|
self:with_classes(unpack(b.classes))
|
|
end
|
|
if b.not_classes then
|
|
self:without_classes(unpack(b.not_classes))
|
|
end
|
|
else
|
|
self.includes = self.includes or {}
|
|
self.includes[#self.includes + 1] = b
|
|
end
|
|
return self
|
|
end
|
|
|
|
function builder:build()
|
|
if self.codes and #self.codes == 1 and not self.inverted and not self.ranges and not self.classes and not self.not_classes and not self.includes then
|
|
return "{test = function(self, cc) return cc == " .. self.codes[1] .. " end}"
|
|
else
|
|
local codes_list = table.concat(self.codes or {}, ', ')
|
|
local ranges_list = ''
|
|
for i, r in ipairs(self.ranges or {}) do ranges_list = ranges_list .. (i > 1 and ', {' or '{') .. tostring(r[1]) .. ', ' .. tostring(r[2]) .. '}' end
|
|
local classes_list = ''
|
|
if self.classes then classes_list = "'" .. table.concat(self.classes, "', '") .. "'" end
|
|
local not_classes_list = ''
|
|
if self.not_classes then not_classes_list = "'" .. table.concat(self.not_classes, "', '") .. "'" end
|
|
|
|
local subs_list = ''
|
|
for i, r in ipairs(self.includes or {}) do subs_list = subs_list .. (i > 1 and ', ' or '') .. r:build() .. '' end
|
|
|
|
local src = [[cl.new():with_codes(
|
|
]] .. codes_list .. [[
|
|
):with_ranges(
|
|
]] .. ranges_list .. [[
|
|
):with_classes(
|
|
]] .. classes_list .. [[
|
|
):without_classes(
|
|
]] .. not_classes_list .. [[
|
|
):with_subs(
|
|
]] .. subs_list .. [[
|
|
)]]
|
|
|
|
if self.inverted then
|
|
src = src .. ':invert()'
|
|
end
|
|
|
|
return src
|
|
end
|
|
end
|
|
|
|
return builder
|
|
|
|
end
|