Ir al contenido

Módulo:auto cat

De Wikcionario, el diccionario libre
Documentación del módulo


Módulo que genera estructura automática para las páginas de las Categorías.

Uso

{{auto cat}}

Subpáginas

Esta documentación está transcluida desde Módulo:auto cat/doc.
Los editores pueden experimentar en la zona de pruebas de este módulo.
Por favor, añade las categorías e interwikis a la subpágina de documentación. Subpáginas de este módulo.
local export = {}

local copy = function(x) local y = {}; for i=1,#x do y[i] = x[i] end return y end
local copy2 = function(x) local y = {}; for i=2,#x do y[i-1] = x[i] end return y end

local insert = table.insert
local concat = table.concat

local m_str = require("Módulo:string")
local find = m_str.find
local sub = m_str.sub
local match = m_str.match
local split = m_str.split
local lower = m_str.lower
local upper = m_str.upper

local function lcfirst(s)
	return lower(sub(s, 1, 1))..sub(s, 2)
end
local function ucfirst(s)
	return upper(sub(s, 1, 1))..sub(s, 2)
end

local m_leng = require("Módulo:lenguas")
local cod_a_idioma = m_leng.cod_a_idioma
local cod_a_familia = m_leng.cod_a_familia
local obtener_dag = m_leng.obtener_dag

local m_nombres = mw.loadData("Módulo:lenguas/nombre_a_cod")

local m_sc = require("Módulo:scripts")
local sc_get_by_code = m_sc.getByCode

local m_csem = {}
for _,arr in pairs(require("Módulo:contexto/csem")) do
	m_csem[arr[1]] = arr
end

local m_uso = {}
for _,arr in pairs(require("Módulo:contexto/uso")) do
	if arr[2] then
		m_uso[arr[2]] = true
	end
end

local m_ambito = {}
for _,arr in pairs(require("Módulo:contexto/ámbito")) do
	m_ambito[ucfirst(arr[1])] = arr
end

local m_escr = {}
for _,esc in pairs(require("Módulo:lengua/escrituras")) do
	m_escr[esc] = true
end

local m_grafemas = mw.loadData("Módulo:auto cat/grafemas")
local m_lemas = mw.loadData("Módulo:auto cat/gramática")
local m_wikc = mw.loadData("Módulo:auto cat/wikcionario")
local m_etim = mw.loadData("Módulo:auto cat/etimología")
local m_pron = mw.loadData("Módulo:auto cat/pron-graf")

local FUNDAMENTAL = 1
local USO = 2
local AMBITO = 3
local CSEM = 4
local WIKCIONARIO = 5
local SWADESH = 6
local DICVIS = 7
local TESAURO = 8
local IDIOMAS = 9
local LENGUA = 10
local GRAFEMAS = 11
local ESCRITURAS = 12
local LEMAS = 13
local FORMAS = 14
local ETIMOLOGIA = 15
local PLANTILLAS = 16
local PRONUNCIACION = 17 -- incluye rimas
local TRADUCCIONES = 18
local USUARIOS = 19

local function obtener_alfabeto(args)
	-- por el momento, si no está standardChars, entonces no genero el alfabeto.
	-- En un futuro, podría hacer que genere el alfabeto que provee directamente el script,
	-- pero hay que implementar la función que devuelva eso porque la que está ahora mismo devuelve un rango de caracteres en regex
	if not args["idioma"] or not args["idioma"].standardChars then 
		return ""
	end
	local ignorar_script = {["Brai"] = true, ["Sgnw"] = true}
	local abc = {}
	if type(args["idioma"].standardChars) == "string" then
		abc[1] = args["idioma"].standardChars
	else
		for script in args["idioma"][4]:gmatch("([^,]+)%s*,?%s*") do -- tomo todos los scripts que haya, y para cada uno busco el alfabeto
			if script == "All" then
				return ""
			end
			if not ignorar_script[script] then
				-- local chars = sc_get_by_code(script):getCharacters()
				local script_ = args["idioma"].standardChars[script]
				if script_ then 
					insert(abc, split(upper(script_), ""))
				end
			end
		end
	end
	local t = {}
	for _,alfabeto in ipairs(abc) do
		if alfabeto then
			local mem = {["-"] = true} --ignoro el guion porque eso es parte de los regex en el caso de los alfabetos obtenidos directo del script
			insert(t, "<div style=\"font-size:90%; text-align:center\">\n")
			insert(t, "{|class=\"plainlinks\" align=\"center\" style=\"padding:3px 15px 3px 15px;\"\n")
			insert(t, "|style=\"text-align: center; font-weight:bold; font-size:100%; padding-left:15px; padding-right:15px\"|\n")
			local pg = args["pagename"]
			for i,c in ipairs(alfabeto) do
				if not mem[c] then
					mem[c] = true
					insert(t, "["..tostring(mw.uri.canonicalUrl("Categoría:"..pg, "from="..c)).." "..c.."]&nbsp;&nbsp;\n")
				end
			end
			insert(t, "|}\n</div>\n")
		end
	end
	return concat(t)
