Ir al contenido

Módulo:flex

De Wikcionario, el diccionario libre

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

local export = {}

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

local m_table = require("Módulo:tabla")
local deepcopy = m_table.deepCopy
local cartprod = m_table.cartProd

local m_str = require("Módulo:string")
local find = m_str.find
local gsub = m_str.gsub
local gmatch = m_str.gmatch
local match = m_str.match
local sub = m_str.sub
local split = m_str.split
local len = m_str.len

export.COLOR_H = "var(--wikt-palette-grey-2)"
export.COLOR_NP = "var(--wikt-palette-purple-2)"
export.COLOR_INF = "var(--wikt-palette-orange-2)"
export.COLOR_IND = "var(--wikt-palette-green-2)"
export.COLOR_COND = "var(--wikt-palette-blue-2)"
export.COLOR_SUBJ = "var(--wikt-palette-yellow-2)"
export.COLOR_IMPER = "var(--wikt-palette-red-2)"

function export.separar_palabras(original, ayuda, rx_espacio)
	rx_espacio = rx_espacio or "[%s%-‐־]+" -- REVISAR: queremos que el maqaf se comporte como un guion normal?
	ayuda = ayuda or original
	local palabras = {}
	local separadores = {}
	local tmp = ""
	local j = 1
	for c in gmatch(ayuda, ".") do
		local d = sub(original, j, j)
		local c_es_espacio = find(c, rx_espacio)
		local d_es_espacio = find(d, rx_espacio)
		if d == c or (d_es_espacio and c_es_espacio) then
			if j > 1 and c_es_espacio then
				insert(palabras, tmp)
				insert(separadores, d)
				tmp = ""
			else
				tmp = tmp..d
			end
			j = j + 1
		else
			if j > 1 and c_es_espacio then
				insert(palabras, tmp)
				insert(separadores, "")
				tmp = ""
			else
				tmp = tmp..c
				j = j + 1
			end
		end
	end
	
	if tmp ~= "" then
		insert(palabras, tmp)
	end
	
	return palabras, separadores
end

function export.f_links(v, tit, fn_normalizacion, noespacio)
	noespacio = noespacio or "[^%s%-‐־]"
	local guion = sub(v, 1, 1)
	v = sub(v, 2)
    v = gsub(v, "("..noespacio.."*)", function(m)
    	if guion then
    		m = guion..m
    		guion = nil
    	end
    	if m == "" then
    		return ""
    	end
    	local nota = match(m, "{([^}]+)}") or match(m, "%[([^%]]+)%]")
    	if nota then
    		m = gsub(m, "{([^}]+)}", "")
    		m = gsub(m, "%[([^%]]+)%]", "")
    	end
        local a = gsub(m, "[~#]", "")
        local b = gsub(m, "##", "")
        b = gsub(b, "~~", "")
        b = gsub(b, "#(.-)#", "<span style='color:var(--color-warning, DarkGoldenrod); font-weight: bold;'>%1</span>")
        b = gsub(b, "~(.-)~", "<span style='color:var(--color-success, Green); font-weight: bold;'>%1</span>")
        
        -- por las dudas si hay símbolos que abarquen varias palabras: ej: [[community manager]] -> communit#y managers# (piensa q el plural regular es communities managers), no se puede procesar
        a = gsub(a, "[~#{}%[%]]", "")
        b = gsub(b, "[~#{}%[%]]", "")
        if type(fn_normalizacion) == "function" then
        	a = fn_normalizacion(a)
        end
		if a == tit then
			return "<span style='color:var(--color-visited, MediumSlateBlue);'>"..b.."</span>"..(nota and "<sup>"..nota.."</sup>" or "")
		end
        return "[["..a.."|"..b.."]]"..(nota and "<sup>"..nota.."</sup>" or "")
    end)
    return v
end
local f_links = export.f_links

function export.f(v)
    v = gsub(v, "(%S+)", function(m)
        local b = gsub(m, "##", "")
        b = gsub(b, "~~", "")
        b = gsub(b, "{([^}]+)}", "<sup>%1</sup>")
        b = gsub(b, "#(.-)#", "<span style='color:var(--color-warning, DarkGoldenrod); font-weight: bold;'>%1</span>")
        b = gsub(b, "~(.-)~", "<span style='color:var(--color-success, Green); font-weight: bold;'>%1</span>")
        b = gsub(b, "[~#{}]", "") -- por las dudas
        return b
    end)
    return v
