La documentación para este módulo puede ser creada en Módulo:etimología/doc

local export = {}
local insert = table.insert
local concat = table.concat

local m_str = require("Módulo:String")
local ucfirst = m_str.ucfirst
local lcfirst = m_str.lcfirst
local substr = m_str.sub
local strlen = m_str.ulen
local strfind = m_str.find
local strsubn = m_str.gsub
local strfind = m_str.find

local obtener_idioma = require("Módulo:lenguas").cod_a_idioma
local generar_error = require("Módulo:traza")
local sortkey = require("Módulo:sortkey").generarSortkey

-- por ahora sin uso
--local function normalizar_cat(x)
--    if x == "latín" then
--        return "latino"
--    end
--    return x
--end

-- Equivalente de l+
local function l_iteracion(p, Idioma, num, tr, alt, glosa, glosa_alt, nl, nlglosa)
    if not p then
        return ""
    end
    
    local t = {}
    
    if p:find("[^a-zA-ZÀ-ž-]+$") then
    	generar_error("etimo")	
    end

	if nl then
		insert(t, alt and " "..alt or " ''"..p.."''")
	else
    	insert(t, " [["..p.."#"..Idioma..(num and " "..num or "").."|''"..(alt and alt or p).."'']]")
	end

    if num then
        insert(t, "<sub>"..num.."</sub>")
    end
    
    if glosa then
    	if nlglosa then
        	glosa = "[["..glosa.."#Español|\""..(glosa_alt and glosa_alt or glosa).."\"]]"
    	else
    		glosa = "\""..(glosa_alt and glosa_alt or glosa).."\""
    	end
    end

    if tr or glosa then
        insert(t, " (")
        if tr then
            insert(t, "''"..tr.."''")
            if glosa then
                insert(t, ", "..glosa)
            end
        else
            insert(t, glosa)
        end
        insert(t, ")")
    end

    return concat(t)
end

local function l_palabras(t, args, i_, l_, k_, sufijo)
	local i = i_ or 2
	local l = l_ or #args
	local k = k_ or 1
	local poner_coma = false
	while i <= l do
		if poner_coma then
			if i == #args then
				if args["e"] and args["e"] ~= "" then
					insert(t, " e")
				else
					insert(t, " y")
				end
			else
				insert(t, ",")
			end
		end
		
		insert(t, l_iteracion(args[i], args["Idioma"], args["num"][k], args["tr"][k], args["alt"][k], args["glosa"][k], args["glosa-alt"][k], args["nl"][k], args["nlglosa"][k]))
		if sufijo then
			insert(t, sufijo) -- caso de las marcas registradas	
		end

		i = i + 1
		k = k + 1
		poner_coma = true
	end
end

local function compuesto(args)
	assert(args[2] and args[3], "El número de argumentos recibidos es insuficiente")
	local t = {}
	insert(t, "Compuesto")
	if args["nota"] and args["nota"] ~= "" then
		insert(t, " ("..args["nota"]..")")	
	end
	insert(t, " de")
	l_palabras(t, args)
	if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
		insert(t, "[[Categoría:"..args["LENG"]..":Palabras formadas por composición|"..sk.."]]")
		if args["nota"] == "acronímico" then
			insert(t, "[[Categoría:"..args["LENG"]..":Palabras formadas por composición acronímica|"..sk.."]]")
		elseif args["nota"] == "cruce" then
			insert(t, "[[Categoría:"..args["LENG"]..":Palabras formadas por cruce|"..sk.."]]")
		end
	end
	return concat(t)
end

local function expresiva(args)
	local t = {}
	insert(t, "Voz [[expresión|expresiva]]")
	if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
		insert(t, "[[Categoría:"..args["LENG"]..":Palabras de origen expresivo|"..sk.."]]")
	end
	return concat(t)
end

local function regresiva(args)
	assert(args[2], "El número de argumentos recibidos es insuficiente")
	local t = {}
	insert(t, "Derivación regresiva de")
	l_palabras(t, args)
	if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
		insert(t, "[[Categoría:"..args["LENG"]..":Palabras formadas por derivación regresiva|"..sk.."]]")
	end
	return concat(t)
end

local function metatesis(args)
	assert(args[2], "El número de argumentos recibidos es insuficiente")
	local t = {}
	insert(t, "Metátesis"..(args["nota"] and " ("..args["nota"]..")" or "").." de")
	l_palabras(t, args)
	if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
		insert(t, "[[Categoría:"..args["LENG"]..":Palabras formadas por metátesis|"..sk.."]]")
	end
	return concat(t)
end

local function fonetica(args)
	assert(args[2], "El número de argumentos recibidos es insuficiente")
	local t = {}
	insert(t, "Alteración fonética"..(args["nota"] and " ("..args["nota"]..")" or "").." de")
	l_palabras(t, args)
	if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
		insert(t, "[[Categoría:"..args["LENG"]..":Palabras formadas por alteración fonética|"..sk.."]]")
	end
	return concat(t)
end