end

local function generar_aviso(tipo, texto)
	local header = {
		["info"] = "<table style=\"aviso\" class=\"plainlinks ambox ambox-notice\">"
	}
	
	local imagen = {
		["info"] = "[[Imagen:Emblem-notice.svg]]"
	}
	
	return require( "Módulo:TemplateStyles" )( "Plantilla:metaplantilla de avisos/styles.css" )..
		header[tipo]..
		"<tr><td class=\"ambox-image\"><div style=\"width:52px;\">"..
		imagen[tipo]..
		"</div></td><td class=\"ambox-text\">"..
		texto..
		"</td></tr></table>"
end

local function generar_titulo(texto, args)
	local t = {}
	if args["oculta"] then
		insert(t, "__HIDDENCAT__")
		insert(t, generar_aviso("info", "Esta es una categoría de mantenimiento que no se muestra directamente en los artículos. Si deseas habilitar la visualización de estas categorías, puedes hacerlo en [[Especial:Preferencias|tus preferencias]].\n\n"))
	end
	insert(t, "<div style=\"background-color: var(--background-color-neutral, #eaecf0); color: var(--color-base, #202122); border:1px dotted var(--border-color-content-added, #a3d3ff); padding:8px; width:95%; margin:10px 0px 0px 0px;\">\n")
	if texto then
		if args["Idioma"] then
			insert(t, "<div style=\"font-size:110%; text-align:center\">"..args["Idioma"]..": "..texto)
		else
			insert(t, "<div style=\"font-size:110%; text-align:center\">"..texto)
		end
		insert(t, "</div>\n")
	end
	return concat(t)..obtener_alfabeto(args).."</div>\n"
end

local function generar_categorias(padres, args)
	local padres_ = {}
	for _,padre in ipairs(padres) do
		if padre and padre ~= "" then
			if args["COD"] then
				insert(padres_, "[[Categoría:"..args["COD"]..":"..padre.."]]")
			else
				insert(padres_, "[[Categoría:"..padre.."|0]]")
			end
		end
	end
    return padres_
end

local handlers = {}

handlers[FUNDAMENTAL] =
function (clave, args)
    if clave == "Fundamental" then
        return true, generar_titulo("Fundamental", args), generar_categorias({}, args)
    end
    return nil
end

handlers[USO] =
function (clave, args)
    if clave == "Registros lingüísticos" then
        return true, generar_titulo("Registros lingüísticos", args), generar_categorias({}, args)
    end
	if m_uso[clave] then
		return true, generar_titulo("Lista de "..clave..".", args), generar_categorias({"Registros lingüísticos"}, args)
	end
    return nil
end

handlers[AMBITO] =
function (clave, args)
    if clave == "Ámbitos" then
        return true, generar_titulo("Ámbitos", args), generar_categorias({}, args)
    end
	local padres_ = m_ambito[clave]
	if padres_ then
		local padres = copy2(padres_)
		if not padres[1] then
			padres[1] = "Ámbitos"
		end
		return true, generar_titulo("Lista de términos propios de "..clave..".", args), generar_categorias(padres, args)
	end
    return nil
end

handlers[CSEM] =
function (clave, args)
    if clave == "Campos semánticos" then
        return true, generar_titulo("Campos semánticos", args), generar_categorias({}, args)
    end
    local padres_ = m_csem[clave]
	if padres_ then
		local padres = copy2(padres_)
		if not padres[1] then
			padres[1] = "Campos semánticos"
		end
		return true, generar_titulo("Lista de términos relacionados con "..lcfirst(clave)..".", args), generar_categorias(padres, args)
	end
	return nil
