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

--tomado de https://en.wiktionary.org/wiki/Module:es-pronunc

--Autores: Benwing2 & Tmagc

local export = {}

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

local m_table = require("Módulo:tabla")

local m_prefijos = require("Módulo:generar-pron/es/prefijos")

local NO_HIATO = "Desde 1999 se recomienda considerar siempre diptongo, a efectos de acentuación gráfica, la combinación entre vocales cerradas “[[átono|átonas]]” (/iu/, /ui/), o entre vocales cerradas con vocales abiertas ambas “[[átono|átonas]]” (/ua/, /ei/, /io/, etc.). Esta recomendación se transforma en prescripción a partir de la reforma ortográfica de 2010, por lo que muchas palabras que se podían ''escribir'' con hiato deberán escribirse en diptongo. No obstante, esto no implica una proscripción en la pronunciación. [https://www.rae.es/espanol-al-dia/palabras-como-guion-truhan-fie-liais-etc-se-escriben-sin-tilde Más información]."
local DOBLE_SEPARACION = "Cuando ciertos prefijos están presentes, la agrupación natural de sílabas (fonética) puede cambiar. Algunos ejemplos son: ''transatlántico'' (trans-at-lán-ti-co en lugar de tran-sa-tlán-ti-co), ''subrayar'' (sub-ra-yar en lugar de su-bra-yar), ''abrogar'' (ab-ro-gar en lugar de a-bro-gar). Para estos casos en el lenguaje escrito se recomienda dividir la palabra agrupando el prefijo, sobre todo cuando influye en la pronunciación de la erre. [https://lema.rae.es/dpd/?key=guion#21 Más información]."
local DOBLE_VOCAL = "Dos vocales seguidas no pueden separarse nunca a final de línea, formen diptongo, triptongo o hiato. Para palabras con ''h'' intercalada, se actuará como si esta letra muda no existiese. Quedan exceptuadas de esta consideración las palabras compuestas. [https://lema.rae.es/dpd/?key=guion#21 Más información]."
local LETRA_HUERFANA = "Por motivos estéticos, debe evitarse dejar una letra huérfana a final de línea. [https://lema.rae.es/dpd/srv/search?key=guion Más información]."
local NO_PS = "Las palabras que comienzan por ps-, pt- gn- o mn- admiten dos grafías: con la primera consonante (''psicología'', ''gnoseología'') o sin ella (''sicología'', ''noseología''). Mientras que la segunda opción refleja mejor la pronunciación, la primera es preferida en la norma culta. [https://www.rae.es/dpd/g Más información]." 
local FITOVARIANTES = "Casi todas los términos científicos con el sufijo -fito admiten dos variantes, una llana y la otra esdrújula. Excepciones se pueden encontrar por ejemplo en sínfito, que es un término que ya estaba asentado en griego y en latín y en donde sólo la forma esdrújula es válida. [https://www.rae.es/dpd/-fito Más información]"
local IACO = "Las palabras terminadas con el sufijo -iaco admiten dos variantes: una esdrújula con hiato (-íaco, 'i.a.ko) y otra llana con diptongo (-iaco, 'ia.ko). La primera es la prefereida en América, mientras que la segunda es más usual en España."
local MAYUSCULA_DISCIPLINAS = "En general, los nombres de las disciplinas van en minúscula (“La medicina ha experimentado grandes avances en los últimos años”). Se usa mayúscula en ciertos contextos académicos y en especial cuando están referidas a asignaturas particulares que ofrece una determinada institución (“El profesor de Cálculo Numérico es extraordinario”). [https://www.rae.es/dpd/may%C3%BAsculas Más información]"
local MAYUSCULA_TAXONES = "“Se escriben con mayúscula los nombres de los grupos taxonómicos zoológicos y botánicos superiores al género, cuando se usan en aposición: orden Roedores, familia Leguminosas; pero estos mismos términos se escriben con minúscula cuando se usan como adjetivos o como nombres comunes: El castor es un mamífero roedor; Hemos tenido una buena cosecha de leguminosas.” [https://www.rae.es/dpd/may%C3%BAsculas Más información]"
local MAYUSCULA_PUNTOS_CARDINALES = "Los puntos cardinales se escriben con minúscula. Sólo se escriben con mayúscula cuando forman parte de un nombre propio."
local ORDINALES_COMPUESTOS = "De los ordinales compuestos, los correspondientes a la primera y a la segunda decena se pueden escribir en una o en dos palabras. Si es en una palabra, no puede llevar tilde y el primer compuesto se mantiene invariante (vigesimoprimero, vigesimoprimera, vigésimo primero, o vigésima primera, pero no *vigésimoprimero ni *vigesimaprimera ni *vigésimo primera). A partir de la tarcera decena, sí o sí deberán ser dos palabras. [https://https://www.rae.es/dpd/ordinales Más información]."
local PREFIJO_TRANS = "Generalmente, las palabras admiten combinarse con los prefijos trans- o tras-. Algunas excepciones a esto son: 1. Palabras en donde el significado del prefijo es “detrás”, en donde sólo suele admitirse -tras (trastienda) 2. Palabras en donde el segundo elemento empieza con s, en donde sólo suele admitirse -trans (transexual). [https://www.rae.es/dpd/tras- Más información]"
--[=[
REVISAR:

16. AGREGAR TABLA CON INFORMACION DE PREFIJOS (ej: transatlántico -> trans-at-lán-ti-co , en lugar de tran-sat-lán-ti-co, que es como lo hace ahora)

YA IMPLEMENTADO:

1. Port latest changes to production module. [DONE]
2. Finish work on rhymes and hyphenation. [DONE]
3. Handle <hmp:...> for homophones. [DONE]
4. Don't add comma before phonetic IPA. [DONE]
5. Handle secondary stress, suffixes, etc. in syllabification. [DONE]
6. Need some changes to syllable splitting in consonant clusters. (e.g. 'cum‧min‧gto‧ni‧ta') [DONE]
8. Propagate qualifiers on individual pronun terms to rhymes and hyph. (creo que está)
7. Fix handling of references to correspond to Portuguese module. [DONE]
9. Support raw phonemic/phonetic pronunciations. [DONE]
10. Support overall audio. [DONE]
11. Keep th/ph/kh/gh/tz ([[Ertzaintza]]) together when syllabifying (but not bh due to [[subhumano]], [[subhistoria]], etc.). [DONE]
12. Support <q:...> and <qq:...> on audio. [DONE]
13. Support <a:...> and <aa:...> (using {{a|...}}, left and right) on terms, rhymes, hyphenation, homophones and
    audio. [DONE]
14. Support # instead of ; as separator between audio file and gloss and make sure it works if gloss has embedded # or
    ;. [DONE]
15. Use parse_inline_modifiers() in [[Module:parse utilities]]. [DONE]
]=]

