Module:Feature

-- local lib = {}

function lib.json(frame) local args = (frame.args and lib.arguments(frame.args)) or lib.arguments(frame)

return require('Module:JSON').encode(mw.loadData('Module:' .. args[1])) end function lib.mergeFrames(frame, parent) local args = {}

if frame then for k,v in pairs(frame.args) do           args[k] = v        end end

if parent then for k,v in pairs(parent.args) do           args[k] = v        end end

return args end

function lib.arguments(origArgs) local args = {}

for k, v in pairs(origArgs) do       if v ~= '' then args[k] = v       end end

return args end

function lib.getSortedKeys(tab) local keys = {} local len_keys = 0

for k,_ in pairs(tab) do   	len_keys = len_keys + 1 keys[len_keys] = k   end

table.sort(keys) return keys end

function lib.groupedArguments(args, numeric) if numeric ~= false then numeric = true end local concat = table.concat local trim = mw.text.trim local type,tonumber = type,tonumber local base = {} local groups = {} for k, v in pairs(args) do       v = trim(v) or ''

if v ~= '' then if type(k) == 'string' then k = trim(k) or ''

if k ~= '' then local splittable = lib.split(k, ':', true)

if #splittable == 1 then base[k] = v                   else local group = trim(splittable[1]) or '' local key = trim(concat(splittable, ':', 2)) or ''

if key ~=  and group ~=  then if numeric then group = tonumber(group)

if group ~= nil then if groups[group] == nil then groups[group] = {} end

groups[group][key] = v                               else base[k] = v                               end else if groups[group] == nil then groups[group] = {} end

groups[group][key] = v                           end else base[k] = v                       end end end else base[k] = v           end end end return base, groups end

function lib.ternary(cond, T, F)   if cond then return T   end

return F end

function lib.tbl_concat(frame) local args = (frame.args and lib.arguments(frame.args)) or lib.arguments(frame) args["pre"] = args["pre"] or args["prepend"]  or "" args["app"] = args["app"] or args["append"]   or "" args["sep"] = args["sep"] or args["separator"] or "," args["tbl"] = args["tbl"] or args[1] if args["sep"] == "false" then args["sep"] = "" end if args["index"] ~= nil then return args["pre"] .. args["tbl"][tonumber(args["index"])] .. args["app"] end

local s = {} local s_len = 0 local indexed_args = {} for i,v in ipairs(args["tbl"]) do       s_len = s_len + 1 s[s_len] = args["pre"] .. v .. args["app"] indexed_args[i] = true end

local keys = {} local keys_len = 0 for k in pairs(args["tbl"]) do   	if indexed_args[k] == nil then keys_len = keys_len + 1 keys[keys_len] = k	   end end

if keys_len ~= 0 then table.sort(keys)

for k = 1, keys_len do       	s_len = s_len + 1 s[s_len] = args["pre"] .. args["tbl"][keys[k]] .. args["app"] end end

return table.concat(s,args["sep"]) end

function lib.tbl_debug(tbl) return table.tostring(tbl) end

function lib.split(str, pattern, plain) -- Splits string into a table --   -- str: string to split -- pattern: pattern to use for splitting local plain = plain or false local sub = string.sub local find = string.find local out = {} local len_out = 0 local i = 1 local split_start, split_end = find(str, pattern, i, plain)

while split_start do   	len_out = len_out + 1 out[len_out] = sub(str, i, split_start - 1) i = split_end + 1 split_start, split_end = find(str, pattern, i, plain) end

out[len_out + 1] = sub(str, i)   return out end

-- Returns an iterator over keys sorted alphabetically -- https://www.lua.org/pil/19.3.html function lib.pairsByAlphabeticalKeys(t, f)   local a = {} local a_len = 0

for n in pairs(t) do    	a_len = a_len + 1 a[a_len] = n   end

table.sort(a, f)   local i = 0      -- iterator variable local iter = function   -- iterator function i = i + 1

if a[i] == nil then return nil end

return a[i], t[a[i]] end

return iter end

function lib.in_array(arr, val) for index, value in ipairs(arr) do       if value == val then return true end end return false end

function lib.string_to_bool(val) return val == 'true' and val ~= 'false' end

-- Helper functions function table.val_to_str(v) if type(v) == "string" then v = string.gsub(v, "\n", "\\n")

if string.match(string.gsub(v, "[^'\"]", ""), '^"+$') then return "'" .. v .. "'"       end

return '"' .. string.gsub(v, '"', '\\"') .. '"' end

return type(v) == "table" and table.tostring(v) or tostring(v) end

function table.key_to_str(k) if type(k) == "string" and string.match(k, "^[_%a][_%a%d]*$") then return k   end return "[" .. table.val_to_str(k) .. "]" end

function table.tostring(tbl) local result = {} local len_result = 0 local indexed_args = {}

for i,v in ipairs(tbl) do   	len_result = len_result + 1 result[len_result] = table.val_to_str(v) indexed_args[i] = true end

for k, v in pairs(tbl) do   	if indexed_args[k] == nil then len_result = len_result + 1 result[len_result] = table.key_to_str(k) .. "=" .. table.val_to_str(v) end end

return "{" .. table.concat(result, ",") .. "}" end

function table.sort_by_keys(tbl, ...) local a = {...} table.sort(tbl, function (u,v)		for i = 1, #a do			if u[a[i]] > v[a[i]] then return false end			if u[a[i]] < v[a[i]] then return true end		end	end) end

return lib -- --