local p = {}

-- Forma femenina d'un mot
local function forma_fem(mot, exc_fem)
	local exc = exc_fem[mot]
	if exc then return exc end
	
	local fem = mot
	fem = mw.ustring.gsub(fem, "an$", "ana")
	if string.find(mot, "e$") and not string.find(mot, "ble$") then
		fem = string.gsub(fem, "go$", "ga")
		fem = string.gsub(fem, "e$", "a")
	end
	fem = mw.ustring.gsub(fem, "ene$", "ena")
	fem = mw.ustring.gsub(fem, "in$", "ina")
	fem = mw.ustring.gsub(fem, "a(%l)i$", "à%1ia")
	fem = mw.ustring.gsub(fem, "i(%l)i$", "í%1ia")
	fem = string.gsub(fem, "o$", "a")
	fem = mw.ustring.gsub(fem, "(oó)n$", "ona")
	fem = string.gsub(fem, "([aio])vo$", "%1va")
	fem = string.gsub(fem, "io$", "ia")
	fem = string.gsub(fem, "esto$", "esta")
	fem = mw.ustring.gsub(fem, "un$", "una")
	fem = string.gsub(fem, "ł([oe])go$", "ł%1ga")
	fem = string.gsub(fem, "([òoàaèeìiòoùu])zeno$", "%1zena")
	fem = mw.ustring.gsub(fem, "azo$", "aza")
	fem = mw.ustring.gsub(fem, "aso$", "asa")
	fem = mw.ustring.gsub(fem, "eze$", "eza")
	fem = mw.ustring.gsub(fem, "ese$", "esa")
	fem = mw.ustring.gsub(fem, "ezo$", "eza")
	fem = mw.ustring.gsub(fem, "eso$", "esa")
	fem = mw.ustring.gsub(fem, "izo$", "iza")
	fem = mw.ustring.gsub(fem, "iso$", "isa")
	fem = mw.ustring.gsub(fem, "oso$", "osa")
	fem = mw.ustring.gsub(fem, "aro$", "ara")
	fem = mw.ustring.gsub(fem, "ero$", "era")
	fem = mw.ustring.gsub(fem, "ozo$", "oza")
	fem = mw.ustring.gsub(fem, "uzo$", "uza")
	fem = mw.ustring.gsub(fem, "uso$", "usa")
	fem = mw.ustring.gsub(fem, "([bcdfglmnprstvyzłx])à$", "%1ada")
    if fem == mot then
		local no_fem = false
		if string.find(mot, "a$") then
			no_fem = true
		elseif string.find(mot, "ble$") then
			no_fem = true
		elseif string.find(mot, "biłe$") then
			no_fem = true
		elseif string.find(mot, "re$") then
			no_fem = true
			if mot == "re" or mot == "vicere"or mot == "viceré"or mot == "ré" then
				fem = mot .. "zina"
			end
		elseif string.find(mot, "[cinsv][ai]łe$") and mot ~= "uficiałe"  then
			no_fem = true
		elseif string.find(mot, "del$") then
			no_fem = true
		elseif string.find(mot, "mim$") then
			no_fem = true
		elseif string.find(mot, "ar$") then
			no_fem = true
		elseif string.find(mot, "es$") then
			no_fem = true
		elseif string.find(mot, "%a[cepts]ante$") and mot ~= "bastansa"  then
			no_fem = true
		elseif string.find(mot, "[jz]ente$") and mot ~= "serzente" then
			no_fem = true
		end
		if no_fem == false then
			fem = mot .. "a"
		end
    end
    return fem
end

-- Forma femenina d'una locució
function p.fem(lema)
	if type(lema) == "table" then lema = lema.args[1] end -- des de plantilles via invoke o des de mòduls via require
	local exc_fem = mw.loadData("Module:Vec-flesion/femenín")
	if lema:find("[^ ]+ [^ ]+") then
		local exc = exc_fem[lema]
		if exc then return exc end
		local preposicions = {" a ", " al ", " con ", " contro ", " do ", " d'", " del ", " dintro ",
				" in ", " indrio ", " drio", " intrà ",
				" fora ", " par ", " col ", " coi ", " che ", " un ", " do ", " soto ", " soto "}
		for i, prep in ipairs(preposicions) do
			offset = mw.ustring.find(lema, prep, 1, true)
			if offset then
				local part1 = mw.ustring.sub(lema, 1, offset-1)
				local part2 = mw.ustring.sub(lema, offset)
				return p.fem(part1) .. part2 -- expressament recursiu per a locucions complexes
			end
		end
		local femenins = {}
		for part in mw.text.gsplit(lema, " ", true) do
			if string.find(part, "ałe$") and #femenins > 0 then -- adjectius en -al invariables
				table.insert(femenins, part)
			else
				table.insert(femenins, forma_fem(part, exc_fem))
			end
		end
		return table.concat(femenins, " ")
	else
		return forma_fem(lema, exc_fem)
	end
end

