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, "^(+)") then
syll = syll .. mw.ustring.match(remainder, "^(+)")
remainder = mw.ustring.gsub(remainder, "^(+)", "")
end
if mw.ustring.find(remainder, "^(+)") then
syll = syll .. mw.ustring.match(remainder, "^(+)")
remainder = mw.ustring.gsub(remainder, "^(+)", "")
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, "^") 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, "^") or not mw.ustring.find(syllables, "")) then
syll = mw.ustring.gsub(syll, "^(?)pp()", "%1p'%2")
syll = mw.ustring.gsub(syll, "^(?)tt()", "%1t'%2")
syll = mw.ustring.gsub(syll, "^(?)kk()", "%1k'%2")
syll = mw.ustring.gsub(syll, "^(?)cc()", "%1c'%2")
syll = mw.ustring.gsub(syll, "^(?)p()", "%1b%2")
syll = mw.ustring.gsub(syll, "^(?)t()", "%1d%2")
syll = mw.ustring.gsub(syll, "^(?)k()", "%1g%2")
end
end
syllables = 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, "$") 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, "()%1$") then
stems.types = {"long vowel"}
stems.i = mw.ustring.gsub(stems.i, "i$", "i")
-- Stems ending in a u-diphthong replace u with v
elseif mw.ustring.find(stems.normal, "()$") then
stems.types = {"u-diphthong"}
stems.i = mw.ustring.gsub(stems.i, "i$", "vi")
-- Stems ending in a i-diphthong have don't get an extra -i
elseif mw.ustring.find(stems.normal, "()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, "()$") then
stems.types = {"rounded"}
-- Stems ending in -ä replace the vowel with -ei-.
elseif mw.ustring.find(stems.normal, "()ä$") 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, "()a$") then
if #syllables > 1 then
-- *-eda adjectives do not have -oi-
if mw.ustring.find(syllables, "") or mw.ustring.find(stems.normal, "d$") 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
if #syllables > 2 and mw.ustring.find(stems.normal, "toma$") then
stems.final = mw.ustring.gsub(stems.final, "ttoma$", "t'oin")
stems.final = mw.ustring.gsub(stems.final, "()toma$", "%1toin")
stems.t = stems.final .. "t"
stems.n = stems.final .. "n"
end
-- Stems ending in -e may drop the -e in some forms, resulting in contraction
elseif mw.ustring.find(stems.normal, "$") then
stems.types = {"e"}
stems.final = mw.ustring.gsub(stems.final, "$", "i")
stems.final = mw.ustring.gsub(stems.final, "ji$", "i")
stems.i = mw.ustring.gsub(stems.i, "i$", "i")
if mw.ustring.find(stems.normal, "cc$") then
stems.types = {"cce"}
if not inf_e then
stems.t = mw.ustring.gsub(stems.t, "cct$", "ct")
end
elseif mw.ustring.find(stems.normal, "$") then
stems.types = {"kce, pce, kse, pse"}
stems.k = mw.ustring.gsub(stems.k, "()k$", "%1k")
stems.n = mw.ustring.gsub(stems.n, "sn$", "ss")
stems.t = mw.ustring.gsub(stems.t, "()t$", "%1t")
elseif mw.ustring.find(stems.normal, "c$") then
stems.types = {"Vce"}
stems.n = mw.ustring.gsub(stems.n, "cn$", "nn")
stems.t = mw.ustring.gsub(stems.t, "ct$", "ct")
elseif mw.ustring.find(stems.normal, "h$") then
stems.types = {"Vhe"}
stems.t = mw.ustring.gsub(stems.t, "ht$", "ht")
elseif mw.ustring.find(stems.normal, "k$") then
stems.types = {"Vke"}
stems.k = mw.ustring.gsub(stems.k, "kk$", "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, "n$") and ne_t_stem then
stems.types = {"Vne-Vt"}
stems.k = mw.ustring.gsub(stems.k, "nk$", "tk")
stems.n = mw.ustring.gsub(stems.n, "nn$", "nn")
stems.t = mw.ustring.gsub(stems.t, "nt$", "tt")
elseif mw.ustring.find(stems.normal, "$") then
stems.types = {"Vle, Vne, Vre, Vse"}
stems.k = mw.ustring.gsub(stems.k, "()k$", "%1k")
stems.n = mw.ustring.gsub(stems.n, "()n$", "%1n")
stems.n = mw.ustring.gsub(stems.n, "()n$", "%1%1")
stems.t = mw.ustring.gsub(stems.t, "()t$", "%1t")
elseif mw.ustring.find(stems.normal, "m$") then
stems.types = {"Vme"}
if not inf_e then
stems.t = mw.ustring.gsub(stems.t, "mt$", "nt")
end
elseif mw.ustring.find(stems.normal, "t$") then
stems.types = {"cte, hte, ste, tte"}
elseif mw.ustring.find(stems.normal, "kt$") 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, "ktt$", "kt")
end
elseif mw.ustring.find(stems.normal, "nt$") 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, "ntt$", "tt")
end
elseif mw.ustring.find(stems.normal, "t$") 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, "tk$", "tk")
stems.n = mw.ustring.gsub(stems.n, "tn$", "nn")
if not inf_e then
stems.t = mw.ustring.gsub(stems.t, "tt$", "tt")
end
elseif mw.ustring.find(stems.normal, "t$") 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, "+()$", "%1")
stems.final = mw.ustring.gsub(stems.final, "m$", "n")
end
end
if da_stem and stems.types == "Vte" then
stems.normal = mw.ustring.gsub(stems.normal, "$", 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, "") then
vowels.a = "a"
vowels.e = "ë"
vowels.u = "u"
end
return vowels
end
return export