Module:gl-reinteg-common

local export = {}

local romut_module = "Module:romance utilities"

local rsubn = mw.ustring.gsub local rfind = mw.ustring.find local rmatch = mw.ustring.match

local unaccented_vowel = "aeiouàAEIOUÀ" local accented_vowel = "áéíóúýâêôÁÉÍÓÚÝÂÊÔ" local maybe_accented_vowel = "ãõÃÕ" local vowel = unaccented_vowel .. accented_vowel .. maybe_accented_vowel local V = "[" .. vowel .. "]" export.V = V local AV = "[" .. accented_vowel .. "]" export.AV = AV local NAV = "[^" .. accented_vowel .. "]" export.NAV = NAV local C = "[^" .. vowel .. ".]" export.C = C local remove_accent = { ["á"]="a", ["é"]="e", ["í"]="i", ["ó"]="o", ["ú"]="u", ["ý"]="y", ["â"]="a", ["ê"]="e", ["ô"]="o", ["Á"]="A", ["É"]="E", ["Í"]="I", ["Ó"]="O", ["Ú"]="U", ["Ý"]="Y", ["Â"]="A", ["Ê"]="E", ["Ô"]="O" } export.remove_accent = remove_accent

-- version of rsubn that discards all but the first return value local function rsub(term, foo, bar) local retval = rsubn(term, foo, bar) return retval end

export.rsub = rsub

-- version of rsubn that returns a 2nd argument boolean indicating whether -- a substitution was made. local function rsubb(term, foo, bar) local retval, nsubs = rsubn(term, foo, bar) return retval, nsubs > 0 end

export.rsubb = rsubb

-- apply rsub repeatedly until no change local function rsub_repeatedly(term, foo, bar) while true do		local new_term = rsub(term, foo, bar) if new_term == term then return term end term = new_term end end

export.rsub_repeatedly = rsub_repeatedly

function export.remove_final_accent(stem) return rsub(stem, "(" .. AV .. ")(" .. C .. "*)$", function(v, c) return (remove_accent[v] or v) .. c end) end

local prepositions = { -- a + optional article "a ", "às? ", "aos? ", -- com + optional article "com ", "coa?s? ", "d'", -- de + optional article "de ", "d[oa]s? ", "d'", -- en/em + optional article "em ", "n[oa]s? ", -- por + optional article "por ", "pol[oa]s? ", -- others "para ", "at[áé] ", "com[oa] ", "entre ", "se[nm] ", "sob? ", "sobre ", }

local function call_handle_multiword(term, special, make_fun, fun_name) local retval = require(romut_module).handle_multiword(term, special, make_fun, prepositions) if retval then if #retval ~= 1 then error("Internal error: Should have one return value for " .. fun_name .. ": " .. table.concat(retval, ",")) end return retval[1] end return nil end

local function make_try(word) return function(from, to) local newval, changed = rsubb(word, from, to) if changed then return newval end return nil end end

function export.make_plural(term, special) local retval = call_handle_multiword(term, special, export.make_plural, "make_plural") if retval then return retval end

local try = make_try(term) -- This is ported from Module:pt-common and based off of http://agal-gz.org/faq/doku.php?id=pt_agal:normas:norma_da_agal:morfologia:o_nome. return try("ão$", "ões") or		try("aõ$", "oens") or try("(" .. AV .. ".*)[ei]l$", "%1eis") or -- final unstressed -el or -il try("el$", "éis") or -- final stressed -el try("il$", "is") or -- final stressed -il try("(" .. AV .. ".*)ol$", "%1ois") or -- final unstressed -ol try("ol$", "óis") or -- final stressed -ol try("(" .. V .. ")l$", "%1is") or -- any other vowel + -l try("m$", "ns") or -- final -m try("(" .. V .. ")$", "%1s") or -- final vowel try("([ºª])$", "%1s") or -- ordinal indicator try("([íú]s)$", "%1es") or -- país -> países try("(" .. AV .. ")s$", function(av) return (remove_accent[av] or av) .. "ses" end) or -- final -ês, -ós etc. try("^(" .. NAV .. "*" .. C .. "[ui]s)$", "%1es") or -- final stressed -us or -is after consonant try("^(" .. NAV .. "*[aeo][ui]s)$", "%1es") or -- final stressed diphthong + -s e.g. deus try("([aeo])iz$", "%1ízes") or -- raiz -> raízes try("([aeo])uz$", "%1úzes") or -- same for u; not sure if there are any examples try("([rzn])$", "%1es") or -- final -r, -z, -n: hífen, flor, pior, cruz, rapaz try("([sx])$", "%1") or -- unstressed final -s, final cluster with -s or final -x: no change term .. "s" end

