Module:ro-adjective

local export = {} local data = {} data.forms = {}

local form_names = { "na_indef_sg_m", "na_indef_sg_f", "na_indef_pl_m", "na_indef_pl_f", "na_def_sg_m", "na_def_sg_f", "na_def_pl_m", "na_def_pl_f", "gd_indef_sg_m", "gd_indef_sg_f", "gd_indef_pl_m", "gd_indef_pl_f", "gd_def_sg_m", "gd_def_sg_f", "gd_def_pl_m", "gd_def_pl_f", }

local consonants = { i = { str = 'ștr'; st = 'șt'; sc = 'șt'; d = 'z'; s = 'ș'; t = 'ț'; x = 'cș'; },	e = { sc = 'șt'; } }

-- these adjectives have different defaults local endings = { {pattern = "(([stz])or)$", fs = "%2oare", mp = "%2ori", fp = "%2oare"}, {pattern = "os$", fs = "oasă", mp = "oși", fp = "oase"}, {pattern = "iesc$", fs = "iască", mp = "iești", fp = "iești"}, {pattern = "esc$", fs = "ească", mp = "ești", fp = "ești"}, {pattern = "(([iy])an)$", fs = "%2ană", mp = "%2eni", fp = "%2ene"}, {pattern = "ean$", fs = "eană", mp = "eni", fp = "ene"}, {pattern = "eț$", fs = "eață", mp = "eți", fp = "ețe"}, {pattern = "iu$", fs = "ie", mp = "ii", fp = "ii"}, }

local m_links = require("Module:links") local lang = require("Module:languages").getByCode("ro")

local PAGENAME = mw.title.getCurrentTitle.text

local function make_definite(word, gender) local definite if gender == "m" or gender == "n" then if word:find("u$") then definite = word .. "l" elseif word:find("e$") then definite = word .. "le" else definite = word .. "ul" end elseif gender == "f" then if word:find("ă$") then definite = word:gsub("ă$", "a") elseif mw.ustring.find(word, "[aeiouăâî]ie") then definite = word:gsub("e$", "a") elseif mw.ustring.find(word, "ie$") then definite = word:gsub("e$", "a") elseif mw.ustring.find(word, "e$") then definite = word .. "a" elseif mw.ustring.find(word, "a$") then definite = word .. "ua" end else error("Invalid or missing gender") end

return definite end

local function make_feminine(word) local f	if word:find("e$") then f = word elseif word:find("[aăâiîeou]i$") then f = word .. "e" elseif word:find("iu$") then f = mw.ustring.gsub(word, "u$", "e") elseif word:find("u$") then f = word:sub(1, -2) .. "ă" elseif word:match("[cg]h?i$") then f = word:sub(1, -2) .. "e" elseif word:match("[^aioăâî]$") then f = word .. "ă" else error("Feminine of \"" .. word .. "\" could not be generated automatically") end if f and f:match("[âei]ă$") then f = f:gsub("ă$", "e") end return f end

local function split(word) local stem, cons if word:match('[aeiouăâî][iu]$') then stem, cons = word:match('^(.-[aeiouăâî]-)([iu])$') else stem, cons = word:match('^(.-[aeiouăâî]-)([bcdfghj-np-tv-zșț]-)$') end return stem, cons end

local function find_cons(cons, mode) for i = -3, -1 do		if consonants[mode][mw.ustring.sub(cons, i)] and not mw.ustring.match(mw.ustring.sub(cons, 1, i-1), "^[șj]$") then cons = mw.ustring.sub(cons, 1, i-1) .. consonants[mode][mw.ustring.sub(cons, i)] break end end

return cons end