--[=[

En total consideramos que (a grandes rasgos) hay 6 pron posibles:
1. seseante + yeísta (General)
2. seseante + lleísta (Litoral)
3. seseante + sheísta (CABA)
4. seseante + zheísta (Interior)
5. no seseante + yeísta (España)
6. no seseante + lleísta (España)
]=]

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 strmatchit = m_str.gmatch
local strsubrep = m_str.gsub_rep
local strsplit = m_str.split
local strupper = m_str.upper
local strlower = m_str.lower
local strucfirst = m_str.ucfirst
local strnfd = m_str.toNFD
local strnfc = m_str.toNFC
local strstrip = m_str.strip
local substr = m_str.sub
local strlen = m_str.len
local strexplode = m_str.explode_utf8

local function strsub(s, a, b)
	local c, _ = strsubn(s, a, b)
	return c
end

--CONVENCION: mayúscula para patrones encerrados entre corchetes, minúscula para todo lo demás
local ag = u(0x0301) -- acute =  ́
local gr = u(0x0300) -- grave =  ̀
local circunflejo = u(0x0302) -- circumflex =  ̂
local virgulilla = u(0x0303) -- tilde =  ̃
local dieresis = u(0x0308) -- diaeresis =  ̈
local ac_primario = u(0x02C8)
local ac_secundario = u(0x02CC)

local diacritico = ag .. gr .. circunflejo
local DIACRITICO = "[" .. diacritico .. "]"
local tilde = ag .. gr
local TILDE = "[" .. tilde .. "]"
local acentos_ipa = ac_primario..ac_secundario
local ACENTOS_IPA = "[" .. acentos_ipa .. "]"

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

local vocales = "aeiouüAEIOUÜ"
local VOCAL = "[" .. vocales .. "]"
local vocales_tildadas = "áéíóúàèìòùÁÉÍÓÚÀÈÌÒÙ"
local VOCAL_TILDADA = "[" .. vocales_tildadas .. "]"
local CONS = "[^" .. vocales .. vocales_tildadas .. separador .. "]"
local CONS_SALVO_H = "[^" .. vocales .. vocales_tildadas .. separador .. "h]"
local CONS_O_SEP_PALABRA = "[^" .. vocales .. vocales_tildadas .. separador_excepto_palabras .. "]"
--local T = "[^" .. vocales .. "lrɾjw" .. separador .. "]" -- obstruent or nasal

-- Para las notas al pie
local vocales_cerradas_atonas = "iu"
local VOCAL_CERRADA_ATONA = "["..vocales_cerradas_atonas.."]"
local vocales_abiertas_atonas = "aeo"
local VOCAL_ABIERTA_ATONA = "["..vocales_abiertas_atonas.."]"
local VOCAL_GENERAL = "[" .. vocales .. vocales_tildadas .. "]"

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

local TEMP_I = u(0xFFF1)
local TEMP_J = u(0xFFF2)
local TEMP_U = u(0xFFF3)
local TEMP_Y_CONS = u(0xFFF4)
local TEMP_QU = u(0xFFF5)
local TEMP_QU_CAPS = u(0xFFF6)
local TEMP_GU = u(0xFFF7)
local TEMP_GU_CAPS = u(0xFFF8)
local TEMP_H = u(0xFFF9)
local TEMP_Y = u(0xFFFA)
local TEMP_W = u(0xFFFB)
local TEMP_TCHR = u(0xFFFC)
local foot_boundari = "|"
local terminador = "#"
local comodin_yeista = "ɟ"
local comodin_chancho = "ĉ"
local comodin_jota = "ħ"
local comodin_deshielo = "ĥ"
local comodin_thrauna = "ţ"

local COMODINES = "[" .. TEMP_I .. TEMP_J .. TEMP_U .. TEMP_Y_CONS .. TEMP_QU .. TEMP_QU_CAPS .. TEMP_GU .. TEMP_GU_CAPS .. TEMP_H .. TEMP_Y .. TEMP_W .. TEMP_TCHR ..
comodin_yeista .. comodin_chancho .. comodin_jota .. comodin_deshielo .. comodin_thrauna ..
"g" .. "%" .. foot_boundari .. terminador .. "]"

local recuperar_comodin = {
    [TEMP_I] = "i",
	[TEMP_J] = "i", -- i como semivocal
    [TEMP_U] = "u",
    [TEMP_Y_CONS] = "y",
    [TEMP_QU] = "qu",
    [TEMP_QU_CAPS] = "Qu",
    [TEMP_GU] = "gu",
    [TEMP_GU_CAPS] = "Gu",
    [TEMP_H] = "h", -- h que no se aspirada
    [TEMP_Y] = "i", --sufijos -ay/-ey/-oy/-uy
	[TEMP_W] = "w̝", -- hueso, huevo, etc. (la otra w ya la procesamos antes)
	[TEMP_TCHR] = "tchr",
	[comodin_jota] = "h",  -- fake aspirated "h" to real "h"
	[comodin_chancho] = "t͡ʃ", -- fake "ch" to real "ch"
	[comodin_yeista] = "ʝ", --phonetic and "ɟ͡ʝ" or "ʝ", -- fake "y" to real "y
	[comodin_deshielo] = "desh",
	[comodin_thrauna] = "ʈ͡ʂ",
	["g"] = "ɡ", -- U+0067 LATIN SMALL LETTER G → U+0261 LATIN SMALL LETTER SCRIPT G
	[foot_boundari] = "&#124;",
	[terminador] = "",
}

local recuperar_comodin_silabeo = {
    [TEMP_I] = "i",
	[TEMP_J] = "i", -- i como semivocal
    [TEMP_U] = "u",
    [TEMP_Y_CONS] = "y",
    [TEMP_QU] = "qu",
    [TEMP_QU_CAPS] = "Qu",
    [TEMP_GU] = "gu",
    [TEMP_GU_CAPS] = "Gu",
    [TEMP_H] = "h", -- h que no se aspirada
    [TEMP_Y] = "i", --sufijos -ay/-ey/-oy/-uy
	[TEMP_W] = "u", -- hueso, huevo, etc. (la otra w ya la procesamos antes)
	[TEMP_TCHR] = "tchr",
	[comodin_jota] = "h",  -- fake aspirated "h" to real "h"
	[comodin_chancho] = "ch", -- fake "ch" to real "ch"
	[comodin_yeista] = "y", --phonetic and "ɟ͡ʝ" or "ʝ", -- fake "y" to real "y
	[comodin_deshielo] = "desh",
	[comodin_thrauna] = "tchr",
	["ɡ"] = "g", -- AL REVÉS QUE EN LA OTRA TABLA
	[foot_boundari] = "&#124;",
	[terminador] = "",
}


local no_acentuado = m_table.listToSet({
	"el", "la", "los", "las", "un", -- artículos
	"me", "te", "se", "lo", "le", "nos", "os", "les", -- pron. objeto
	"mi", "mis", "tu", "tus", "su", "sus", -- posesivos
	"que", "quien", "cuan", "cual",  -- pron. relativos
	"y", "e", "o", "u", "ni", -- conjunciones
	"de", "del", "a", "al", -- preposiciones y articulos
	"por", "en", "con", "sin", "tras", -- más preposiciones
	"mas", --pero
	"so", --de so pretexto
	"si",
})

