Module:Core

local Utils = {}

-- * Collection functions.

function Utils.find(tbl, v_, k_) for _, v in pairs(tbl) do		if k_ 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.ifind(arr, v_) for i, v in ipairs(arr) do		if v == v_ then return i		end end return false 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

-- * 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=) -- "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) return pcall(function return require(string.format("Module:%s", name)) end) 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(nil, test) mw.log(fn and fn(result) or result) end end end

return Utils