Module:yrk-decl

From Wiktionary, the free dictionary
Jump to navigation Jump to search

local export = {}

local V = "[аăяэеоёыиӣуӯю]"
local C = "[бвгджзйклмнпрстфхцчшщӈь]"
local P = "[ьй]"
local D = "[̇̆̄]"

local function shorten(word)
	local stem = word
	if mw.ustring.sub(stem, -1, -1) == "ӑ" then
		stem = mw.ustring.sub(stem, 1, -2)
	elseif mw.ustring.sub(stem, -2, -1) == "я̆" then
		stem = mw.ustring.sub(stem, 1, -3) .. "ь"
	end
	stem = mw.ustring.gsub(stem, "(" .. D .. ")ь", "%1й")
	stem = mw.ustring.gsub(stem, "(" .. V .. ")ь", "%1й")
	return stem
end

local function lengthen(word)
	local stem = word
	if mw.ustring.sub(stem, -1, -1) == "ӑ" then
		stem = shorten(word)
	elseif mw.ustring.sub(stem, -2, -1) == "я̆" then
		stem = shorten(word)
	else
		if mw.ustring.sub(stem, -1, -1) == "э" or mw.ustring.sub(stem, -1, -1) == "е" then
			stem = mw.ustring.sub(stem, 1, -1) .. "ˮэ"
		elseif mw.ustring.sub(stem, -2, -1) == "э̇" then
			stem = mw.ustring.sub(stem, 1, -1) .. "ˮэ̇"
		elseif mw.ustring.sub(stem, -1, -1) == "и" or mw.ustring.sub(stem, -1, -1) == "ӣ" then
			stem = mw.ustring.sub(stem, 1, -1) .. "ˮи"
		elseif mw.ustring.sub(stem, -1, -1) == "ы" or mw.ustring.sub(stem, -2, -1) == "ы̄" then
			stem = mw.ustring.sub(stem, 1, -1) .. "ˮы"
		elseif mw.ustring.sub(stem, -1, -1) == "о" or mw.ustring.sub(stem, -1, -1) == "ё" then
			stem = mw.ustring.sub(stem, 1, -1) .. "ˮо"
		elseif mw.ustring.sub(stem, -1, -1) == "у" or mw.ustring.sub(stem, -1, -1) == "ю" then
			stem = mw.ustring.sub(stem, 1, -1) .. "ˮу"
		elseif mw.ustring.sub(stem, -1, -1) == "ӯ" or mw.ustring.sub(stem, -2, -1) == "ю̄" then
			stem = mw.ustring.sub(stem, 1, -1) .. "ˮу"
		else
			stem = stem .. "ˮӑ"
		end
	end
	return stem
end
	

local function metathesis(word)
	local stem = word
	if mw.ustring.sub(stem, -2, -2) == "ӑ" and mw.ustring.match(stem, C .. "$")  then
		stem = mw.ustring.sub(stem, 1, -3) .. mw.ustring.sub(stem, -1, -1)
	end
	return stem
end

local function app_x(word)
	local stem = word
	if mw.ustring.sub(word, -3, -2) == "ӑ" and mw.ustring.match(word, C .. "$") then
		stem = metathesis(stem) .. "ӑ"
	end
	if mw.ustring.sub(stem, -1, -1) == "э" or mw.ustring.sub(stem, -1, -1) == "е" then
		stem = mw.ustring.sub(stem, 1, -1) .. "хэ"
		elseif mw.ustring.sub(stem, -2, -1) == "э̇" then
			stem = mw.ustring.sub(stem, 1, -1) .. "хэ̇"
	elseif mw.ustring.sub(stem, -1, -1) == "и" or mw.ustring.sub(stem, -1, -1) == "ӣ" then
		stem = mw.ustring.sub(stem, 1, -1) .. "хи"
	elseif mw.ustring.sub(stem, -1, -1) == "ы" or mw.ustring.sub(stem, -2, -1) == "ы̄" then
		stem = mw.ustring.sub(stem, 1, -1) .. "хы"
	elseif mw.ustring.sub(stem, -1, -1) == "о" or mw.ustring.sub(stem, -1, -1) == "ё" then
		stem = mw.ustring.sub(stem, 1, -1) .. "хо"
	elseif mw.ustring.sub(stem, -1, -1) == "у" or mw.ustring.sub(stem, -1, -1) == "ю" then
		stem = mw.ustring.sub(stem, 1, -1) .. "ху"
	elseif mw.ustring.sub(stem, -1, -1) == "ӯ" or mw.ustring.sub(stem, -2, -1) == "ю̄" then
		stem = mw.ustring.sub(stem, 1, -1) .. "ху"
	elseif mw.ustring.sub(stem, -1, -1) == "ʼ" then
		stem = mw.ustring.sub(stem, 1, -2) .. "гӑ"
	elseif mw.ustring.sub(stem, -1, -1) == "ˮ" then
		stem = mw.ustring.sub(stem, 1, -2) .. "кӑ"
	else
		stem = mw.ustring.sub(stem, 1, -1) .. "хӑ"
	end
	return stem