local function acortamiento(args)
	local t = {}
	insert(t, "Acortamiento")
	if args["nota"] and args["nota"] ~= "" then
		insert(t, " ("..args["nota"]..")")
	end
	if args[2] and args[2] ~= "" then
		insert(t, " de")
		l_palabras(t, args)
	end
	if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
		insert(t, "[[Categoría:"..args["LENG"]..":Palabras formadas por acortamiento|"..sk.."]]")
	end
	return concat(t)
end

local function abreviatura(args)
	local t = {}
	insert(t, "Abreviatura")
	if args["nota"] and args["nota"] ~= "" then
		insert(t, " ("..args["nota"]..")")
	end
	if args[2] and args[2] ~= "" then
		insert(t, " de")
		l_palabras(t, args)
	end
	if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
		insert(t, "[[Categoría:"..args["LENG"]..":Abreviaturas|"..sk.."]]")
	end
	return concat(t)	
end

local function sigla(args)
	local t = {}
	insert(t, "Sigla")
	if args["nota"] and args["nota"] ~= "" then
		insert(t, " ("..args["nota"]..")")
	end
	if args[2] and args[2] ~= "" then
		insert(t, " de")
		l_palabras(t, args)
	end
	if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
		insert(t, "[[Categoría:"..args["LENG"]..":Siglas|"..sk.."]]")
	end
	return concat(t)
end

local function diminutivo(args)
	assert(args[2], "El número de argumentos recibidos es insuficiente")
	local t = {}
	insert(t, "Diminutivo"..(args["nota"] and " ("..args["nota"]..")" or "").." de")
	l_palabras(t, args)
	if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
		-- insert(t, "[[Categoría:"..args["LENG"]..":Palabras formadas por sufijación|"..sk.."]]")
		insert(t, "[[Categoría:"..args["LENG"]..":Palabras formadas por sufijo diminutivo|"..sk.."]]")
	end
	return concat(t)
end

local function aumentativo(args)
	assert(args[2], "El número de argumentos recibidos es insuficiente")
	local t = {}
	insert(t, "Aumentativo"..(args["nota"] and " ("..args["nota"]..")" or "").." de")
	l_palabras(t, args)
	if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
		-- insert(t, "[[Categoría:"..args["LENG"]..":Palabras formadas por sufijación|"..sk.."]]")
		insert(t, "[[Categoría:"..args["LENG"]..":Palabras formadas por sufijo aumentativo|"..sk.."]]")
	end
	return concat(t)
end

local function sufijo(args)
	assert(args[2] and args[3], "El número de argumentos recibidos es insuficiente")
	if substr(args[3], 1, 1) ~= "-" then
		args[3] = "-"..args[3]
	end
	local t = {}
	insert(t, "De")
	l_palabras(t, args, 2, 2, 1)
	insert(t, " y el sufijo")
	l_palabras(t, args, 3, 3, 2)
	if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
		--insert(t, "[[Categoría:"..args["LENG"]..":Palabras formadas por sufijación|"..sk.."]]")
		insert(t, "[[Categoría:"..args["LENG"]..":Palabras con el sufijo "..args[3].."|"..sk.."]]")
	end
	return concat(t)
end

local function prefijo(args)
	assert(args[2] and args[3], "El número de argumentos recibidos es insuficiente")
	local L = strlen(args[2])
	if substr(args[2], L, L) ~= "-" then
		args[2] = args[2].."-"
	end
	local t = {}
	insert(t, "Del prefijo")
	l_palabras(t, args, 2, 2, 1)
	insert(t, " y")
	l_palabras(t, args, 3, 3, 2)
	if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
		--insert(t, "[[Categoría:"..args["LENG"]..":Palabras formadas por prefijación|"..sk.."]]")
		insert(t, "[[Categoría:"..args["LENG"]..":Palabras con el prefijo "..args[2].."|"..sk.."]]")
	end
	return concat(t)
end

local function infijo(args)
	assert(args[2] and args[3], "El número de argumentos recibidos es insuficiente")
	if substr(args[3], 1, 1) ~= "-" then
		args[3] = "-"..args[3]
	end
	local L = strlen(args[3])
    if substr(args[3], L, L) ~= "-" then
		args[3] = args[3].."-"
	end
	local t = {}
	insert(t, "De")
	l_palabras(t, args, 2, 2, 1)
	insert(t, " y el infijo")
	l_palabras(t, args, 3, 3, 2)
	if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
		--insert(t, "[[Categoría:"..args["LENG"]..":Palabras formadas por infijación|"..sk.."]]")
		insert(t, "[[Categoría:"..args["LENG"]..":Palabras con el infijo "..args[3].."|"..sk.."]]")
	end
	return concat(t)
end

