Módulo:generar-pron/yua

La documentación para este módulo puede ser creada en Módulo:generar-pron/yua/doc

-- PRONUNCIACIÓN PARA EL MAYA YUCATECO
-- Autor: Tmagc
-- Revisado por 26agcp

local export = {}

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

local m_str = require("Módulo:String")

local u = m_str.char
local strfind = m_str.find
local strsubn = m_str.gsub
local strsubb = m_str.gsubb
local strsubrep = m_str.gsub_rep
local strlower = m_str.lower
local strstrip = m_str.strip
local strsplit = m_str.split
local strhtml = m_str.encode_html

--CONVENCION: mayúscula para patrones encerrados entre corchetes, minúscula para todo lo demás
local ac_primario = u(0x02C8)
local ac_secundario = u(0x02CC)

local acentos_ipa = ac_primario..ac_secundario
local ACENTOS_IPA = "[" .. acentos_ipa .. "]"

local divsil = u(0xFFF0)
local sepsil = "%-." .. divsil
local SEPARADORES_SILABICOS = "[" .. sepsil .. "]"
local SALVO_SEPARADORES_SILABICOS = "[^" .. sepsil .. "]"
local seppal = "# "
local separador_excepto_palabras = acentos_ipa .. sepsil
local separador = separador_excepto_palabras .. seppal
local SEPARADOR = "[" .. separador .. "]"

local PUNTUACION = "[%(%)%[%]%{%}¡!¿?.,;:–—]"
local PUNTUACION_EXTRA = "[%(%)%[%]%{%}¡!¿?.,;:–—\"“”„‟‘’«»»«‹››‹]"

local apostrofe = "'ʼꞌꞋ’" -- son distintos
local APOSTROFE = "["..apostrofe.."]"

local vocales = "aeiouáéíóúAEIOUÁÉÍÓÚ"
local VOCAL = "["..vocales.."]"
local consonantes = "bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ"
local CONS = "["..consonantes.."]"

local vocal_ipa = "aeiouáéíóúàèìòù"

local permitido = vocales..consonantes..apostrofe..separador.."·|%s" --asumo que limpié la puntuación

local quitar_tilde = {
	["á"] = "a",
	["é"] = "e",
	["í"] = "i",
	["ó"] = "o",
	["ú"] = "u",
	["a"] = "a",
	["e"] = "e",
	["i"] = "i",
	["o"] = "o",
	["u"] = "u"
}

-- single characters that map to IPA sounds
local mapeo_1c = {
    ["C"] = "t͡ʃ",
    ["S"] = "t͡s",
    ["H"] = "t͡ʃʼ",
    ["Z"] = "t͡sʼ",
    ["K"] = "kʼ",
    ["P"] = "pʼ",
    ["T"] = "tʼ",
	["y"] = "j",
}

local mapeo_1b = {
	[APOSTROFE] = "ʔ",
	--["a"] = "a",
	["b"] = "ɓ",
	--["e"] = "e",
	--["i"] = "i",
	["j"] = "h",
	--["k"] = "k",
	--["l"] = "l",
	--["m"] = "m",
	--["n"] = "n",
	--["o"] = "o",
	--["p"] = "p",
	["r"] = "ɾ",
	--["s"] = "s",
	--["t"] = "t",
	--["u"] = "u",
	--["w"] = "w",
	["x"] = "ʃ",
}

local mapeo_1 = {
	["a"..APOSTROFE.."a"] = "áa̰",
	["e"..APOSTROFE.."e"] = "éḛ",
	["i"..APOSTROFE.."i"] = "íḭ",
	["o"..APOSTROFE.."o"] = "óo̰",
	["u"..APOSTROFE.."u"] = "úṵ",
}

-- character sequences of two that map to IPA sounds
local mapeo_2 = {
	["aa"] = "àː",
	["áa"] = "áː",
	["ee"] = "èː",
	["ée"] = "éː",
	["ii"] = "ìː",
	["íi"] = "íː",
	["oo"] = "òː",
	["óo"] = "óː",
	["uu"] = "ùː",
	["úu"] = "úː",
	["ch"] = "C",
	["ts"] = "S",
}

