Module:urj-fin-common

From Wiktionary, the free dictionary
Jump to navigation Jump to search
This module needs documentation.
Please document this module by describing its purpose and usage on the documentation page.

local export = {}

-- Split the word into syllables of C(C)V(V) shape
function export.split_syllables(word)
	local syllables = {}
	local remainder = word
	
	while remainder ~= "" do
		local syll = ""
		
		if mw.ustring.find(remainder, "^([^aeiouäëöü%-]+)") then
			syll = syll .. mw.ustring.match(remainder, "^([^aeiouäëöü%-]+)")
			remainder = mw.ustring.gsub(remainder, "^([^aeiouäëöü%-]+)", "")
		end
		
		if mw.ustring.find(remainder, "^([aeiouäëöü%-]+)") then
			syll = syll .. mw.ustring.match(remainder, "^([aeiouäëöü%-]+)")
			remainder = mw.ustring.gsub(remainder, "^([aeiouäëöü%-]+)", "")
		end
		
		table.insert(syllables, syll)
	end
	
	-- Assume that suffixes are attached to words of at least two syllables.
	if mw.ustring.find(word, "^%-") then
		table.insert(syllables, 1, "")
	end
	
	return syllables
end

-- Apply gradation to a word
function export.apply_gradation(word)
	local syllables = export.split_syllables(word)
	
	for i, syll in ipairs(syllables) do
		-- The first and last consonant do not gradate
		if i > 1 then
			-- Apply suffixal gradation to single consonants at the beginning of odd-numbered syllables
			if i % 2 == 1 and mw.ustring.find(syll, "^[ptks][aeiouäëöü]") then
				syll = mw.ustring.gsub(syll, "^p", "b")
				syll = mw.ustring.gsub(syll, "^t", "d")
				syll = mw.ustring.gsub(syll, "^k", "g")
				syll = mw.ustring.gsub(syll, "^s", "h")
			end
			
			-- Apply radical gradation
			-- Does the next syllable begin with more than one consonant, or does it contain no vowels (final consonant)?
			if i < #syllables and (mw.ustring.find(syllables[i+1], "^[^aeiouäëöü][^aeiouäëöü]") or not mw.ustring.find(syllables[i+1], "[aeiouäëöü]")) then
				syll = mw.ustring.gsub(syll, "^([lrmn]?)pp([aeiouäëöü])", "%1p'%2")
				syll = mw.ustring.gsub(syll, "^([lrmn]?)tt([aeiouäëöü])", "%1t'%2")
				syll = mw.ustring.gsub(syll, "^([lrmn]?)kk([aeiouäëöü])", "%1k'%2")
				syll = mw.ustring.gsub(syll, "^([lrmn]?)cc([aeiouäëöü])", "%1c'%2")
				syll = mw.ustring.gsub(syll, "^([lrmn]?)p([aeiouäëöü])", "%1b%2")
				syll = mw.ustring.gsub(syll, "^([lrmn]?)t([aeiouäëöü])", "%1d%2")
				syll = mw.ustring.gsub(syll, "^([lrmn]?)k([aeiouäëöü])", "%1g%2")
			end
		end
		
		syllables[i] = syll
	end
	
	return table.concat(syllables, "")
end