end

local function join(...)
	local t = {}
	for _, s in ipairs(arg) do
		if type(s) == "table" then
			for _, v in ipairs(s) do
				table.insert(t, v)
			end
		else
			table.insert(t, s)
		end
	end
	return t
end

local function append(t, x)
	if not x then return t end
	if type(t) == "string" then
		return t .. x
	end
	local r = {}
	for _, v in ipairs(t) do
		table.insert(r, v .. x)
	end
	return r
end

local function process(data, result)
	-- nominative
	if not data.no_singular then
		result["nom_sg"] = result.stem_nos
		result["gen_sg"] = result.stem_ges
		result["acc_sg"] = result.stem_acs
		result["all_sg"] = result.stem_als
		result["loc_sg"] = result.stem_los
		result["abl_sg"] = result.stem_abs
		result["pro_sg"] = result.stem_prs
	end
	
	if not data.no_dual then
		result["nom_dl"] = result.stem_nod
		result["gen_dl"] = result.stem_nod
		result["acc_dl"] = result.stem_nod
		result["all_dl"] = result.stem_ald
		result["loc_dl"] = result.stem_lod
		result["abl_dl"] = result.stem_abd
		result["pro_dl"] = result.stem_prd
	end
	
	if not data.no_plural then
		result["nom_pl"] = result.stem_nop
		result["gen_pl"] = result.stem_gep
		result["acc_pl"] = result.stem_acp
		result["all_pl"] = result.stem_alp
		result["loc_pl"] = result.stem_lop
		result["abl_pl"] = result.stem_abp
		result["pro_pl"] = result.stem_prp
	end

	return result
end

local inflections = {}

