Used by Module:gem-decl-noun. Do not use directly.
local export = {}
local m_IPA = require("Module:IPA")
local lang = require("Module:languages").getByCode("gem-pro")
local letters_internal = {
{ "ai", "aj" }, { "au", "aw" }, { "eu", "ew" }, { "iu", "iw" },
{ "hw", "hʷ" }, { "kw", "kʷ" }, { "gw", "gʷ" },
{ "ē₂", "ë" }, { "į̄", "ǐ" }, { "ǫ̂", "ơ" },
}
local phonetic_rules = {
{ "a", "ɑ" },
{ "ā", "ɑː" }, { "ë", "eː" }, { "ē", "ɛː" }, { "ī", "iː" }, { "ō", "ɔː" }, { "ū", "uː" },
{ "ê", "ɛːː" }, { "ô", "ɔːː" },
{ "ą", "ɑ̃" }, { "į", "ĩ" }, { "ų", "ũ" },
{ "ǐ", "ĩː" }, { "ǭ", "ɔ̃ː" },
{ "ơ", "ɔ̃ːː" },
{ "f", "ɸ" }, { "þ", "θ" },
{ "h", "x" }, { "hʷ", "xʷ" },
{ "^x", "h" }, { "^xʷ", "hʷ" },
{ "b", "β" }, { "^β", "b" }, { "mβ", "mb" },
{ "d", "ð" }, { "^ð", "d" }, { "()ð", "%1d" },
{ "g", "ɣ" }, { "nɣʷ", "ŋʷɡʷ" }, { "nɣ", "ŋɡ" },
}
local vowels = {
"a", "e", "i", "u",
"ā", "ē", "ë", "ī", "ō", "ū",
"ê", "ô",
"ą", "į", "ų",
"ǐ", "ǭ",
"ơ",
"-"
}
local onsets = {
"b", "p", "d", "t", "þ",
"g", "k", "kʷ", "gʷ",
"f", "s", "h", "hʷ", "z",
"l", "m", "n", "r", "j", "w",
"bl", "pl", "fl", "br", "pr", "fr", "þl", "wl",
"dr", "tr", "þr",
"gl", "kl", "hl", "gr", "kr", "hr", "wr",
"gn", "kn", "hn", "fn",
"dw", "tw", "þw", "kw", "hw",
"sp", "st", "sk", "sw", "sl", "sm", "sn", "sw",
"spr", "str", "skr",
"spl", "skl",
}
local codas = {
"b", "p", "pp", "þ", "d", "t", "f", "g", "k", "h",
"s", "z",
"l", "m", "n", "r", "j", "w",
"hʷ", "ww", "wz",
"sp", "st", "sk",
"lp", "lt", "lk",
"lb", "ld", "lg",
"lf", "lþ", "lh",
"rp", "rt", "rk",
"rb", "rd", "rg",
"rf", "rþ", "rh",
"mp", "nt", "nk", "nn",
"mb", "nd", "ng",
"mf", "nþ", "nh", "nhs",
"lm", "rl", "rm", "rn", "wh", "wr", "wl", "fl", "sl",
"ps", "ts", "ks", "hs", "ls", "ns", "rs", "þs", "sts", "hts",
"lks", "lhs", "nks", "rks", "rgz", "rhs", "nþs", "hsl",
"lms", "rls", "rms", "rns", "hst", "hsl", "rht", "rkt",
"ht", "rht",
"nz", "ndz", "dz", "gz", "ngz", "rz", "rbz", "rdz", "zn",
"ndr", "ntr", "ngr", "nkr", "nstr",
"jp", "jb", "js", "jz", "jt", "jd", "jþ", "jf", "jk", "jg", "jh", "jr",
"jst", "jzd", "jts", "jdz", "jks", "jgz", "jsk", "jzg", "jstr", "jzdr",
"jn", "jm", "jw", "jþm",
}
for _, val in ipairs(vowels) do
vowels = true
end
for _, val in ipairs(onsets) do
onsets = true
end
for _, val in ipairs(codas) do
codas = true
end
local function letters_to_internal(word)
local phonemes = {}
for _, rule in ipairs(letters_internal) do
word = mw.ustring.gsub(word, rule, rule)
end
mw.ustring.gsub(word, ".", function(c)
table.insert(phonemes, c)
end)
return phonemes
end
local function word_from_internal(word)
for _, rule in ipairs(letters_internal) do
word = mw.ustring.gsub(word, rule, rule)
end
return word
end
local function get_onset(syll)
local consonants = {}
for i = 1, #syll do
if vowels] then
break
end
table.insert(consonants, syll)
end
return table.concat(consonants)
end
local function get_coda(syll)
local consonants = {}
for i = #syll, 1, -1 do
if vowels] then
break
end
table.insert(consonants, 1, syll)
end
return table.concat(consonants)
end
local function get_vowel(syll)
for i = 1, #syll do
if vowels] then return syll end
end
end
-- Split the word into syllables of CV shape
local function split_syllables(remainder)
local syllables = {}
local syll = {}
while #remainder > 0 do
local phoneme = table.remove(remainder, 1)
if vowels then
table.insert(syll, phoneme)
table.insert(syllables, syll)
syll = {}
else
table.insert(syll, phoneme)
end
end
-- If there are phonemes left, then the word ends in a consonant
-- Add them to the last syllable
for _, phoneme in ipairs(syll) do
table.insert(syllables, phoneme)
end
-- Split consonant clusters between syllables
for i, current in ipairs(syllables) do
if i > 1 then
local previous = syllables
local onset = get_onset(current)
-- Shift over consonants until the syllable onset is valid
while not (onset == "" or onsets) do
table.insert(previous, table.remove(current, 1))
onset = get_onset(current)
end
-- If there is no vowel at all in this syllable
if not get_vowel(current) then
for j = 1, #current do
table.insert(syllables, table.remove(current, 1))
end
table.remove(syllables, i)
end
end
end
for _, syll in ipairs(syllables) do
local onset = get_onset(syll)
local coda = get_coda(syll)
if not (onset == "" or onsets) then
require("Module:debug").track("gem-ipa/bad onset")
error("onset error: ")
end
if not (coda == "" or codas) then
require("Module:debug").track("gem-ipa/bad coda")
error("coda error: ")
end
end
return syllables
end
local function convert_word(word)
-- Convert word to a better internal representation
local phonemes = letters_to_internal(word)
-- Split into syllables
local syllables = split_syllables(phonemes)
for i, syll in ipairs(syllables) do
for j = 1, #syll - 1 do
if syll == syll then
syll = ""
end
end
syllables = table.concat(syll)
end
word = table.concat(syllables, ".")
for _, rule in ipairs(phonetic_rules) do
word = mw.ustring.gsub(word, rule, rule)
end
return word
end
local function convert_words(words)
words = mw.ustring.lower(words)
local result = {}
for word in mw.text.gsplit(words, " ") do
table.insert(result, convert_word(word))
end
return table.concat(result, " ")
end
function export.show_full(frame)
local params = {
= { default = mw.title.getCurrentTitle().nsText ~= 'Reconstruction' and 'wurdą' or mw.title.getCurrentTitle().subpagetext }
}
local args = require("Module:parameters").process(frame:getParent().args, params)
local words = args:lower()
local categories = {}
local out = m_IPA.format_IPA_full { lang = lang, items = {{ pron = "/" .. convert_words(words) .. "/" }} }
return out .. require("Module:utilities").format_categories(categories)
end
function export.show(words)
if type(words) == "table" then -- assume a frame
words = words.args:lower() or mw.title.getCurrentTitle().subpageText:lower()
end
return convert_words(words)
end
local function i_mutation(word)
local upperc = false
--local dash = false
if mw.ustring.find(word, "^%u") then
word = mw.ustring.lower(word)
upperc = true
end
--[[if mw.ustring.find(word, "^%-") then
word = mw.ustring.sub(word, 2)
dash = true
end]]
local repeated = false
local phonemes = letters_to_internal(word)
-- Split into syllables
local syllables = split_syllables(phonemes)
for i, syll in ipairs(syllables) do
--[[for j=1, #syll-1 do
if syll==syll then
syll = ""
repeated = true
end
end]]
syllables = table.concat(syll)
end
for i = #syllables, 1, -1 do
mw.ustring.gsub(syllables, "e()", "i%1")
if mw.ustring.find(syllables, "") then
if not mw.ustring.find(syllables, "je") then
syllables = mw.ustring.gsub(syllables, "e", "i")
end
if i ~= 1 then
syllables = mw.ustring.gsub(syllables, "e", "i")
end
end
end
local new_word = table.concat(syllables)
local vowels_s = "aeiuāēëīōūêôąįųǭį̄ǫ̂"
new_word = word_from_internal(new_word)
new_word = mw.ustring.gsub(new_word, "uu", "wu")
new_word = mw.ustring.gsub(new_word, "(i)u", "%1w")
new_word = mw.ustring.gsub(new_word, "()u()", "%1w%2")
new_word = mw.ustring.gsub(new_word, "()i()", "%1j%2")
new_word = mw.ustring.gsub(new_word, "()uj", "%1wj")
-- Exception for compound words
new_word = mw.ustring.gsub(new_word, "andaulit", "andawlit")
if upperc then
return mw.ustring.upper(mw.ustring.sub(new_word, 1, 1)) .. mw.ustring.sub(new_word, 2)
--elseif dash then
-- return "-" .. new_word
else
return new_word
end
end
function export.determine_sievers(stem)
if mw.ustring.find(stem, "..$") then
-- Two light syllables = one heavy
return "ij"
elseif mw.ustring.find(stem, "^$") or mw.ustring.find(stem, "$") or mw.ustring.find(stem, "$") then
return "j"
else
return "ij"
end
end
function export.i_mutations(word)
local words = mw.text.split(word, " ")
if #words > 1 then
local new_word = i_mutation(words)
table.remove(words)
table.insert(words, new_word)
return table.concat(words, " ")
else
return i_mutation(word)
end
end
return export