Module:Template invocation

--[[ SPDX-FileCopyrightText: © 2014 Mr. Stradivarius 

SPDX-License-Identifier: CC-BY-SA-3.0 AND GFDL-1.3-or-later

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 = '', 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