inflections["I"] = function(data)
	local result = {}
	local word = data.args[1] or error("must specify the nominative singular")
	
	-- vowel stems --
	if mw.ustring.match(word, V .. "$") or mw.ustring.match(word, D .. "$") then
		result.stem_nos = word
		result.stem_acs = word .. "м"
		result.stem_ges = word .. "ʼ"
		result.stem_als = word .. "н"
		result.stem_los = app_x(word) .. "на"
		result.stem_abs = app_x(word) .. "д"
		result.stem_prs = word .. "вна"
		
		result.stem_nod = app_x(word) .. "ʼ"
		result.stem_ald = app_x(word) .. "няʼ"
		result.stem_lod = app_x(word) .. "няна"
		result.stem_abd = app_x(word) .. "няд"
		result.stem_prd = app_x(word) .. "нямна"
		
		result.stem_nop = word .. "ˮ"
		result.stem_acp = data.args[2] or error("must specify the accusative plural")
		result.stem_gep = result.stem_acp .. "ˮ"
		result.stem_alp = app_x(word) .. "ˮ"
		result.stem_lop = app_x(word) .. "ˮна"
		result.stem_abp = app_x(word) .. "т"
		result.stem_prp = result.stem_acp .. "ˮмӑна"
		
	-- consonant stems --
	elseif mw.ustring.match(word, C .. "$") then
		result.stem_nos = word
		result.stem_acs = word .. "м"
		result.stem_ges = word .. "ʼ"
		if mw.ustring.match(word, P .. "$") then
			result.stem_als = metathesis(mw.ustring.sub(word, 1, -2)) .. "я̆н"
		else result.stem_als = metathesis(word) .. "ӑн" end
		result.stem_los = app_x(metathesis(word) .. "ă") .. "на"
		result.stem_abs = app_x(metathesis(word) .. "ă") .. "д"
		if mw.ustring.match(word, P .. "$") then
			result.stem_prs = metathesis(mw.ustring.sub(word, 1, -2)) .. "ювна"
		else result.stem_prs = metathesis(word) .. "увна" end
		
		result.stem_nod = app_x(metathesis(word) .. "ă") .. "ʼ"
		result.stem_ald = app_x(metathesis(word) .. "ă") .. "няʼ"
		result.stem_lod = app_x(metathesis(word) .. "ă") .. "няна"
		result.stem_abd = app_x(metathesis(word) .. "ă") .. "няд"
		result.stem_prd = app_x(metathesis(word) .. "ă") .. "нямна"
		
		result.stem_nop = word .. "ˮ"
		result.stem_acp = data.args[2] or error("must specify the accusative plural")
		result.stem_gep = result.stem_acp .. "ˮ"
		result.stem_alp = app_x(metathesis(word) .. "ă") .. "ˮ"
		result.stem_lop = app_x(metathesis(word) .. "ă") .. "ˮна"
		result.stem_abp = app_x(metathesis(word) .. "ă") .. "т"
		result.stem_prp = result.stem_acp .. "ˮмӑна"
		
	-- Vn-stems --
	elseif mw.ustring.match(word, V .. "ʼ$") or mw.ustring.match(word, D .. "ʼ$") then
		word = mw.ustring.sub(word, 1, -2)
		result.stem_nos = word .. "ʼ"
		result.stem_acs = { word .. "м", word .. "нм" }
		result.stem_ges = word .. "нʼ"
		result.stem_als = word .. "нд"
		result.stem_los = app_x(word .. "ӈʼ") .. "на"
		result.stem_abs = app_x(word .. "ӈʼ") .. "д"
		result.stem_prs = word .. "мна"
		
		result.stem_nod = word .. "ӈгʼ"
		result.stem_ald = app_x(word .. "ӈʼ") .. "няʼ"
		result.stem_lod = app_x(word .. "ӈʼ") .. "няна"
		result.stem_abd = app_x(word .. "ӈʼ") .. "няд"
		result.stem_prd = app_x(word .. "ӈʼ") .. "нямна"
		
		result.stem_nop = word .. "нˮ"
		result.stem_acp = data.args[2] or error("must specify the accusative plural")
		result.stem_gep = result.stem_acp .. "ˮ"
		result.stem_alp = word .. "ӈгˮ"
		result.stem_lop = app_x(word .. "ӈʼ") .. "ˮна"
		result.stem_abp = app_x(word .. "ӈʼ") .. "т"
		result.stem_prp = result.stem_acp .. "ˮмӑна"
		
	-- m-stems --
	elseif mw.ustring.sub(word, -2, -1) == "мʼ" then
		word = mw.ustring.sub(word, 1, -3)
		result.stem_nos = word .. "мʼ"
		result.stem_acs = word .. "вм"
		result.stem_ges = word .. "вʼ"
		result.stem_als = word .. "мд"
		result.stem_los = { app_x(word .. "мʼ") .. "на", app_x(word .. "мӈʼ") .. "на" }
		result.stem_abs = { app_x(word .. "мʼ") .. "д", app_x(word .. "мӈʼ") .. "д" }
		result.stem_prs = word .. "мна"
		
		result.stem_nod = { word .. "мгʼ", word .. "мӈгʼ"}
		result.stem_ald = { app_x(word .. "мʼ") .. "няʼ", app_x(word .. "мӈʼ") .. "няʼ" }
		result.stem_lod = { app_x(word .. "мʼ") .. "няна", app_x(word .. "мӈʼ") .. "няна" }
		result.stem_abd = { app_x(word .. "мʼ") .. "няд", app_x(word .. "мӈʼ") .. "няд" }
		result.stem_prd = { app_x(word .. "мʼ") .. "нямна", app_x(word .. "мӈʼ") .. "нямна" }
		
		result.stem_nop = word .. "вˮ"
		result.stem_acp = data.args[2] or error("must specify the accusative plural")
		result.stem_gep = result.stem_acp .. "ˮ"
		result.stem_alp = { word .. "мгˮ", word .. "мӈгˮ"}
		result.stem_lop = { app_x(word .. "мʼ") .. "ˮна", app_x(word .. "мӈʼ") .. "ˮна" }
		result.stem_abp = { app_x(word .. "мʼ") .. "т", app_x(word .. "мӈʼ") .. "т" }
		result.stem_prp = result.stem_acp .. "ˮмӑна"
		
	-- Cn-stems --
	elseif mw.ustring.sub(word, -1, -1) == "ʼ" then
		word = mw.ustring.sub(word, 1, -2)
		result.stem_nos = word .. "ʼ"
		if mw.ustring.match(word, P .. "$") then
			result.stem_acs = metathesis(mw.ustring.sub(word, 1, -2)) .. "я̆м"
		else result.stem_acs = metathesis(word) .. "ӑм" end
		result.stem_ges = word .. "ʼ"
		if mw.ustring.match(word, P .. "$") then
			result.stem_als = metathesis(mw.ustring.sub(word, 1, -2)) .. "я̆нд"
		else result.stem_als = metathesis(word) .. "ӑнд" end
		if mw.ustring.match(word, P .. "$") then
			result.stem_los = app_x(metathesis(mw.ustring.sub(word, 1, -2)) .. "яӈʼ") .. "на"
		else result.stem_los = app_x(metathesis(word) .. "ӑӈʼ") .. "на" end
		if mw.ustring.match(word, P .. "$") then
			result.stem_abs = app_x(metathesis(mw.ustring.sub(word, 1, -2)) .. "яӈʼ") .. "д"
		else result.stem_abs = app_x(metathesis(word) .. "ӑӈʼ") .. "д" end
		if mw.ustring.match(word, P .. "$") then
			result.stem_prs = metathesis(mw.ustring.sub(word, 1, -2)) .. "я̆мна"
		else result.stem_prs = metathesis(word) .. "ӑмна" end
		
		if mw.ustring.match(word, P .. "$") then
			result.stem_nod = metathesis(mw.ustring.sub(word, 1, -2)) .. "я̆ӈгʼ"
		else result.stem_nod = metathesis(word) .. "ӑӈгʼ" end
		if mw.ustring.match(word, P .. "$") then
			result.stem_ald = app_x(metathesis(mw.ustring.sub(word, 1, -2)) .. "яӈʼ") .. "няʼ"
		else result.stem_ald = app_x(metathesis(word) .. "ӑӈʼ") .. "няʼ" end
		if mw.ustring.match(word, P .. "$") then
			result.stem_lod = app_x(metathesis(mw.ustring.sub(word, 1, -2)) .. "яӈʼ") .. "няна"
		else result.stem_lod = app_x(metathesis(word) .. "ӑӈʼ") .. "няна" end
		if mw.ustring.match(word, P .. "$") then
			result.stem_abd = app_x(metathesis(mw.ustring.sub(word, 1, -2)) .. "яӈʼ") .. "няд"
		else result.stem_abd = app_x(metathesis(word) .. "ӑӈʼ") .. "няд" end
		if mw.ustring.match(word, P .. "$") then
			result.stem_prd = app_x(metathesis(mw.ustring.sub(word, 1, -2)) .. "яӈʼ") .. "нямна"
		else result.stem_prd = app_x(metathesis(word) .. "ӑӈʼ") .. "нямна" end
		
		if mw.ustring.match(word, P .. "$") then
			result.stem_nop = metathesis(mw.ustring.sub(word, 1, -2)) .. "я̆ˮ"
		else result.stem_nop = metathesis(word) .. "ӑˮ" end
		result.stem_acp = data.args[2] or error("must specify the accusative plural")
		result.stem_gep = result.stem_acp .. "ˮ"
		if mw.ustring.match(word, P .. "$") then
			result.stem_alp = metathesis(mw.ustring.sub(word, 1, -2)) .. "я̆ӈгˮ"
		else result.stem_alp = metathesis(word) .. "ӑӈгˮ" end
		if mw.ustring.match(word, P .. "$") then
			result.stem_lop = app_x(metathesis(mw.ustring.sub(word, 1, -2)) .. "яӈʼ") .. "ˮна"
		else result.stem_lop = app_x(metathesis(word) .. "ӑӈʼ") .. "ˮна" end
		if mw.ustring.match(word, P .. "$") then
			result.stem_abp = app_x(metathesis(mw.ustring.sub(word, 1, -2)) .. "яӈʼ") .. "т"
		else result.stem_abp = app_x(metathesis(word) .. "ӑӈʼ") .. "т" end
		result.stem_prp = result.stem_acp .. "ˮмӑна"
		
	-- d-stems --
	elseif mw.ustring.sub(word, -2, -1) == "дˮ" then
		word = mw.ustring.sub(word, 1, -3)
		result.stem_nos = shorten(word) .. "ˮ"
		result.stem_acs = word .. "дм"
		result.stem_ges = word .. "дʼ"
		result.stem_als = shorten(word) .. "т"
		result.stem_los = app_x(shorten(word) .. "ˮ") .. "на"
		result.stem_abs = app_x(shorten(word) .. "ˮ") .. "д"
		result.stem_prs = lengthen(word) .. "мна"
		
		result.stem_nod = shorten(word) .. "кʼ"
		result.stem_ald = app_x(shorten(word) .. "ˮ") .. "няʼ"
		result.stem_lod = app_x(shorten(word) .. "ˮ") .. "няна"
		result.stem_abd = app_x(shorten(word) .. "ˮ") .. "няд"
		result.stem_prd = app_x(shorten(word) .. "ˮ") .. "нямна"
		
		result.stem_nop = word .. "дˮ"
		result.stem_acp = data.args[2] or error("must specify the accusative plural")
		result.stem_gep = result.stem_acp .. "ˮ"
		result.stem_alp = shorten(word) .. "кˮ"
		result.stem_lop = app_x(shorten(word) .. "ˮ") .. "ˮна"
		result.stem_abp = app_x(shorten(word) .. "ˮ") .. "т"
		result.stem_prp = result.stem_acp .. "ˮмӑна"
	
	-- s-stem
	elseif mw.ustring.sub(word, -2, -1) == "сˮ" then
		word = mw.ustring.sub(word, 1, -3)
		result.stem_nos = shorten(word) .. "ˮ"
		result.stem_acs = word .. "см"
		result.stem_ges = word .. "сʼ"
		result.stem_als = shorten(word) .. "т"
		result.stem_los = app_x(shorten(word) .. "ˮ") .. "на"
		result.stem_abs = app_x(shorten(word) .. "ˮ") .. "д"
		if mw.ustring.match(lengthen(word), V .. "$") then
			result.stem_prs = lengthen(word) .. "мна"
		else
			result.stem_prs = lengthen(word) .. "ˮмӑна"
		end
		
		result.stem_nod = word .. "кʼ"
		result.stem_ald = app_x(word .. "ˮ") .. "няʼ"
		result.stem_lod = app_x(word .. "ˮ") .. "няна"
		result.stem_abd = app_x(word .. "ˮ") .. "няд"
		result.stem_prd = app_x(word .. "ˮ") .. "нямна"
		
		result.stem_nop = word .. "сˮ"
		result.stem_acp = data.args[2] or error("must specify the accusative plural")
		result.stem_gep = result.stem_acp .. "ˮ"
		result.stem_alp = word .. "кˮ"
		result.stem_lop = app_x(shorten(word) .. "ˮ") .. "ˮна"
		result.stem_abp = app_x(shorten(word) .. "ˮ") .. "т"
		result.stem_prp = result.stem_acp .. "ˮмӑна"
		
	-- l/r-stem
	elseif mw.ustring.match(word, "[лр]ˮ$") then
		word = mw.ustring.sub(word, 1, -2)
		result.stem_nos = word .. "ˮ"
		result.stem_acs = word .. "м"
		result.stem_ges = word .. "ʼ"
		result.stem_als = word .. "т"
		result.stem_los = app_x(shorten(word) .. "ˮ") .. "на"
		result.stem_abs = app_x(shorten(word) .. "ˮ") .. "д"
		result.stem_prs = word .. "мӑна"
		
		result.stem_nod = word .. "кʼ"
		result.stem_ald = app_x(word .. "ˮ") .. "няʼ"
		result.stem_lod = app_x(word .. "ˮ") .. "няна"
		result.stem_abd = app_x(word .. "ˮ") .. "няд"
		result.stem_prd = app_x(word .. "ˮ") .. "нямна"
		
		result.stem_nop = word .. "ˮ"
		result.stem_acp = data.args[2] or error("must specify the accusative plural")
		result.stem_gep = result.stem_acp .. "ˮ"
		result.stem_alp = word .. "кˮ"
		result.stem_lop = app_x(word .. "ˮ") .. "ˮна"
		result.stem_abp = app_x(word .. "ˮ") .. "т"
		result.stem_prp = result.stem_acp .. "ˮмӑна"
	elseif mw.ustring.sub(word, -1, -1) == "ˮ" then
		error("must specify the nominative plural for ˮ-final stems")

	end	
	
	return process(data, result)