local function confijo(args)
	assert(args[2] and args[3], "El número de argumentos recibidos es insuficiente")
	local L = strlen(args[2])
	if substr(args[2], L, L) ~= "-" then
		args[2] = args[2].."-"
	end
	local t = {}
	insert(t, "Del prefijo")
	l_palabras(t, args, 2, 2, 1)
	if args[4] and args[4] ~= "" then
		insert(t, ",")
		l_palabras(t, args, 3, 3, 2)
		if substr(args[4], 1, 1) ~= "-" then
			args[4] = "-"..args[4]
		end
		insert(t, " y el sufijo")
		l_palabras(t, args, 4, 4, 3)
		if args["ns"] == 0 then
	        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
			--insert(t, "[[Categoría:"..args["LENG"]..":Palabras formadas por prefijación|"..sk.."]]")
			insert(t, "[[Categoría:"..args["LENG"]..":Palabras con el prefijo "..args[2].."|"..sk.."]]")
			--insert(t, "[[Categoría:"..args["LENG"]..":Palabras formadas por sufijación|"..sk.."]]")
			insert(t, "[[Categoría:"..args["LENG"]..":Palabras con el sufijo "..args[4].."|"..sk.."]]")
		end
	else		
		if substr(args[3], 1, 1) ~= "-" then
			args[3] = "-"..args[3]
		end
		insert(t, " y el sufijo")
		l_palabras(t, args, 3, 3, 2)		
		if args["ns"] == 0 then
	        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
			--insert(t, "[[Categoría:"..args["LENG"]..":Palabras formadas por prefijación|"..sk.."]]")
			insert(t, "[[Categoría:"..args["LENG"]..":Palabras con el prefijo "..args[2].."|"..sk.."]]")
			--insert(t, "[[Categoría:"..args["LENG"]..":Palabras formadas por sufijación|"..sk.."]]")
			insert(t, "[[Categoría:"..args["LENG"]..":Palabras con el sufijo "..args[3].."|"..sk.."]]")
		end
	end
	return concat(t)
end

local function onomatopeya(args)
	local t = {}
	insert(t, "Onomatopéyica")
	if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
        insert(t, "[[Categoría:"..args["LENG"]..":Palabras de origen onomatopéyico|"..sk.."]]")
	end
	return concat(t)
end

local function incierta(args)
	local t = {}
	insert(t, "Incierta")
	if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
        insert(t, "[[Categoría:"..args["LENG"]..":Palabras de origen incierto|"..sk.."]]")
	end
	return concat(t)
end

local function eponimo(args)
    assert(args[2], "El número de argumentos recibidos es insuficiente")
	local t = {}
	insert(t, "Epónimo: "..args[2])
	if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
        insert(t, "[[Categoría:"..args["LENG"]..":Palabras de origen epónimo|"..sk.."]]")
	end
	return concat(t)
end

local function pronominal(args)
    assert(args[2], "El número de argumentos recibidos es insuficiente")
	local t = {}
	insert(t, "De")
	l_palabras(t, args, 2, 2, 1)
	insert(t, " con el [[pronombre reflexivo]] [[átono]]")
	return concat(t)
end

local function femenino(args)
    assert(args[2], "El número de argumentos recibidos es insuficiente")
    if args[3] and not substr(args[3],1,1) == "-" then
        args[3] = "-"..args[3]
    end
	local t = {}
	insert(t, "De")
	l_palabras(t, args, 2, 2, 1)
	insert(t, " y el [[sufijo flexivo]]")
	if args[3] then
        if substr(args[3],1,1) ~= "-" then
            args[3] = "-"..args[3]
        end
        l_palabras(t, args, 3, 3, 2)
    else
        insert(t, " -a")
	end
	insert(t, " para el femenino")
	return concat(t)
end

local function masculino(args)
    assert(args[2], "El número de argumentos recibidos es insuficiente")
    if args[3] and not substr(args[3],1,1) == "-" then
        args[3] = "-"..args[3]
    end
	local t = {}
	insert(t, "De")
	l_palabras(t, args, 2, 2, 1)
	insert(t, " y el [[sufijo flexivo]]")
	if args[3] then
        if substr(args[3],1,1) ~= "-" then
            args[3] = "-"..args[3]
        end
        l_palabras(t, args, 3, 3, 2)
    else
        insert(t, " -o")
	end
	insert(t, " para el masculino")
	return concat(t)
end

local function plural(args)
    assert(args[2], "El número de argumentos recibidos es insuficiente")
    if args[3] and not substr(args[3],1,1) == "-" then
        args[3] = "-"..args[3]
    end
	local t = {}
	insert(t, "De")
	l_palabras(t, args, 2, 2, 1)
	insert(t, " y el [[sufijo flexivo]]")
	if args[3] then
        if substr(args[3],1,1) ~= "-" then
            args[3] = "-"..args[3]
        end
        l_palabras(t, args, 3, 3, 2)
    else
        insert(t, " -s")
	end
	insert(t, " para el plural")
	return concat(t)
end

local function participio(args)
	assert(args[2], "El número de argumentos recibidos es insuficiente")
	local t = {}
	insert(t, "Participio"..(args["nota"] and " ("..args["nota"]..")" or "").." de")
	l_palabras(t, args)
	if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
		insert(t, "[[Categoría:"..args["LENG"]..":Palabras formadas por sufijo participio|"..sk.."]]")
	end
	return concat(t)
end

local function lexicalizacion(args)
	assert(args[2], "El número de argumentos recibidos es insuficiente")
	local t = {}
	insert(t, "Lexicalización"..(args["nota"] and " ("..args["nota"]..")" or "").." de")
	l_palabras(t, args)
	if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
		insert(t, "[[Categoría:"..args["LENG"]..":Palabras formadas por lexicalización|"..sk.."]]")
	end
	return concat(t)
