local m_str_utils = require("Module:string utilities")
local codepoint = m_str_utils.codepoint
local find = m_str_utils.find
local gcodepoint = m_str_utils.gcodepoint
local gsub = m_str_utils.gsub
local len = m_str_utils.len
local match = m_str_utils.match
local sub = m_str_utils.sub
local u = m_str_utils.char
local upper = m_str_utils.upper
local export = {}
export.vowels_back_unrounded = "aâı"
export.vowels_back_rounded = "ouû"
export.vowels_front_unrounded = "eiî"
export.vowels_front_rounded = "öü"
export.vowels_back = export.vowels_back_unrounded .. export.vowels_back_rounded
export.vowels_front = export.vowels_front_unrounded .. export.vowels_front_rounded
export.vowels = export.vowels_back .. export.vowels_front
export.voiceless_consonants = "çfhkptsş"
export.voiced_consonants = "bcdgğjlmnrvyz"
export.consonants = export.voiceless_consonants .. export.voiced_consonants
function is_in(c, str)
if len(c) ~= 1 then
error("argument with bad length: " .. tostring(len(c)) .. " ~= 1")
end
return find(str, c) ~= nil
end
function export.is_vowel(c)
return is_in(c, export.vowels)
end
function export.is_voiceless_consonant(c)
return is_in(c, export.voiceless_consonants)
end
function export.is_voiced_consonant(c)
return is_in(c, export.voiced_consonants)
end
function export.get_last_vowel(str)
return match(str, "([" .. export.vowels .. "])[^" .. export.vowels .. "]*$")
end
function export.starts_with_vowel(str)
if match(str, "^[" .. export.vowels .. "]") then
return true
else
return false
end
end
function export.starts_with_consonant(str)
return not starts_with_vowel(str)
end
function export.ends_with_vowel(str)
if match(str, "[" .. export.vowels .. "]$") then
return true
else
return false
end
end
function export.ends_with_consonant(str)
return not ends_with_vowel(str)
end
function export.ends_with_voiceless_consonant(str)
if match(str, "[" .. export.voiceless_consonants .. "]$") then
return true
else
return false
end
end
function export.soften(str)
str = gsub(str, "ç$", "c")
str = gsub(str, "p$", "b")
str = gsub(str, "t$", "d")
str = gsub(str, "k$", "ğ")
return str
end
function export.get_2_way_harmony(vowel)
if match(vowel, "^[" .. export.vowels_back .. "]$") then
return "a"
elseif match(vowel, "^[" .. export.vowels_front .. "]$") then
return "e"
else
error("'" .. export.vowel .. "' is not a vowel")
end
end
function export.get_4_way_harmony(vowel)
if match(vowel, "^[" .. export.vowels_back_unrounded .. "]$") then
return "ı"
elseif match(vowel, "^[" .. export.vowels_back_rounded .. "]$") then
return "u"
elseif match(vowel, "^[" .. export.vowels_front_unrounded .. "]$") then
return "i"
elseif match(vowel, "^[" .. export.vowels_front_rounded .. "]$") then
return "ü"
else
error("'" .. export.vowel .. "' is not a vowel")
end
end
function export.get_ki_harmony(vowel)
if match(str, "^[" .. export.vowels_back_unrounded .. export.vowels_back_rounded .. export.vowels_front_unrounded .. "]$") then
return "i"
elseif match(str, "^[" .. export.vowels_front_rounded .. "]$") then
return "ü"
else
error("'" .. export.vowel .. "' is not a vowel")
end
end
function export.attach_suffixes(base, suffixes, base_vowel, generate_2_way_aorist, generate_4_way_aorist)
local result = base
local previous_char = u(codepoint(base, -1))
local previous_vowel = base_vowel or export.get_last_vowel(base) or "i" -- yemek -> yiyor
local remaining_suffixes = suffixes
for c in gcodepoint(suffixes) do
c = u(c)
remaining_suffixes = sub(remaining_suffixes, 2)
if c == "R" then -- aorist R
if export.is_vowel(previous_char) then
c = "r"
else
if generate_2_way_aorist and generate_4_way_aorist then
ar = export.attach_suffixes(result, "Ar" .. remaining_suffixes, nil, generate_2_way_aorist, generate_4_way_aorist)
ir = export.attach_suffixes(result, "Ir" .. remaining_suffixes, nil, generate_2_way_aorist, generate_4_way_aorist)
for _, v in ipairs(ir) do
ar[#ar + 1] = v
end
return ar
elseif generate_2_way_aorist or generate_4_way_aorist then
previous_char = (generate_2_way_aorist and export.get_2_way_harmony or export.get_4_way_harmony)(previous_vowel)
previous_vowel = previous_char
result = result .. previous_char
c = "r"
else
error("suffixes contain an aorist placeholder after a consonant but no harmony is specified")
end
end
elseif c == "Y" then -- intervocalic Y
c = export.is_vowel(previous_char) and "y" or nil
elseif c == "N" then -- intervocalic N
c = export.is_vowel(previous_char) and "n" or nil
elseif c == "S" then -- intervocalic S
c = export.is_vowel(previous_char) and "s" or nil
elseif c == "J" then -- interconsonantal I
c = export.is_vowel(previous_char) and nil or export.get_4_way_harmony(previous_vowel)
elseif c == "D" then -- d/t
c = export.is_voiceless_consonant(previous_char) and "t" or "d"
elseif c == "A" then -- 2-way
c = export.get_2_way_harmony(previous_vowel)
elseif c == "I" then -- 4-way
c = export.get_4_way_harmony(previous_vowel)
end
if c ~= nil then
if c == upper(c) then
error("unrecognized placeholder '" .. c .. "'")
end
result = result .. c
previous_char = c
if export.is_vowel(c) then
previous_vowel = c
end
end
end
return { result }
end
return export