Module:User:Redboywild

This is a private module sandbox of Redboywild, for their own experimentation. Items in this module may be added and removed at Redboywild's discretion; do not rely on this module's stability.


local export={}
local pos_functions = {}
local lang = require("Module:languages").getByCode("ro")

PAGENAME = mw.title.getCurrentTitle().text

function export.show(frame)
	local args = frame:getParent().args
	NAMESPACE = mw.title.getCurrentTitle().nsText
	PAGENAME = mw.title.getCurrentTitle().text
	
	local poscat = frame.args[1] or error("Part of speech has not been specified. Please pass parameter 1 to the module invocation.")
	
	local params = {
		["head"] = {},
		["suff"] = {type = "boolean"},
	}
	
	if pos_functions[poscat] then
		for key, val in pairs(pos_functions[poscat].params) do
			params[key] = val
		end
	end
	
	args = require("Module:parameters").process(args, params)
	
	local genders = {}
	local inflections = {}
	local categories = args["suff"] and {"Romanian suffixes"} or {"Romanian " .. poscat}
	local sort_key = {}
	local appendix = {}
	
	if pos_functions[poscat] then
		local head2 = pos_functions[poscat].func(class, args, genders, inflections, categories, poscat, appendix)
		head = head or head2
	end
	
	if #appendix == 0 then
		appendix[1] = ""
	end
	
	return
		require("Module:headword").full_headword(lang, sc, head, nil, genders, inflections, categories, nil) .. appendix[1]
end

local function remove_duplicates(array)
	local hm = {}
	for key, val in ipairs(array) do
		if hm[val] then
			table.remove(array, key)
		else
			hm[val] = true
		end
	end
end

local function compare(a1, a2)
	if #a1 == #a2 then
		local hm = {}
		for key, val in ipairs(a1) do
			hm[val] = true
		end
		for key, val in ipairs(a2) do
			if not hm[val] then
				return false
			end
		end
		return true
	else
		return false
	end
end

vow_changes = {
	["a"] = {"ă", "e"},
	["ă"] = {"e"},
	["e"] = {"a", "ea"}, -- "a" is a special case
	["ea"] = {"e"},
	["o"] = {"oa"},
	["oa"] = {"o"},
}

vow_change_forms = {
	["a_ă"] = {}, -- this might not actually be a thing, hmm
	["a_e"] = {},
	["ă_e"] = {mp = true, fp = true},
	["e_a"] = {f = true},
	["e_a2"] = {f = true, fp = true}, --deșert
	["e_ea"] = {f = true},
	["ea_e"] = {mp = true, fp = true},
	["o_oa"] = {f = true, fp = true},
	["oa_o"] = {mp = true},
}

cons_changes = {
	["sc"] = {"șt"},
	["șc"] = {"șt"},
}

local function split_vow(vow)
	local pre, post = "", ""
	if vow:match("^[iu][aeo]") then
		pre = mw.ustring.sub(vow, 1, 1)
		vow = mw.ustring.sub(vow, 2)
	end
	if vow:match("[aeo][iu]$") then
		post = mw.ustring.sub(vow, -1)
		vow = mw.ustring.sub(vow, 1, -2)
	end
	return pre, vow, post
end

local function find_vow_change(word1, word2)
	if word1 == word2 then
		return {} --???
	else
		local stem, pre, vow, post, cons, res
		stem, vow, cons = split(word1)
		pre, vow, post = split_vow(vow)
		if vow_changes[vow] then
			for key, val in pairs(vow_changes[vow]) do
				res = stem .. pre .. val .. post .. cons
				res = mw.ustring.gsub(res, "iea", "ia")
				res = mw.ustring.gsub(res, "iă", "ie")
				--res = mw.ustring.gsub(res, "([șj])ea", "%1a")
				if word2 == res then
					if val == "a" and pre == "" and stem:find("[șj]$") then
						val = "a2"
					end
					return vow_change_forms[vow .. "_" .. val] or error("Unrecognized vowel change")
				end
			end
			local stem2 = split(word2)
			return find_vow_change(stem, stem2) or "nope"
		end
	end
end