end

local function denominal(args)
	assert(args[2], "El número de argumentos recibidos es insuficiente")
	local t = {}
	insert(t, "Denominal"..(args["nota"] and " ("..args["nota"]..")" or "").." de")
	l_palabras(t, args)
	if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
		insert(t, "[[Categoría:"..args["LENG"]..":Palabras formadas por sufijo denominal|"..sk.."]]")
	end
	return concat(t)
end

local function deadjetival(args)
	assert(args[2], "El número de argumentos recibidos es insuficiente")
	local t = {}
	insert(t, "Deadjetival"..(args["nota"] and " ("..args["nota"]..")" or "").." de")
	l_palabras(t, args)
	if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
		insert(t, "[[Categoría:"..args["LENG"]..":Palabras formadas por sufijo deadjetival|"..sk.."]]")
	end
	return concat(t)
end

local function deverbal(args)
	assert(args[2], "El número de argumentos recibidos es insuficiente")
	local t = {}
	insert(t, "Deverbal"..(args["nota"] and " ("..args["nota"]..")" or "").." de")
	l_palabras(t, args)
	if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
		insert(t, "[[Categoría:"..args["LENG"]..":Palabras formadas por sufijo deverbal|"..sk.."]]")
	end
	return concat(t)
end

local function calco(args)
    assert(args[2] and args[3], "El número de argumentos recibidos es insuficiente")
	local t = {}
	local id = (obtener_idioma(args[2]))[1]
	local Id = ucfirst(id)
	insert(t, "Calco"..(args["nota"] and " ("..args["nota"]..")" or "").." del "..id)
    if (not args["glosa"][1]) and args[4] then -- En la versión anterior hacía esto sólo para esta función, por qué?
    	args["glosa"][1] = args[4]
    end
	insert(t, l_iteracion(args[3], Id, args["num"][1], args["tr"][1], args["alt"][1], args["glosa"][1], args["glosa-alt"][1], args["nl"][1], args["nlglosa"][1]))
	if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
        insert(t, "[[Categoría:"..args["LENG"]..":Palabras formadas por calco|"..sk.."]]")
        insert(t, "[[Categoría:"..args["LENG"]..":Palabras provenientes del "..id.."|"..sk.."]]")
	end
	return concat(t)
end

local function marca(args)
    assert(args[2], "El número de argumentos recibidos es insuficiente")
	local t = {}
	local L = #args
	if L > 2 then
		insert(t, "De las marcas registradas")
	else
		insert(t, "De la marca registrada")
	end
		
	l_palabras(t, args, 2, L, 1, "<sup>®</sup>")
    if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
        insert(t, "[[Categoría:"..args["LENG"]..":Palabras de marcas registradas|"..sk.."]]")
	end
	return concat(t)
end

local function dialecto_de_ojo(args)
	assert(args[2], "El número de argumentos recibidos es insuficiente")
	local t = {}
	insert(t, "Dialecto del ojo "..(args["nota"] and " ("..args["nota"]..")" or "").." para")
	l_palabras(t, args)
	return concat(t)
end

local function endogena(args)
    assert(args[2], "El número de argumentos recibidos es insuficiente")
	local t = {}
	insert(t, "De")
	l_palabras(t, args)
	if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
        insert(t, "[[Categoría:"..args["LENG"]..":Palabras endógenas|"..sk.."]]")	
	end
	return concat(t)
end

local function artificial(args)
	generar_error("invento")
	local t = {}
    if args[2] then
	    insert(t, "Término artificial, inventado por "..args[2])
    else
        insert(t, "Palabra artificial")
    end
    if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
        insert(t, "[[Categoría:"..args["LENG"]..":Palabras artificales|"..sk.."]]")	
	end
	return concat(t)
end

local function autor(args)
    assert(args[2], "El número de argumentos recibidos es insuficiente")
	local t = {}
	insert(t, "Acuñado por "..args[2])
	return concat(t)
end

local function popularizado_por(args)
    assert(args[2], "El número de argumentos recibidos es insuficiente")
	local t = {}
	insert(t, "Populariazado por "..args[2])
	return concat(t)
end

local function metaforica(args)
	local t = {}
	insert(t, "De origen metafórico")
	if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
        insert(t, "[[Categoría:"..args["LENG"]..":Palabras de origen metafórico|"..sk.."]]")	
	end
	return concat(t)
end

local function biblica(args)
	local t = {}
	insert(t, "De origen bíblico")
	if args["ns"] == 0 then
        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
        insert(t, "[[Categoría:"..args["LENG"]..":Palabras de origen bíblico|"..sk.."]]")	
	end
	return concat(t)
end

local function sumadepartes(args)
	error("Parámetro obsoleto (utilice “no aplica” en su lugar)")
end

local function noaplica(args)
	local s = args["tit"]
	s = strsubn(s, "%S+", "[[%0]]")
	s = strsubn(s, "%]%s+%[", "] + [")
    return s
end