end
local f = export.f

function export.parsear_arreglo(st)
	st = gsub(st, "%[", "{")
	st = gsub(st, "%]", "}")
	return split(st, "%s*;%s*")
end

function export.combinar_copulativa(flex1, flex2, separador, claves)
	local c = {}
	claves = claves or flex1

	for form,_ in pairs(claves) do		
		if type(flex1[form]) ~= "table" then
			flex1[form] = {flex1[form]}
		end
		if type(flex2[form]) ~= "table" then
			flex2[form] = {flex2[form]}
		end
		c[form] = cartprod(flex1[form], flex2[form], function (x, y)
			return x..separador..y
		end)
	end
	return c
end

local function lcs(s, t)
	if not s or not t then
		return "#"..t.."#"
	end
    local j = 0
    for i = 1, #s do
        if sub(s, i, i) ~= sub(t, i, i) then
            break
        end
        j = j+1
    end
    return sub(t, 1, j).."#"..sub(t, j+1).."#"
end

function export.desactivar_formas(formas_generadas, desactivar, claves)
	local def = false

	if not desactivar then
		return deepcopy(formas_generadas), def
	end
    
	claves = claves or formas_generadas

	local tmp = {}

	for form,_ in pairs(claves) do
		if desactivar(form) then
			tmp[form] = {}
			def = true
		else
			tmp[form] = deepcopy(formas_generadas[form])
		end
	end

	return tmp, def
end

function export.comprobar_defectivo(formas_generadas, excluir, propagar)
	propagar = propagar or {}
	excluir = excluir or {}

	local defectivo = false
	
	local function excluir_fn(form)
		for _,exc in ipairs(excluir) do
			if form:find(exc) then
				return true
			end
		end
		return false
	end

	for form,_ in pairs(formas_generadas) do
		local val = formas_generadas[form][1] or ""
		local def_ = false

		if val:find("^#?%s*[%-—―]+%s*#?$") then
			def_ = true
			formas_generadas[form] = {}
		elseif val:find("^#?%s*no%s*#?$") then
			def_ = true
			formas_generadas[form] = {}
			local tiempo, i = match(form, "^(.*)(%d+)$")
			if tiempo then
				for _,s in ipairs(propagar) do
					formas_generadas[tiempo..s] = {}
				end
			end
		end

		if def_ and not excluir_fn(form) then
			defectivo = true
		end
	end

	return defectivo
end

function export.sobreescribir_formas(formas_generadas, formas_manuales, modo_lcs, mapeos, claves)
	local tmp = {}
	local mapear = {}
	local sobreescribir = {}
	local irr = false

	mapeos = mapeos or {}
	claves = claves or formas_generadas

	for form,_ in pairs(claves) do
		local arr = formas_generadas[form]
		if arr == nil then
			arr = {}
		end
		if type(arr) == "string" then
			arr = {arr}
		end
		if type(formas_manuales[form]) == "string" and formas_manuales[form] ~= "" then
			formas_manuales[form] = {formas_manuales[form]}
		end
		if type(formas_manuales[form]) == "table" and #formas_manuales[form] > 0 then
			tmp[form] = deepcopy(formas_manuales[form])
			for i,b in ipairs(tmp[form]) do
				b = gsub(b, "%[(.-)%]", "{%1}")
				local presente
				for _,c in ipairs(arr) do
					if b == c then
						presente = true
						break
					end
				end
				if presente then
					tmp[form][i] = b
				else
					tmp[form][i] = modo_lcs and lcs(arr[i], b) or "#"..b.."#"
					if not find(formas_manuales[form][i], "[{%[]") then
						irr = true
					end
				end
			end
			mapear[form] = mapeos[form]
    		sobreescribir[form] = false
		else
			tmp[form] = arr
		end
	end

	for form,arr in pairs(mapear) do
		for _,form2 in ipairs(arr) do
			if sobreescribir[form2] ~= false then
				tmp[form2] = deepcopy(tmp[form])
			end
		end
	end

	return tmp, irr
end

function export.agregar_enlaces(formas, tit, fn_normalizacion, noespacio)
	local tmp = {}
	for form,arr in pairs(formas) do
		tmp[form] = deepcopy(arr)
        
        for i,b in ipairs(tmp[form]) do
            tmp[form][i] = f_links(b, tit, fn_normalizacion, noespacio)
        end
	end
	return tmp
end

