- Welcome to the Kancolle Wiki!
- If you have any questions regarding site content, account registration, etc., please visit the KanColle Wiki Discord
Difference between revisions of "Module:Core"
Jump to navigation
Jump to search
Line 1: | Line 1: | ||
− | |||
− | + | local Utils = {} | |
− | function | + | -- * Function functions :V |
− | + | ||
+ | function Utils.id(x) | ||
+ | return x | ||
+ | end | ||
+ | |||
+ | -- * Number functions. | ||
+ | |||
+ | function Utils.round(x) | ||
+ | return math.floor(x + 0.5) | ||
end | end | ||
-- * Collection functions. | -- * Collection functions. | ||
− | function | + | function Utils.find(tbl, v_, k_) |
− | + | for _, v in pairs(tbl) do | |
− | + | if k_ and v and v[k_] == v_ or not k_ and v == v_ then | |
− | + | return v | |
+ | end | ||
+ | end | ||
+ | return false | ||
+ | end | ||
+ | |||
+ | function Utils.includes(tbl, v_, k_) | ||
+ | for _, v in pairs(tbl) do | ||
+ | if k_ and v and v[k_] == v_ or not k_ and v == v_ then | ||
+ | return true | ||
+ | end | ||
+ | end | ||
+ | return false | ||
+ | end | ||
+ | |||
+ | function Utils.map(tbl, fn) | ||
+ | local result = {} | ||
+ | for k, v in pairs(tbl) do | ||
+ | table.insert(result, fn(v, k)) | ||
+ | end | ||
+ | return result | ||
+ | end | ||
+ | |||
+ | function Utils.filter(tbl, pred) | ||
+ | local result = {} | ||
+ | for k, v in pairs(tbl) do | ||
+ | if pred(v, k) then | ||
+ | table.insert(result, v) | ||
+ | end | ||
+ | end | ||
+ | return result | ||
+ | end | ||
+ | |||
+ | function Utils.first(tbl) | ||
+ | for k, v in pairs(tbl) do | ||
+ | return k, v | ||
+ | end | ||
+ | end | ||
+ | |||
+ | function Utils.keys(tbl) | ||
+ | local result = {} | ||
+ | for k, _ in pairs(tbl) do | ||
+ | table.insert(result, k) | ||
+ | end | ||
+ | return result | ||
+ | end | ||
+ | |||
+ | function Utils.ifind(arr, v_) | ||
+ | for i, v in ipairs(arr) do | ||
+ | if v == v_ then | ||
+ | return i | ||
+ | end | ||
+ | end | ||
+ | return false | ||
+ | end | ||
+ | |||
+ | function Utils.ifindBy(arr, p) | ||
+ | for i, v in ipairs(arr) do | ||
+ | if p(v) then | ||
+ | return v, i | ||
+ | end | ||
+ | end | ||
+ | return false | ||
+ | end | ||
+ | |||
+ | function Utils.imax(arr) | ||
+ | local maxValue | ||
+ | local maxIndex | ||
+ | for i, v in ipairs(arr) do | ||
+ | if not maxValue or v > maxValue then | ||
+ | maxValue = v | ||
+ | maxIndex = i | ||
+ | end | ||
+ | end | ||
+ | return maxValue | ||
+ | end | ||
+ | |||
+ | function Utils.imap(arr, fn) | ||
+ | local result = {} | ||
+ | for i, v in ipairs(arr) do | ||
+ | table.insert(result, fn(v, i)) | ||
+ | end | ||
+ | return result | ||
+ | end | ||
+ | |||
+ | function Utils.ifilter(arr, pred) | ||
+ | local result = {} | ||
+ | for i, v in ipairs(arr) do | ||
+ | if pred(v, i) then | ||
+ | table.insert(result, v) | ||
+ | end | ||
+ | end | ||
+ | return result | ||
+ | end | ||
+ | |||
+ | function Utils.ifirst(arr) | ||
+ | for k, v in ipairs(arr) do | ||
+ | return k, v | ||
+ | end | ||
+ | end | ||
+ | |||
+ | function Utils.insertNew(arr, el) | ||
+ | if not Utils.find(arr, el) then | ||
+ | table.insert(arr, el) | ||
+ | end | ||
+ | end | ||
+ | |||
+ | function Utils.concat(arr1, arr2) | ||
+ | for i = 1, #arr2 do | ||
+ | arr1[#arr1 + 1] = arr2[i] | ||
+ | end | ||
+ | return arr1 | ||
+ | end | ||
+ | |||
+ | Utils.join = table.concat | ||
+ | |||
+ | function Utils.ijoin(arr, sep) | ||
+ | sep = sep or "" | ||
+ | return table.concat(arr, sep) | ||
+ | end | ||
+ | |||
+ | function Utils.icopy(arr) | ||
+ | return Utils.imap(arr, function(v) return v end) | ||
+ | end | ||
+ | |||
+ | function Utils.isort(arr) | ||
+ | local result = Utils.icopy(arr) | ||
+ | table.sort(result) | ||
+ | return result | ||
+ | end | ||
+ | |||
+ | function Utils.isum(arr, result) | ||
+ | result = result or 0 | ||
+ | for _, v in ipairs(arr) do | ||
+ | result = result + (v or 0) | ||
+ | end | ||
+ | return result | ||
+ | end | ||
+ | |||
+ | -- * Number functions. | ||
+ | |||
+ | function Utils.round(x) | ||
+ | return x % 2 ~= 0.5 and math.floor(x + 0.5) or x - 0.5 | ||
+ | end | ||
+ | |||
+ | -- * String functions. | ||
+ | |||
+ | function Utils.pad(s, n, c) | ||
+ | c = c or " " | ||
+ | n = n or 0 | ||
+ | s = tostring(s) or "" | ||
+ | return #s < n and string.rep(c, n - #s) .. s or s | ||
+ | end | ||
+ | |||
+ | function Utils.trim(s) | ||
+ | return string.gsub(s, "^%s*(.-)%s*$", "%1") | ||
+ | end | ||
+ | |||
+ | function Utils.startsWith(s, ss) | ||
+ | return string.sub(s, 1, string.len(ss)) == ss | ||
+ | end | ||
+ | |||
+ | -- Capitalize each word in a string. | ||
+ | function Utils.capitalize(s) | ||
+ | s = s:gsub("(%s)(%l)", function(a, b) return a .. string.upper(b) end) | ||
+ | s = s:gsub("^(%l)", function(a) return string.upper(a) end) | ||
+ | return s | ||
+ | end | ||
+ | |||
+ | -- * Wikitext/HTML functions. | ||
+ | |||
+ | function Utils.category(name) | ||
+ | return "[[" .. "Category:" .. name .. "]]" | ||
+ | end | ||
+ | |||
+ | function Utils.red(s) | ||
+ | return Utils.format{[[<span style="color:red">${s}</span>]], s = s} | ||
+ | end | ||
+ | |||
+ | -- * Calling arbitrary Lua functions using #invoke. | ||
+ | |||
+ | -- Used to call Formatting:tooltip in Template:Tooltip, mainly because Lua code properly escapes characters, | ||
+ | -- so that span's title attribute always works. | ||
+ | function Utils.method(frame) | ||
+ | local m = require("Module:" .. frame.args[1]) | ||
+ | local f = frame.args[2] | ||
+ | local args = {} | ||
+ | for k, v in ipairs(frame.args) do | ||
+ | if type(k) == "number" and k >= 3 and type(v) == "string" then | ||
+ | table.insert(args, v) | ||
+ | end | ||
+ | end | ||
+ | return m[f](m, unpack(args)) | ||
+ | end | ||
+ | |||
+ | -- * Frame functions. | ||
+ | |||
+ | local getArgs = require("Module:GetArgs") | ||
+ | |||
+ | -- Unused. | ||
+ | function Utils.getContext(frame) | ||
+ | local frame1 = frame:getParent() | ||
+ | if frame1 then | ||
+ | local frame2 = frame1:getParent() | ||
+ | if frame2 then | ||
+ | return { pagename = frame2:getTitle(), args = getArgs{ frame = frame2 } } | ||
+ | else | ||
+ | return { pagename = frame1:getTitle(), args = getArgs{ frame = frame1 } } | ||
+ | end | ||
+ | else | ||
+ | return { pagename = frame:getTitle(), args = getArgs{ frame = frame } } | ||
end | end | ||
− | |||
− | |||
end | end | ||
− | function | + | -- getParent -> getArgs |
− | + | function Utils.getParentArgs(frame) | |
− | if | + | local frame1 = frame:getParent() |
− | + | if frame1 then | |
+ | return getArgs{ frame = frame1 } | ||
+ | else | ||
+ | return nil | ||
end | end | ||
− | |||
− | |||
end | end | ||
− | return Module | + | -- getArgs + getParent -> getArgs, "implicit" args can be defined in the template (e.g. pagename={{PAGENAME}}) |
+ | -- "explicit" args are user defined. | ||
+ | function Utils.getTemplateArgs(frame) | ||
+ | local frame1 = frame:getParent() | ||
+ | if frame1 then | ||
+ | return { implicit = getArgs{ frame = frame }, explicit = getArgs{ frame = frame1 } } | ||
+ | else | ||
+ | return { implicit = getArgs{ frame = frame }, explicit = {} } | ||
+ | end | ||
+ | end | ||
+ | |||
+ | function Utils.requireModule(name) | ||
+ | local success, data = pcall(function () return require(string.format("Module:%s", name)) end) | ||
+ | -- module without return (or empty, nil, false, true return) gives success = true, data = true | ||
+ | if data == true then | ||
+ | return false, nil | ||
+ | else | ||
+ | return success, data | ||
+ | end | ||
+ | end | ||
+ | |||
+ | -- * Testing functions. | ||
+ | |||
+ | function Utils.debugPrint(x, i) | ||
+ | i = i or 0 | ||
+ | if type(x) == "table" then | ||
+ | for k, v in pairs(x) do | ||
+ | mw.log( | ||
+ | string.rep(" ", i) .. tostring(k) .. " : " .. type(k) .. " = " .. | ||
+ | (type(v) == "table" and "table" or tostring(v) .. " : " .. type(v)) | ||
+ | ) | ||
+ | if type(v) == "table" then | ||
+ | Utils.debugPrint(v, i + 1) | ||
+ | end | ||
+ | end | ||
+ | else | ||
+ | mw.log(tostring(x) .. " : " .. type(x)) | ||
+ | end | ||
+ | end | ||
+ | |||
+ | local function showValue(v) | ||
+ | return type(v) == "string" and string.format('"%s"', v) or type(v) == "function" and '"function"' or tostring(v) | ||
+ | end | ||
+ | |||
+ | function Utils.js(x, i) | ||
+ | i = i or 0 | ||
+ | local r = "" | ||
+ | if type(x) == "table" then | ||
+ | r = "{\n" | ||
+ | for k, v in pairs(x) do | ||
+ | if type(v) == "table" then | ||
+ | r = r .. string.rep(" ", i + 1) .. tostring(k) .. ": " .. Utils.js(v, i + 1) | ||
+ | else | ||
+ | r = r .. string.rep(" ", i + 1) .. tostring(k) .. ": " .. showValue(v) .. ",\n" | ||
+ | end | ||
+ | end | ||
+ | r = r .. string.rep(" ", i) .. (i == 0 and "}\n" or "},\n") | ||
+ | else | ||
+ | return showValue(x) | ||
+ | end | ||
+ | return r | ||
+ | end | ||
+ | |||
+ | function Utils.registerFormatTests(obj, tests, fn) | ||
+ | obj.run_format_tests = function() | ||
+ | for _, test in ipairs(tests) do | ||
+ | local result = obj.format(nil, test) | ||
+ | mw.log(fn and fn(result) or result) | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | |||
+ | function Utils.registerTableTests(obj, tests, fn) | ||
+ | obj.run_table_tests = function() | ||
+ | for _, test in ipairs(tests) do | ||
+ | local result = obj:Table(test) | ||
+ | mw.log(fn and fn(result) or result) | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | |||
+ | function Utils.test(obj, desc, fn) | ||
+ | obj.test = function() | ||
+ | mw.log(desc) | ||
+ | fn(obj) | ||
+ | mw.log("ok") | ||
+ | end | ||
+ | end | ||
+ | |||
+ | Utils.log = mw.log | ||
+ | |||
+ | function Utils.format(s, lookup) | ||
+ | if not lookup then | ||
+ | lookup = s | ||
+ | s = lookup[1] | ||
+ | table.remove(lookup, 1) | ||
+ | end | ||
+ | return (string.gsub(s, '${([^%.%!%:%}%[%]]+)%[?([^%.%!%:%}%]]*)%]?%.?([^%!%:%}]*)!?([^%:%}]?):?([^%}]*)}', | ||
+ | function(name, element, attribute, conversion, format_spec) | ||
+ | --local start_of_value, end_of_value, value = string.find(x, '^${(.-)[[.!:}]') | ||
+ | --local start_of_access, end_of_access, access = string.find(x, '^${.-%[(.-)%][!:}]') | ||
+ | --if not access then | ||
+ | -- start_of_access, end_of_access, access = string.find(x, '^${[^:]-%.(.-)[!:}]') | ||
+ | --end | ||
+ | --local start_of_conversion, end_of_conversion, conversion = string.find(x, '^${.-!(.)[:}]') | ||
+ | --local start_of_format_spec, end_of_format_spec, format_spec = string.find(x, ':(.*)}$') | ||
+ | |||
+ | local value = lookup[name] | ||
+ | if string.len(element) > 0 then | ||
+ | value = value[element] | ||
+ | elseif string.len(attribute) > 0 then | ||
+ | value = value[attribute] | ||
+ | end | ||
+ | |||
+ | if string.len(conversion) > 0 then | ||
+ | if conversion == 's' then | ||
+ | value = tostring(value) | ||
+ | end | ||
+ | end | ||
+ | |||
+ | if string.len(format_spec) > 0 then | ||
+ | local start_of_sign, end_of_sign, sign = string.find(format_spec, '([+%- ])') | ||
+ | local start_of_width, end_of_width, width, comma, precision, option = string.find(format_spec, '(%d*)(,?)([.0-9]*)([bcdeEfFgGnosxX%%]?)$') | ||
+ | precision = string.sub(precision, 2) | ||
+ | local number = tonumber(value) | ||
+ | if #width > 0 then | ||
+ | if number then | ||
+ | value = string.format(string.format(number % 1 ~= 0 and "%%0%s.%sf" or "%%0%sd", width, #precision > 0 and precision or 0), number) | ||
+ | end | ||
+ | value = string.format(string.format("%%0%ss", width), value) | ||
+ | elseif #precision > 0 and number then | ||
+ | value = string.format(string.format("%%0%s.%sf", width, precision), number) | ||
+ | end | ||
+ | if sign then | ||
+ | if number and number > 0 then | ||
+ | if sign == "+" then | ||
+ | value = "+" .. value | ||
+ | elseif sign == " " then | ||
+ | value = " " .. value | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | |||
+ | return value | ||
+ | end)) | ||
+ | end | ||
+ | |||
+ | function Utils.split(string, separator, max_split, plain) | ||
+ | assert(separator ~= '') | ||
+ | assert(max_split == nil or max_split >= 1) | ||
+ | |||
+ | local default_separator = false | ||
+ | |||
+ | local result = {} | ||
+ | |||
+ | if not separator or separator == '' then | ||
+ | separator = '%s+' | ||
+ | plain = false | ||
+ | string = mw.text.trim(string) | ||
+ | if string == '' then | ||
+ | return result | ||
+ | end | ||
+ | end | ||
+ | |||
+ | max_split = max_split or -1 | ||
+ | |||
+ | local item_index, start_index = 1, 1 | ||
+ | local separator_start, separator_end = mw.ustring.find(string, separator, start_index, plain) | ||
+ | while separator_start and max_split ~= 0 do | ||
+ | result[item_index] = mw.ustring.sub(string, start_index, separator_start - 1) | ||
+ | item_index = item_index + 1 | ||
+ | start_index = separator_end + 1 | ||
+ | separator_start, separator_end = mw.ustring.find(string, separator, start_index, plain) | ||
+ | max_split = max_split - 1 | ||
+ | end | ||
+ | result[item_index] = mw.ustring.sub(string, start_index) | ||
+ | |||
+ | return result | ||
+ | end | ||
+ | |||
+ | return Utils |
Revision as of 10:23, 29 March 2019
Documentation for this module may be created at Module:Core/doc
local Utils = {}
-- * Function functions :V
function Utils.id(x)
return x
end
-- * Number functions.
function Utils.round(x)
return math.floor(x + 0.5)
end
-- * Collection functions.
function Utils.find(tbl, v_, k_)
for _, v in pairs(tbl) do
if k_ and v and v[k_] == v_ or not k_ and v == v_ then
return v
end
end
return false
end
function Utils.includes(tbl, v_, k_)
for _, v in pairs(tbl) do
if k_ and v and v[k_] == v_ or not k_ and v == v_ then
return true
end
end
return false
end
function Utils.map(tbl, fn)
local result = {}
for k, v in pairs(tbl) do
table.insert(result, fn(v, k))
end
return result
end
function Utils.filter(tbl, pred)
local result = {}
for k, v in pairs(tbl) do
if pred(v, k) then
table.insert(result, v)
end
end
return result
end
function Utils.first(tbl)
for k, v in pairs(tbl) do
return k, v
end
end
function Utils.keys(tbl)
local result = {}
for k, _ in pairs(tbl) do
table.insert(result, k)
end
return result
end
function Utils.ifind(arr, v_)
for i, v in ipairs(arr) do
if v == v_ then
return i
end
end
return false
end
function Utils.ifindBy(arr, p)
for i, v in ipairs(arr) do
if p(v) then
return v, i
end
end
return false
end
function Utils.imax(arr)
local maxValue
local maxIndex
for i, v in ipairs(arr) do
if not maxValue or v > maxValue then
maxValue = v
maxIndex = i
end
end
return maxValue
end
function Utils.imap(arr, fn)
local result = {}
for i, v in ipairs(arr) do
table.insert(result, fn(v, i))
end
return result
end
function Utils.ifilter(arr, pred)
local result = {}
for i, v in ipairs(arr) do
if pred(v, i) then
table.insert(result, v)
end
end
return result
end
function Utils.ifirst(arr)
for k, v in ipairs(arr) do
return k, v
end
end
function Utils.insertNew(arr, el)
if not Utils.find(arr, el) then
table.insert(arr, el)
end
end
function Utils.concat(arr1, arr2)
for i = 1, #arr2 do
arr1[#arr1 + 1] = arr2[i]
end
return arr1
end
Utils.join = table.concat
function Utils.ijoin(arr, sep)
sep = sep or ""
return table.concat(arr, sep)
end
function Utils.icopy(arr)
return Utils.imap(arr, function(v) return v end)
end
function Utils.isort(arr)
local result = Utils.icopy(arr)
table.sort(result)
return result
end
function Utils.isum(arr, result)
result = result or 0
for _, v in ipairs(arr) do
result = result + (v or 0)
end
return result
end
-- * Number functions.
function Utils.round(x)
return x % 2 ~= 0.5 and math.floor(x + 0.5) or x - 0.5
end
-- * String functions.
function Utils.pad(s, n, c)
c = c or " "
n = n or 0
s = tostring(s) or ""
return #s < n and string.rep(c, n - #s) .. s or s
end
function Utils.trim(s)
return string.gsub(s, "^%s*(.-)%s*$", "%1")
end
function Utils.startsWith(s, ss)
return string.sub(s, 1, string.len(ss)) == ss
end
-- Capitalize each word in a string.
function Utils.capitalize(s)
s = s:gsub("(%s)(%l)", function(a, b) return a .. string.upper(b) end)
s = s:gsub("^(%l)", function(a) return string.upper(a) end)
return s
end
-- * Wikitext/HTML functions.
function Utils.category(name)
return "[[" .. "Category:" .. name .. "]]"
end
function Utils.red(s)
return Utils.format{[[<span style="color:red">${s}</span>]], s = s}
end
-- * Calling arbitrary Lua functions using #invoke.
-- Used to call Formatting:tooltip in Template:Tooltip, mainly because Lua code properly escapes characters,
-- so that span's title attribute always works.
function Utils.method(frame)
local m = require("Module:" .. frame.args[1])
local f = frame.args[2]
local args = {}
for k, v in ipairs(frame.args) do
if type(k) == "number" and k >= 3 and type(v) == "string" then
table.insert(args, v)
end
end
return m[f](m, unpack(args))
end
-- * Frame functions.
local getArgs = require("Module:GetArgs")
-- Unused.
function Utils.getContext(frame)
local frame1 = frame:getParent()
if frame1 then
local frame2 = frame1:getParent()
if frame2 then
return { pagename = frame2:getTitle(), args = getArgs{ frame = frame2 } }
else
return { pagename = frame1:getTitle(), args = getArgs{ frame = frame1 } }
end
else
return { pagename = frame:getTitle(), args = getArgs{ frame = frame } }
end
end
-- getParent -> getArgs
function Utils.getParentArgs(frame)
local frame1 = frame:getParent()
if frame1 then
return getArgs{ frame = frame1 }
else
return nil
end
end
-- getArgs + getParent -> getArgs, "implicit" args can be defined in the template (e.g. pagename={{PAGENAME}})
-- "explicit" args are user defined.
function Utils.getTemplateArgs(frame)
local frame1 = frame:getParent()
if frame1 then
return { implicit = getArgs{ frame = frame }, explicit = getArgs{ frame = frame1 } }
else
return { implicit = getArgs{ frame = frame }, explicit = {} }
end
end
function Utils.requireModule(name)
local success, data = pcall(function () return require(string.format("Module:%s", name)) end)
-- module without return (or empty, nil, false, true return) gives success = true, data = true
if data == true then
return false, nil
else
return success, data
end
end
-- * Testing functions.
function Utils.debugPrint(x, i)
i = i or 0
if type(x) == "table" then
for k, v in pairs(x) do
mw.log(
string.rep(" ", i) .. tostring(k) .. " : " .. type(k) .. " = " ..
(type(v) == "table" and "table" or tostring(v) .. " : " .. type(v))
)
if type(v) == "table" then
Utils.debugPrint(v, i + 1)
end
end
else
mw.log(tostring(x) .. " : " .. type(x))
end
end
local function showValue(v)
return type(v) == "string" and string.format('"%s"', v) or type(v) == "function" and '"function"' or tostring(v)
end
function Utils.js(x, i)
i = i or 0
local r = ""
if type(x) == "table" then
r = "{\n"
for k, v in pairs(x) do
if type(v) == "table" then
r = r .. string.rep(" ", i + 1) .. tostring(k) .. ": " .. Utils.js(v, i + 1)
else
r = r .. string.rep(" ", i + 1) .. tostring(k) .. ": " .. showValue(v) .. ",\n"
end
end
r = r .. string.rep(" ", i) .. (i == 0 and "}\n" or "},\n")
else
return showValue(x)
end
return r
end
function Utils.registerFormatTests(obj, tests, fn)
obj.run_format_tests = function()
for _, test in ipairs(tests) do
local result = obj.format(nil, test)
mw.log(fn and fn(result) or result)
end
end
end
function Utils.registerTableTests(obj, tests, fn)
obj.run_table_tests = function()
for _, test in ipairs(tests) do
local result = obj:Table(test)
mw.log(fn and fn(result) or result)
end
end
end
function Utils.test(obj, desc, fn)
obj.test = function()
mw.log(desc)
fn(obj)
mw.log("ok")
end
end
Utils.log = mw.log
function Utils.format(s, lookup)
if not lookup then
lookup = s
s = lookup[1]
table.remove(lookup, 1)
end
return (string.gsub(s, '${([^%.%!%:%}%[%]]+)%[?([^%.%!%:%}%]]*)%]?%.?([^%!%:%}]*)!?([^%:%}]?):?([^%}]*)}',
function(name, element, attribute, conversion, format_spec)
--local start_of_value, end_of_value, value = string.find(x, '^${(.-)[[.!:}]')
--local start_of_access, end_of_access, access = string.find(x, '^${.-%[(.-)%][!:}]')
--if not access then
-- start_of_access, end_of_access, access = string.find(x, '^${[^:]-%.(.-)[!:}]')
--end
--local start_of_conversion, end_of_conversion, conversion = string.find(x, '^${.-!(.)[:}]')
--local start_of_format_spec, end_of_format_spec, format_spec = string.find(x, ':(.*)}$')
local value = lookup[name]
if string.len(element) > 0 then
value = value[element]
elseif string.len(attribute) > 0 then
value = value[attribute]
end
if string.len(conversion) > 0 then
if conversion == 's' then
value = tostring(value)
end
end
if string.len(format_spec) > 0 then
local start_of_sign, end_of_sign, sign = string.find(format_spec, '([+%- ])')
local start_of_width, end_of_width, width, comma, precision, option = string.find(format_spec, '(%d*)(,?)([.0-9]*)([bcdeEfFgGnosxX%%]?)$')
precision = string.sub(precision, 2)
local number = tonumber(value)
if #width > 0 then
if number then
value = string.format(string.format(number % 1 ~= 0 and "%%0%s.%sf" or "%%0%sd", width, #precision > 0 and precision or 0), number)
end
value = string.format(string.format("%%0%ss", width), value)
elseif #precision > 0 and number then
value = string.format(string.format("%%0%s.%sf", width, precision), number)
end
if sign then
if number and number > 0 then
if sign == "+" then
value = "+" .. value
elseif sign == " " then
value = " " .. value
end
end
end
end
return value
end))
end
function Utils.split(string, separator, max_split, plain)
assert(separator ~= '')
assert(max_split == nil or max_split >= 1)
local default_separator = false
local result = {}
if not separator or separator == '' then
separator = '%s+'
plain = false
string = mw.text.trim(string)
if string == '' then
return result
end
end
max_split = max_split or -1
local item_index, start_index = 1, 1
local separator_start, separator_end = mw.ustring.find(string, separator, start_index, plain)
while separator_start and max_split ~= 0 do
result[item_index] = mw.ustring.sub(string, start_index, separator_start - 1)
item_index = item_index + 1
start_index = separator_end + 1
separator_start, separator_end = mw.ustring.find(string, separator, start_index, plain)
max_split = max_split - 1
end
result[item_index] = mw.ustring.sub(string, start_index)
return result
end
return Utils