local function origen(args, cat)
    assert(args[1], "El número de argumentos recibidos es insuficiente")
    local t = {"Del "}
    local i = 1
    local L = #args
    local idioma = ""
    local idioma_d = ""
    local Idioma = ""
    
    while true do
    	local nuevo_idioma = nil
        if args[3*i-2] == "sufijo" then
        	nuevo_idioma = "sufijo"
        	if args[3*i-1] and substr(args[3*i-1], 1, 1) ~= "-" then
        		args[3*i-1] = "-"..args[3*i-1]
        	end
        elseif args[3*i-2] == "prefijo" then
        	nuevo_idioma = "prefijo"
        	if args[3*i-1] then
        		local L_ = strlen(args[3*i-1])
        		if substr(args[3*i-1], L_, L_) ~= "-" then
        			args[3*i-1] = args[3*i-1].."-"
        		end
        	end
        else
        	nuevo_idioma = obtener_idioma(args[3*i-2])[1]
        end
        
        local nuevo_idioma_d = nuevo_idioma..(args["d"][i] and " ("..args["d"][i]..")" or "")
        if nuevo_idioma_d ~= idioma_d then
            idioma = nuevo_idioma
            idioma_d = nuevo_idioma_d
            Idioma = ucfirst(idioma)
            if i > 1 then
            	insert(t, " del ")	
            end
            insert(t, idioma_d)
        end
        
        insert(t, l_iteracion(args[3*i-1], Idioma, args["num"][i], args["tr"][i], args["alt"][i], args["glosa"][i] and args["glosa"][i] or args[3*i], args["glosa-alt"][i], args["nl"][i], args["nlglosa"][i]))
		
		if args["ns"] == 0 then
	        local sk = sortkey(args["tit"], args["leng"], args["idioma_obj"])
	        if cat then
	    		if idioma == "sufijo" then
					insert(t, "[[Categoría:"..args["LENG"]..":Palabras con el sufijo "..args[3*i-1].."|"..sk.."]]")
	    		elseif idioma == "prefijo" then
					insert(t, "[[Categoría:"..args["LENG"]..":Palabras con el prefijo "..args[3*i-1].."|"..sk.."]]")
				else
	        		insert(t, "[[Categoría:"..args["LENG"]..":Palabras provenientes del "..idioma.."|"..sk.."]]")
	        	end
	        end
		end
    
        i = i + 1
        if 3*i-2 > L then
            break
        end
        
        if 3*i-2 >= L-2 then
            if (args["e"] and args["e"] ~= "") or (args[3*i-2] == args[3*i-5] and args[3*i-1] and strfind(args[3*i-1], "^%-?i")) then
                insert(t, " e")
            else
                insert(t, " y")
            end
        else            
            insert(t, ",")
        end
    end
    return concat(t)
end

local callbacks = {
	["compuesto"] = compuesto,
    ["compuesta"] = compuesto,
    ["COMP"] = compuesto,
    ["voz expresiva"] = expresiva,
    ["expresiva"] = expresiva,
    ["EXPR"] = expresiva,
    ["derivación regresiva"] = regresiva,
    ["regresiva"] = regresiva,
    ["REG"] = regresiva,
    ["metátesis"] = metatesis,
    ["trasposición"] = metatesis,
    ["vesre"] = metatesis,
    ["MET"] = metatesis,
    ["fone"] = fonetica,
    ["FONE"] = fonetica,
    ["fonética"] = fonetica,
    ["alteración fonética"] = fonetica,
    ["adición"] = fonetica,
    ["epéntesis"] = fonetica,
    ["prótesis"] = fonetica,
    ["metaplasmo"] = fonetica,
    ["FON"] = fonetica,
    ["acortamiento"] = acortamiento,
    ["apócope"] = acortamiento,
    ["síncopa"] = acortamiento,
    ["aféresis"] = acortamiento,
    ["abreviación"] = abreviatura,
    ["abreviatura"] = abreviatura,
    ["sigla"] = sigla,
    ["siglas"] = sigla,
    ["supresión"] = acortamiento,
    ["acort"] = acortamiento,
    ["ACORT"] = acortamiento,
    ["diminutivo"] = diminutivo,
    ["dimi"] = diminutivo,
    ["DIMI"] = diminutivo,
    ["aumentativo"] = aumentativo,
    ["aume"] = aumentativo,
    ["AUME"] = aumentativo,
    ["sufijo"] = sufijo,
    ["SUF"] = sufijo,
    ["prefijo"] = prefijo,
    ["PREF"] = prefijo,
    ["infijo"] = infijo,
    ["INF"] = infijo,
    ["confijo"] = confijo,
    ["circunfijo"] = confijo,
    ["CIRCUNF"] = confijo,
    ["CONF"] = confijo,
    ["onomatopeya"] = onomatopeya,
    ["onomatopéyico"] = onomatopeya,
    ["onomatopéyica"] = onomatopeya,
    ["onom"] = onomatopeya,
    ["ONOM"] = onomatopeya,
    ["incierto"] = incierta,
    ["incierta"] = incierta,
    ["INC"] = incierta,
    ["epónimo"] = eponimo,
    ["epónima"] = eponimo,
    ["epon"] = eponimo,
    ["EPON"] = eponimo,
    ["pronominal"] = pronominal,
    ["PRON"] = pronominal,
    ["femenino"] = femenino,
    ["masculino"] = masculino,
    ["FEM"] = femenino,
    ["plural"] = plural,
    ["PLUR"] = plural,
    ["participio"] = participio,
    ["part"] = participio,
    ["PART"] = participio,
    ["lexicalización"] = lexicalizacion,
    ["lexi"] = lexicalizacion,
    ["LEXI"] = lexicalizacion,
    ["denominal"] = denominal,
    ["denom"] = denominal,
    ["DENOM"] = denominal,
    ["deadjetival"] = deadjetival,
    ["deadj"] = deadjetival,
    ["DEADJ"] = deadjetival,
    ["deverbal"] = deverbal,
    ["deverb"] = deverbal,
    ["DEVERB"] = deverbal,
    ["calco"] = calco,
    ["CALC"] = calco,
    ["marca"] = marca,
    ["dialecto de ojo"] = dialecto_de_ojo,
    ["dialecto del ojo"] = dialecto_de_ojo,
    ["endógeno"] = endogena,
    ["endógena"] = endogena,
    ["endo"] = endogena,
    ["ENDO"] = endogena,
    ["artificial"] = artificial,
    ["invento"] = artificial,
    ["autor"] = autor,
    ["acuñado"] = autor,
    ["pop"] = popularizado_por,
    ["popularizado"] = popularizado_por,
    ["metafórico"] = metaforica,
    ["metafórica"] = metaforica,
    ["meta"] = metaforica,
    ["META"] = metaforica,
    ["bíblico"] = biblica,
    ["bíblica"] = biblica,
    ["suma de partes"] = sumadepartes,
    ["suma"] = sumadepartes,
    ["no aplica"] = noaplica,
}