end

local infl_table = [=[{| class="vsSwitcher inflection-table" data-toggle-category="declension" border="1px solid #aaaaaa" style="border-collapse:collapse; background:#DDFFFF; text-align:center; width:60%"
! colspan="4" class="vsToggleElement" style="background: #00AAFF; font-weight: bold;" | Declension of {{{nom_sg}}} (regular)
|- class="vsHide"
! style="width:25%;background:#00AAFF" |
! style="width:25%;background:#00AAFF" | singular
! style="width:25%;background:#00AAFF" | dual
! style="width:25%;background:#00AAFF" | plural
|- class="vsHide"
! style="width:20%;background:#00AAFF" | nominative
| {{{nom_sg}}}
| {{{nom_dl}}}
| {{{nom_pl}}}
|- class="vsHide"
! style="width:20%;background:#00AAFF" | genitive
| {{{gen_sg}}}
| {{{gen_dl}}}
| {{{gen_pl}}}
|- class="vsHide"
! style="width:20%;background:#00AAFF" | accusative
| {{{acc_sg}}}
| {{{acc_dl}}}
| {{{acc_pl}}}
|- class="vsHide"
! style="width:20%;background:#00AAFF" | allative
| {{{all_sg}}}
| {{{all_dl}}}
| {{{all_pl}}}
|- class="vsHide"
! style="width:20%;background:#00AAFF" | locative
| {{{loc_sg}}}
| {{{loc_dl}}}
| {{{loc_pl}}}
|- class="vsHide"
! style="width:20%;background:#00AAFF" | ablative
| {{{abl_sg}}}
| {{{abl_dl}}}
| {{{abl_pl}}}
|- class="vsHide"
! style="width:20%;background:#00AAFF" | prolative
| {{{pro_sg}}}
| {{{pro_dl}}}
| {{{pro_pl}}}
|}]=]