end

handlers[WIKCIONARIO] =
function(clave, args)
    if clave == "Wikcionario" and not args["cod"] then -- Categoría:Wikcionario solo es válida cuando no hay código de idioma
        return true, generar_titulo("Wikcionario", args), generar_categorias({}, args)
    end
	local padres = m_wikc[clave]
	if padres then
		if padres[1] == "Mantenimiento" then
			args["oculta"] = true
		end
		if clave == "Mantenimiento" then
			args["oculta"] = true
			if args["cod"] then -- si hay código de idioma, el padre es la categoría del idioma y no Categoría:Wikcionario
				padres = {}
			end
		end
		return true, generar_titulo(clave, args), generar_categorias(padres, args)
	end
	return nil
end

handlers[SWADESH] =
function(clave, args)
	if clave == "Lista Swadesh" then
		return true, generar_titulo("Lista de [[w:Lista Swadesh|vocabulario básico altamente resistente a préstamos]], concepto del lingüista [[w:Morris Swadesh|Mauricio Swadesh]].", args), generar_categorias({}, args)
	end
	return nil
end

handlers[DICVIS] =
function(clave, args)
	if clave == "Diccionario visual" then
		return true, generar_titulo("Diccionario visual", args), generar_categorias({}, args)
	end
	return nil
end

handlers[TESAURO] = function(clave, args)
	if clave == "Tesauro" then
		return true, generar_titulo("Tesauro", args), generar_categorias({}, args)
    end
    return nil
end

handlers[IDIOMAS] =
function (clave, args)
    if clave == "Idiomas" then
        return true, generar_titulo("Idiomas", args), generar_categorias({}, args)
    end
    if find(clave, "^Idiomas .+") then
        return true, generar_titulo(clave, args), generar_categorias({"Idiomas"}, args)
    end
    if clave == "Familias de idiomas" then
        return true, generar_titulo("Familias de idiomas", args), generar_categorias({}, args)
    end
    return nil
end

