Módulo:generar-pron/nci
La documentación para este módulo puede ser creada en Módulo:generar-pron/nci/doc
-- PRONUNCIACION PARA EL NÁHUATL
-- Este módulo cubre todas las variantes de náhuatl, por lo que todas redirigen acá para generar la pronunciación
-- Por lo tanto, hay un popurrí de los símbolos que se usan en cada región. Por ejemplo, en algunas uasn macrones
-- para alargar vocales. Esto sin embargo no produce ninguna colisión entre ninguna variante.
-- Pero sí que hay algunas incompatibilidades entre las variantes:
-- 1. El saltillo es una glotal en el nahua clásico, en los demás es una /h/
-- 2. Las tildes representan un saltillo en todas las variantes excepto en Mecayapan y Tatahuicapan, en donde se usan para acentuar.
-- Asimismo, supuestamente hay algo así como una corriente "new school" que propone una ortografía nueva,
-- 100% regular https://netza.org/archivo/por-que-la-ortografia-moderna-es-la-mejor/. En base a esto,
-- la ortografía clásica tiene algunas irregularidades en el sentido de que no es 1 letra 1 fonema el mapeo
-- en ciertos casos:
-- la C: mapea como /s/ antes de E o I, mapea como /k/ sino
-- la QU: mapea como /k/, cuidado porque si reemplazo una por una va a mapear como /ku/
-- En los demás casos, se mapean ciertos digrafos calcados del español (gü, rr, etc.)
--
-- Autor: Tmagc
local export = {}
local insert = table.insert
local concat = table.concat
local m_str = require("Módulo:String")
local u = m_str.char
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 strfind = m_str.find
local strnfd = m_str.toNFD
local strnfc = m_str.toNFC
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 = "[%(%)%[%]%{%}¡!¿?.,;:–—\"“”„‟‘’«»»«‹››‹]"
-- grafía
local virgulilla = u(0x0303)
local dieresis = u(0x0308)
local cedilla = u(0x0327)
local tildes = u(0x0301) -- puede ser un saltillo o para marcar la acentuación
local apostrofes = "'ʼꞌꞋ"..u(0x0300)..u(0x0302) -- el acento grave y el circunflejo mapea a un saltillo siempre
local macrones = u(0x0304)..u(0x0331)
local vocales = "aeioöAEIOÖ"
local VOCAL_SIN_TILDAR = "["..vocales.."]["..macrones.."]?"
local VOCAL = VOCAL_SIN_TILDAR.."["..tildes.."]?"
local consonantes = "bcdfghjklmnñpqrstuvwxyzçBCDFGHJKLMNÑPQRSTUVWXYZÇüÜ"
local CONS = "["..consonantes.."]"
local CONS_O_TILDE = "["..consonantes..tildes.."]"
local permitido = vocales..consonantes..macrones..apostrofes..tildes.."·|%s"
-- IPA
local vocales_ipa = "aeioɔ"
local VOCAL_IPA = "["..vocales_ipa.."]"
local CONS_IPA = "[^"..vocales_ipa..separador.."]"
local mapeo_fono_1 = {
["a"] = "a",
["b"] = "b",
["c"] = "k",
["d"] = "d",
["e"] = "e",
["f"] = "f",
["g"] = "g",
--["h"] = saltillo,
["i"] = "i",
--["j"] = saltillo,
["k"] = "k",
["l"] = "l",
["m"] = "m",
["n"] = "n",
["ñ"] = "ɲ",
["o"] = "o",
["p"] = "p",
["q"] = "k",
["r"] = "ɾ",
["s"] = "s",
["t"] = "t",
["u"] = "w",
["v"] = "b",
["w"] = "w",
["x"] = "ʃ",
["y"] = "j",
["z"] = "s",
["ç"] = "s",
["ö"] = "ɔ",
["ü"] = "w",
}
local mapeo_fono_2 = {
["ce"] = "se",
["ch"] = "t͡ʃ",
["ci"] = "si",
["cu"] = "kʷ",
["gü"] = "w",
["hu"] = "w",
["ku"] = "kʷ",
["lh"] = "l",
--["ll"] = "j", debería hacer esto? NO, la doble l es para forzar una separación de sílaba
["qu"] = "k",
["tl"] = "t͡ɬ",
["ts"] = "t͡s",
["tz"] = "t͡s",
--["uh"] = "w", esto no sé cómo tratarlo, supuestamente es de las terminaciones -uhua, pero provocará un loop infinito cuando intente juntar la hu también. No es más fácil silabear u-hua y ya?
["iy"] = "j",
["yi"] = "j", -- yi después de vocal e iy después de consonante son como una y simple [j]. Ēyi "tres" [eːj] y Quiyahuitl "lluvia" [ˈkja.witɬ]
}
local function aislar_diacriticos(texto)
texto = strnfd(texto)
texto = strsubrep(texto, "(["..tildes.."])([".. virgulilla .. dieresis .. cedilla .. macrones .."]+)", "%2%1")
texto = strsubrep(texto, "(["..macrones.."])([".. virgulilla .. dieresis .. cedilla .."]+)", "%2%1")
texto = strsubn(texto, ".[" .. virgulilla .. dieresis .. cedilla .. "]", {
["n" .. virgulilla] = "ñ",
["N" .. virgulilla] = "Ñ",
["o" .. dieresis] = "ö",
["O" .. dieresis] = "Ö",
["u" .. dieresis] = "ü",
["U" .. dieresis] = "Ü",
["c" .. cedilla] = "ç",
["C" .. cedilla] = "Ç",
})
return texto
end
local function recomponer_diacriticos(texto)
return strnfc(texto)
end
local function normalizar(texto)
texto = strlower(texto)
texto = aislar_diacriticos(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 separar_en_silabas(p, acentuacion_lr)
p = aislar_diacriticos(p)
p = divsil..p..divsil
local C_VOCAL = acentuacion_lr and VOCAL or VOCAL_SIN_TILDAR
local C_CONS = acentuacion_lr and CONS or CONS_O_TILDE
-- Primero: las sílabas son todas del estilo CVC, el punto es que no puede haber dos vocales seguidas o dos consonantes seguidas en una misma sílaba
p = strsubrep(p, "(" .. C_VOCAL .. C_CONS .. "?" .. ")(" .. C_CONS .. "+" .. C_VOCAL .. C_CONS .. "?" .. ")", "%1"..divsil.."%2")
p = strsubrep(p, "(" .. C_VOCAL .. ")(" .. C_VOCAL .. ")", "%1"..divsil.."%2")
p = strsubrep(p, "ll", "l"..divsil.."l")
--Segundo, eximo de la regla anterior los digrafos
for cc, fono in pairs(mapeo_fono_2) do
local a, b = cc:sub(1,1), cc:sub(2)
local A, B = a:upper(), b == "ü" and "Ü" or b:upper()
p = strsubrep(p, "(["..a..A.."])"..divsil.."(["..b..B.."]"..C_VOCAL..")", divsil.."%1%2")
p = strsubrep(p, "(["..a..A.."]["..b..B.."])"..divsil.."("..C_VOCAL..")", divsil.."%1%2")
p = strsubrep(p, "(["..a..A.."])"..divsil.."(["..b..B.."])("..C_CONS..")", "%1%2"..divsil.."%3")
end
-- correcciones finales
p = strsubn(p, "["..divsil.."]+", divsil)
p = strsubrep(p, SEPARADORES_SILABICOS.."("..C_CONS.."+)"..SEPARADORES_SILABICOS.."("..SALVO_SEPARADORES_SILABICOS.."-"..C_VOCAL..")", divsil.."%1%2")
p = strsubrep(p, SEPARADORES_SILABICOS.."("..SALVO_SEPARADORES_SILABICOS.."-)"..SEPARADORES_SILABICOS.."("..C_CONS.."+)"..SEPARADORES_SILABICOS, divsil.."%1%2"..divsil)
p = strsubn(p, "["..divsil.."]+", divsil)
p = strstrip(p, "["..divsil.." ]+")
p = recomponer_diacriticos(p)
return p
end
local function acentuar(p, acentuacion_lr)
p = aislar_diacriticos(p)
if not acentuacion_lr then -- reglas normales
--Si la palabra termina en E, es aguda. Ejemplo: TEOTLÉ, NOPILTSINÉ, KETSALKOATLÉ. En cualquier otro caso es llana.
if strfind(p, "e$") or not strfind(p, SEPARADORES_SILABICOS) then
return strsubn(p, SEPARADORES_SILABICOS.."?".."("..SALVO_SEPARADORES_SILABICOS.."+)$", ac_primario.."%1")
end
return strsubn(p, SEPARADORES_SILABICOS.."?".."("..SALVO_SEPARADORES_SILABICOS.."+"..SEPARADORES_SILABICOS..SALVO_SEPARADORES_SILABICOS.."+)$", ac_primario.."%1")
else -- reglas para Mecayapan y Tatahuicapan: la tilde marca la acentuación
local encontrado
p, encontrado = strsubb(p, SEPARADORES_SILABICOS.."?".."("..SALVO_SEPARADORES_SILABICOS.."+".."["..tildes.."]"..")", ac_primario.."%1")
if not encontrado then
if strfind(p, "[lLrR]$") or not strfind(p, SEPARADORES_SILABICOS) then --termina en -l, -r o es una única sílaba: mono o aguda
p = strsubn(p, SEPARADORES_SILABICOS.."?".."("..SALVO_SEPARADORES_SILABICOS.."+)$", ac_primario.."%1")
else -- varias sílabas y no termina en -l -r --> es LLANA
p = strsubn(p, SEPARADORES_SILABICOS.."?".."("..SALVO_SEPARADORES_SILABICOS.."+"..SEPARADORES_SILABICOS..SALVO_SEPARADORES_SILABICOS.."+)$", ac_primario.."%1")
end
end
return p
end
end
local function generar_pron(texto, fone, saltillo_es_h, acentuacion_lr)
texto = normalizar(texto)
local convertido = {}
local fragmentos = strsplit(texto, "%s*|%s*")
for _,fragmento in ipairs(fragmentos) do
local palabras = strsplit(fragmento, "%s")
local palabras_convertidas = {}
for _,p in ipairs(palabras) do
p = separar_en_silabas(p, acentuacion_lr)
p = strsubn(p, SEPARADORES_SILABICOS, ".")
p = acentuar(p, acentuacion_lr) -- ya la deja descompuesta
-- mapeo fonológico
for a,b in pairs(mapeo_fono_2) do
p = strsubn(p, a, b)
end
if not acentuacion_lr then
p = strsubn(p, "["..tildes.."]", saltillo_es_h and "h" or "Ɂ")
else
p = strsubn(p, "["..tildes.."]", "")
end
p = strsubn(p, "[jh]", saltillo_es_h and "h" or "Ɂ")
p = strsubn(p, ".", mapeo_fono_1)
p = strsubn(p, "["..apostrofes.."]", "Ɂ")
p = strsubn(p, "["..macrones.."]", "ː")
p = strsubn(p, "i([aeo])", "j%1")
p = strsubrep(p, "ɾɾ", "r")
p = strsubrep(p, "^ɾ", "r")
insert(palabras_convertidas, p)
end
insert(convertido, concat(palabras_convertidas, " "))
end
return {{strhtml(concat(convertido, " | "))}}
end
-- Punto de entrada externo, recibe el título de página y los argumentos de plantilla
function export.procesar_pron_args(titulo, args, saltillo_es_h, acentuacion_lr)
if #args["ayuda"] < 1 then
args["ayuda"][1] = titulo
end
if #args["fone"] < 1 and #args["fono"] < 1 then
--local x = pron_abc[args["ayuda"][1]]
--if x then
-- args["tl"] = x
-- args["ayuda"][1] = x
--end
local A = #args["ayuda"]
local j = 1 -- indice de la ayuda
local k = 1 -- cantidad de pronunciaciones insertadas (máximo 9)
while k <= 9 and j <= A do
local fono = generar_pron(args["ayuda"][j], saltillo_es_h, acentuacion_lr)
for i,_ in ipairs(fono) do
insert(args["fono"], fono[i])
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 = separar_en_silabas(args["ayuda"][1], acentuacion_lr)
args["d"][1] = strsubn(aux, SEPARADORES_SILABICOS, "-")
end
end
local rim = args["fono"][1][1]
rim = strsubn(rim, "^.*ˈ(.-)$", "%1")
args["rima"][1] = strsubn(rim, ".-".."("..VOCAL_IPA..".*"..")".."$", "%1")
end
return args
end
return export