-- Entrada para {{etimología}}
function export.mostrar(frame)
	local title_ = mw.title.getCurrentTitle()
	local title = title_.fullText -- no sirve parent_frame:getTitle()
	if title == "Plantilla:etimología" then
		return "Use esta plantilla en el espacio principal."	
	end
	local params = {
		[1] = {},
		["e"] = {},
		["leng"] = {},
		["d"] = {lista=true},
		["glosa"] = {lista=true},
		["glosa-alt"] = {lista=true},
		["nl"] = {lista = true},
		["nolink"] = {alias_de="nl"},
		["nlglosa"] = {lista = true},
		["nolinkglosa"] = {alias_de="nl"},
		["num"] = {lista=true},
		["núm"] = {alias_de="num"},
		["tr"] = {lista=true},
		["transcripción"] = {alias_de="tr"},
		["tl"] = {alias_de="tr"},
		["transliteración"] = {alias_de="tr"},
		["alt"] = {lista=true},
		["diacrítico"] = {alias_de="alt"},
		["nota"] = {},
		["tilde"] = {},
		["texto-prefijo"] = {},
		["otro"] = {},
	}

    local parent_frame = frame:getParent()
	local args = require("Módulo:parámetros").obtener_parametros(parent_frame.args, params)
	
	local e = false
	for k,v in ipairs(args) do
		if strfind(v, "[%[%]%{%}%|%=]") then
			e = true
			break
		end
	end
	
	for k,v in pairs(args) do
		if strfind(v, "[%[%]%{%}%|%=]") then
			e = true
			break
		end
	end
	
	if (args[1] and (strfind(args[1], " para") or strfind(args[1], " y"))) or
	(args[2] and (strfind(args[2], " para") or strfind(args[2], " y"))) then
		generar_error("sufijopara")	
	end
	
	if e then
		generar_error("etimo")
	end

	if args["tilde"] and args["tilde"] ~= "" then
		generar_error("tilde")
	end
	
	if args["texto-prefijo"] and args["texto-prefijo"] ~= "" then
		generar_error("texto-prefijo")
	end
	
    if args["otro"] and args["otro"] ~= "" then
		generar_error("otro")
	end

    if not args["leng"] then
    	args["leng"] = "es"
    end
    args["LENG"] = args["leng"]:upper()
    args["idioma_obj"] = obtener_idioma(args["leng"])
    args["idioma"] = args["idioma_obj"][1]
    args["Idioma"] = ucfirst(args["idioma"])
    args["ns"] = mw.title.getCurrentTitle().namespace
    args["tit"] = mw.title.getCurrentTitle().fullText
    
    if not args[1] then
    	if strfind(args["tit"], "%S%s+%S") then
    		return noaplica(args)
    	else
    		return frame:extensionTag('span', "''Si puedes, incorpórala: [[Plantilla:etimología|ver cómo]]''"..(args["ns"] == 0 and "[[Categoría:"..args["LENG"]..":Palabras de etimología sin precisar]]" or ""), {style ="color:green; font-size:90%"})
		end    
    end

    local cb = callbacks[args[1]]
    if not cb or (cb == prefijo and args[4] and args[4] ~= "") then
    	return origen(args, true)
    end

    return cb(args)