-- aislar_diacriticos salvo ñ y ü
local function aislar_diacriticos(text)
	text = strnfd(text)
	text = strsubn(text, ".[" .. virgulilla .. dieresis .. "]", {
		["n" .. virgulilla] = "ñ",
		["N" .. virgulilla] = "Ñ",
		["u" .. dieresis] = "ü",
		["U" .. dieresis] = "Ü",
	})
	return text
end

local function quitar_diacriticos(text) -- salvo virgulilla y diéresis
	text = strnfd(text)
	text = strsubn(text, "[" .. ag .. gr .. circunflejo .. ac_primario .. ac_secundario .. "]", "")
	return strnfc(text)
end
-- convert i/u between vowels to glide
local vowel_to_glide = { ["i"] = "j", ["u"] = "w" }
local vowel_to_glide_silabeo = { ["i"] = TEMP_J, ["u"] = TEMP_W }
	
local tildar = {
	["a"] = "á",
	["e"] = "é",
	["i"] = "í",
	["o"] = "ó",
	["u"] = "ú",
}

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

local diacritico_a_IPA = { [ag] = ac_primario, [gr] = ac_secundario, [circunflejo] = "" }
local pron_abc = {{"a"},{"be","be larga"},{"ce"},{"de"},{"e"},{"efe"},{"ge"},{"hache"},{"i","i latina"},
	{"jota"},{"ka"},{"ele"},{"eme"},{"ene"},{"o"},{"pe"},{"cu"},{"erre"},{"ese"},{"te"},{"u"},
	{"ve","ve corta","uve"},{"doble ve","doble u","uve doble"},{"equis"},{"i","i griega","ye"},{"zeta"},{"eñe"}}

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)

    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 determinar_acentuacion(acento_id)
	if acento_id then
		if acento_id == -1 then
			return "monosílaba"
		elseif acento_id == 0 then
			return "doble acentuada"
		elseif acento_id == 1 then
			return "aguda"
		elseif acento_id == 2 then
			return "llana"
		elseif acento_id == 3 then
			return "esdrújula"
		elseif acento_id >= 4 then
			return "sobreesdrújula"
		else
			return nil
		end
	else
		return nil
	end
end

--Convierte los diacríticos a notación IPA
local function reemplazar_tildes(w)
	local silabas = strsplit(w, SEPARADORES_SILABICOS)
	local L = #silabas
	local sufijo = nil
	
	if L >= 4 and silabas[L-1] == "men" and silabas[L] == "te" then
		sufijo = {ac_primario.."men", divsil.."te"}
		silabas[L-1], silabas[L] = nil, nil
		L = L - 2
	end
	
	local sustituido = false
	local sust = false
	
	for i,silaba in ipairs(silabas) do
		silabas[i], sust = strsubb(silaba, "^(.*)(" .. DIACRITICO .. ")(.*)$",	function(pre, diacr, post) return diacritico_a_IPA[diacr] .. pre .. post end)
		sustituido = sustituido or sust
	end
	
	if not sustituido then
		if L > 1 then
			if strfind(w, "[^" .. vocales .. "ns]$") or strfind(w, CONS..CONS.."$") then -- las palabras que terminan en doble consonante son agudas a menos que lleven tilde https://www.rae.es/espanol-al-dia/por-que-biceps-se-escribe-con-tilde-si-es-una-palabra-llana-terminada-en-s
				silabas[L] = ac_primario .. silabas[L] --aguda
			else
				silabas[L - 1] = ac_primario .. silabas[L - 1] --grave
			end
		else --Si L==1, entonces el monosílabo es tónico ya que no tiene circunflejos
			silabas[1] = ac_primario .. silabas[1]
		end 
	end
	
	local p = silabas[1]
	
	for i,s in ipairs(silabas) do
		if i > 1 then
			if strfind(s, ACENTOS_IPA) then
				p = p .. s
			else
				p = p .. divsil .. s
			end
		end
	end
	
	if sufijo then
		return p .. sufijo[1] .. sufijo[2]
	else
		return p
	end
end

--Se obtiene la longitud silábica, acentuación (hacerlo con la ayuda, no con el original)
local function obtener_informacion(w)
	if type(w) ~= "string" then
		return nil	
	end
	local silabas = strsplit(w, SEPARADORES_SILABICOS)
	
	local L = #silabas
	local sufijo = nil
	if L >= 4 and silabas[L-1] == "men" and silabas[L] == "te" then
		sufijo = "-men-te"
		silabas[L-1], silabas[L] = nil, nil
		L = L - 2
	end
	
	local acento_id = nil
	local acento_idx = nil
	local lleva_tilde = nil
	
	for i,silaba in ipairs(silabas) do
		lleva_tilde = strfind(silaba, "^(.*)(" .. VOCAL_TILDADA .. ")(.*)$")
		if lleva_tilde then
			acento_id = L == 1 and -1 or L - i + 1
			acento_idx = i
			break
		end
	end
	
	if not lleva_tilde then
		if L == 1 then
			acento_id = -1 --monosílabo
			acento_idx = 1
		else
			if strfind(w, "[^" .. vocales .. "ns]$") or strfind(w, CONS..CONS.."$") then -- las palabras que terminan en doble consonante son agudas a menos que lleven tilde https://www.rae.es/espanol-al-dia/por-que-biceps-se-escribe-con-tilde-si-es-una-palabra-llana-terminada-en-s
				acento_id = 1 -- aguda
				acento_idx = L
			else
				acento_id = 2 -- grave
				acento_idx = L - 1
			end
		end
	end
	
	if sufijo then --por ahora el único caso contemplado son los adverbios que terminan en -mente
		return L + 2, determinar_acentuacion(0), "ente" --0 para indicar doble acentuación
	else
		local x = nil
		if lleva_tilde then
			x = strfind(silabas[acento_idx], VOCAL_TILDADA)
			if not x then
				return nil,nil
			end
		else
			x = strfind(silabas[acento_idx], VOCAL)
			if not x then
				return nil,nil
			end
			local q = substr(silabas[acento_idx], x-1, x+1)
			if q == "que" or q == "qui" or q == "gue" or q == "gui" then
				x = x+1
			end
		end
		return L, determinar_acentuacion(acento_id)
	end
end