local mapeo_3 = {
	["ch"..APOSTROFE] = "H",
	["ts"..APOSTROFE] = "Z",
	["k"..APOSTROFE] = "K",
	["p"..APOSTROFE] = "P",
	["t"..APOSTROFE] = "T",
}

local function normalizar(texto)
	texto = strlower(texto)
	texto = strsubrep(texto, PUNTUACION, " | ") -- convierto lo que delimite fragmentos a los IPA foot boundaries |
	texto = strsubrep(texto, PUNTUACION_EXTRA, "") -- elimino la puntuación restante que haya quedado
	texto = strsubrep(texto, "[%-‐]", " ") --los guiones pasan a ser espacios (austro-húngaro, franco-italiano)
	
	if strfind(texto, "[^"..permitido.."]") then
		error("caracteres no permitidos en el título")
	end

    texto = strsubrep(texto, "%s*|%s*|%s*", " | ") --finalmente, elimino las barras y espacios de más
    texto = strsubrep(texto, "%s+", " ")
	texto = strstrip(texto, "[%s|]+")
	
	return texto
end

local function silabear(p)
	-- 1. Separo si hay un único caracter de consonante entre dos vocales
	p = strsubrep(p, "(" .. VOCAL .. APOSTROFE ..  "?)(" .. CONS  .. VOCAL .. ")", "%1"..divsil.."%2")
	
	-- 2. Separo ch, ch', ts, ts'
	p = strsubrep(p, "(" .. VOCAL .. APOSTROFE .. "?" .. CONS .. "?" .. CONS .. "?" .. APOSTROFE .. "?)(" .. "[cC][hH]" .. APOSTROFE .. "?"  .. VOCAL .. ")", "%1"..divsil.."%2")
	p = strsubrep(p, "(" .. VOCAL .. APOSTROFE .. "?" .. CONS .. "?" .. CONS .. "?" .. APOSTROFE .. "?)(" .. "[tT][sS]" .. APOSTROFE .. "?"  .. VOCAL .. ")", "%1"..divsil.."%2")
	p = strsubrep(p, "(" .. VOCAL .. APOSTROFE .. "?" .. "[cC][hH]" .. APOSTROFE .. "?)(" .. CONS .. "?" .. CONS .. "?" .. APOSTROFE .. "?" .. VOCAL .. ")", "%1"..divsil.."%2")
	p = strsubrep(p, "(" .. VOCAL .. APOSTROFE .. "?" .. "[tT][sS]" .. APOSTROFE .. "?)(" .. CONS .. "?" .. CONS .. "?" .. APOSTROFE .. "?" .. VOCAL .. ")", "%1"..divsil.."%2")
	
	-- 3. Separo p', t', k'
	p = strsubrep(p, "(" .. VOCAL .. APOSTROFE .. "?" .. CONS .. "?" .. CONS .. "?" .. APOSTROFE .. "?)(" .. "[pPtTkK]" .. APOSTROFE  .. VOCAL .. ")", "%1"..divsil.."%2")
	p = strsubrep(p, "(" .. VOCAL .. APOSTROFE .. "?" .. "[pPtTkK]" .. APOSTROFE .. ")(" .. CONS .. CONS .. "?" .. APOSTROFE .. "?" .. VOCAL .. ")", "%1"..divsil.."%2")
	
	-- 4. Separo el apóstrofe con la vocal anterior siempre y cuando sean vocales diferentes (el apóstrofe en los demás casos se contempló en 1.)
	p = strsubn(p, "([aeiou])(" .. APOSTROFE .. ")([aeiou])", function(a,b,c) return a == c and a..b..c or a..b..divsil..c end)
	
	-- 5. Separo el resto de consonantes
	p = strsubrep(p, "(" .. VOCAL .. APOSTROFE .. "?" .. CONS .. CONS .. "?" .. APOSTROFE .. "?)(" .. CONS .. CONS .. "?" .. APOSTROFE .. "?" .. VOCAL .. ")", "%1"..divsil.."%2")
	
	-- 6. Separo el resto de vocales (siempre y cuando no formen un único grupo, ie, sean distintas sin considerar tildes)
	p = strsubn(p, "("..VOCAL..")("..VOCAL..")", function(a,b) return quitar_tilde[a] == quitar_tilde[b] and a..b or a..divsil..b end)
	
	p = strsubn(p, "["..divsil.."]+", divsil)
	p = strstrip(p, "["..divsil.." ]+")
	
	return p