function export.make_stems(stem, overrides)
	local stems = {normal = stem}
	
	stems.final = stems.normal
	
	local da_stem = overrides and overrides.da_stem
	local ne_t_stem = overrides and overrides.ne_t_stem
	local inf_e = overrides and overrides.inf_e
	
	if mw.ustring.find(stems.normal, "[^aeiouäëöü]$") then
		da_stem = da_stem and mw.ustring.find(stems.normal, "t$")
		stems.normal = stems.normal .. export.detect_harmony(stems.normal).e
	else
		da_stem = false
	end
	
	stems.i = stems.normal .. "i"
	stems.k = stems.normal .. "k"
	stems.n = stems.normal .. "n"
	stems.t = stems.normal .. "t"
	stems.types = {"unknown"}
	
	local syllables = export.split_syllables(stems.normal)
	
	
	-- Stems ending in a long vowel replace the second vowel with a diphthong
	if mw.ustring.find(stems.normal, "([aeiouäëöü])%1$") then
		stems.types = {"long vowel"}
		stems.i = mw.ustring.gsub(stems.i, "[aeiouäëöü]i$", "i")
	-- Stems ending in a u-diphthong replace u with v
	elseif mw.ustring.find(stems.normal, "([aeioäëö])[uü]$") then
		stems.types = {"u-diphthong"}
		stems.i = mw.ustring.gsub(stems.i, "[uü]i$", "vi")
	-- Stems ending in a i-diphthong have don't get an extra -i
	elseif mw.ustring.find(stems.normal, "([aeouäëöü])i$") then
		stems.types = {"i-diphthong"}
		stems.i = mw.ustring.gsub(stems.i, "ii$", "i")
	elseif #syllables == 1 then
		stems.types = {"short monosyllable"}
	else
		-- Stems ending in a simple -i get -eji- in the plural
		if mw.ustring.find(stems.normal, "i$") then
			stems.types = {"i"}
			stems.i = mw.ustring.gsub(stems.i, "ii$", export.detect_harmony(stems.i).e .. "ji")
		elseif mw.ustring.find(stems.normal, "([ouöü])$") then
			stems.types = {"rounded"}
		-- Stems ending in -ä replace the vowel with -ei-.
		elseif mw.ustring.find(stems.normal, "([^aeiouäëöü])ä$") then
			if #syllables > 1 then
				stems.types = {"a-ei"}
				stems.i = mw.ustring.gsub(stems.i, "äi$", "ei")
			end
		-- Stems ending in -a replace the vowel with -oi- in the past stem,
		-- but only if the preceding syllable does not contain rounded vowels.
		-- Otherwise, replace with -ei- as above.
		elseif mw.ustring.find(stems.normal, "([^aeiouäëöü])a$") then
			if #syllables > 1 then
				-- *-eda adjectives do not have -oi-
				if mw.ustring.find(syllables[#syllables-1], "[ou]") or mw.ustring.find(stems.normal, "[eë]d[aä]$") then
					stems.types = {"a-ei"}
					stems.i = mw.ustring.gsub(stems.i, "ai$", "ëi")
				else
					stems.types = {"a-oi"}
					stems.i = mw.ustring.gsub(stems.i, "ai$", "oi")
				end
			end
		-- Stems ending in -e may drop the -e in some forms, resulting in contraction
		elseif mw.ustring.find(stems.normal, "[^aeiouäëöü][eë]$") then
			stems.types = {"e"}
			
			stems.final = mw.ustring.gsub(stems.final, "[eë]$", "i")
			stems.final = mw.ustring.gsub(stems.final, "ji$", "i")
			
			stems.i = mw.ustring.gsub(stems.i, "[eë]i$", "i")
			
			if mw.ustring.find(stems.normal, "cc[eë]$") then
				stems.types = {"cce"}
				if not inf_e then
					stems.t = mw.ustring.gsub(stems.t, "cc[eë]t$", "ct")
				end
			elseif mw.ustring.find(stems.normal, "[pk][cs][eë]$") then
				stems.types = {"kce, pce, kse, pse"}
				stems.k = mw.ustring.gsub(stems.k, "[kp]([cs])[eë]k$", "%1k")
				stems.n = mw.ustring.gsub(stems.n, "[kp]s[eë]n$", "ss")
				stems.t = mw.ustring.gsub(stems.t, "[kp]([cs])[eë]t$", "%1t")
			elseif mw.ustring.find(stems.normal, "[aeiouäëöü%-]c[eë]$") then
				stems.types = {"Vce"}
				stems.n = mw.ustring.gsub(stems.n, "c[eë]n$", "nn")
				stems.t = mw.ustring.gsub(stems.t, "c[eë]t$", "ct")
			elseif mw.ustring.find(stems.normal, "[aeiouäëöü%-]h[eë]$") then
				stems.types = {"Vhe"}
				stems.t = mw.ustring.gsub(stems.t, "h[eë]t$", "ht")
			elseif mw.ustring.find(stems.normal, "[aeiouäëöü%-]k[eë]$") then
				stems.types = {"Vke"}
				stems.k = mw.ustring.gsub(stems.k, "k[eë]k$", "kk")
				
				if stems.normal == "näke" or stems.normal == "teke" or #syllables > 2 then
					stems.t = mw.ustring.gsub(stems.t, "ket$", "kt")
				end
			elseif mw.ustring.find(stems.normal, "[aeiouäëöü%-]n[eë]$") and ne_t_stem then
				stems.types = {"Vne-Vt"}
				stems.k = mw.ustring.gsub(stems.k, "n[eë]k$", "tk")
				stems.n = mw.ustring.gsub(stems.n, "n[eë]n$", "nn")
				stems.t = mw.ustring.gsub(stems.t, "n[eë]t$", "tt")
			elseif mw.ustring.find(stems.normal, "[aeiouäëöü%-][lnrs][eë]$") then
				stems.types = {"Vle, Vne, Vre, Vse"}
				stems.k = mw.ustring.gsub(stems.k, "([lnrs])[eë]k$", "%1k")
				stems.n = mw.ustring.gsub(stems.n, "([lnrs])[eë]n$", "%1n")
				stems.n = mw.ustring.gsub(stems.n, "([lns])n$", "%1%1")
				stems.t = mw.ustring.gsub(stems.t, "([lnrs])[eë]t$", "%1t")
			elseif mw.ustring.find(stems.normal, "[aeiouäëöü%-]m[eë]$") then
				stems.types = {"Vme"}
				if not inf_e then
					stems.t = mw.ustring.gsub(stems.t, "m[eë]t$", "nt")
				end
			elseif mw.ustring.find(stems.normal, "[chst]t[eë]$") then
				stems.types = {"cte, hte, ste, tte"}
			elseif mw.ustring.find(stems.normal, "kt[eë]$") then
				stems.types = {"kte"}
				
				stems.final = mw.ustring.gsub(stems.final, "ti$", "ci")
				stems.i = mw.ustring.gsub(stems.i, "ti$", "ci")
				
				if not inf_e then
					stems.t = mw.ustring.gsub(stems.t, "kt[eë]t$", "kt")
				end
			elseif mw.ustring.find(stems.normal, "nt[eë]$") then
				stems.types = {"nte"}
				
				stems.final = mw.ustring.gsub(stems.final, "ti$", "ci")
				stems.i = mw.ustring.gsub(stems.i, "ti$", "ci")
				stems.n = mw.ustring.gsub(stems.n, "nten$", "nn")
				
				if not inf_e then
					stems.t = mw.ustring.gsub(stems.t, "nt[eë]t$", "tt")
				end
			elseif mw.ustring.find(stems.normal, "[aeiouäëöü%-]t[eë]$") then
				stems.types = {"Vte"}
				
				stems.final = mw.ustring.gsub(stems.final, "ti$", "ci")
				stems.i = mw.ustring.gsub(stems.i, "ti$", "ci")
				
				stems.k = mw.ustring.gsub(stems.k, "t[eë]k$", "tk")
				stems.n = mw.ustring.gsub(stems.n, "t[eë]n$", "nn")
				if not inf_e then
					stems.t = mw.ustring.gsub(stems.t, "t[eë]t$", "tt")
				end
			elseif mw.ustring.find(stems.normal, "t[eë]$") then
				stems.types = {"te"}
				
				stems.final = mw.ustring.gsub(stems.final, "ti$", "ci")
				stems.i = mw.ustring.gsub(stems.i, "ti$", "ci")
			end
			
			if #syllables >= 3 then
				stems.final = mw.ustring.gsub(stems.final, "i$", "")
			end
			
			-- Simplify final consonant clusters
			stems.final = mw.ustring.gsub(stems.final, "[^aeiouäëöü%-]+([^aeiouäëöü])$", "%1")
			stems.final = mw.ustring.gsub(stems.final, "m$", "n")
		end
	end
	
	if da_stem and stems.types[1] == "Vte" then
		stems.normal = mw.ustring.gsub(stems.normal, "[eë]$", export.detect_harmony(stems.normal).a)
		stems.types = {"Vta"}
	end
	
	return stems
end

function export.detect_harmony(stem)
	local vowels = {}
	vowels.a = "ä"
	vowels.e = "e"
	vowels.u = "ü"
	
	if mw.ustring.find(stem, "[aëou]") then
		vowels.a = "a"
		vowels.e = "ë"
		vowels.u = "u"
	end
	
	return vowels
end

return export