--Pasos finales al dividir en sílabas (2 puntos de entrada: la función de generar
--pronunciación y la que separa en sílabas propiamente dicha)
local function separar_en_silabas_final(word)

	--PASO 0: BUSCAR EN LA TABLA DE PREFIJOS: extraer sílabas conocidas y que no puedan deducirse regularmente (tran, trans)
	
	--PASO 1: Divida tras cada grupo de vocales + última consonante que no sea h, o bien entre consonantes que estén
	--rodeades por vocales, pero sin contar la 'h' (prohibir --> prohi.bir)
	
	word = strsubrep(word, "(" .. VOCAL .. DIACRITICO .. "*)(" .. CONS_SALVO_H .. VOCAL .. ")", "%1"..divsil.."%2")
	word = strsubrep(word, "(" .. VOCAL .. DIACRITICO .. "*" .. CONS .. "+)(" .. CONS .. VOCAL .. ")", "%1"..divsil.."%2")

	--PASO 2: Vuelva a juntar algunos grupos de consonantes
	
	-- Juntar consonantes fricativas y oclusivas con l y con r. A ecepción de dl.
	word = strsubn(word, "([pbfvkctg])"..divsil.."([lrɾ])", divsil.."%1%2")
	word = strsubn(word, "d%"..divsil.."([rɾ])", divsil.."d%1")
	
	 -- swing, switch, etc.
	word = strsubn(word, "s"..divsil.."w", divsil.."sw")
	-- Juntar ch, sh, zh, ph, th, dh, fh, kh or gh. NO Juntar bh (subhumano, subhúmedo)
	word = strsubn(word, "([cszptdfkg])"..divsil.."h", divsil.."%1h")
	-- Juntar las ll y rr
	word = strsubn(word, "l"..divsil.."l", divsil.."ll")
	word = strsubn(word, "r"..divsil.."r", divsil.."rr")
	
	-- Juntar tz (([[Ertzaintza]], [[quetzal]], [[hertziano]], palabras Vascas, Nahualt o Alemanas) -- dudo de que sea lo correcto
	-- word = strsubn(word, "t"..divsil.."z", divsil.."tz")
	
	-- PASO 3: Separar tl cuando aparezca al final de una palabra. (Palabras mexicanas como Nahuatl, Popocatepetl, etc.)
	-- https://catalog.ldc.upenn.edu/docs/LDC2019S07/Syllabification_Rules_in_Spanish.pdf
	-- https://www.spanishdict.com/guide/spanish-syllables-and-syllabification-rules.
	-- --> esto está mal, tl no es una sílaba aparte ni siquiera en náhuatl
	-- word = strsubn(word, "([^"..divsil.."])tl$", "%1"..divsil.."tl")

	-- PASO 4: separar los hiatos 
	-- vocal abierta + vocal abierta (opcional h)
	word = strsubrep(word, "([aeoAEO]" .. DIACRITICO .. "*)(h?[aeo])", "%1"..divsil.."%2")
	-- vocal abierta + vocal tildada
	word = strsubrep(word, "([aeoAEO]" .. DIACRITICO .. "*)(h?" .. VOCAL .. TILDE .. ")", "%1"..divsil.."%2")
	-- vocal cerrada tildada + vocal abierta
	word = strsubn(word, "([iuüyIUÜY]" .. TILDE .. ")(h?[aeo])", "%1"..divsil.."%2")

	-- ESto no parece español...
	-- dos vocales seguidas tildadas WTF????
	word = strsubrep(word, "([iuüyIUÜY]" .. TILDE .. ")(h?" .. VOCAL .. TILDE .. ")", "%1"..divsil.."%2")
	-- ii (como antiincendios, según la RAE tanto 'antincendios' como 'antiincendios' son válidas; 'hawaiiano', 'shiita')
	word = strsubrep(word, "([iI]" .. DIACRITICO .. "*)(h?i)", "%1"..divsil.."%2")
	-- uu (calculo que por las dudas, le mandó 'vacuum' de ejemplo, pero eso no es español)
	word = strsubrep(word, "([uU]" .. DIACRITICO .. "*)(h?u)", "%1"..divsil.."%2")

	word = strsub(word, SEPARADORES_SILABICOS.."+", divsil)
	word = strstrip(word, SEPARADORES_SILABICOS.."+")

	return word
end

-- FUNCION QUE DIVIDE EN SILABAS (SÓLO PARA UNA PALBRA; SI HAY VARIAS PALABRAS HACERLO DE A UNA POR VEZ POR FAVOR)
local function separar_en_silabas(w)
	if type(w) ~= "string" or strfind(w, "%s") then
		return nil
	end
	
	local p = normalizar(w)
	
	p = strsubn(p, "|", "")
	p = strsubrep(p, "%s+", divsil_fijo) --cambio espacio normalizado por divisor de sílaba fijo
	
	p = strsubn(p, "y(" .. VOCAL .. ")", TEMP_Y_CONS .. "%1")
	
	--Cambio tchr por el comodin
	p = strsubn(p, "tchr", TEMP_TCHR)

	-- Mantenemos junta la 'sh' cuando se trate de desh- (deshuesar, deshonra, deshecho), en los demás casos la separamos.
	-- Para hacerlo, cambiamos la h en los segundos casos
	p = strsubn(p, "^([Dd]es)h", "%1" .. TEMP_H)
	p = strsubn(p, "([ %-][Dd]es)h", "%1" .. TEMP_H)

	-- Cambiamos 'qu' y 'gu'
	-- Dicen que 'qu' va bien reemplazarlo, pero hace agua con 'quietud'
	p = strsubn(p, "qu(" .. VOCAL .. ")", TEMP_QU .. "%1")
	p = strsubn(p, "Qu(" .. VOCAL .. ")", TEMP_QU_CAPS .. "%1")
	p = strsubn(p, "gu(" .. VOCAL .. ")", TEMP_GU .. "%1")
	p = strsubn(p, "Gu(" .. VOCAL .. ")", TEMP_GU_CAPS .. "%1")

	--Agregamos glides (paranoia, baiano, abreuense, alauita, Malaui, marihuana, parihuela, antihielo, pelluhuano, náhuatl)
	--NOTA IMPORTANTE: conviene hacerlo de atrás hacia adelante para que no se generen cosas raras como 'an.tih.ie.lo'

	p = strsubrep(p, "(.*" .. VOCAL .. DIACRITICO .. "*)(h?)([iu])(" .. VOCAL .. ")",function (v1, h, iu, v2) return v1 .. divsil .. h .. vowel_to_glide_silabeo[iu] .. v2 end)

	-- Entro a la función que separa ya pre-procesado a formato IPA
	p = separar_en_silabas_final(p)
	
	p = strsubn(p, COMODINES, recuperar_comodin_silabeo)
	p = strsubn(p, divsil, "-")
	return strnfc(p)
end

-- EXPORTAR A IPA. Es decir, ya teniendo el texto re-escrito para facilitar la pronunciación.
local function generar_pron(text, phonetic)
	if type(text) ~= "string" then
		return {},{}
	end

	local distincion_seseo = false
	local distincion_yeismo = false
	local distincion_sheismo = false
	
	text = normalizar(text)
	
	--Comienzo a sustituir
	--Observación general: el orden en el que sustituimos importa
	
	-- Make prefixes unstressed unless they have an explicit stress marker; also make certain
	-- monosyllabic words (e.g. [[el]], [[la]], [[de]], [[en]], etc.) without stress marks be
	-- unstressed.
	local words = strsplit(text, " ")
	for i, word in ipairs(words) do
		if no_acentuado[word] then
			words[i] = strsubn(word, "^(.*" .. VOCAL .. ")", "%1" .. circunflejo) --pongo el circunflejo para indicar que no debe haber acentuación
		end
	end
	-- put # at word beginning and end and double ## at text/foot boundary beginning/end
	text = concat(words, " ")
	text = strsubn(text, " | ", "# | #")
	text = "##" .. strsubn(text, " ", "# #") .. "##"

	--determinar el sonido apropiado para la y
	-- Nota: sufijos -ay/-ey/-oy/-uy se acentúan, pero no -ai/-ei/-oi/-ui
	-- Nota: -uy mapea a /uj/ mientras que -ui mapea a /wi/
	
	text, distincion_sheismo = strsubb(text, "y(" .. VOCAL .. ")", comodin_yeista.."%1") -- ɟ -> comodín del yeísmo
	
	--Esto no es conveniente hacerlo
	--text = strsubn(text, "([aeou])y#", "%1" .. TEMP_Y .. "#") -- pongo marca privada por el momento
	--text = strsubn(text, "y", "i")

	--Necesitamos procesar sh/ch justo acá (para no hacer lío con la x exhausto (??))
	text = strsubn(text, "ch", comodin_chancho) -- otro comodín más
	text = strsubn(text, "#desh", comodin_deshielo) --comodín para preservar 'desh' (deshuesar, etc.)
	text = strsubn(text, "sh", "ʃ") --reemplazo sh
	text = strsubn(text, "zh", "ʒ") --reemplazo zh
	text = strsubn(text, comodin_deshielo, "#desh") --restauro desh
	text = strsubn(text, "tchr", comodin_thrauna)
	text = strsubn(text, "#p([st])", "#%1") -- Saco la p inicial de psicología o pterodáctilo
	text = strsubn(text, "#[mg]n", "#n") -- Saco la g inicial de gnoseología y la m de mnemónico
	
	--tl al final de la palabra
	text = strsubn(text, "tl#", "t#")

	--x
	text = strsubn(text, "#x", "#s") -- reemplazo la x inicial: xenofobia, xilófono, etc.
	text = strsubn(text, "x", "ks") --> reemplazo las demás x: excusa, eximir, etc.

	--c, g, q
	text, distincion_seseo = strsubb(text, "c([ie])",  "θ"  .. "%1") -- Busco si hay ceceos y los sustituyo. ¿Por qué habían puesto la z?
	text = strsubn(text, "g([iey])", "x%1") -- must happen after handling of x above
	text = strsubn(text, "gu([ie])", "g%1")
	text = strsubn(text, "gü([ie])", "gu%1")
	text = strsubn(text, "ng([^aeiouüwhlr#])", "n%1") -- [[Bangkok]], [[ángstrom]], [[electroswing]], no aplica para [[branding]] (hay que acentuarla manualmente)
	text = strsubn(text, "qu([ie])", "k%1")
	text = strsubn(text, "ü", "u") -- [[Düsseldorf]], [[hübnerita]], obsolete [[freqüentemente]], etc.
	text = strsubn(text, "q", "k") -- [[quark]], [[Qatar]], [[burqa]], [[Iraq]], etc.

	-- map various consonants to their phoneme equivalent
	text = strsubn(text, "[cjñrv]", {["c"]="k", ["j"]="x", ["ñ"]="ɲ", ["r"]="ɾ", ["v"]="b" })

	-- ([[hielo]], [[enhiesto]], [[deshielo]], ...)
	local word_initial_hi, syl_initial_hi, initial_hi
	text, word_initial_hi = strsubb(text, "#h?[iy](" .. VOCAL .. ")", "#j%1")
	text, syl_initial_hi = strsubb(text, "(" .. CONS .. SEPARADORES_SILABICOS .. "*)h[iy](" .. VOCAL .. ")", "%1j%2")
	initial_hi = word_initial_hi or syl_initial_hi
	--  ([[huevo]], [[deshuesar]])
	text = strsubb(text, "(" .. CONS_O_SEP_PALABRA .. SEPARADORES_SILABICOS .. "*)hu(" .. VOCAL .. ")", "%1" .. TEMP_W .. "%2")

	
	-- sustituyo la "ll" final (ej: [[krill]])
	text = strsubn(text, "ll#", "l#")
	--Busco si hay algún posible lleísmo
	text, distincion_yeismo = strsubb(text, "ll", "ʎ") --sustituyo y busco lleísmos

	if distincion_yeismo then
		distincion_sheismo = true
	end

	--Sustituyo rr y lr por r ¿no falta buscar el separador silábico en lr y sr?
	text = strsubn(text, "ɾɾ", "r")
	text = strsubn(text, "([#lnsθ])ɾ", "%1r") --([[alrededor]], [[malrotar]]), nr ([[enriquecer]], [[sonrisa]], etc.), sr ([[Israel]], [[desregular]], etc.), zr ([[Azrael]], [[cruzrojista]]), rr
	text = strsubn(text, "nn", "N") --doble n (ennoblecer) ¿por qué una N grande en lugar de meter un separador silábico?
	text = strsubn(text, "bb", "B") --doble b (subbase) ¿por qué una B grande en lugar de meter un separador silábico?

	text = strsubn(text, "(" .. CONS .. ")%1", "%1") -- elimino consonantes dobles [[Addis Abeba]], [[cappa]], [[descender]], [[crackear]]
	text = strsubn(text, "sθ", "θ") -- elimino sz como en [[fascinante]]

	-- restablezco las consonantes dobles, MUY OSCURO ESTO
	text = strsubn(text, "N", "nn")
	text = strsubn(text, "B", "bb")

	--sustitución de oclusivas (T) cuando se juntan con ptk --> esta parte no tiene sentido
	--local voice_stop = { ["p"] = "b", ["t"] = "d", ["k"] = "g" }
	--text = strsubn(text, "t(" .. SEPARADOR .. "*[sθ])", "!%1") -- eximir -ts-, -tz-
	--text = strsubn(text, "([ptk])(" .. SEPARADOR .. "*" .. T .. ")", function(stop, after) return voice_stop[stop] .. after end)
	--text = strsubn(text, "!", "t") -- recuperar -ts-, -tz-

	text = strsubn(text, "n([# .]*[bpm])", "m%1") --nb, bp, nm por mb, mp, mm (ejemplo: enviar, inmoral, etc.)

	text = strsubn(text, "h", "") --sacar la h muda

	-- i and u between vowels -> consonant-like substitutions: [[paranoia]], [[baiano]], [[abreuense]], [[alauita]],
	-- [[Malaui]], etc.; also with h, as in [[marihuana]], [[parihuela]], [[antihielo]], [[pelluhuano]], [[náhuatl]],
	-- etc. Add .* at the beginning so we go right-to-left, in the case of [[hawaiiano]] -> ha.wai.iano.
	text = strsubrep(text, "(.*" .. VOCAL .. DIACRITICO .. "*h?)([iu])(" .. VOCAL .. ")",
		function (v1, iu, v2) return v1 .. vowel_to_glide[iu] .. v2 end
	)
	
	-- switch -> swich
	text = strsubn(text, "t".."("..SEPARADORES_SILABICOS.."?"..comodin_chancho..")", "%1")
	
	words = strsplit(text, "[#(%s)]+")
	local ac_words = {}
	for _,word in ipairs(words) do
		if #word > 0 then
			if strfind(word, "|") then
				insert(ac_words, word)
			else
				insert(ac_words, reemplazar_tildes(separar_en_silabas_final(word)))
			end
		end
	end
	
	text = concat(ac_words, " ")
	text = strsubn(text, " | ", "# | #")
	text = "##" .. strsubn(text, " ", "# #") .. "##"

	--diphthongs; do not include TEMP_Y here
	text = strsubn(text, "i([aeou])", "j%1")
	text = strsubn(text, "u([aeio])", "w%1")
	text = strsubn(text, "([aeiou])y", "%1j")
	--text = strsubn(text, TEMP_Y, "i") -- -ay/-ey/-oy/-uy
	
	local hay_z = false
	text, hay_z = strsubb(text, "z", "θ")
    distincion_seseo = distincion_seseo or hay_z

	-- suppress syllable mark before IPA stress indicator
	text = strsubn(text, "%.(" .. ACENTOS_IPA .. ")", "%1")
	--make all primary stresses but the last one be secondary
	text = strsubrep(text, ac_primario.."(.+)"..ac_primario, ac_secundario.."%1"..ac_primario)

	--phonetic transcription --> más fino, lo que se escribe entre [] corchetes
	if phonetic then
		-- θ, s, f before voiced consonants
		local voiced = "mnɲbd"..comodin_yeista.."gʎ" .. TEMP_W
		local r_cluster = "ɾr"
		local tovoiced = {
			["θ"] = "θ̬",
			--["s"] = "z", --no existe tal cosa
			--["f"] = "v", --no existe tal cosa
		}
		local function voice(sound, following)
			return tovoiced[sound] .. following
		end
		--text = strsubn(text, "([θs])(" .. SEPARADOR .. "*[" .. voiced .. r .. "])", voice) --mal
		--text = strsubn(text, "(f)(" .. SEPARADOR .. "*[" .. voiced .. "])", voice) --mal

		text = strsubn(text, "([θ])(" .. SEPARADOR .. "*[" .. voiced .. r_cluster .. "])", voice) --única sustitución que tiene sentido

		-- aproximantes
		local stop_to_fricative = {["b"] = "β", ["d"] = "ð", [comodin_yeista] = "ʝ", ["g"] = "ɣ"}
		local fricative_to_stop = {["β"] = "b", ["ð"] = "d", ["ʝ"] = comodin_yeista, ["ɣ"] = "g"}
		text = strsubn(text, "[bd"..comodin_yeista.."g]", stop_to_fricative) --convierto todo a fricativa
		text = strsubn(text, "([mnɲ]" .. SEPARADOR .. "*)([βɣ])", --salvo las precedidas por m,n,ng (convierto de nuevo)
			function(nasal, fricative) return nasal .. fricative_to_stop[fricative] end
		)
		text = strsubn(text, "([lʎmnɲ]" .. SEPARADOR .. "*)([ðʝ])",  --salvo las precedidas por lm,ln,lng, (convierto de nuevo)
			function(nasal_l, fricative) return nasal_l .. fricative_to_stop[fricative] end
		)
		text = strsubn(text, "(##" .. ACENTOS_IPA .. "*)([βɣðʝ])", --salvo las sílabas acentuadas (convierto de nuevo)
			function(stress, fricative) return stress .. fricative_to_stop[fricative] end
		)

		text = strsubn(text, "[td]", {["t"] = "t̪", ["d"] = "d̪"}) --dentalización

		-- nasal assimilation before consonants
		local labiodental, dentialveolar, dental, alveolopalatal, palatal, velar =	"ɱ", "n̪", "n̟", "nʲ", "ɲ", "ŋ"
		local nasal_assimilation = {
			["f"] = labiodental,
			["t"] = dentialveolar, ["d"] = dentialveolar,
			["θ"] = dental,
			[comodin_chancho] = alveolopalatal,	["ʃ"] = alveolopalatal,	["ʒ"] = alveolopalatal,
			[comodin_yeista] = palatal, ["ʎ"] = palatal,
			["k"] = velar, ["x"] = velar, ["g"] = velar,
		}
		text = strsubn(text, "n(" .. SEPARADOR .. "*)(.)", function(stress, following) return (nasal_assimilation[following] or "n") .. stress .. following end)

		-- lateral assimilation before consonants
		text = strsubn(text, "l(" .. SEPARADOR .. "*)(.)",
			function(stress, following)
				local l = "l"
				if following == "t" or following == "d" then -- dentialveolar
					l = "l̪"
				elseif following == "θ" then -- dental
					l = "l̟"
				elseif following == comodin_chancho or following == "ʃ" then -- alveolopalatal
					l = "lʲ"
				end
				return l .. stress .. following
			end)

		--semivowels
		text = strsubn(text, "([aeouãẽõũ][iĩ])", "%1̯")
		text = strsubn(text, "([aeioãẽĩõ][uũ])", "%1̯")

		-- voiced fricatives are actually approximants
		text = strsubn(text, "([βðɣ])", "%1̞")
	end

	-- final conversions
	text = strsubn(text, COMODINES, recuperar_comodin)
	text = strsubn(text, divsil, ".")
	text = strnfc(text)
	
	local pron = {}
	local fone = {}

	if distincion_seseo then
		local seseante = strsubn(text, "θ", "s")
		if distincion_yeismo then
			for i=1,6 do
				pron[i] = {}
				fone[i] = {}
			end
			pron[1][1], fone[1][1] = "seseante, yeísta", strsubn(seseante, "ʎ", "ʝ")
			pron[2][1], fone[2][1] = "seseante, no yeísta", seseante
			pron[3][1], fone[3][1] = "seseante, sheísta", strsubn(seseante, "[ʎʝ]", "ʃ")
			pron[4][1], fone[4][1] = "seseante, zheísta", strsubn(seseante, "[ʎʝ]", "ʒ")
			pron[5][1], fone[5][1] = "no seseante, yeísta", strsubn(text, "ʎ", "ʝ")
			pron[6][1], fone[6][1] = "no seseante, no yeísta", text
		elseif distincion_sheismo then
			for i=1,4 do
				pron[i] = {}
				fone[i] = {}
			end
			pron[1][1], fone[1][1] = "seseante, no sheísta", seseante
			pron[2][1], fone[2][1] = "seseante, sheísta", strsubn(seseante, "ʝ", "ʃ")
			pron[3][1], fone[3][1] = "seseante, zheísta", strsubn(seseante, "ʝ", "ʒ")
			pron[4][1], fone[4][1] = "no seseante", text
		else
			for i=1,2 do
				pron[i] = {}
				fone[i] = {}
			end
			pron[1][1], fone[1][1] = "seseante", seseante
			pron[2][1], fone[2][1] = "no seseante", text
		end
	else
		if distincion_yeismo then
			for i=1,4 do
				pron[i] = {}
				fone[i] = {}
			end
			pron[1][1], fone[1][1] = "yeísta", strsubn(text, "ʎ", "ʝ")
			pron[2][1], fone[2][1] = "no yeísta", text
			pron[3][1], fone[3][1] = "sheísta", strsubn(text, "[ʎʝ]", "ʃ")
			pron[4][1], fone[4][1] = "zheísta", strsubn(text, "[ʎʝ]", "ʒ")
		elseif distincion_sheismo then
			for i=1,3 do
				pron[i] = {}
				fone[i] = {}
			end
			pron[1][1], fone[1][1] = "no sheísta", text
			pron[2][1], fone[2][1] = "sheísta", strsubn(text, "ʝ", "ʃ")
			pron[3][1], fone[3][1] = "zheísta", strsubn(text, "ʝ", "ʒ")
		else
			pron[1] = {}
			fone[1] = {}
			pron[1][1], fone[1][1] = "pronunciación", text
		end
	end

	return pron, fone
end

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

	if #args["fone"] < 1 and #args["fono"] < 1 then
		if #titulo == 1 then
			if titulo >= "a" and titulo <= "z" then
				args["ayuda"] = pron_abc[string.byte(titulo) - 96]
				args["tl"] = args["ayuda"]
			elseif titulo >= "A" and titulo <= "Z" then
				args["ayuda"] = pron_abc[string.byte(titulo) - 64]
				args["tl"] = args["ayuda"]
			end
		elseif titulo == "ñ" or titulo == "Ñ" then
			args["ayuda"] = pron_abc[27]
			args["tl"] = args["ayuda"]
		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 pron, fone = generar_pron(args["ayuda"][j], true)
			for i,_ in ipairs(pron) do
				insert(args["pron"], pron[i])
				insert(args["fone"], fone[i])
				k = k + 1
				if k > 9 then
					break
				end
			end
			j = j + 1
		end
	else
		require("Módulo:traza")("es-pron")
		for i, _ in ipairs(args["pron"]) do
			if args["pron"][i] and args["pron"][i][1] then
				local c = args["pron"][i][1]:sub(1,1)
				local cc = args["pron"][i][1]:sub(1,2)
				local cccc = args["pron"][i][1]:sub(1,4)
				local cccccc = args["pron"][i][1]:sub(1,6)
				if cc == 'se' then
					args["pron"][i][1] = 'seseante'
				elseif cccccc == 'no ses' or cccc == 'dist' then
					args["pron"][i][1] = 'no seseante'
				elseif 	cc == 'ye' then
					args["pron"][i][1] = 'yeísta'
				elseif cccc == 'no ye' then
					args["pron"][i][1] = 'no yeísta'
				elseif cc == 'll' then
					args["pron"][i][1] = 'lleísta'
				elseif cc == 'sh' then
					args["pron"][i][1] = 'sheísta'
				elseif cc == 'zh' then
					args["pron"][i][1] = 'zheísta'
				elseif cccc == 'riop' then
					args["pron"][i][1] = 'rioplatense'
				end
			end
		end
	end
	
	if not strfind(args["ayuda"][1], VOCAL_GENERAL) then
		return args	
	end
	
	if not args["rima"][1] then
		local palabras = strsplit(args["ayuda"][1], "%s+")
		local rims = {}
		local _, fono = generar_pron(palabras[#palabras], false)
		for _,f in ipairs(fono) do
			local rim = f[1]
			rim = strsub(rim, "^.*"..ac_primario.."(.-)$", "%1")
			rim = strsub(rim, ".-".."("..VOCAL_GENERAL..".*"..")".."$", "%1")
			if rim and rim ~= "" then
				rims[rim] = true
			end
		end
		for rim,v in pairs(rims) do
			insert(args["rima"], rim)
		end
	end
	
	if strfind(args["ayuda"][1], "%s") then
		return args
	end
	
	if #args["d"] < 1 and #titulo > 1 and titulo ~= "ñ" and titulo ~= "Ñ" then
		if not args["ls"][1] and not args["ac"][1] and #titulo > 1 then
			local ls = {}
			local ac = {}
			for _,a in ipairs(args["ayuda"]) do
				ss_ = separar_en_silabas(a)
				local lon, ace = obtener_informacion(ss_)
				ls[lon] = true
				ac[ace] = true
			end
			for lon,_ in pairs(ls) do
				insert(args["ls"], lon)
			end
			for ace,_ in pairs(ac) do
				insert(args["ac"], ace)
			end
		end
		
		-- obtenida la “información” de la palabra en base a la “ayuda”, determino cómo mostrar la grafía original
		if not vino_ayuda then -- situación normal
			-- Notas sobre división en sílabas...
			local letras = strexplode(tit)
			local prefijo = ""
			local pref_idx = 0
			
			for i,c in ipairs(letras) do
				if i > 5 then
					break
				end
				prefijo = prefijo .. c
				if m_prefijos[prefijo] then
					pref_idx = i
				end
			end
		
			if pref_idx >= 2 then
				if not args["dnota"][1] then
					args["dnota"][1] = DOBLE_SEPARACION
				end
			end
			args["d"][1] = separar_en_silabas(args["ayuda"][1])
			
			-- grafías
			if strfind(args["ayuda"][1], "^p[st]") or strfind(args["ayuda"][1], "^[mg]n") then
				if #args["g"] == 0 then
					local no_ps = args["ayuda"][1]:sub(2)
					insert(args["g"], no_ps)
					insert(args["gnota"], NO_PS)
				end
			elseif args["ayudaextra"][1] == "mpc" then
				if not args["g"][1] then
					args["g"][1] = strsubn(args["ayuda"][1], "^[a-zA-ZÀ-ž]", function(c) return strfind(c, "%u") and strlower(c) or strupper(c) end)
					args["gnota"][1] = MAYUSCULA_PUNTOS_CARDINALES
				end					
			elseif args["ayudaextra"][1] == "mt" then
				if not args["g"][1] then
					args["g"][1] = strsubn(args["ayuda"][1], "^[a-zA-ZÀ-ž]", function(c) return strfind(c, "%u") and strlower(c) or strupper(c) end)
					args["gnota"][1] = MAYUSCULA_TAXONES
				end									
			elseif args["ayudaextra"][1] == "md" then
				if not args["g"][1] then
					args["g"][1] = strsubn(args["ayuda"][1], "^[a-zA-ZÀ-ž]", function(c) return strfind(c, "%u") and strlower(c) or strupper(c) end)
					args["gnota"][1] = MAYUSCULA_DISCIPLINAS
				end
			elseif args["ayudaextra"][1] == "ocespacio" then
				if not args["g"][1] then
					if strfind(args["ayuda"][1], "^([%S]+[cs]im)[oa][%S]+$") then --decimoprimero, decimosegundo, etc. pero también decimaprimera (subestándar pero existe)
						args["g"][1] = strsubn(args["ayuda"][1], "^([%S]+[cs]im)[oa]([%S]+)([oa]s?)$", function(a, b, c) return strsub(a,"e([sc]im)","é%1")..c.." "..(b == "ctav" and "o"..b or b)..c end)
					else
						args["g"][1] = strsubn(args["ayuda"][1], "^([%S]+[cs]im)[oa]s?%s+([%S]+)([oa]s?)$", function(a, b, c) return strsub(a, "[áéíóú]", quitar_tilde).."o"..b..c end)
					end
					args["gnota"][1] = ORDINALES_COMPUESTOS
				end
			
			elseif args["ayudaextra"][1] == "ocgénero" then
				if not args["g"][1] then
					args["g"][1] = strsubn(args["ayuda"][1], "^(.-[eé][sc]im)([oa])(.-)$", function(a, b, c) return b == "o" and a.."a"..c or a.."o"..c end)
					args["gnota"][1] = ORDINALES_COMPUESTOS
				end
			end
			
			-- variantes
			if strfind(args["d"][1], VOCAL..SEPARADORES_SILABICOS.."fi"..SEPARADORES_SILABICOS.."to".."$") then
				if not args["v"][1] then
					args["v"][1] = strsubn(args["ayuda"][1], "("..VOCAL..")".."fito$", function(v) return tildar[v].."fito" end)
					args["vnota"][1] = FITOVARIANTES
				end
			elseif strfind(args["d"][1], VOCAL_TILDADA..SEPARADORES_SILABICOS.."fi"..SEPARADORES_SILABICOS.."to".."$") then
				if not args["v"][1] then
					args["v"][1] = strsubn(args["ayuda"][1], "("..VOCAL_TILDADA..")".."fito$", function(v) return quitar_tilde[v].."fito" end)
					args["vnota"][1] = FITOVARIANTES
				end
			elseif strfind(args["d"][1], "[ií]"..SEPARADORES_SILABICOS.."?".."a"..SEPARADORES_SILABICOS.."co".."$") then
				if not args["v"][1] then
					args["v"][1] = strsubn(args["ayuda"][1], "([ií]aco)$", function(v) return v == "iaco" and "íaco" or "iaco" end)
					args["vnota"][1] = IACO
				end
			elseif strfind(args["ayuda"][1], "^tran?s") and args["ayudaextra"][1] and (args["ayudaextra"][1] == "trans" or args["ayudaextra"][1] == "tras") then
				insert(args["v"], strsub(args["ayuda"][1], "^(tra)(n?)(s)", function(a, b, c) return b == "n" and "tras" or "trans" end))
				insert(args["vnota"], PREFIJO_TRANS)
			end
			
			if #args["dnota"] == 0 then
				if strfind(args["d"][1], "[^qQgG]"..VOCAL_CERRADA_ATONA.."h?"..VOCAL_CERRADA_ATONA) or strfind(args["d"][1], "[^qQgG]"..VOCAL_CERRADA_ATONA.."h?"..VOCAL_ABIERTA_ATONA) then --ignorar que, qui, gue, gui
					insert(args["dnota"], NO_HIATO)
				elseif strfind(args["d"][1], SEPARADORES_SILABICOS..VOCAL_GENERAL..SEPARADORES_SILABICOS) or strfind(args["d"][1], "^"..VOCAL_GENERAL..SEPARADORES_SILABICOS) or strfind(args["d"][1], SEPARADORES_SILABICOS..VOCAL_GENERAL.."$") then
					insert(args["dnota"], LETRA_HUERFANA)
				elseif strfind(args["d"][1], VOCAL_GENERAL.."h?"..SEPARADORES_SILABICOS.."h?"..VOCAL_GENERAL) then
					insert(args["dnota"], DOBLE_VOCAL)
				end
			end
		else -- palabra extranjera, vino con ayuda --> veo cómo quedaría mejor
			local tit_sombra = quitar_diacriticos(tit)
			local ss_ayuda = quitar_diacriticos(ss_)
			local ss = tit
			local j0 = 0 -- desde dónde debería buscar la próxima coincidencia de letras
			
			while true do
				local i = strfind(ss_ayuda, "[a-zA-ZÀ-ž]%-[a-zA-ZÀ-ž]")
				if not i or i < 1 then
					break
				end
				local a, b = substr(ss_ayuda, i, i), substr(ss_ayuda, i+2, i+2)
				local ab = a..b 
				local j = strfind(tit_sombra, ab, j0) -- veo si encuentro la separación
				if j then -- Si aparece en el título, entonces inserto separador ahí miemo
					tit_sombra = substr(tit_sombra, 1, j).."-"..substr(tit_sombra, j+1)
					ss = substr(ss, 1, j).."-"..substr(ss, j+1)
					j0 = j+2 -- incremento dos: por la primera letra y por el guion
				else --Sino, veo si al menos coincide con una de las dos letras
					local k = strfind(tit_sombra, a, j0) or math.huge
					local l = strfind(tit_sombra, b, j0) or math.huge
					if k < l and k >= 1 then
						tit_sombra = substr(tit_sombra, 1, k).."-"..substr(tit_sombra, k+1)
						ss = substr(ss, 1, k).."-"..substr(ss, k+1)
						j0 = k+2
					elseif l < k and l >= 2 then
						tit_sombra = substr(tit_sombra, 1, l-1).."-"..substr(tit_sombra, l)
						ss = substr(ss, 1, l-1).."-"..substr(ss, l)
						j0 = l+1 -- en este caso se agrega sólo el guion porque la letra considerada es la segunda
					end
				end
				ss_ayuda = substr(ss_ayuda, i+2) -- trunco la ayuda para obtener la siguiente separación
			end
			
			--junto sílabas que sólo tengan consonantes
			ss = "-"..ss.."-"
			ss = strsubrep(ss, "("..SEPARADORES_SILABICOS..CONS.."+)"..SEPARADORES_SILABICOS.."("..SALVO_SEPARADORES_SILABICOS.."-"..VOCAL_GENERAL..")", "%1%2")
			ss = strsubrep(ss, "("..SEPARADORES_SILABICOS..SALVO_SEPARADORES_SILABICOS.."-)"..SEPARADORES_SILABICOS.."("..CONS.."+"..SEPARADORES_SILABICOS..")", "%1%2")
			
			-- limpio los separadores de más
			ss = strsubn(ss, SEPARADORES_SILABICOS .. "+", "-")
			ss = strstrip(ss, SEPARADOR)
			
			args["d"][1] = ss
			
			if #args["dnota"] == 0 then
				if strfind(args["d"][1], SEPARADORES_SILABICOS.."[a-zA-ZÀ-ž]"..SEPARADORES_SILABICOS) or strfind(args["d"][1], "^".."[a-zA-ZÀ-ž]"..SEPARADORES_SILABICOS) or strfind(args["d"][1], SEPARADORES_SILABICOS.."[a-zA-ZÀ-ž]".."$") then
					insert(args["dnota"], LETRA_HUERFANA)
				elseif strfind(args["d"][1], VOCAL_GENERAL.."h?"..SEPARADORES_SILABICOS.."h?"..VOCAL_GENERAL) then
					insert(args["dnota"], DOBLE_VOCAL)
				end
			end
		end
	end

	return args

end

return export