end

local function generar_pron(text)
	text = normalizar(text)
	local convertido = {}
	local fragmentos = strsplit(text, "%s*|%s*")
	
	for _,fragmento in ipairs(fragmentos) do
	    local palabras = strsplit(fragmento, "%s")
		local palabras_convertidas = {}
	    for _,p in ipairs(palabras) do
	    	p = silabear(p)
			p = strsubn(p, divsil, ".")
	    	
	    	-- mapeo fonológico
	    	for a,b in pairs(mapeo_3) do
	    		p = strsubn(p, a, b)
	    	end
	    	for a,b in pairs(mapeo_2) do
	    		p = strsubn(p, a, b)
	    	end
	    	for a,b in pairs(mapeo_1) do
	    		p = strsubn(p, a, b)
	    	end
	    	for a,b in pairs(mapeo_1b) do
	    		p = strsubn(p, a, b)
	    	end
	    	for a,b in pairs(mapeo_1c) do
	    		p = strsubn(p, a, b)
	    	end
	    	
	    	-- Si empieza por vocal, agrego la glotal
	    	p = strsubn(p, "^(["..vocal_ipa.."])", "ʔ%1")
	    	
	    	insert(palabras_convertidas, p)
	    end
	    insert(convertido, concat(palabras_convertidas, " "))
	end
	
	local conservador = concat(convertido, " | ")
	
	-- variante reducida: 
	-- 1. Al final de palabra, la letra L se transcribe /h/.
	local reducido = strsubn(conservador, "l ", "h ")
	reducido = strsubn(reducido, "l$", "h")
	-- 2. Al final de sílaba, la letra B se transcribe /ʔ/.
	reducido = strsubn(reducido, "ɓ ", "ʔ ")
	reducido = strsubn(reducido, "ɓ$", "ʔ")
	reducido = strsubn(reducido, "ɓ%.", "ʔ.")
	
	if reducido == conservador then
    	return {{"pronunciación"}}, {{strhtml(conservador)}}
	end
		
	return {{"conservador"}, {"reducido"}}, {{strhtml(conservador)}, {strhtml(reducido)}}
end

-- Punto de entrada externo, recibe el título de página y los argumentos de plantilla
function export.procesar_pron_args(titulo, args)
	if #args["ayuda"] < 1 then
		args["ayuda"][1] = titulo
	end

	if #args["fone"] < 1 and #args["fono"] < 1 then
		local A = #args["ayuda"]
		local j = 1 -- indice de la ayuda
		local k = 1 -- cantidad de pronunciaciones insertadas (máximo 9)
		local rims = {} -- rimas
		while k <= 9 and j <= A do
			local pron, fono = generar_pron(args["ayuda"][j])
			for i,_ in ipairs(fono) do
				table.insert(args["pron"], pron[i])
				table.insert(args["fono"], fono[i])
				
				local rim = fono[i][1]
				rim = strsubn(rim, "^.*"..SEPARADOR.."(.-)$", "%1")
				rim = strsubn(rim, ".-(["..vocal_ipa.."].*)$", "%1")
				rims[rim] = true
				
				k = k + 1
				if k > 9 then
					break
				end
			end
			j = j + 1
		end
		
		local tiene_espacios = strfind(titulo, " ")
		if not tiene_espacios then
			if not args["d"][1] then
				local aux = silabear(args["ayuda"][1])
				args["d"][1] = strsubn(aux, divsil, "-")
			end
		end
		
		for r,_ in pairs(rims) do
			insert(args["rima"], r)
		end
	end

	return args

end
 
return export