-- Plural d'un mot
local function forma_plural(mot, exc_plural)
	local exc = exc_plural[mot]
	if exc then return exc end
	
	local plural = mot
	-- a -> es, amb canvis morfològics
	if string.find(mot, "a$") then
		plural = string.gsub(plural, "ca$", "ghe")
		plural = string.gsub(plural, "ga$", "ghe")
		plural = mw.ustring.gsub(plural, "sa$", "se")
		plural = string.gsub(plural, "ja$", "je")
		plural = mw.ustring.gsub(plural, "([gc])ua$", "%1ue")
		plural = mw.ustring.gsub(plural, "[àa]na$", "ane")
		plural = mw.ustring.gsub(plural, "[èeé]na?$", "ene")
		plural = mw.ustring.gsub(plural, "ina?$", "ine")
		plural = mw.ustring.gsub(plural, "[òóo]na?$", "one")
		plural = mw.ustring.gsub(plural, "una$", "une")
		if plural == mot then plural = string.gsub(mot, "a$", "e") end
	elseif mw.ustring.find(mot, "[àéèíóòúaeiou]n?$") then
		plural = mw.ustring.gsub(plural, "[àa]n$", "ani")
		plural = mw.ustring.gsub(plural, "[èeé]n?$", "eni")
		plural = mw.ustring.gsub(plural, "in?$", "ini")
		plural = mw.ustring.gsub(plural, "[òóo]n?$", "oni")
		plural = mw.ustring.gsub(plural, "un$", "uni")
		if plural == mot then plural = mot .. "i" end
	else
		plural = mw.ustring.gsub(plural, "([çxzw])$", "%1i")
		if plural == mot then
			plural = mot .. "i"
		end
	end
	return plural
end

-- Forma plural d'una locució
function p.plural(lema)
	if type(lema) == "table" then lema = lema.args[1] end -- des de plantilles via invoke o des de mòduls via require
	local exc_plural = mw.loadData("Module:Vec-flesion/plurałe")
	if lema:find("[^ ]+ [^ ]+") then
		local exc = exc_plural[lema]
		if exc then return exc end
		local preposicions =  {" a ", " al ", " con ", " contro ", " do ", " d'", " del ", " dintro ",
				" in ", " indrio ", " drio", " intrà ",
				" fora ", " par ", " col ", " coi ", " che ", " un ", " do ", " soto ", " soto "}
		for i, prep in ipairs(preposicions) do
			local offset = mw.ustring.find(lema, prep, 1, true)
			if offset then
				local part1 = mw.ustring.sub(lema, 1, offset - 1)
				local part2 = mw.ustring.sub(lema, offset)
				return p.plural(part1) .. part2
			end
		end
		local plurals = {}
		for part in mw.text.gsplit(lema, " ", true) do
			table.insert(plurals, forma_plural(part, exc_plural))
		end
		return table.concat(plurals, " ")
	else
		return forma_plural(lema, exc_plural)
	end
end

-- Funció auxiliar per l’apostrofació de l’article masculí, retorna true o false
-- Limitacions: vegeu plantilla:deod'
local function sapostrofa(text)
	local apostrofa = {
		["her "]=false, ["his "]=false, -- paraules amb angles que provoquen falsos apostrofs 
		["hakk"]=false, -- h consonant (hakka)
    	["hawa"]=false, -- h consonant (hawaià)
    	["hia"]=false, ["hie"]=false, ["hio"]=false, ["hui"]=false, -- vocal consonant
    	["uix"]=true, -- excepció per u vocal
    	["ha"]=true, ["he"]=true, ["hi"]=true, ["hí"]=true, ["ho"]=true, ["hu"]=true, ["hy"]=true, -- excepte anteriors
    	["ia"]=false, ["ià"]=false, ["ie"]=false, ["io"]=false, ["iu"]=false, -- i consonant
    	["ua"]=false, ["ue"]=false, ["ui"]=false, ["uí"]=false, ["uï"]=false, ["uo"]=false, -- u consonant
    	["ya"]=false, ["ye"]=false, ["yi"]=false, ["yo"]=false, ["yu"]=false, -- y consonant
    	["a"]=true, ["à"]=true, ["e"]=true, ["è"]=true, ["é"]=true,
    	["i"]=true, ["í"]=true, ["ï"]=true, ["y"]=true,
    	["o"]=true, ["ò"]=true, ["ó"]=true, ["u"]=true, ["ú"]=true, ["ü"]=true, -- excepte anteriors
    	["1 "]=true, ["11 "]=true -- dates amb "1 de" o "11 de "
    	}

    local elText = mw.ustring.lower(require('module:Delink')._delink({text}))
    for i = 4, 1, -1 do
        local lletres = mw.ustring.sub(elText, 1, i)
        local apo = apostrofa[lletres]
        if apo ~= nil then
            return apo
        end
    end
    return false
end

function p.apostrofar(frame)
	args = frame:getParent().args
	local text = args[2] or ""
	local ret = (args[1] or "") .. " " .. text
	if sapostrofa(text) then
		local article = mw.language.getContentLanguage():lcfirst(args[1])
		if article == "el" then
			ret = "l'" .. text
		elseif article == "al" then
			ret = "a l'" .. text
		elseif article == "del" then
			ret = "de l'" .. text
		elseif article == "pal" then
			ret = "par l'" .. text
		elseif article == "col" then
			ret = "co l'" .. text
		elseif article == "un" then
			ret = "un'" .. text
		elseif article == "dal" then
			ret = "da l'" .. text
		end
		if article ~= args[1] then
			ret = mw.language.getContentLanguage():ucfirst(ret)
		end
	end
	return ret
end

function p.ordinal(number, feminine)
	local suffix = {["1"] = 'o', ["2"] = 'o', ["3"] = 'o'}
	if feminine then
		return number .. 'a'
	elseif suffix[number] then
		return number .. suffix[number]
	else
		return number .. 'o'
	end
end

return p
Traesto fora da Wikipèdia - L'ençiclopedia łìbara e cołaboradiva in łéngua Vèneta "https://vec.wikipedia.org/w/index.php?title=Modulo:Vec-flesion&oldid=1094022"