function export.make_feminine(term, is_noun, special) local retval = call_handle_multiword(term, special, function(term) return export.make_feminine(term, is_noun) end,		"make_feminine") if retval then return retval end

local try = make_try(term)

-- This is ported from Module:pt-common and based off of http://agal-gz.org/faq/doku.php?id=pt_agal:normas:norma_da_agal:morfologia:o_nome. return -- Exceptions: afegão (afegã), alazão (alazã), alemão (alemã), ancião (anciã), --            anglo-saxão (anglo-saxã), beirão (beirã/beiroa), bretão (bretã), cão (cã), --            castelão (castelã/castelona[rare]/casteloa[rare]), catalão (catalã), chão (chã), --            cristão (cristã), fodão (fodão since from foda), grão (grã), lapão (lapoa), --            letão (letã), meão (meã), órfão (órfã), padrão (padrão), pagão (pagã), --            paleocristão (paleocristã), parmesão (parmesã), romão (romã), são (sã), --            saxão (saxã), temporão (temporã), teutão (teutona/teutã/teutoa), vão (vã), --            varão (varoa), verde-limão (invariable), vilão (vilã/viloa) try("ám$", "á") or		try("ao$", "á") or		try("om$", "ona") or		try("ão$", "ona") or		try("o$", "a") or		-- ordinal indicator try("º$", "ª") or -- francês, português, inglês, holandês etc.		try("ês$", "esa") or		-- francez, portuguez, inglez, holandez (archaic) try("ez$", "eza") or		-- adjectives in: -- * -ador, -edor (amortecedor, comovedor, etc.), -idor (inibidor, etc.) -- * -tor (condutor, construtor, coletor, etc.) -- * -sor (admissor, censor, decisor, etc.) -- but not: -- * anterior/posterior/inferior/maior/pior/melhor -- * bicolor/incolor/multicolor/etc., indolor, etc.		try("([dts][oô]r)$", "%1a") or		-- amebeu, aqueu, aquileu, arameu, cananeu, cireneu, egeu, eritreu, -- europeu, galileu, indo-europeu/indoeuropeu, macabeu, mandeu, pigmeu, -- proto-indo-europeu -- Exceptions: judeu (judia), sandeu (sandia) try("eu$", "eia") or		is_noun and try("e$", "a") or -- note: espanhol (espanhola), but this is the only case in -ol (vs. bemol, mongol with no		-- change in the feminine) term end

function export.make_masculine(term, special) local retval = call_handle_multiword(term, special, export.make_masculine, "make_masculine") if retval then return retval end

local try = make_try(term)

return try("([dts])ora$", "%1or") or		try("a$", "o") or		-- ordinal indicator try("ª$", "º") or		term end

-- FIXME: Next two copied from Module:es-common. Move to a utilities module.

-- Add links around words. If multiword_only, do it only in multiword terms. function export.add_links(term, multiword_only) if term == "" or term == " " then return term end if not term:find("%[%[") then if rfind(term, "[%s%p]") then --optimization to avoid loading Module:headword on single-word terms local m_headword = require("Module:headword") if m_headword.head_is_multiword(term) then term = m_headword.add_multiword_links(term) end end if not multiword_only and not term:find("%[%[") then term = "" .. term .. "" end end return term end

function export.strip_redundant_links(term) -- Strip redundant brackets surrounding entire term. return rmatch(term, "^%[%[([^%[%]]*)%]%]$") or term end

return export