pos_functions["adjectives3"] = {
	params = {
		[1] = {},
		["f"] = {list = true},
		["mp"] = {list = true},
		["fp"] = {list = true},
		["pl"] = {list = true},
	},
	func = function(class, args, genders, inflections, categories, poscat, appendix)
		PAGENAME = args["head"] or PAGENAME
		
		local types = {
			i = true,
			inv = true,
		}
		
		local type = args[1]
		
		local f, mp, fp = args["f"], args["mp"], args["fp"]
		
		if type == "inv" then
			table.insert(inflections, {label = "invariable"})
			table.insert(categories, "Romanian invariable adjectives")
		else
			table.insert(genders, "m")
			table.insert(genders, "n")
			if #f == 0 then
				table.insert(f, make_feminine2(PAGENAME))
			end
			if #mp == 0 then
				table.insert(mp, export.make_plural_lite(PAGENAME, "m"))
			end
			if #fp == 0 then
				if type == "i" then
					fp = mp
				else
					table.insert(fp, export.make_plural_lite(make_feminine_weird(PAGENAME), "f", "-e"))
				end
			end
			if #f == 1 and f[1] == PAGENAME then
				table.insert(genders, "f")
			else
				f.label = "feminine singular"
				table.insert(inflections, f)
			end
			if compare(mp, fp) then
				mp.label = "masculine, feminine and neuter plural"
				table.insert(inflections, mp)
			else
				mp.label = "masculine plural"
				table.insert(inflections, mp)
				fp.label = "feminine and neuter plural"
				table.insert(inflections, fp)
			end
		end
		return args["head"]
	end
}		

local function remove_ending(word)
	if word:match("[eu]$") then
		return word:match("(.+)[eu]$")
	end
	return word
end
		

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

local function make_feminine2(word)
	local f = nil
	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 form could not be generated automatically")
	end
	
	if f:match("[âei]ă$") then
		f:gsub("ă$", "e")
	end
	f:gsub("iea", "ia")
	return f
end

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

local function find_cons(cons)
	for i = -3, -1 do
		if consonants[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[mw.ustring.sub(cons, i)]
			break
		end
	end
	return cons
end

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

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

local function make_plural_liter(word, g, ending)
	local pl
	local suf1, suf2, pre1, pre2 = mw.ustring.sub(word, -1), mw.ustring.sub(word, -2), mw.ustring.sub(word, 1, -2), mw.ustring.sub(word, 1, -3)
	if g == 'm' then
		if suf1 == 'i' then
			pl = word
		else
			local stem, vow, cons = split(word:match('^(.-)[eu]?$'))
			pl = stem .. vow .. cons .. 'i'
		end
	elseif g == 'f' then
		if suf1 == 'a' then
			if suf2 == 'ea' then
				pl = mw.ustring.sub(word, 1, -2) .. 'le'
			elseif suf2 == 'ia' then
				pl = mw.ustring.sub(word, 1, -2) .. 'ele'
			else
				pl = word .. 'le'
			end
		elseif suf2 == 'ie' then
			if ending == 'e' then
				pl = word
			else
				local stem, vow, cons = split(pre2)
				if cons ~= '' then
					if ending == 'i' then
						pl = stem .. vow .. cons .. 'ii'
					end
				else
					if ending == 'i' then
						pl = stem .. vow .. 'i'
					end
				end
			end
		elseif suf1 == 'e' or suf1 == 'ă' then
			if ending == 'e' or ending == 'i' then
				pl = pre1 .. ending
			end
		end
	end
	return pl
end

function export.ro_num(frame)
	local args = frame.args
	local head = args.head
	local type = "card"
	if head:find("lea$") or head:find("ul$") then
		type = "ord"
	end
	
	local genders = {}
	local inflections = {}
	local categories = {}
	local sort_key = {}
	local conj = {}
	
	if pos_functions[type] then
		local head2 = pos_functions[type](class, args, genders, inflections, categories)
		head = head2
	end
	
	return
		require("Module:headword").full_headword(lang, sc, head, nil, genders,
			inflections, NAMESPACE == "" and categories or {"Romanian numerals"}, nil)
end

pos_functions["ord"] = function(class, args, genders, inflections, categories)
	local head = args.head or PAGENAME
	function link(head, al)
		if head:find(" ") then
			head = mw.text.split(head, " ")
			head = "[[" .. table.concat(head, "]] [[") .. "]]"
		end
		return (al and "al " or "") .. head
	end
	table.insert(genders, "m")
	table.insert(genders, "n")
	local f, al, card
	if head:find("lea") then
		if head:match("doilea$") then
			card = head:match("(.-)doilea$")
			f = card .. "doua"
			card = card .. "doi"
		else
			card =  head:match("(.-)u?lea")
			f = card .. "a"
		end
		f = {term = f, alt = "a " .. f}
		al = true
	elseif head:match("ul$") then
		f = head:match("(.-)ul$") .. "a"
		card = "unu"
		al = false
	end
	table.insert(inflections, {label = "ordinal form of", card})
	table.insert(inflections, {label = "feminine", f})
	table.insert(categories, "Romanian numerals")
	table.insert(categories, "Romanian ordinal numbers")
	return link(head, al)
end

return export