local function make_plural(word, g)	local pl	local suf1, suf2, pre1 = mw.ustring.sub(word, -1), mw.ustring.sub(word, -2), mw.ustring.sub(word, 1, -2) if g == 'm' then if suf1 == 'i' then pl = word else local stem, cons = split(word:match('^(.-)[eu]?$')) cons = find_cons(cons, 'i') pl = stem .. cons .. 'i'		end elseif g == 'f' then if suf1 == 'a' then if suf2 == 'ea' then pl = pre1 .. 'le' elseif suf2 == 'ia' then pl = pre1 .. 'ele' else pl = word .. 'le' end else if suf1 == 'e' then pl = word elseif suf1 == 'ă' then local stem, cons = split(word:match('^(.-)ă$')) cons = find_cons(cons, 'e') pl = stem .. cons .. 'e'			end end end

return pl end

local function remove_duplicates(array) local existing = {} for i, val in ipairs(array) do		if existing[val] then table.remove(array, i)			if array.maxindex then array.maxindex = array.maxindex - 1 end else existing[val] = true end end end

local function make_indef_sg_m(lemma, only) --Try to recreate the masculine singular indefinite form if it's	--not the lemma. Many of these situations will never happen. local ret = lemma

if only.def then if only.pl then if only.f then --def-pl-f ret = lemma:match("(.+)ele$") else --def-pl-m ret = lemma:match("(.+)ii$") end else if only.f then --def-sg-f ret = lemma:match("(.+)a$") else --def-sg-m ret = lemma:match("(.+)ul$") end end else if only.pl then if only.f then --indef-pl-f ret = lemma:match("(.+)e$") else --indef-pl-m ret = lemma:match("(.+)i") end else if only.f then --indef-sg-f ret = lemma:match("(.+)ă") end end end

if not ret then error("Could not recreate the masculine indefinite singular form.") end

return ret end

--also used in Module:ro-headword function export.make_basic_forms(ms, fs, mp, fp, i_mode, only) local base = make_indef_sg_m(ms[1], only) local ending = false local param_track = {redundant = false, needed = false} for i, val in ipairs(endings) do		if base:match(val.pattern) then local match = base:match(val.pattern) require("Module:debug").track("ro-adjective/" .. match) if fs[1] or mp[1] or fp[1] or i_mode then require("Module:debug").track("ro-adjective/" .. match .. "/custom") require("Module:debug").track("ro-adjective/custom") else require("Module:debug").track("ro-adjective/" .. match .. "/default") require("Module:debug").track("ro-adjective/default") end ending = i			break end end if not fs[1] then if ending then local form = mw.ustring.gsub(base, endings[ending].pattern, endings[ending].fs) table.insert(fs, 1, form) else table.insert(fs, 1, make_feminine(base)) end if only.def then fs[1] = make_definite(fs[1], "f") end if fs.maxindex == 0 then fs.maxindex = 1 end remove_duplicates(fs) else if (ending and mw.ustring.gsub(base, endings[ending].pattern, endings[ending].fs)		or make_feminine(base)) == fs[1] then param_track.redundant = true else param_track.needed = true end end if not mp[1] then if ending then local form = mw.ustring.gsub(base, endings[ending].pattern, endings[ending].mp) table.insert(mp, 1, form) else table.insert(mp, 1, make_plural(base, "m")) end if only.def then mp[1] = mp[1] .. "i" end if mp.maxindex == 0 then mp.maxindex = 1 end remove_duplicates(mp) else if (ending and mw.ustring.gsub(base, endings[ending].pattern, endings[ending].mp)		or make_plural(base, "m")) == mp[1] then param_track.redundant = true else param_track.needed = true end end if i_mode then --mw.clone does not work for i = 1, mp.maxindex do			fp[i] = mp[i] end fp.maxindex = mp.maxindex else if only.def then if not fp[1] then table.insert(fp, 1, make_plural(make_feminine(base), "f") .. "le") if fp.maxindex == 0 then fp.maxindex = 1 end end else --for each feminine singular form, generate a feminine plural form if			--one has not already been provided local newindex = 0 for i, form in ipairs(fs) do				if fp[i] == "-" then fp[i] = nil else newindex = i					if not fp[i] then if ending and i == 1 then local form = mw.ustring.gsub(base, endings[ending].pattern, endings[ending].fp) table.insert(fp, 1, form) else table.insert(fp, i, make_plural(form, "f")) end if only.def then fp[i] = fp[i] .. "le" end newindex = i					else if ((ending and i == 1) and mw.ustring.gsub(base, endings[ending].pattern, endings[ending].fp)						or make_plural(form, "f")) == fp[i] then param_track.redundant = true else param_track.needed = true end end end end fp.maxindex = newindex if fp.maxindex == 0 then error("There must be at least one feminine plural form") end end remove_duplicates(fp) end if param_track.redundant then require("Module:debug").track("ro-adjective/parameters/redundant") end if param_track.needed then require("Module:debug").track("ro-adjective/parameters/needed") end if not param_track.redundant and not param_track.needed then require("Module:debug").track("ro-adjective/parameters/none") end end