--Nombre de idioma o familia
handlers[LENGUA] =
function (clave, args)
	if args["cod"] then
		return nil -- si ya tiene prefijado un código, no puede ser un idioma, véase Categoría:KU:Árabe
	end
	clave = lcfirst(clave)
	local cod = m_nombres[clave]
	if not cod then
		return nil
	end
	
	local es_familia = match(clave, "^lenguas")

	local idioma
	if not es_familia then
		idioma = cod_a_idioma(cod)
	else
		idioma = cod_a_familia(cod)
	end
	local dag, familia = obtener_dag(idioma, es_familia)
	local arbol = require("Módulo:DAG").dagAHtml(dag, "Árbol genealógico")
	
	local t = {}
	local i = 1
	local function insert(s)
		t[i] = s
		i = i + 1
	end
	
	local cat = {}
	local i_ = 1
	local function insert_cat(s)
		cat[i_] = "[[Categoría:"..s.."]]"
		i_ = i_ + 1
	end
	
	-- En realidad final va al comienzo de todo, me confundí xd
	local final = {}
	local i__ = 1
	local function insert_final(s)
		final[i__] = s
		i__ = i__ + 1
	end
	
	
	insert("=== Información ===\n")
	insert("* '''Código''': <code>"..cod.."</code>\n")
	insert("* '''Nombre canónico''': "..clave.."\n")
	insert("* '''ID de Wikidata''': [https://www.wikidata.org/wiki/Q"..tostring(idioma[2]).." "..tostring(idioma[2]).."]\n")
	
	if familia then
		insert("* '''Familia''': [[:Categoría:"..familia.."|"..familia.."]]\n")
		insert_cat(familia)
	else
		if es_familia then
			insert_cat("Familias de idiomas")
		end
	end
	
	if not es_familia then
		insert("* '''Script(s)''': ")
		
		for script in idioma[4]:gmatch("([^,]+)%s*,?%s*") do
			insert("[[Wikcionario:Lista de scripts#" .. script .. "|<code>" .. script .. "</code>]] ")
			--insert_cat("Script "..script)
		end
		insert_cat("Idiomas")
		insert("\n")
	end
	
	if idioma.otherNames then
		insert("* '''Otros nombres''': ")
		for l,n in ipairs(idioma.otherNames) do
			if l == 1 then
				insert(n)	
			else
				insert(", "..n)
			end
		end
		insert(".\n")
	end
	
	insert("=== Véase también ===\n")
	insert("* [[File:Question Mark Icon.png|25px]] [[Apéndice:"..upper(cod)..":Referencia|Página de referencia]]\n")
	if not es_familia then
		insert("* [[File:Wiktionary-logo.svg|25px]] [["..clave.."|Entrada]] en el Wikcionario.\n")
	end
	
	local titulo_wikipedia = mw.wikibase.sitelink("Q"..tostring(idioma[2]), 'eswiki')
	if titulo_wikipedia then
		insert("* [[File:Wikipedia-logo.svg|25px]] [[w:"..titulo_wikipedia.."|Entrada]] en Wikipedia.\n")
	end
	
	insert("* [[File:Wikidata-logo.svg|25px]] [[wikidata:Q"..tostring(idioma[2]).."|Entrada]] en Wikidata.\n")
	insert("* [[File:Commons-logo.svg|25px]] [[commons:"..clave.."|Búsqueda]] en Wikimedia Commons.\n")
	
	if not es_familia then
		insert("* [[Wikcionario:Códigos de idioma|Lista]] completa de idiomas.\n")	
	else
		insert("* [[Wikcionario:Familias de idiomas|Lista]] completa de familias.\n")
	end
	
	local im = mw.title.new("Lang-"..cod..".gif", 6)
    if im and im.fileExists then
    	insert_final("[[File:Lang-"..cod..".gif|200px]]\n\n")
    end

	
	insert_final("Esta es la categoría principal ")
	if not es_familia then
		insert_final("del idioma "..clave..".\n")
	else
		insert_final("de las "..clave..".\n")
	end

	local hay_arg = false
	
	if not es_familia then
		for j, arg in ipairs(args) do
			if j == 1 then
				insert_final("Se habla en: [["..args[1].."]]")
				insert_cat("Idiomas de "..args[1])
			else
				insert_final(", [["..args[j].."]]")
				insert_cat("Idiomas de "..args[j])
			end
			hay_arg = true
		end
	end
	
	if hay_arg then
		insert_final(".\n")	
	end
  
	-- https://stackoverflow.com/questions/31455768/html-table-cell-spacing-only-between-cells-no-outer-one
	return true, "<table border=0 cellspacing=0 cellpadding=0 style=\"margin:-10px;width:99.9%;border-spacing:10px;\">\n<tr>\n<td style=\"text-align:left;vertical-align:top;\">\n"..concat(final)..concat(t).."</td>\n<td style=\"text-align:center;\">\n"..arbol.."</td>\n</tr>\n</table>\n", cat
end

handlers[GRAFEMAS] =
function (clave, args)
	if clave == "Grafemas" then
		return true, generar_titulo("Grafemas", args), generar_categorias({}, args)
	end
	for k,padres in pairs(m_grafemas) do
		if clave == k then
			return true, generar_titulo(clave, args), generar_categorias(padres, args)
		end
		if find(clave, "^"..k.." .+") then
			return true, generar_titulo(clave, args), generar_categorias({k}, args)
		end
	end
    return nil
end

handlers[ESCRITURAS] =
function(clave, args)
	if clave == "Escrituras" then
		return true, generar_titulo("Lista de escrituras.", args), generar_categorias({}, args)
	end

	local x = m_escr[clave]
	if x then
		return true, generar_titulo(clave, args), generar_categorias({"Escrituras"}, args)
	end
	return nil
end

handlers[LEMAS] =
function (clave, args)
    if clave == "Lemas" then
        return true, generar_titulo("Lemas", args), generar_categorias({}, args)
    end
	for k,padres in pairs(m_lemas) do
		if clave == k then
			return true, generar_titulo(clave, args), generar_categorias(padres, args)
		end
		if find(clave, "^"..k.." .+") then
			return true, generar_titulo(clave, args), generar_categorias({k}, args)
		end
	end
    return nil
end