local function link(text)
	return require("Module:links").full_link{ term = text, lang = require("Module:languages").getByCode("yrk") }
end

local function mention(text)
	return require("Module:links").full_link({ term = text, lang = require("Module:languages").getByCode("yrk") }, "term")
end

function export.show(frame)
	local infl_type = frame.args[1]
	local infl = inflections[infl_type]
	local args = frame:getParent().args
	local title = args["title"] or mw.title.getCurrentTitle().text

	local data = { title = title, headword = headword, args = args }

	if args["n"] then
		if args["n"] == "s" or args["n"] == "sg" then
			data.no_dual = true
			data.no_plural = true
		elseif args["n"] == "d" or args["n"] == "dl" then
			data.no_singular = true
			data.no_plural = true
		elseif args["n"] == "p" or args["n"] == "pl" then
			data.no_singular = true
			data.no_dual = true
		end
	end

	local forms = infl(data)

	local function repl(form)
		if form == "title" then
			return "'''" .. title .. "'''"
		else
			local value = forms[form]
			if not value then
				return "—"
			elseif type(value) == "table" then
				local result = {}
				for _, f in ipairs(value) do
					table.insert(result, link(f))
				end
				return table.concat(result, ", ")
			else
				return link(value)
			end
		end
	end

	local result = mw.ustring.gsub(infl_table, "{{{([a-z0-9_:]+)}}}", repl)
	result = mw.ustring.gsub(result, "{{m|yrk|([^}]-)}}", mention)
	return result
end

return export