--Process forms that were given explicitly local function process_explicit_forms(data, extra_args) for arg, val in pairs(extra_args) do		local arg_parts, count, valid = {}, 0, false for i, part in ipairs(mw.text.split(arg, "_")) do			arg_parts[part] = true count = count + 1 end for i, form in ipairs(form_names) do			local counter = 0 for j, part in ipairs(mw.text.split(form, "_")) do				if arg_parts[part] then counter = counter + 1 end end if count == counter then if val == "-" then data.forms[form] = nil else data.forms[form] = {val} end valid = true end end if not valid then error("The parameter \"" .. arg .. "\" is not used by this template.") end end end

local function make_table(data) data.info = table.concat(data.info, ", ") if data.info == "" then data.info = nil end local function show_form(form) if not form then return "&mdash;" elseif type(form) ~= "table" then error("a non-table value was given in the list of inflected forms.") elseif #form == 0 then return "&mdash;" end local ret = {} for key, subform in ipairs(form) do			table.insert(ret, m_links.full_link({lang = lang, term = subform})) end return table.concat(ret, " ") end local function repl(param) if param == "lemma" then return m_links.full_link({lang = lang, alt = data.lemma}, "term") elseif param == "info" then return data.info and " (" .. data.info .. ")" or "" else return show_form(data.forms[param]) end end local result = [=[ Declension of

return (mw.ustring.gsub(result, "", repl)) end