handlers[FORMAS] =
function (clave, args)
    if clave == "Formas flexivas" then
        return true, generar_titulo("Formas flexivas", args), generar_categorias({}, args)
    end
	if find(clave, "^Formas no can.ni") then
		return nil
	end
    if find(clave, "^Formas .+") then
        return true, generar_titulo(clave, args), generar_categorias({"Formas flexivas"}, args)
    end
    if find(clave, "^Gerundios") then
        return true, generar_titulo(clave, args), generar_categorias({"Formas flexivas"}, args)
    end
    if find(clave, "^Participios") then
        return true, generar_titulo(clave, args), generar_categorias({"Formas flexivas"}, args)
    end
    if find(clave, "^Supinos") then
        return true, generar_titulo(clave, args), generar_categorias({"Formas flexivas"}, args)
    end
    return nil
end

handlers[ETIMOLOGIA] =
function (clave, args)
	if clave == "Palabras por origen" then
		return true, generar_titulo("Palabras por origen", args), generar_categorias({}, args)
	end
	-- Etimología de otro idioma
	local m = {match(clave, "^Palabras provenientes del (.+)$")}
	if m[1] then
		return true, generar_titulo("Lista de "..lcfirst(clave)..".", args),  generar_categorias({"Palabras por idioma de origen|"..m[1]}, args)
	end
	m = {match(clave, "^Palabras documentadas desde el siglo [IVX]+$")}
	if m[1] then
		return true, generar_titulo("Lista de "..lcfirst(clave)..".", args),  generar_categorias({"Palabras por época de origen"}, args)
	end
	-- Prefijos, infijos, sufijos
	m = {match(clave, "^Palabras con el prefijo (.+)$")}
	if m[1] then
		return true, generar_titulo("Lista de "..lcfirst(clave)..".", args),  generar_categorias({"Palabras formadas por prefijación|"..m[1]}, args)
	end
	m = {match(clave, "^Palabras con el infijo (.+)$")}
	if m[1] then
		return true, generar_titulo("Lista de "..lcfirst(clave)..".", args),  generar_categorias({"Palabras formadas por infijación|"..m[1]}, args)
	end
	m = {match(clave, "^Palabras con el sufijo (.+)$")}
	if m[1] then
		return true, generar_titulo("Lista de "..lcfirst(clave)..".", args),  generar_categorias({"Palabras formadas por sufijación|"..m[1]}, args)
	end
	-- Otros tipos de etimologías
	local padres = m_etim[clave]
	if padres then
		return true, generar_titulo("Lista de "..lcfirst(clave)..".", args), generar_categorias(padres, args)
	end
	
	return nil
end

handlers[PLANTILLAS] =
function (clave, args)
	if clave == "Plantillas" then
		return true, generar_titulo("Plantillas", args), generar_categorias({}, args)
	end

	if find(clave, "^Plantillas .+") then
		return true, generar_titulo(clave, args), generar_categorias({"Plantillas"}, args)
	end

	return nil
end

-- Pron-graf
handlers[PRONUNCIACION] =
function(clave, args)
	if clave == "Pronunciación" then
		return true, generar_titulo("Pronunciación", args), generar_categorias({}, args)
    end

	local padres = m_pron[clave]
    if padres then
        return true, generar_titulo("Lista de "..lcfirst(clave)..".", args), generar_categorias(padres, args)
    end

    if clave == "Rimas" then
    	return true, generar_titulo("Lista de rimas.", args), generar_categorias({"Pronunciación"}, args)
    end
    
    local m = {match(clave, "^Rimas:(.+)$")}
    
    if m[1] then
    	return true, generar_titulo("Lista de rimas con /"..m[1].."/.", args), generar_categorias({"Rimas"}, args)
    end

    return nil
end

handlers[TRADUCCIONES] =
function (clave, args)
    if clave == "Traducciones" then
		return true, generar_titulo("Traducciones (del español hacia otros idiomas).", args), generar_categorias({}, args)
    end

	local m = {match(clave, "^Español%-(.+)$")}
	
	if m[1] then
		local a = lcfirst(m[1])
		if m_nombres[a] then
			args["oculta"] = true
			return true, generar_titulo("En esta categoría se encuentran todas las entradas traducidas al "..a..".", args), generar_categorias({"Traducciones"}, args)
		end
	end
	return nil