end

-- Entrada para {{etim}}
function export.mostrar_etim(frame)
	local title_ = mw.title.getCurrentTitle()
	local title = title_.fullText -- no sirve parent_frame:getTitle()
	if title == "Plantilla:etim" then
		return "Use esta plantilla en el espacio principal."	
	end
	
	local params = {
		[1] = {},
		["e"] = {},
		["leng"] = {},
		["d"] = {lista=true},
		["glosa"] = {lista=true},
		["glosa-alt"] = {lista=true},
		["nl"] = {lista = true},
		["nolink"] = {alias_de="nl"},
		["nlglosa"] = {lista = true},
		["nolinkglosa"] = {alias_de="nl"},
		["num"] = {lista=true},
		["núm"] = {alias_de="num"},
		["tr"] = {lista=true},
		["transcripción"] = {alias_de="tr"},
		["tl"] = {alias_de="tr"},
		["transliteración"] = {alias_de="tr"},
		["alt"] = {lista=true},
		["diacrítico"] = {alias_de="alt"},
		["nota"] = {},
		["tilde"] = {},
		["texto-prefijo"] = {},
		["otro"] = {},
	}

    local parent_frame = frame:getParent()
	local args = require("Módulo:parámetros").obtener_parametros(parent_frame.args, params)
	
	local e = false
	for k,v in ipairs(args) do
		if strfind(v, "[%[%]%{%}%|%=]") then
			e = true
			break
		end
	end
	
	for k,v in pairs(args) do
		if strfind(v, "[%[%]%{%}%|%=]") then
			e = true
			break
		end
	end
	
	if e then
		generar_error("etimo")
	end

	if args["tilde"] and args["tilde"] ~= "" then
		generar_error("tilde")
	end
	
	if args["texto-prefijo"] and args["texto-prefijo"] ~= "" then
		generar_error("texto-prefijo")
	end
	
    if args["otro"] and args["otro"] ~= "" then
		generar_error("otro")
	end

    if not args["leng"] then
    	args["leng"] = "es"
    end
    args["LENG"] = args["leng"]:upper()

    if not args[1] then
    	error("El número de parámetros recibidos es insuficiente.")
    end
    
    args["idioma_obj"] = obtener_idioma(args["leng"])
    args["idioma"] = args["idioma_obj"][1]
    args["Idioma"] = ucfirst(args["idioma"])
    args["ns"] = mw.title.getCurrentTitle().namespace
    args["tit"] = mw.title.getCurrentTitle().fullText

    local cb = callbacks[args[1]]
    if not cb then
    	return lcfirst(origen(args, false))
    end

    return lcfirst(cb(args))
end


local strfind = m_str.find