function export.show(frame) local args = frame:getParent.args if args[12] then require("Module:debug").track("ro-decl-adj/old") local params = { [1] = {list = true, allow_holes = true}, }		args = require("Module:parameters").process(args, params) data.info = {} local form_order = { "na_indef_sg_m", "na_indef_sg_f", "na_indef_pl_m", "na_indef_pl_f", "na_def_sg_m", "na_def_sg_f", "na_def_pl_m", "na_def_pl_f", "gd_def_sg_m", "gd_def_sg_f", "gd_def_pl_m", "gd_def_pl_f", }		for key, form in ipairs(form_order) do			data.forms[form] = {args[1][key]} end data.forms.gd_indef_sg_m = mw.clone(data.forms.na_indef_sg_m) data.forms.gd_indef_sg_f = mw.clone(data.forms.na_indef_pl_f) data.forms.gd_indef_pl_m = mw.clone(data.forms.na_indef_pl_m) data.forms.gd_indef_pl_f = mw.clone(data.forms.na_indef_pl_f) data.lemma = PAGENAME else require("Module:debug").track("ro-decl-adj/new") local params = { [1] = {},			["f"] = {list = true, allow_holes = true}, ["mp"] = {list = true, allow_holes = true}, ["fp"] = {list = true, allow_holes = true}, ["pl"] = {list = true, allow_holes = true}, ["lemma"] = {}, ["only"] = {}, }		local extra_args args, extra_args = require("Module:parameters").process(args, params, true) data.lemma = args["lemma"] or PAGENAME data.info = {} data.only = {} if args.only then for i, val in ipairs(mw.text.split(args.only, "-")) do				data.only[val] = true end end local f = data.forms for i, form in ipairs(form_names) do			f[form] = {} end f.na_indef_sg_m = {make_indef_sg_m(data.lemma, data.only)} local modes = {} if args[1] then for key, val in ipairs(mw.text.split(args[1], "-")) do				modes[val] = true end end if modes.det then data.only.indef = true end local only_modes = { ["indef"] = "indefinite", ["def"] = "definite", ["sg"] = "singular", ["pl"] = "plural", ["m"] = "masculine", ["f"] = "feminine", }		if modes.inv then table.insert(data.info, "invariable") for key, form in ipairs(form_names) do				if form:find("indef") then f[form] = {data.lemma} end end else f.na_indef_sg_f, f.na_indef_pl_m, f.na_indef_pl_f = args["f"], args["pl"].maxindex > 0 and args["pl"] or args["mp"], args["pl"].maxindex > 0 and args["pl"] or args["fp"] export.make_basic_forms(f.na_indef_sg_m, f.na_indef_sg_f, f.na_indef_pl_m, f.na_indef_pl_f, modes.i, {}) if modes.det then table.insert(data.info, "determiner declension") f.gd_indef_sg_m = {f.na_indef_sg_m[1]:match("^(.*)[eu]?$") .. "ui"} f.gd_indef_sg_f = {f.na_indef_sg_m[1]:match("^(.*)[eu]?$") .. "ei"} f.gd_indef_pl_m = {f.na_indef_sg_m[1]:match("^(.*)[eu]?$") .. "or"} f.gd_indef_pl_f = mw.clone(f.gd_indef_pl_m) else --forms derived from the masculine singular f.na_def_sg_m = {make_definite(f.na_indef_sg_m[1], "m")} f.gd_def_sg_m = {f.na_def_sg_m[1]:find("e$") and f.na_def_sg_m[1]:sub(1, -2) .. "ui" or f.na_def_sg_m[1] .. "ui"} f.gd_indef_sg_m = {f.na_indef_sg_m[1]} --forms derived from the feminine singular for i = 1, f.na_indef_sg_f.maxindex do					if f.na_indef_sg_f[i] ~= nil then table.insert(f.na_def_sg_f, make_definite(f.na_indef_sg_f[i], "f")) end end --forms derived from the masculine plural for i = 1, f.na_indef_pl_m.maxindex do 					if f.na_indef_pl_m[i] ~= nil then table.insert(f.na_def_pl_m, f.na_indef_pl_m[i] .. "i") table.insert(f.gd_indef_pl_m, f.na_indef_pl_m[i]) table.insert(f.gd_def_pl_m, f.na_indef_pl_m[i] .. "lor") end end --forms derived from the feminine plural for i = 1, f.na_indef_pl_f.maxindex do 					if f.na_indef_pl_f[i] ~= nil then table.insert(f.na_def_pl_f, f.na_indef_pl_f[i] .. "le") table.insert(f.gd_indef_sg_f, f.na_indef_pl_f[i]) table.insert(f.gd_indef_pl_f,f.na_indef_pl_f[i]) table.insert(f.gd_def_pl_f, f.na_indef_pl_f[i] .. "lor") if f.na_indef_pl_f[i]:find("[^aăâeiîou]ii$") then --this could cause issues if the feminine singular and --feminine plural are not in sync table.insert(f.gd_def_sg_f, f.na_indef_sg_f[i] .. "i") else table.insert(f.gd_def_sg_f, f.na_indef_pl_f[i] .. "i") end end end end process_explicit_forms(data, extra_args) end for key, name in pairs(only_modes) do			if data.only[key] then table.insert(data.info, name .. " only") for i, form in ipairs(form_names) do if not ("_" .. form .. "_"):find("_" .. key .. "_") then f[form] = nil end end end end end return make_table(data) end

return export