Module:Template invocation: Difference between revisions

    From Nonbinary Wiki
    (create module for making template invocations from a template name and a table of arguments, based from User:Anomie's code in Module:Unsubst)
     
    m (12 revisions imported from wikipedia:Module:Template_invocation)
     
    (11 intermediate revisions by 4 users not shown)
    Line 1: Line 1:
    -- This module makes a template invocation from a template name and a table
    -- This module provides functions for making MediaWiki template invocations.
    -- of arguments.
     
    local checkType = require('libraryUtil').checkType


    local p = {}
    local p = {}
    ------------------------------------------------------------------------
    --        Name:  p.name
    --      Purpose:  Find a template invocation name from a page name or a
    --                mw.title object.
    --  Description:  This function detects whether a string or a mw.title
    --                object has been passed in, and uses that to find a
    --                template name as it is used in template invocations.
    --  Parameters:  title - full page name or mw.title object for the
    --                template (string or mw.title object)
    --      Returns:  String
    ------------------------------------------------------------------------
    function p.name(title)
    if type(title) == 'string' then
    title = mw.title.new(title)
    if not title then
    error("invalid title in parameter #1 of function 'name'", 2)
    end
    elseif type(title) ~= 'table' or type(title.getContent) ~= 'function' then
    error("parameter #1 of function 'name' must be a string or a mw.title object", 2)
    end
    if title.namespace == 10 then
    return title.text
    elseif title.namespace == 0 then
    return ':' .. title.prefixedText
    else
    return title.prefixedText
    end
    end
    ------------------------------------------------------------------------
    --        Name:  p.invocation
    --      Purpose:  Construct a MediaWiki template invocation.
    --  Description:  This function makes a template invocation from the
    --                name and the arguments given. Note that it isn't
    --                perfect: we have no way of knowing what whitespace was
    --                in the original invocation, the named parameters will be
    --                alphabetically sorted, and any parameters with duplicate keys
    --                will be removed.
    --  Parameters:  name - the template name, formatted as it will appear
    --                    in the invocation. (string)
    --                args - a table of template arguments. (table)
    --                format - formatting options. (string, optional)
    --                    Set to "nowiki" to escape, curly braces, pipes and
    --                    equals signs with their HTML entities. The default
    --                    is unescaped.
    --      Returns:  String
    ------------------------------------------------------------------------


    function p.invocation(name, args, format)
    function p.invocation(name, args, format)
    -- Copy the invocation args and convert magic words.
    checkType('invocation', 1, name, 'string')
    -- We need to make a copy of the table rather than just using the original,
    checkType('invocation', 2, args, 'table')
    -- as some of the values may be erased when building the invocation.
    checkType('invocation', 3, format, 'string', true)
     
    -- Validate the args table and make a copy to work from. We need to
    -- make a copy of the table rather than just using the original, as
    -- some of the values may be erased when building the invocation.
    local invArgs = {}
    local invArgs = {}
    for k, v in pairs(args) do
    for k, v in pairs(args) do
    local typek = type(k)
    local typev = type(v)
    if typek ~= 'string' and typek ~= 'number'
    or typev ~= 'string' and typev ~= 'number'
    then
    error("invalid arguments table in parameter #2 of " ..
    "'invocation' (keys and values must be strings or numbers)", 2)
    end
    invArgs[k] = v
    invArgs[k] = v
    end
    end
    Line 17: Line 79:
    openb = '{{',
    openb = '{{',
    closeb = '}}',
    closeb = '}}',
    pipe = '|'
    pipe = '|',
    equals = '='
    }
    }
    if format == 'nowiki' then
    if format == 'nowiki' then
    Line 30: Line 93:
    ret[#ret + 1] = name
    ret[#ret + 1] = name
    for k, v in ipairs(invArgs) do
    for k, v in ipairs(invArgs) do
    if v:find('=', 1, true) then
    if type(v) == 'string' and v:find('=', 1, true) then
    -- Likely something like 1=foo=bar, we need to do it as a named arg
    -- Likely something like 1=foo=bar which needs to be displayed as a named arg.
    break
    else
    ret[#ret + 1] = seps.pipe
    ret[#ret + 1] = v
    invArgs[k] = nil -- Erase the key so that we don't add the value twice
    end
    end
    ret[#ret + 1] = seps.pipe
    ret[#ret + 1] = v
    invArgs[k] = nil -- Erase the key so that we don't add the value twice
    end
    end
    for k, v in pairs(invArgs) do
    local keys = {} -- sort parameter list; better than arbitrary order
    for k, _ in pairs(invArgs) do
    keys[#keys + 1] = k
    end
    table.sort(keys, function (a, b)
    -- Sort with keys of type number first, then string.
    if type(a) == type(b) then
    return a < b
    elseif type(a) == 'number' then
    return true
    end
    end)
    for _, v in ipairs(keys) do -- Add named args based on sorted parameter list
    ret[#ret + 1] = seps.pipe
    ret[#ret + 1] = seps.pipe
    ret[#ret + 1] = k
    ret[#ret + 1] = tostring(v)
    ret[#ret + 1] = '='
    ret[#ret + 1] = seps.equals
    ret[#ret + 1] = v
    ret[#ret + 1] = invArgs[v]
    end
    end
    ret[#ret + 1] = seps.closeb
    ret[#ret + 1] = seps.closeb

    Latest revision as of 12:00, 21 May 2021

    Documentation for this module may be created at Module:Template invocation/doc

    -- This module provides functions for making MediaWiki template invocations.
    
    local checkType = require('libraryUtil').checkType
    
    local p = {}
    
    ------------------------------------------------------------------------
    --         Name:  p.name
    --      Purpose:  Find a template invocation name from a page name or a
    --                mw.title object.
    --  Description:  This function detects whether a string or a mw.title
    --                object has been passed in, and uses that to find a
    --                template name as it is used in template invocations.
    --   Parameters:  title - full page name or mw.title object for the
    --                template (string or mw.title object)
    --      Returns:  String
    ------------------------------------------------------------------------
    
    function p.name(title)
    	if type(title) == 'string' then
    		title = mw.title.new(title)
    		if not title then
    			error("invalid title in parameter #1 of function 'name'", 2)
    		end
    	elseif type(title) ~= 'table' or type(title.getContent) ~= 'function' then
    		error("parameter #1 of function 'name' must be a string or a mw.title object", 2)
    	end
    	if title.namespace == 10 then
    		return title.text
    	elseif title.namespace == 0 then
    		return ':' .. title.prefixedText
    	else
    		return title.prefixedText
    	end
    end
    
    ------------------------------------------------------------------------
    --         Name:  p.invocation
    --      Purpose:  Construct a MediaWiki template invocation.
    --  Description:  This function makes a template invocation from the
    --                name and the arguments given. Note that it isn't
    --                perfect: we have no way of knowing what whitespace was
    --                in the original invocation, the named parameters will be
    --                alphabetically sorted, and any parameters with duplicate keys
    --                will be removed.
    --   Parameters:  name - the template name, formatted as it will appear
    --                    in the invocation. (string)
    --                args - a table of template arguments. (table)
    --                format - formatting options. (string, optional)
    --                    Set to "nowiki" to escape, curly braces, pipes and
    --                    equals signs with their HTML entities. The default
    --                    is unescaped.
    --      Returns:  String
    ------------------------------------------------------------------------
    
    function p.invocation(name, args, format)
    	checkType('invocation', 1, name, 'string')
    	checkType('invocation', 2, args, 'table')
    	checkType('invocation', 3, format, 'string', true)
    
    	-- Validate the args table and make a copy to work from. We need to
    	-- make a copy of the table rather than just using the original, as
    	-- some of the values may be erased when building the invocation.
    	local invArgs = {}
    	for k, v in pairs(args) do
    		local typek = type(k)
    		local typev = type(v)
    		if typek ~= 'string' and typek ~= 'number'
    			or typev ~= 'string' and typev ~= 'number'
    		then
    			error("invalid arguments table in parameter #2 of " ..
    			"'invocation' (keys and values must be strings or numbers)", 2)
    		end
    		invArgs[k] = v
    	end
    
    	-- Get the separators to use.
    	local seps = {
    		openb = '{{',
    		closeb = '}}',
    		pipe = '|',
    		equals = '='
    	}
    	if format == 'nowiki' then
    		for k, v in pairs(seps) do
    			seps[k] = mw.text.nowiki(v)
    		end
    	end
    
    	-- Build the invocation body with numbered args first, then named.
    	local ret = {}
    	ret[#ret + 1] = seps.openb
    	ret[#ret + 1] = name
    	for k, v in ipairs(invArgs) do
    		if type(v) == 'string' and v:find('=', 1, true) then
    			-- Likely something like 1=foo=bar which needs to be displayed as a named arg.
    		else
    			ret[#ret + 1] = seps.pipe
    			ret[#ret + 1] = v
    			invArgs[k] = nil -- Erase the key so that we don't add the value twice
    		end
    	end
    	local keys = {} -- sort parameter list; better than arbitrary order
    	for k, _ in pairs(invArgs) do
    		keys[#keys + 1] = k
    	end
    	table.sort(keys, function (a, b)
    			-- Sort with keys of type number first, then string.
    			if type(a) == type(b) then
    				return a < b
    			elseif type(a) == 'number' then
    				return true
    			end
    		end)
    	for _, v in ipairs(keys) do -- Add named args based on sorted parameter list
    		ret[#ret + 1] = seps.pipe
    		ret[#ret + 1] = tostring(v)
    		ret[#ret + 1] = seps.equals
    		ret[#ret + 1] = invArgs[v]
    	end
    	ret[#ret + 1] = seps.closeb
    
    	return table.concat(ret)
    end
    
    return p