function export.etimologia2(frame)
	local parent_frame = frame:getParent()
	local args = parent_frame.args
	local x = args[1]
	
	local PALABRA = "['“”«»‘’\"%[%]%{%}%|a-zA-ZÀ-ž%*%-=]+"
	local PREFIJO = "['“”«»‘’\"%[%]%{%}%|a-zA-ZÀ-ž%*%-=]+%-['%]]*"
	local SUFIJO = "['%[]*%-['“”«»‘’\"%[%]%{%}%|a-zA-ZÀ-ž%*%-=]+"
	
	if not x or x == "" then
		generar_error("vacia")
		return frame:extensionTag('span', "''Si puedes, incorpórala: [[Plantilla:etimología|ver cómo]]''"..(args["ns"] == 0 and "[[Categoría:"..args["LENG"]..":Palabras de etimología sin precisar]]" or ""), {style ="color:green; font-size:90%"})	
	end
	
	if strfind(x, "^ *[Dd]e *"..PALABRA.."[%.,:; ]*$") or strfind(x, "^ *[vV]er *"..PALABRA.."[%.,:; ]*$") or strfind(x, "^ *[vV].ase *"..PALABRA.."[%.,:; ]*$") then
		generar_error("endo")
		return x
	end
	if strfind(x, "^ *[Dd]el *"..PALABRA.." *"..PALABRA.."[%.,:; ]*$") 
	or strfind(x, "^ *[Dd]el *"..PALABRA.." *"..PALABRA.." *"..PALABRA.."[%.,:; ]*$") 
	or strfind(x, "^ *[Dd]el "..PALABRA.."[%.,:; ]*$") 
	or strfind(x, "^ *[Dd]e *origen *"..PALABRA.."[%.,:; ]*$")  then
		generar_error("origen")
		return x
	end

	if strfind(x, "^ *[dD]el *prefijo *"..PALABRA.." *y *el *sufijo *"..PALABRA.."[%.,:; ]*$")
	or strfind(x, "^ *[dD]e *"..PREFIJO.." *[%+y]* *"..SUFIJO.."[%.,:; ]*$") then
		generar_error("confijo2")
		return x
	end
	
	if strfind(x, "^ *[dD]el *prefijo *"..PALABRA.." *,? *"..PALABRA.." *y *el *sufijo *"..PALABRA.."[%.,:; ]*$") then
		generar_error("confijo3")
		return x
	end
	
	if strfind(x, "^ *[dD]el *prefijo *"..PALABRA.." *y *"..PALABRA.."[%.,:; ]*$") 
	or strfind(x, "^ *[dD]e *"..PREFIJO.." *[%+y]* *"..PALABRA.."[%.,:; ]*$") then
		generar_error("prefijo")
		return x
	end

	if strfind(x, "^ *[dD]e *"..PALABRA.." *,? *y *el *sufijo *"..PALABRA.."[%.,:; ]*$") 
	or strfind(x, "^ *[dD]e *"..PALABRA.." *%+* *"..SUFIJO.."[%.,:; ]*$") then
		generar_error("sufijo")
		return x
	end
	
	if strfind(x, "^ *[dD]?e?l? *[Dd]iminutivo *de *"..PALABRA.."[%.,:; ]*$") or strfind(x, "^ *[dD]e *"..PALABRA.." *,? *y *el *sufijo diminutivo *"..PALABRA.."[%.,:; ]*$") then
		generar_error("diminutivo")
		return x
	end
	
	if strfind(x, "^ *[dD]?e?l? *[Aa]umentativo *de *"..PALABRA.."[%.,:; ]*$") or strfind(x, "^ *[dD]e *"..PALABRA.." *,? *y *el *sufijo aumentativo *"..PALABRA.."[%.,:; ]*$") then
		generar_error("aumentativo")
		return x
	end
	
	if strfind(x, "^ *[cC]ompuesto *de *"..PALABRA.." *y *"..PALABRA.."[%.,:; ]*$") 
	or strfind(x, "^ *[cC]omposici.n *de *"..PALABRA.." *y *"..PALABRA.."[%.,:; ]*$") 
	or strfind(x, "^ *[dD]e *"..PALABRA.." *,? *y *"..PALABRA.."[%.,:; ]*$") then
		generar_error("compuesto")
		return x
	end
	
	if strfind(x, "^ *[pP]?o?r? *[cC]alco *[Dd]el *"..PALABRA.." *"..PALABRA.."[%.,:; ]*$") then
		generar_error("calco")
		return x
	end
	
	if strfind(x, "^ *[pP]?o?r? *[mM]et.tesis *[Dd]e *"..PALABRA.."[%.,:; ]*$")
	or strfind(x, "^ *[pP]?o?r? *[tT]ran?sposici.n *[Dd]e *"..PALABRA.."[%.,:; ]*$") 
	or strfind(x, "^ *[pP]?o?r? *[vV]esre *[Dd]e *"..PALABRA.."[%.,:; ]*$") then
		generar_error("meta")
		return x
	end
	
	if strfind(x, "^ *[pP]?o?r? *[Aa]lteraci.n *[fF]on.tica *[Dd]e *"..PALABRA.."[%.,:; ]*$")
	or strfind(x, "^ *[pP]?o?r? *[Pp]r.tesis *[Dd]e *"..PALABRA.."[%.,:; ]*$")
	or strfind(x, "^ *[pP]?o?r? *[Pp]aragoge *[Dd]e *"..PALABRA.."[%.,:; ]*$")
	or strfind(x, "^ *[pP]?o?r? *[eE]p.ntesis *[Dd]e *"..PALABRA.."[%.,:; ]*$")
	or strfind(x, "^ *[pP]?o?r? *[Mm]etaplasmo *[Dd]e *"..PALABRA.."[%.,:; ]*$")
	or strfind(x, "^ *[pP]?o?r? *[aA]dici.n *[Dd]e *"..PALABRA.."[%.,:; ]*$") then
		generar_error("fone")
		return x
	end
	
	if strfind(x, "^ *[pP]?o?r? *[Aa]cortamiento *[Dd]e *"..PALABRA.."[%.,:; ]*$")
	or strfind(x, "^ *[pP]?o?r? *[Aa]p.cope *[Dd]e *"..PALABRA.."[%.,:; ]*$")
	or strfind(x, "^ *[pP]?o?r? *[Ss].ncopa *[Dd]e *"..PALABRA.."[%.,:; ]*$")
	or strfind(x, "^ *[pP]?o?r? *[aA]f.resis *[Dd]e *"..PALABRA.."[%.,:; ]*$")
	or strfind(x, "^ *[pP]?o?r? *[Aa]breviaci.n *[Dd]e *"..PALABRA.."[%.,:; ]*$")
	or strfind(x, "^ *[pP]?o?r? *[Aa]breviatura *[Dd]e *"..PALABRA.."[%.,:; ]*$") then
		generar_error("abrev")
		return x
	end
	
	if strfind(x, "^ *[Dd]?e? *o?r?i?g?e?n? *[Oo]nomatop?.?y?i?c?.? *$") then
		generar_error("onom")
		return x
	end
	
	if strfind(x, "^ *[Dd]?e? *o?r?i?g?e?n? *[Ee]xpresiv.? *$") then
		generar_error("expr")
		return x
	end
	
	if strfind(x, "^ *[Dd]?e? *o?r?i?g?e?n? *[Ii]nciert.? *$") then
		generar_error("incerta")
		return x
	end
	
	generar_error("otro")
	return x
end

return export