Module:parameters: Difference between revisions

no edit summary
No edit summary
No edit summary
Line 1: Line 1:
local export = {}
local export = {}


-- A helper function to escape magic characters in a string
local function track(page, calling_module, calling_function, param_name)
-- Magic characters: ^$()%.[]*+-?
return true
local plain = require("Module:string").pattern_escape
end


-- A helper function that removes empty numeric indexes in a table,
function export.process(args, params, return_unknown, calling_module, calling_function)
-- so that the values are tightly packed like in a normal Lua table.
local remove_holes = require("Module:table").compressSparseArray
 
function export.process(args, params, return_unknown)
local args_new = {}
local args_new = {}
if not calling_module then
track("no calling module")
end
if not calling_function then
track("no calling function", calling_module)
end
-- Process parameters for specific properties
-- Process parameters for specific properties
Line 20: Line 23:
for name, param in pairs(params) do
for name, param in pairs(params) do
if param.required then
if param.required then
if param.alias_of then
track("required alias", calling_module, calling_function, name)
end
required[name] = true
required[name] = true
end
if name == 1 and param.no_lang_code then
if not params["notlangcode"] then
error("The parameter \"notlangcode\" must be enabled for this template.", 2)
elseif not args["notlangcode"] and require("Module:languages").getByCode(args[name]) then
error("The parameter \"" .. name .. "\" should not be a language code.", 2)
end
end
end
if param.list then
if param.list then
-- A helper function to escape magic characters in a string
-- Magic characters: ^$()%.[]*+-?
local plain = require("Module:string/pattern_escape")
local key = name
local key = name
if type(name) == "string" then
if type(name) == "string" then
Line 68: Line 86:
end
end


--Process required changes to `params`
--Process required changes to `params`.
for _, name in ipairs(names_with_equal_sign) do
if #names_with_equal_sign > 0 then
params[string.gsub(name, "=", "")] = params[name]
local m_params_data = calling_module and mw.loadData("Module:parameters/data")[calling_module]
params[name] = nil
-- If there is a ready-made version in the data module, use that.
if m_params_data and m_params_data[calling_function .. "_no_equals"] then
params = m_params_data[calling_function .. "_no_equals"]
-- Otherwise, shallow copy the params table and substitute the keys.
else
params = require("Module:table").shallowcopy(params)
for _, name in ipairs(names_with_equal_sign) do
track("name with equals", calling_module, calling_function, name)
params[string.gsub(name, "=", "")] = params[name]
params[name] = nil
end
end
end
end


-- Process the arguments
-- Process the arguments
local args_unknown = {}
local args_unknown = {}
local max_index
for name, val in pairs(args) do
for name, val in pairs(args) do
Line 111: Line 141:
-- If no index was found, use 1 as the default index.
-- If no index was found, use 1 as the default index.
-- This makes list parameters like g, g2, g3 put g at index 1.
-- This makes list parameters like g, g2, g3 put g at index 1.
index = index or 1
-- If `separate_no_index` is set, then use 0 as the default instead.
index = index or (param and param.separate_no_index and 0) or 1
-- If the argument is not in the list of parameters, trigger an error.
-- If the argument is not in the list of parameters, trigger an error.
Line 130: Line 161:
if val == "" and not param.allow_empty then
if val == "" and not param.allow_empty then
val = nil
val = nil
-- Track empty parameters, unless (1) allow_empty is set or (2) they're numbered parameters where a higher numbered parameter is also in use (e.g. track {{l|en|term|}}, but not {{l|en||term}}).
if type(name) == "number" and not max_index then
-- Find the highest numbered parameter that's in use/an empty string, as we don't want parameters like 500= to mean we can't track any empty parameters with a lower index than 500.
local max_contiguous_index = 0
while args[max_contiguous_index + 1] do
max_contiguous_index = max_contiguous_index + 1
end
if max_contiguous_index > 0 then
for name, val in pairs(args) do
if type(name) == "number" and name > 0 and name <= max_contiguous_index and ((not max_index) or name > max_index) and val ~= "" then
max_index = name
end
end
end
max_index = max_index or 0
end
if type(name) ~= "number" or name > max_index then
track("empty parameter", calling_module, calling_function, name)
end
end
end
Line 137: Line 187:
elseif param.type == "number" then
elseif param.type == "number" then
val = tonumber(val)
val = tonumber(val)
elseif param.type then
track("unrecognized type", calling_module, calling_function, name)
track("unrecognized type/" .. tostring(param.type), calling_module, calling_function, name)
end
end
Line 153: Line 206:
-- Store the highest index we find.
-- Store the highest index we find.
args_new[name].maxindex = math.max(index, args_new[name].maxindex)
args_new[name].maxindex = math.max(index, args_new[name].maxindex)
if args_new[name][0] then
args_new[name].default = args_new[name][0]
args_new[name][0] = nil
end
elseif args[param.alias_of] == nil then
elseif args[param.alias_of] == nil then
if params[param.alias_of] and params[param.alias_of].list then
if params[param.alias_of] and params[param.alias_of].list then
Line 185: Line 242:
-- The required table should now be empty.
-- The required table should now be empty.
-- If any entry remains, trigger an error, unless we're in the template namespace.
-- If any entry remains, trigger an error, unless we're in the template namespace.
if mw.title.getCurrentTitle().nsText ~= "Template" then
if mw.title.getCurrentTitle().namespace ~= 10 then
local list = {}
local list = {}
for name, param in pairs(required) do
for name, param in pairs(required) do
table.insert(list, name)
table.insert(list, name)
end
end
if #list > 0 then
local count = #list
error('The parameters "' .. mw.text.listToText(list, '", "', '" and "') .. '" are required.', 2)
if count == 1 then
error('The parameter "' .. list[1] .. '" is required.', 2)
elseif count == 2 then
error('The parameters "' .. table.concat(list, '" and "') .. '" are required.', 2)
elseif count > 2 then
error('The parameters "' .. mw.text.listToText(list, '", "', '", and "') .. '" are required.', 2)
end
end
end
end
Line 204: Line 255:
for name, val in pairs(args_new) do
for name, val in pairs(args_new) do
if type(val) == "table" and not params[name].allow_holes then
if type(val) == "table" and not params[name].allow_holes then
args_new[name] = remove_holes(val)
args_new[name] = require("Module:parameters/remove_holes")(val)
end
end
end
end