end

-- Usuarios por idioma, debería fusionarlo con el handler de arriba?
handlers[USUARIOS] = 
function(clave, args)
	if clave == "Usuarios" then
		return true, generar_titulo("Lista de usuarios.", args), generar_categorias({}, args)
	end
	if clave == "Usuarios por tipo" then
		return true, generar_titulo("Lista de usuarios por tipo.", args), generar_categorias({"Usuarios"}, args)
	end
	if clave == "Usuarios por país" then
		return true, generar_titulo("Lista de usuarios por país.", args), generar_categorias({"Usuarios"}, args)
		end
	if clave == "Usuarios por idioma" then
		return true, generar_titulo("Lista de usuarios por idioma.", args), generar_categorias({"Usuarios"}, args)
	end
	if clave == "Usuarios por familia de idioma" then
		return true, generar_titulo("Lista de usuarios por familia de idioma.", args), generar_categorias({"Usuarios"}, args)
	end
	
	local m = {match(clave, "^Usuarios (.+)%-(.+)$")}

	if m[1] then
		local c = {["1"]="básico", ["2"]="intermedio", ["3"]="avanzado", ["4"]="experto", ["5"]="profesional", ["N"]="nativo"}
		local nivel = c[m[2]]
		assert(nivel)
		assert(not args["idioma"])
		local idioma = cod_a_idioma(m[1], true)
		if idioma then
			return true, generar_titulo("Lista de usuarios que hablan "..idioma[1]..", nivel "..nivel..".", args), generar_categorias({"Usuarios por idioma"}, args)
		end
		local familia = cod_a_familia(m[1], true)
		if familia then
			return true, generar_titulo("Lista de usuarios que manejan "..familia[1]..", nivel "..nivel..".", args), generar_categorias({"Usuarios por familia de idioma"}, args)
		end
	end

	m = {match(clave, "^Usuarios de (.+)$")}

	if m[1] then
		return true, generar_titulo(clave, args), generar_categorias({"Usuarios por país"}, args)
	end

	m = {match(clave, "^Usuarios (.+)$")}

	if m[1] then
		return true, generar_titulo(clave, args), generar_categorias({"Usuarios por tipo"}, args)
	end
	
	return nil
end

function export.categorizar(frame)
	local title = mw.title.getCurrentTitle().fullText
    if title == "Plantilla:auto cat" then
    	return "Use esta plantilla en el espacio de Categorías."	
    end
	
	local pagename = mw.title.getCurrentTitle().text
	if pagename == "Módulo:auto cat" then
		return nil	
	end
	    
	local ns = mw.title.getCurrentTitle().namespace
    assert(ns == 14, "La plantilla sólo puede utilizarse en el espacio de Categorías")
    
    local args = frame:getParent().args
    args["pagename"] = pagename

	-- Hay un único caso en donde debemos partir la clave
	-- y es cuando está la categoría prefijada con un código de idioma
	local cod, clave
	cod, clave = match(pagename, "^(%u%u%u?):(.+)$")
	if not clave then
		cod, clave = match(pagename, "^(%u%u%u?%-%u%u%u?):(.+)$")
	end
	if not clave then
		cod, clave = match(pagename, "^(%u%u%u?%-%u%u%u?%-%u%u%u?):(.+)$")
	end

	if clave then
		args["COD"] = cod
		args["cod"] = lower(cod)
		args["idioma"] = cod_a_idioma(args["cod"])
		args["Idioma"] = ucfirst(args["idioma"][1])
	else
		clave = pagename
	end

	local t = {}
    
	for i,handler in ipairs(handlers) do
		local terminar, msj, padres = handler(clave, args)
		if terminar == true then
			insert(t, msj)
			if args["COD"] then
				insert(t, "[[Categoría:"..clave.."|"..args["COD"].."]]")
			end

			if not padres[1] and clave ~= "Fundamental" then
				if not args["COD"] then
					insert(t, "[[Categoría:Fundamental]]")
				else
					insert(t, "[[Categoría:"..args["Idioma"].."]]")
				end
			end
			
			for _,pcat in ipairs(padres) do
				insert(t, pcat)
			end
			
			return concat(t)
		end
	end
    error("La categoría no puede ser reconocida.")
end

return export