function export.agregar_colores(formas)
	local tmp = {}
	for form,arr in pairs(formas) do
		tmp[form] = deepcopy(arr)
        
        for i,b in ipairs(tmp[form]) do
            tmp[form][i] = f(b)
        end
	end
	return tmp
end

function export.formatear_formas(formas, lb)
	local tmp = {}
	for form,arr in pairs(formas) do
		if #arr == 0 then
			arr = {"―"}
		end
        tmp[form] = {concat(arr, ", ")}
		if type(lb) == "table" then
			tmp[form].lb = lb[form]
		elseif type(lb) == "function" then
			tmp[form].lb = lb(form)
		end
	end
	return tmp
end

function export.renderizar_encabezado(frame, tit, desc, ref, a, cats, fn_normalizacion, noespacio)
	local t = {}
	insert(t, "'''"..tit.."'''"..(ref and frame:extensionTag("ref", ref) or "")..(desc and " (''"..desc.."'')" or ""))
	for _,ai in ipairs(a) do
		local t2 = {}
		for k,aij in ipairs(ai[2]) do
			if ai[3] and ai[3][k] then
				insert(t2, f_links(aij, tit, fn_normalizacion, noespacio)..frame:extensionTag("ref", ai[3][k]))
			else
				insert(t2, f_links(aij, tit, fn_normalizacion, noespacio))
			end
		end	
		if #t2 > 0 then
			insert(t, (ai[1] and ai[1]..": " or "")..concat(t2, ", "))
		end
	end
	local tcats = {}
	for _,cat in ipairs(cats) do
		insert(tcats, "[[Categoría:"..cat.."]]")
	end
	return concat(t, "&ensp;¦&ensp;")..concat(tcats)
end

function export.renderizar_tabla(frame, titulo, tabla, cats)
	local t = {}
	insert(t, frame:extensionTag("templatestyles", nil, {src = "Módulo:flex/estilo.css"}).."\n")
	insert(t, "<div class='flex mw-collapsible mw-collapsed' style='display:grid'>\n")
	insert(t, "<div class='flex mw-collapsible-toggle'>"..titulo.."&nbsp;[<span class='fakelinks down'>▲</span><span class='fakelinks up'>▼</span>]</div>\n")
	insert(t, "<div class='flex mw-collapsible-content'>\n")
	insert(t, "{| class='flex wikitable' width='100%'\n")
	
	for _,fila in ipairs(tabla) do
		insert(t, "|-\n")
		for _,celda in ipairs(fila) do
			local cont
			local t_celda = {}
			local t_estilo_celda = {}
			
			if type(celda) == "string" then
				cont = celda
				if fila.header and fila.color then
					insert(t_estilo_celda, "background:"..fila.color)
					insert(t_estilo_celda, "color:var(--color-emphasized)")
				end
			elseif type(celda) == "table" then
				if celda.colspan then
					insert(t_celda, "colspan="..celda.colspan)
				end
				if celda.header or fila.header then
					insert(t_estilo_celda, "font-weight:bold")
					insert(t_estilo_celda, "text-align:center")
				end
				if celda.color then
					insert(t_estilo_celda, "background:"..celda.color)
					insert(t_estilo_celda, "color:var(--color-emphasized)")
				elseif fila.color then
					insert(t_estilo_celda, "background:"..fila.color)
					insert(t_estilo_celda, "color:var(--color-emphasized)")
				end
	            if celda.lb then
	            	local sang_ = frame:extensionTag("span", celda.lb.."&ensp;", {class="movil", style="visibility:hidden;"})
                    cont = frame:extensionTag("span", celda.lb.."&ensp;", {class="movil"})..concat(celda, "<br>"..sang_)
                else
				    cont = concat(celda, "<br>")
                end
			end
			
			if #t_estilo_celda > 0 then
				insert(t_celda, "style='"..concat(t_estilo_celda, ";").."'")
			end
			if celda.class then
				insert(t_celda, "class='"..celda.class.."'")
			elseif fila.class then
				insert(t_celda, "class='"..fila.class.."'")
			end
			assert(cont, "Formato de tabla incorrecto")
			insert(t, (celda.header or fila.header) and "! " or "| ")
			insert(t, concat(t_celda, " ").." | "..cont.."\n")
		end
	end
	insert(t, "|}\n")
	insert(t, "</div>\n")
	insert(t, "</div>")
	for _,cat in ipairs(cats) do
		insert(t, "[[Categoría:"..cat.."]]")
	end
	return concat(t)
end

return export