Módulo:parámetros
Apariencia
La documentación para este módulo puede ser creada en Módulo:parámetros/doc
--versión modificada de https://en.wiktionary.org/wiki/Module:parameters
local export = {}
local NO_PERMITIDO = "[#\\<\\>\\[\\]\\{\\}\\|=]"
local insert = table.insert
local concat = table.concat
local tobool = require("Módulo:sí-no")
local escapar = require("Módulo:string/escapar")
local find = string.find
local generar_traza = require("Módulo:traza")
function export.obtener_parametros(args, params)
local args_new = {}
local requerido = {}
local destino = {}
local patron_lista = {}
local props_lista_posicional
--Procesamos los parámetros buscando propiedades específicas
for nombre, propiedades in pairs(params) do
if type(nombre) == "string" and find(nombre, NO_PERMITIDO) then
error("Los parámetros no pueden tener los caracteres #<>[]{}|=")
end
if propiedades.alias_de then
if type(propiedades.alias_de) ~= "string" then
error("Un parámetro solo puede ser alias respecto de uno no posicional")
end
if not params[propiedades.alias_de] then
error("El parámetro "..nombre.." es alias de un parámetro que no existe ("..propiedades.alias_de..")")
end
if params[propiedades.alias_de].alias_de then
error("Un parámetro no puede ser alias de otro parámetro que ya es alias")
end
destino[nombre] = propiedades.alias_de
propiedades = params[propiedades.alias_de] -- hereda las propiedades del parámetro al que apunta
else
-- Evito el doble conteo
if propiedades.requerido then
requerido[nombre] = true
end
if propiedades.lista then
if type(nombre) ~= "number" then
args_new[nombre] = {} -- si es string, inicializo lista vacía
elseif nombre == 1 then
props_lista_posicional = propiedades -- si es numérico, guardo las propiedades para después
props_lista_posicional.lista = nil -- necesario para que no intente dobleindexar parámetros posicionales
end
end
destino[nombre] = nombre
end
if propiedades.lista and type(nombre) == "string" then
patron_lista[nombre] = "^" .. escapar(nombre) .. "(%d*)$" -- solo guardo parámetros no posicionales que son listas
end
end
local function obtener_destino_indice_props(x)
if destino[x] then
return destino[x], (params[destino[x]].lista and 1 or -1), params[destino[x]]
end
if type(x) == "number" then
if props_lista_posicional then -- si guardé las propiedades de esto, quiere decir que los parámetros posicionales comparten todos las mismas propiedades
return x, -1, props_lista_posicional
end
if destino[1] and patron_lista[destino[1]] then -- patron_lista solo puede contener strings como claves, o sea que es un alias de otra lista
return destino[1], x, params[destino[1]]
end
return x, -1, (params[x] or {})
end
for pname, pattern in pairs(patron_lista) do
local _,_,a = find(x, pattern)
if a then
local idx = (a == "") and 1 or tonumber(a)
assert(idx <= 99, "Desborde de lista")
return destino[pname], idx, params[destino[pname]]
end
end
return nil, -1, {}
end
for name, val in pairs(args) do
if val ~= nil and val ~= "" and val:find("%S") then
val = val:gsub("^%s+", ""):gsub("%s+$", "")
local dest, index, props = obtener_destino_indice_props(name)
if dest then
if props.tipo == "bool" then
val = tobool(val)
elseif props.tipo == "num" then
val = tonumber(val)
assert(type(val) == "number", "Parámetro \""..name.."\": debe especificar un número")
elseif type(props.tipo) == "function" then
val = props.tipo(val)
end
if index == -1 then
if args_new[dest] ~= nil then
generar_traza("rep")
end
args_new[dest] = val
else
if args_new[dest][index] ~= nil then
generar_traza("rep")
end
args_new[dest][index] = val
end
requerido[dest] = nil
end
end
end
-- Reemplazo los 'nil' por los valores predeterminados
for name, props in pairs(params) do
if not props.alias_de and props.por_defecto ~= nil then
if type(args_new[name]) == "table" then
if args_new[name][1] == nil then
args_new[name][1] = props.por_defecto
end
elseif args_new[name] == nil then
args_new[name] = props.por_defecto
end
requerido[name] = nil
end
end
-- verifico que no queden parámetros requeridos
local faltante = {}
for name, _ in pairs(requerido) do
insert(faltante, name)
end
assert(#faltante == 0, "Faltan parámetros requeridos: " .. concat(faltante, ", "))
return args_new
end
return export