မဝ်ဂျူ:vot-pronunciation
မံက်ပြာကတ်
Documentation for this module may be created at မဝ်ဂျူ:vot-pronunciation/doc
local export = {}
local m_vot = require("Module:vot")
local m_IPA = require("Module:IPA")
local gsub_lookahead = require("Module:gsub lookahead")
local lang = m_vot.lang
local U = mw.ustring.char
--- <<< DATA START >>> ---
local LONG = "ː"
local STRESS_PRIMARY = "ˈ"
local STRESS_SECONDARY = "ˌ"
local FRONTAL = U(0x0308)
local NONSYLLABIC = U(0x032F)
local TIE = U(0x0361)
local VERYSHORT = U(0x0306)
local PALATAL = "ʲ"
local IPA_VOWELS = "ɑeiouyæøɤɨə"
local AUTO_STRESS = U(0xEEEE)
local IPA_CONSONANTS = m_vot.consonants .. "ɫcčCɟɕʑɲʎï"
local IPA_CONSONANTS_GEMINATABLE = m_vot.consonants_geminatable .. "ɫcčCɕʑɲʎ"
local PALATALIZE = m_vot.palatalize
local UNGEMINATE = "/"
local SHIFT_STRESS = "*"
local ANY_DIACRITICS = "[" .. U(0x0300) .. "-" .. U(0x036F) .. "]*"
local SOME_DIACRITICS = "[" .. U(0x0300) .. "-" .. U(0x036F) .. "]+"
local IPA_VOWEL = "[aõäöü" .. IPA_VOWELS .. "]"
local sep_symbols = m_vot.sep_symbols .. "%*"
--- <<< DATA END >>> ---
--- <<< COMMON START >>> ---
local function split_syllables(word, keep_sep_symbols)
local res = {}
local syllable = ""
local pos = 1
local found_vowel = false
-- the following consonants stick together
while pos <= #word do
if mw.ustring.find(mw.ustring.lower(word), "^[" .. IPA_CONSONANTS .. "][" .. PALATAL .. PALATALIZE .. "]?" .. IPA_VOWEL, pos) then
-- CV: end current syllable if we have found a vowel
if found_vowel then
if syllable then table.insert(res, syllable) end
found_vowel = false
syllable = ""
end
syllable = syllable .. mw.ustring.sub(word, pos, pos)
pos = pos + 1
elseif mw.ustring.find(mw.ustring.lower(word), "^[" .. IPA_CONSONANTS .. "]", pos) then
-- C: continue
syllable = syllable .. mw.ustring.sub(word, pos, pos)
pos = pos + 1
elseif mw.ustring.find(mw.ustring.lower(word), "^" .. IPA_VOWEL, pos) then
if found_vowel then
-- already found a vowel, end current syllable
if syllable then
table.insert(res, syllable)
end
syllable = ""
end
found_vowel = true
-- check for diphthongs or long vowels
local seq_ok = false
for k, v in pairs(m_vot.vowel_sequences) do
if mw.ustring.find(mw.ustring.lower(word), "^" .. v, pos) then
seq_ok = true
break
end
end
if seq_ok then
syllable = syllable .. mw.ustring.sub(word, pos, pos + 1)
pos = pos + 2
else
syllable = syllable .. mw.ustring.sub(word, pos, pos)
pos = pos + 1
end
elseif mw.ustring.find(mw.ustring.lower(word), "^[" .. PALATALIZE .. PALATAL .. "]", pos) then
syllable = syllable .. PALATALIZE
pos = pos + 1
elseif mw.ustring.find(mw.ustring.lower(word), "^[" .. sep_symbols .. "]", pos) then
-- separates syllables
if syllable then
table.insert(res, syllable)
end
local sepchar = mw.ustring.sub(word, pos, pos)
syllable = keep_sep_symbols and sepchar or ""
pos = pos + 1
found_vowel = false
else
-- ?: continue
syllable = syllable .. mw.ustring.sub(word, pos, pos)
pos = pos + 1
end
end
if syllable then
table.insert(res, syllable)
end
return res
end
local function zeroth_round_of_common_replacements(text, narrow)
if narrow then
text = mw.ustring.gsub(text, "l([aouõ])", "ɫ%1")
text = mw.ustring.gsub(text, "lɫ", "ɫɫ")
text = mw.ustring.gsub(text, "([^" .. STRESS_PRIMARY .. STRESS_SECONDARY .. "%*-]+)", function (word)
if mw.ustring.find(word, "[aouõ]") then
return mw.ustring.gsub(word, "l(.?)", function (v) return (mw.ustring.match(v, "[eäöü]") and "l" or "ɫ") .. v end)
else
return word
end
end)
end
text = mw.ustring.gsub(text, "tts", "cc")
text = mw.ustring.gsub(text, "ts", "c")
text = mw.ustring.gsub(text, "ttš", "čč")
text = mw.ustring.gsub(text, "tš", "č")
text = mw.ustring.gsub(text, PALATALIZE .. "(" .. m_vot.consonants .. PALATALIZE .. ")", "%1")
return text
end
local function first_round_of_common_replacements(text)
text = mw.ustring.gsub(text, "n([-" .. AUTO_STRESS .. "]?[kg])", "ŋ%1")
text = mw.ustring.gsub(text, "[aäöõü’]", {
["a"] = "ɑ",
["ä"] = "æ",
["ö"] = "ø",
["õ"] = "ɤ",
["ü"] = "y",
["’"] = ".",
-- ["-"] = STRESS_SECONDARY,
})
return text
end
local function second_round_of_common_replacements(text, narrow)
text = mw.ustring.gsub(text, "%" .. SHIFT_STRESS, STRESS_PRIMARY)
text = mw.ustring.gsub(text, "[cčCgïjšž]", {
["c"] = "t͡s",
["č"] = "t͡ʃ",
["C"] = "c",
["g"] = "ɡ",
["ï"] = "j",
["j"] = "ʝ",
["š"] = "ʃ",
["ž"] = "ʒ"
})
return text
end
local function automatic_palatalization(text, filter)
return mw.ustring.gsub(text, "(" .. filter .. ")(" .. m_vot.consonants .. "?)i", function (c1, c2)
if #c2 == 0 then
return c1 .. PALATAL .. "i"
elseif mw.ustring.match(c2, filter) then
return c1 .. PALATAL .. c2 .. PALATAL .. "i"
else
return c1 .. PALATAL .. c2 .. "i"
end
end)
end
local full_palatal = {
["d"] = "ɟ", ["t"] = "C", -- workaround
["z"] = "ʑ", ["n"] = "ɲ", ["l"] = "ʎ", ["s"] = "ɕ"
}
local function manual_palatalization(text)
if not mw.ustring.find(text, PALATALIZE) then return text end
text = mw.ustring.gsub(text, "([" .. IPA_CONSONANTS .. "])" .. PALATALIZE, function(c)
return full_palatal[c] or c .. PALATAL
end)
text = mw.ustring.gsub(text, PALATALIZE, "")
text = mw.ustring.gsub(text, PALATAL .. PALATAL, PALATAL)
return text
end
local IPA_diphthongs = {
"[aeouɤæøy]i",
"[iouɤ]a",
"[iøye]æ",
"[aoɤei]u",
"[au]ɤ",
"[æøie]y",
"[aiæy]e",
"[ai]o",
}
local function long_vowels_and_diphthongs(text)
text = mw.ustring.gsub(text, "([" .. IPA_VOWELS .. "])%1", "%1" .. LONG)
for _, diphthong in ipairs(IPA_diphthongs) do
local mod_diphthong
if mw.ustring.find(diphthong, "%]$") then
mod_diphthong = mw.ustring.gsub(diphthong, "(.)(%[[^%]]-%])", "%1" .. VERYSHORT .. "?%2")
mod_diphthong = mw.ustring.gsub(diphthong, "(%[[^%]]-%])(%[[^%]]-%])", "%1" .. VERYSHORT .. "?%2")
else
mod_diphthong = mw.ustring.sub(diphthong, 1, -2) .. VERYSHORT .. "?" .. mw.ustring.sub(diphthong, -1, -1)
end
text = mw.ustring.gsub(text, "(" .. mod_diphthong .. ")", "%1" .. NONSYLLABIC)
end
return text
end
local function long_consonants(text)
text = mw.ustring.gsub(text, "(%a)" .. PALATAL .. "%1" .. PALATAL, "%1" .. PALATAL .. LONG)
text = mw.ustring.gsub(text, "(%a)%1", "%1" .. LONG)
text = mw.ustring.gsub(text, LONG .. PALATAL, PALATAL .. LONG)
return text
end
local function add_primary_stress(text)
text = mw.ustring.gsub(text, AUTO_STRESS, "-")
text = mw.ustring.gsub(text, "-%.", "-")
text = mw.ustring.gsub(text, "-", STRESS_SECONDARY)
text = STRESS_PRIMARY .. mw.ustring.gsub(text, " ", " " .. STRESS_PRIMARY)
text = mw.ustring.gsub(text, STRESS_PRIMARY .. "([^ ]+" .. STRESS_PRIMARY .. ")", "%1")
return mw.ustring.toNFC(text)
end
local function is_stressed_syllable(syllable)
return mw.ustring.find(syllable, "^[ " .. AUTO_STRESS .. "%*-]")
end
local function add_secondary_stress(syllables)
local distance = 0
for index, syllable in ipairs(syllables) do
if index == #syllables then break end
local stressed = index == 1 or is_stressed_syllable(syllable)
if stressed then
distance = 0
else
distance = distance + 1
if distance == 2 then
distance = 0
if not is_stressed_syllable(syllables[index + 1]) then
syllables[index] = AUTO_STRESS .. syllable
end
end
end
end
end
local function clean_ungeminate(text)
return mw.ustring.gsub(text, UNGEMINATE, "")
end
local function do_gemination(syllables, diacritic)
local try_to_geminate = false
for index, syllable in ipairs(syllables) do
local stressed = index == 1 or is_stressed_syllable(syllable)
if try_to_geminate and not stressed then
-- check if the initial consonant in this syllable is followed by two vowels
local rest = syllable .. (syllables[index + 1] or "")
if mw.ustring.find(rest, "^[" .. IPA_CONSONANTS_GEMINATABLE .. "]" .. PALATALIZE .. "?" .. m_vot.vowel .. m_vot.vowel) then
-- CVCVV -> CVC:VV
local cg = select(3, mw.ustring.find(syllable, "^([" .. IPA_CONSONANTS_GEMINATABLE .. "]" .. PALATALIZE .. "?)"))
syllables[index - 1] = syllables[index - 1] .. cg
syllables[index] = mw.ustring.gsub(syllable, "^" .. cg, diacritic)
end
end
try_to_geminate = stressed and mw.ustring.find(syllable, "^[ " .. AUTO_STRESS .. "-]?[" .. IPA_CONSONANTS .. PALATALIZE .. TIE .. "]*" .. m_vot.vowel .. "$")
end
end
local function split_syllables_by_words(syllables)
local i = 1
return function()
local r = {}
local e = i
if e <= #syllables then
table.insert(r, (mw.ustring.gsub(syllables[e], "^%s+", "")))
e = e + 1
while e <= #syllables and not mw.ustring.find(syllables[e], "^%s") do
table.insert(r, syllables[e])
e = e + 1
end
i = e
return r
end
end
end
local function do_by_word_syllables(out_syllables, fn)
local old_syllables = {}
for k, v in pairs(out_syllables) do
old_syllables[k] = v
out_syllables[k] = nil
end
local next_word = false
for syllables in split_syllables_by_words(old_syllables) do
fn(syllables)
for i, syllable in ipairs(syllables) do
if next_word and i == 1 then
table.insert(out_syllables, " " .. syllable)
else
table.insert(out_syllables, syllable)
end
end
next_word = true
end
end
local function reduce_final_syllable(syl)
local allowed_finals = {
"(" .. m_vot.consonant .. ")%1",
"g[lɫnr]",
"mp",
"šk",
"lt"
}
if not mw.ustring.find(syl, m_vot.consonant .. m_vot.consonant .. PALATALIZE .. "?$") then
return syl
end
for _, allowed_final in ipairs(allowed_finals) do
if not mw.ustring.find(syl, allowed_final .. PALATALIZE .. "?$") then
return mw.ustring.gsub(syl, PALATALIZE .. "$", "")
end
end
return mw.ustring.sub(mw.ustring.gsub(syl, PALATALIZE .. "$", ""), 1, -2)
end
local function is_syllable_stressed_at(syllable, index)
return index == 1 or is_stressed_syllable(syllable)
end
local function do_reduction_word(syllables, narrow, reduce_completely)
local prev_was_stressed = false
local prev_was_long = false
local syllables_since_last_stressed = 0
local final_vowel_dropped = false
for index, syllable in ipairs(syllables) do
local stressed = is_syllable_stressed_at(syllable, index)
local final = index == #syllables
if stressed then
syllables_since_last_stressed = 0
else
syllables_since_last_stressed = syllables_since_last_stressed + 1
end
prev_was_long = prev_was_long
if not stressed and ((prev_was_stressed and prev_was_long) or (syllables_since_last_stressed > 1 or prev_was_long)) then
syllables[index] = mw.ustring.gsub(syllable, "(" .. m_vot.vowel .. "+)(.*)", function (nucleus, coda)
if mw.ustring.find(nucleus, "(" .. m_vot.vowel .. ")%1") then
return mw.ustring.sub(nucleus, 1, 1) .. coda
end
if not narrow then
local broad_reduce = { ["a"] = "õ", ["ä"] = "e" }
return (broad_reduce[nucleus] or nucleus) .. coda
end
--if mw.ustring.find(nucleus, "i[aä]") then
--return (syllable.find(PALATALIZE) and "" or PALATALIZE) .. mw.ustring.sub(nucleus, 2) .. coda
--end
if mw.ustring.find(nucleus, m_vot.vowel .. m_vot.vowel) then
return nucleus .. coda
end
local reduced = {
["a"] = "ə", ["ä"] = "ə"
}
if not reduced[nucleus] then
return nucleus .. coda
end
if final and reduce_completely and #coda < 1 and mw.ustring.match(nucleus, "[aä]") then
if mw.ustring.find(syllable, "j[aä]") then
return reduced[nucleus] .. VERYSHORT
end
final_vowel_dropped = true
return ""
end
return (reduced[nucleus] or nucleus) .. coda
end)
end
-- reduce the next syllable only if the current syllable is stressed and heavy
prev_was_stressed = stressed
prev_was_long = mw.ustring.find(syllable, m_vot.vowel .. "[" .. IPA_CONSONANTS .. m_vot.vowels .. "]")
end
if final_vowel_dropped then
syllables[#syllables - 1] = reduce_final_syllable(syllables[#syllables - 1] .. syllables[#syllables])
syllables[#syllables] = nil
end
end
local function do_reduction(syllables, narrow, reduce_completely)
do_by_word_syllables(syllables, function(s) do_reduction_word(s, narrow, reduce_completely) end)
end
local diphthongize_broad = {
["e"] = "ie", ["o"] = "uo", ["ø"] = "yø"
}
local diphthongize_narrow = {
["e"] = "ɪ̆e", ["o"] = "ʊ̆o", ["ø"] = "ʏ̆ø"
}
local function do_diphthongization_word(syllables, narrow, reduce_completely)
for index, syllable in ipairs(syllables) do
local stressed = is_syllable_stressed_at(syllable, index)
syllables[index] = mw.ustring.gsub(syllable, "([eoø])%1", function (v)
return ((narrow and not stressed) and diphthongize_narrow or diphthongize_broad)[v]
end)
end
end
local function do_diphthongization(syllables, narrow)
do_by_word_syllables(syllables, function(s) do_diphthongization_word(s, narrow) end)
end
local function pass_diacritics_through(map, consonant)
local consonant, diacritics = mw.ustring.match(consonant, "([" .. IPA_CONSONANTS .. "])([" .. PALATAL .. "]?)")
return map[consonant] .. diacritics
end
local voiceless_sounds = "kptcčfsšh"
local function do_voicing(text)
local devoice = { ["g"] = "k", ["b"] = "p", ["d"] = "t", ["z"] = "s", ["ž"] = "š", ["ʑ"] = "ɕ" }
local semivoice = { ["g"] = "g̊", ["b"] = "b̥", ["d"] = "d̥", ["z"] = "z̥", ["ž"] = "ž̥", ["ʑ"] = "ɕ̊" }
local consonants_to_devoice = "[bdgzž][" .. PALATAL .. "]?"
local vowel = "[" .. IPA_VOWELS .. "]"
-- b/d/g/z/ž is semivoiced if it is not followed by anything
text = mw.ustring.gsub(text, "(" .. consonants_to_devoice .. ")$",
function (consonant)
return pass_diacritics_through(semivoice, consonant)
end)
-- b/d/g/z/ž is devoiced if it is followed by a voiceless sound
text = gsub_lookahead(text, "(" .. consonants_to_devoice .. ")([%s" .. AUTO_STRESS .. "-]+)([" .. voiceless_sounds .. "])",
function (consonant, space, after)
return pass_diacritics_through(devoice, consonant) .. space, after
end)
return text
end
--- <<< COMMON END >>> ---
--- <<< DIALECTS START >>> ---
-- narrow_level 0 = broad, 1 = rhyme, 2 = narrow
-- Luuditsa, Liivtšülä
local function IPA_luuditsa_liivtsula(text, narrow_level)
text = zeroth_round_of_common_replacements(text, narrow_level > 1)
if narrow_level > 0 then
local syllables = split_syllables(text, true)
add_secondary_stress(syllables)
text = table.concat(syllables)
end
local syllables = split_syllables(text, true)
if narrow_level > 1 then
do_gemination(syllables, LONG)
do_reduction(syllables, true, false)
end
text = table.concat(syllables)
if narrow_level > 0 then text = do_voicing(text) end
if narrow_level > 1 then
text = automatic_palatalization(text, "[dnrstz]") -- palatalization
text = mw.ustring.gsub(text, "h([kg])", "x%1")
end
text = clean_ungeminate(text)
text = mw.ustring.gsub(text, "j" .. PALATALIZE, PALATALIZE)
text = manual_palatalization(text)
text = first_round_of_common_replacements(text)
text = long_vowels_and_diphthongs(text)
text = long_consonants(text)
text = second_round_of_common_replacements(text, narrow_level > 1)
return add_primary_stress(text)
end
-- Jõgõperä
local function IPA_jogopera(text, narrow_level)
text = zeroth_round_of_common_replacements(text, narrow_level > 1)
if narrow_level > 0 then
local syllables = split_syllables(text, true)
add_secondary_stress(syllables)
text = table.concat(syllables)
end
local syllables = split_syllables(text, true)
if narrow_level > 1 then
do_gemination(syllables, LONG)
do_reduction(syllables, true, true)
end
text = table.concat(syllables)
if narrow_level > 0 then text = do_voicing(text) end
if narrow_level > 1 then
text = automatic_palatalization(text, "[dnrstz]") -- palatalization
text = mw.ustring.gsub(text, "h([kg])", "x%1")
end
text = clean_ungeminate(text)
text = mw.ustring.gsub(text, "j" .. PALATALIZE, PALATALIZE)
text = manual_palatalization(text)
text = first_round_of_common_replacements(text)
text = long_vowels_and_diphthongs(text)
text = long_consonants(text)
text = second_round_of_common_replacements(text, narrow_level > 1)
return add_primary_stress(text)
end
-- Kattila
local function IPA_kattila(text, narrow_level)
text = zeroth_round_of_common_replacements(text, narrow_level > 1)
if narrow_level > 0 then
local syllables = split_syllables(text, true)
add_secondary_stress(syllables)
text = table.concat(syllables)
end
local syllables = split_syllables(text, true)
if narrow_level > 1 then
do_gemination(syllables, LONG)
end
text = table.concat(syllables)
if narrow_level > 0 then text = do_voicing(text) end
if narrow_level > 1 then
text = automatic_palatalization(text, "[dnrstz]") -- palatalization
text = mw.ustring.gsub(text, "h([kg])", "x%1")
end
text = clean_ungeminate(text)
text = mw.ustring.gsub(text, "j" .. PALATALIZE, PALATALIZE)
text = manual_palatalization(text)
text = first_round_of_common_replacements(text)
if narrow_level > 0 then
local syllables = split_syllables(text, true)
do_diphthongization(syllables, narrow_level > 1)
text = table.concat(syllables)
end
text = long_vowels_and_diphthongs(text)
text = long_consonants(text)
text = second_round_of_common_replacements(text, narrow_level > 1)
return add_primary_stress(text)
end
--- <<< DIALECTS END >>> ---
--- <<< INTERFACE START >>> ---
local function cleanup_for_hyphenate(text)
local no_hyph_symbols = "[" .. UNGEMINATE .. "%*-]"
return mw.ustring.gsub(text, no_hyph_symbols, "")
end
local function run_reductions(text)
local syllables = m_vot.split_syllables(text, true)
local prev_was_stressed = false
local prev_was_long = false
local syllables_since_last_stressed = 0
for index, syllable in ipairs(syllables) do
local stressed = is_syllable_stressed_at(syllable, index)
local final = index == #syllables
if stressed then
syllables_since_last_stressed = 0
else
syllables_since_last_stressed = syllables_since_last_stressed + 1
end
prev_was_long = prev_was_long
if not stressed and ((prev_was_stressed and prev_was_long) or (syllables_since_last_stressed > 1 or prev_was_long)) then
syllables[index] = mw.ustring.gsub(syllable, "(" .. m_vot.vowel .. "+)(.*)", function (nucleus, coda)
if mw.ustring.find(nucleus, "(" .. m_vot.vowel .. ")%1") then
return mw.ustring.sub(nucleus, 1, 1) .. coda
end
local broad_reduce = { ["a"] = "õ", ["ä"] = "e" }
return (broad_reduce[nucleus] or nucleus) .. coda
end)
end
-- reduce the next syllable only if the current syllable is stressed and heavy
prev_was_stressed = stressed
prev_was_long = mw.ustring.find(syllable, m_vot.vowel .. "[" .. IPA_CONSONANTS .. m_vot.vowels .. "]")
end
return table.concat(syllables, "")
end
local function hyphenate_matches(sp, title)
local resp = run_reductions(mw.ustring.lower(sp))
resp = mw.ustring.gsub(cleanup_for_hyphenate(resp), "%.", "")
resp = mw.ustring.gsub(resp, "([bdgzž])([kpsšt])", function(c1, c2) return ({b = "p", d = "t", g = "k", z = "s", ["ž"] = "š"})[c1] .. c2 end)
return resp == mw.ustring.lower(title)
end
local function hyphenate(text)
return m_vot.split_syllables(cleanup_for_hyphenate(text))
end
local function spell_long_consonants(text)
text = mw.ustring.gsub(text, "(t[sš])" .. "(" .. PALATALIZE .. "?)" .. LONG,
function (c, p) return "t" .. c .. p end)
text = mw.ustring.gsub(text, "([" .. m_vot.consonants .. "])" .. "(" .. PALATALIZE .. "?)" .. LONG,
function (c, p) return c .. c .. p end)
text = mw.ustring.gsub(text, "iï", "i")
return text
end
local function generate_rhyme(tuple)
local text = tuple.rhyme
local index = mw.ustring.find(text, "[" .. STRESS_PRIMARY .. STRESS_SECONDARY .. "][^" .. STRESS_PRIMARY .. STRESS_SECONDARY .. "]*$")
if index ~= nil then text = mw.ustring.sub(text, index + 1) end
index = mw.ustring.find(text, "[" .. IPA_VOWELS .. "]")
if index == nil then return nil end
return mw.ustring.sub(text, index)
end
local function make_IPAs(fn, forms, variety)
local p = {}
for _, form in ipairs(forms) do
form = mw.ustring.lower(form)
local suffix = mw.ustring.find(form, "^%-")
local prefix = mw.ustring.find(form, "%-$")
if suffix then form = mw.ustring.gsub(form, "^%-", "") end
if prefix then form = mw.ustring.gsub(form, "%-$", "") end
local broad = fn(form, 0)
local rhyme = fn(form, 1)
local narrow = fn(form, 2)
if prefix then
broad = broad .. "-"
rhyme = nil
narrow = narrow .. "-"
end
if suffix then
broad = "-" .. mw.ustring.gsub(broad, "^" .. STRESS_PRIMARY, "")
rhyme = nil
narrow = "-" .. mw.ustring.gsub(narrow, "^" .. STRESS_PRIMARY, "")
end
table.insert(p, { broad = broad, rhyme = rhyme, narrow = narrow })
end
local result = {
forms = p,
varieties = { variety }
}
return result
end
local function format_IPAs(tuple, title, has_spaces)
local dialects = require("Module:accent qualifier").format_qualifiers(tuple.varieties)
local p = {}
for _, form in ipairs(tuple.forms) do
table.insert(p, {pron = "/" .. form.broad .. "/"})
table.insert(p, {pron = "[" .. form.narrow .. "]"})
end
return "* " .. dialects .. " " .. m_IPA.format_IPA_full(lang, p, nil, nil, nil, has_spaces)
end
local function get_arg_list(param, fallback, allow_dash, required)
if not param or #param == 0 then return required and fallback or nil end
if not allow_dash and #param == 1 and param[1] == "-" then return nil end
if #param == 1 and param[1] == "+" then return fallback end
return param
end
local varieties = {
["Lu"] = { "ဠူဒေတ်သာ", IPA_luuditsa_liivtsula },
["Li"] = { "လိယေတ်သဝ်လာ", IPA_luuditsa_liivtsula },
["J"] = { "ဂျာန်ဂဝ်ဖေအ်ရာ", IPA_jogopera },
["K"] = { "ကေတ္တဳလာ", IPA_kattila },
}
local variety_groups = {
{ "LL", {"Lu", "Li"}, true },
{ nil, "J", false },
{ nil, "K", false },
}
local varieties_merged = {}
for _, group in ipairs(variety_groups) do
if group[1] then
varieties_merged[group[1]] = group[2]
end
end
local function get_variety(variety_code)
if varieties[variety_code] then
return varieties[variety_code]
end
if varieties_merged[variety_code] then
local subvarieties = varieties_merged[variety_code]
local names = {}
local fn = nil
for _, subvariety_code in ipairs(subvarieties) do
local subvariety = varieties[subvariety_code]
fn = subvariety[2]
table.insert(names, subvariety[1])
end
return {table.concat(names, ", "), fn}
end
error("Unrecognized variety code: " .. variety_code)
end
function export.get_variety(variety_code)
return get_variety(variety_code)[1]
end
function export.generate_one(form, variety_code, transcription)
local name, fn = unpack(get_variety(variety_code))
local result = make_IPAs(fn, {form}, name).forms[1]
if transcription then result = result[transcription] end
return result
end
function export.generate_multiple(forms, variety_code, transcription)
local param, name, fn = unpack(get_variety(variety_code))
local result = make_IPAs(fn, forms, name).forms
if transcription then
for i, form in ipairs(result) do
result[i] = form[transcription]
end
end
return result
end
local function add_IPAs(IPAs, spellings, main_code, args, required)
local name, fn = unpack(get_variety(main_code))
local forms = get_arg_list(args, spellings, false, required)
if forms then
table.insert(IPAs, make_IPAs(fn, forms, name))
end
end
function export.show(frame)
local title = mw.title.getCurrentTitle().text
local hyphenation = nil
local rhymes = nil
local categories = {}
local params = {
[1] = { list = true },
["LL"] = { list = true }, -- Luuditsa-Liivtšülä
["Lu"] = { list = true }, -- Luuditsa
["Li"] = { list = true }, -- Liivtšülä
["J"] = { list = true }, -- Jõgõperä
["K"] = { list = true }, -- Kattila,
["dial"] = { type = "boolean" },
["title"] = {}, -- for debugging or demonstration only
}
local args = require("Module:parameters").process(frame:getParent().args, params)
title = args["title"] or title
local dialectal = args.dial
local spellings = get_arg_list(args[1], { mw.ustring.lower(title) }, true, true)
local IPAs = {}
for _, variety_group in ipairs(variety_groups) do
local param, codes, always = unpack(variety_group)
if param then
local split = false
for _, code in ipairs(codes) do
if #args[code] > 0 then
split = true
break
end
end
if split then
for _, code in ipairs(codes) do
add_IPAs(IPAs, spellings, code, args[code] or (param and args[param] or nil), always and not dialectal)
end
else
add_IPAs(IPAs, spellings, param, args[param], always and not dialectal)
end
else
add_IPAs(IPAs, spellings, codes, args[codes], always and not dialectal)
end
end
if #IPAs < 1 then
error("No dialects to display IPA for")
end
local results = {}
local has_spaces = mw.ustring.find(title, " ")
for _, tuple in ipairs(IPAs) do
table.insert(results, format_IPAs(tuple, title, has_spaces))
end
if not hyphenation then
hyphenation = {}
if not has_spaces then
local sp = spellings[1]
if not hyphenate_matches(sp, title) then
-- try to geminate
local syllables = m_vot.split_syllables(sp, true)
do_gemination(syllables, LONG)
sp = spell_long_consonants(clean_ungeminate(table.concat(syllables)))
end
if hyphenate_matches(sp, title) then
table.insert(hyphenation, hyphenate(title))
end
end
end
if not rhymes then
rhymes = {}
if not has_spaces then
local found_rhymes = {}
for _, tuple in ipairs(IPAs) do
for _, form in ipairs(tuple.forms) do
if form.rhyme then
local rhyme = generate_rhyme(form)
if not found_rhymes[rhyme] then
found_rhymes[rhyme] = true
table.insert(rhymes, rhyme)
end
end
end
end
end
end
if #hyphenation > 0 then
local hyphs = {}
for i, h in ipairs(hyphenation) do
table.insert(hyphs, { ["hyph"] = h })
end
table.insert(results, "* " .. require("Module:hyphenation").format_hyphenations(
{ lang = lang, hyphs = hyphs, caption = "ဗီုပြၚ်ဂၠေံဂၠေံ" }))
end
return table.concat(results, "\n") .. require("Module:utilities/format_categories")(categories, lang)
end
--- <<< INTERFACE END >>> ---
return export