Module:Feature

From Predecessor Wiki
Jump to navigation Jump to search
Template-noinfo.svg Documentation
This module has no documentation. If you know how to use this module, please add some. Module:Feature/doc

-- <pre>
local lib = {}

function lib.json(moduleName)
    return require('Module:JSON').encode(mw.loadData('Module:' .. moduleName))
end
 
local function addToTable(target, origin)
    for k, v in pairs(origin) do
        if v ~= '' then
            target[k] = v
        end
    end
    return target
end

function lib.arguments(origArgs)
    return addToTable({}, origArgs)
end

function lib.frameArguments(frame, checkForParentFrame)
	local result
	-- check if the frame has an args table
	if frame.args and type(frame.args) == "table" then
		-- for simplicity, by this point we assume we have a wiki frame.
		-- regardless whether the frame has a parent or not
		-- we prioritize returning just the arguments from args
		result = lib.arguments(frame.args)
		
		-- if checkForParent input is true and the args table is empty
		-- then we return the args from the parent instead
		if checkForParentFrame == true and next(result) == nil then
			local parent = frame:getParent()
			if parent then
				result = lib.arguments(frame:getParent().args)
			end
		end
	else
		-- no args table, so not a wiki frame
		result = lib.arguments(frame)
	end
	
	return result
end

function lib.mergeArguments(frame)
	if not frame.args then
		return lib.arguments(frame)
	end

	local parent = frame:getParent()
	local result = lib.arguments(frame.args)
	if parent and parent.args then
		return addToTable(result, parent.args)
	end
	
	return result
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(args)
    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

function lib.merge_tables(table1, table2)
	--This returns one table, if the other is empty. Otherwise, the actual merge code would throw an error when a table is empty
	if not table1 then 
		return table2
	elseif not table2 then
		return table1
	else
		for i,v in ipairs(table2) do
			table.insert(table1, v)
		end
		return table1
	end
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

function lib.cloneTable(tbl)
	if(type(tbl) == "table") then
		local result = {}
		for k, v in pairs(tbl) do
			result[k] = v
		end
		return result
	else
		return tbl
	end
end

return lib
-- </pre>
-- [[Category:Lua]]