local gsub = mw.ustring.gsub
local sub = mw.ustring.sub
local match = mw.ustring.match
local u = require("Module:string/char")
local export = {}
--àằầèềìòồờùừỳ áắấéếíóốớúứý ảẳẩẻểỉỏổởủửỷ ãẵẫẽễĩõỗỡũữỹ ạặậẹệịọộợụựỵ a̱ă̱â̱e̱ê̱i̱o̱ô̱ơ̱u̱ư̱y̱
local tone_diacritics = { = 2, = 3, = 4, = 5, = 6, = 7 }
local tone_contour = {
= { = "˧˧", = "˧˨", = "˧˥", = "˨˩˧", = "˦ˀ˥", = "˧˨ʔ", = "˩˩" },
= { = "˦˥", = "˩", = "˦", = "˨˦", = "˦ˀ˥", = "˩˧", = "˧" },
}
local initial_ipa = {
= { "ɓ", "ɓ" },
= { "p", "bʱ" },
= { "pʲ","bʱʲ" },
= { "ɓʲ", "ɓʲ" },
= { "k", "k" },
= { "c", "c" },
= { "z", "j" },
= { "t", "dʱ" },
= { "ɗ", "ɗ" },
= { "f", "f" },
= { "ɣ", "ɣ" },
= { "k", "gʱ" },
= { "h", "h" },
= { "k", "k" },
= { "kʰ", "kʰ" },
= { "l", "l" },
= { "m", "m" },
= { "mʲ", "mʲ" },
= { "n", "n" },
= { "ŋ", "ŋ" },
= { "ŋ", "ŋ" },
= { "ɲ", "ɲ" },
= { "p", "p" },
= { "pʰ", "pʰ" },
= { "pʰʲ", "pʰʲ" },
= { "pʲ", "pʲ" },
= { "k", "k" },
= { "kw", "kw" },
= { "r", "r" },
= { "ʂ", "ʂ" },
= { "ɬ", "θ" },
= { "t", "t" },
= { "tʰ", "tʰ" },
= { "ʈ", "ʈ" },
= { "v", "w" },
= { "f", "v" },
= { "s", "s" },
= { "ð", "ð"},
= { "c", "z"},
= { "ʔ", "ʔ" },
= { "", "" },
}
local final_ipa = {
= { "aː", "aː" },
= { "aːk̚", "aːk̚" },
= { "ajk̟̚", "ajk̟̚" },
= { "aːj", "aːj" },
= { "aːm", "aːm" },
= { "aːn", "aːn" },
= { "aːŋ", "aːŋ" },
= { "ajŋ̟", "ajŋ̟" },
= { "aːw", "aːw" },
= { "aːp̚", "aːp̚" },
= { "aːt̚", "aːt̚" },
= { "aw", "aw" },
= { "aj", "aj" },
= { "ak̚", "ak̚" },
= { "am", "am" },
= { "an", "an" },
= { "aŋ", "aŋ" },
= { "ap̚", "ap̚" },
= { "at̚", "at̚" },
= { "ə", "ə" },
= { "ək̚", "ək̚" },
= { "əm", "əm" },
= { "ən", "ən" },
= { "əŋ", "əŋ" },
= { "əp̚", "əp̚" },
= { "ət̚", "ət̚" },
= { "əw", "əw" },
= { "əɯ", "əɯ" },
= { "əj", "əj" },
= { "ɛ", "ɛ" },
= { "ɛk̚", "ɛk̚" },
= { "ɛm", "ɛm" },
= { "ɛn", "ɛn" },
= { "ɛŋ", "ɛŋ" },
= { "ɛw", "ɛw" },
= { "ɛp̚", "ɛp̚" },
= { "ɛt̚", "ɛt̚" },
= { "e", "e" },
= { "ek̚", "ek̚" },
= { "əjk̟̚", "əjk̟̚" },
= { "em", "em" },
= { "en", "en" },
= { "eŋ", "eŋ" },
= { "əjŋ̟", "əjŋ̟" },
= { "ep̚", "ep̚" },
= { "et̚", "et̚" },
= { "ew", "ew" },
= { "i", "i" },
= { "iə", "iə" },
= { "ïk̟̚", "ïk̟̚" },
= { "ïk̟̚", "ïk̟̚" },
= { "iək̚", "iək̚" },
= { "iəm", "iəm" },
= { "iən", "iən" },
= { "iəŋ", "iəŋ" },
= { "iəp̚", "iəp̚" },
= { "iət̚", "iət̚" },
= { "iəw", "iəw" },
= { "im", "im" },
= { "in", "in" },
= { "ïŋ", "ïŋ" },
= { "ip̚", "ip̚" },
= { "it̚", "it̚" },
= { "iw", "iw" },
= { "ɔ", "ɔ" },
= { "waː", "waː" },
= { "waːk̚", "waːk̚" },
= { "wajk̟̚", "wajk̟̚" },
= { "waːj", "waːj" },
= { "waːm", "waːm" },
= { "waːn", "waːn" },
= { "waːŋ", "waːŋ" },
= { "wajŋ̟", "wajŋ̟" },
= { "waːw", "waːw" },
= { "waːp̚", "waːp̚" },
= { "waːt̚", "waːt̚" },
= { "waj", "waj" },
= { "wa", "wa" },
= { "wak̚", "wak̚" },
= { "wam", "wam" },
= { "wan", "wan" },
= { "waŋ", "waŋ" },
= { "wat̚", "wat̚" },
= { "awk͡p̚", "awk͡p̚" },
= { "wɛ", "wɛ" },
= { "wɛm", "wɛm" },
= { "wɛn", "wɛn" },
= { "wɛw", "wɛw" },
= { "wɛt̚", "wɛt̚" },
= { "ɔj", "ɔj" },
= { "ɔm", "ɔm" },
= { "ɔn", "ɔn" },
= { "awŋ͡m", "awŋ͡m" },
= { "ɔk̚", "ɔk̚" },
= { "ɔŋ", "ɔŋ" },
= { "ɔp̚", "ɔp̚" },
= { "ɔt̚", "ɔt̚" },
= { "o", "o" },
= { "əwk͡p̚", "əwk͡p̚" },
= { "oj", "oj" },
= { "om", "om" },
= { "on", "on" },
= { "əwŋ͡m", "əwŋ͡m" },
= { "ok̚", "ok̚" },
= { "oŋ", "oŋ" },
= { "op̚", "op̚" },
= { "ot̚", "ot̚" },
= { "əː", "əː" },
= { "əːj", "əːj" },
= { "əːm", "əːm" },
= { "əːn", "əːn" },
= { "əːŋ", "əːŋ" },
= { "əːp̚", "əːp̚" },
= { "əːt̚", "əːt̚" },
= { "u", "u" },
= { "uə", "uə" },
= { "waːk̚", "waːk̚" },
= { "wajk̟̚", "wajk̟̚" },
= { "waːj", "waːj" },
= { "waːn", "waːn" },
= { "waːŋ", "waːŋ" },
= { "wajŋ̟", "wajŋ̟"},
= { "waːw", "waːw" },
= { "waːp̚", "waːp̚" },
= { "waːt̚", "waːt̚" },
= { "waw", "waw" },
= { "waj", "waj" },
= { "wa", "wa" },
= { "wak̚", "wak̚" },
= { "wam", "wam" },
= { "wan", "wan" },
= { "waŋ", "waŋ" },
= { "wap̚", "wap̚" },
= { "wat̚", "wat̚" },
= { "wə", "wə" },
= { "wək̚", "wək̚" },
= { "wən", "wən" },
= { "wəŋ", "wəŋ" },
= { "wət̚", "wət̚" },
= { "wəj", "wəj" },
= { "ʊwk͡p̚", "ʊwk͡p̚" },
= { "wɛ", "wɛ" },
= {"wɛk̚", "wɛk̚"},
= { "wɛn", "wɛn" },
= { "wɛw", "wɛw" },
= { "wɛp̚", "wɛp̚" },
= { "wɛt̚", "wɛt̚" },
= { "we", "we" },
= { "wəjk̟̚", "wəjk̟̚" },
= { "wen", "wen" },
= { "wəjŋ̟", "wəjŋ̟" },
= { "wet̚", "wet̚" },
= { "weu", "weu" },
= { "uj", "uj" },
= { "win", "win" },
= { "wit̚", "wit̚" },
= { "um", "um" },
= { "un", "un" },
= { "ʊwŋ͡m", "ʊwŋ͡m" },
= { "uə", "uə" },
= { "uək̚", "uək̚" },
= { "uəj", "uəj" },
= { "uəm", "uəm" },
= { "uən", "uən" },
= { "uəŋ", "uəŋ" },
= { "uət̚", "uət̚" },
= { "wəː", "wəː" },
= { "wəːj", "wəːj" },
= { "uən", "uən" },
= { "uət̚", "uət̚" },
= { "up̚", "up̚" },
= { "ut̚", "ut̚" },
= { "wi", "wi" },
= { "wiə", "wiə" },
= { "wïk̟̚", "wïk̟̚" },
= { "win", "win" },
= { "wïk̟̚", "wïk̟̚" },
= { "wiə", "wiə" },
= { "wiən", "wiən" },
= { "wiəŋ̟", "wəŋ" },
= { "wiət̚", "wiət̚" },
= { "wïŋ̟", "wïŋ̟" },
= { "wip̚", "wip̚" },
= { "wit̚", "wit̚" },
= { "wiw", "wiw" },
= { "ɨ", "ɨ" },
= { "ɨə", "ɨə" },
= { "ɨk̚", "ɨk̚" },
= { "ɨj", "ɨj" },
= { "ɨm", "ɨm" },
= { "ɨn", "ɨn" },
= { "ɨŋ", "ɨŋ" },
= { "ɨək̚", "ɨək̚" },
= { "ɨəj", "ɨəj" },
= { "ɨəm", "ɨəm" },
= { "ɨən", "ɨən" },
= { "ɨəŋ", "ɨəŋ" },
= { "ɨəp̚", "ɨəp̚" },
= { "ɨət̚", "ɨət̚" },
= { "ɨəw", "ɨəw" },
= { "ɨt̚", "ɨt̚" },
= { "ɨw", "ɨw" },
= { "i", "i" },
= { "iək̚", "iək̚" },
= { "iəm", "iəm" },
= { "iən", "iən" },
= { "iəŋ", "iəŋ" },
= { "iəp̚", "iəp̚" },
= { "iət̚", "iət̚" },
= { "iəw", "iəw" },
}
local voicing = {
= "bhj",
= "bh",
= "zh",
= "dh",
= "gh",
= "gh",
= "vh",
}
local varieties = {
= { "] – ]", 1 },
= { "]", 2 },
}
function export.ipa(frame)
local p, output = {}, { = {}, = {} }
local output_text = {}
local pronunciations = { = {}, = {} }
local pagename = gsub(gsub(mw.ustring.lower(mw.title.getCurrentTitle().subpageText), "%-", " "), "%,", "")
local args = frame:getParent().args
if args then
for index, item in ipairs(args) do
table.insert(p, (item ~= "") and mw.ustring.lower(gsub(gsub(item, "%-", " "), "%,", "")) or nil)
end
else
table.insert(p, pagename)
end
for variety, _ in ipairs(varieties) do
table.insert(pronunciations, (args ~= "") and args or nil)
end
for i, word in ipairs(p) do
local pronunciations = { = {}, = {} }
for syllable in mw.text.gsplit(word, " ", true) do
local ipa = {}
local initial, final, tone = nil, nil, nil, nil
tone = 1
syllable = mw.ustring.toNFD(syllable)
for diac_pattern, tone_num in pairs(tone_diacritics) do
if match(syllable, diac_pattern) then
tone = tone_num
break
end
end
syllable = mw.ustring.toNFC(gsub(syllable, "", ""))
initial = match(syllable, "^g+") or match(syllable, "^(g)")
or match(syllable, "^g") or match(syllable, "^+") or ""
initial = (match(syllable, "^giê.") and syllable ~= "giên") and "d" or initial
initial = match(syllable, "qu$") and "qu" or initial
final = sub(syllable, mw.ustring.len(initial) + 1, -1)
for loc, location in pairs(varieties) do
local ipa, seq, detoned = {}, location, ""
for voc, _ in pairs(voicing) do
if match(tone,"") and initial == voc then
initial = voicing
break
end
end
if initial_ipa then
table.insert(ipa, initial_ipa)
else
local initial_cluster = ""
initial = gsub(initial, "r$", "ŕ")
for cc in mw.ustring.gcodepoint(initial) do
local ch = u(cc)
initial_cluster = initial_cluster .. initial_ipa
end
initial_cluster = gsub(initial_cluster, "(h)" or "j" or "phj", function(digraph)
return initial_ipa end)
table.insert(ipa, initial_cluster)
end
if final_ipa then
detoned = gsub(final_ipa, "^(.+)", function(nucleus)
if initial .. final == "qua" then
nucleus = final_ipa
elseif initial .. final == "qui" then
nucleus = final_ipa
end
return nucleus end)
table.insert(ipa, detoned)
else
error(("Unrecognised final: \"%s\""):format(final))
end
if tone == 1 and match(final, "") then
tone = 3
end
table.insert(ipa, tone_contour)
table.insert(pronunciations, table.concat(ipa, ""))
end
end
for loc, location in pairs(varieties) do
table.insert(output, table.concat(pronunciations, " "))
end
end
for loc, location in pairs(varieties) do
if args ~= "-" then
if not args then
args = table.concat(output, "], [")
local alternative = args
if alternative ~= args then args = args .. "] ~ [" .. alternative end
end
table.insert(output_text, location, "\n* (''" .. location .. "'') " ..
"]<sup>(])</sup>: <span class=\"IPA\">[" ..
args .. "]</span>")
else
table.insert(output_text, location, "")
end
end
if table.concat(p, "") ~= mw.ustring.lower(pagename) then
table.insert(output_text, #output_text + 1, "\n* ''Phonetic'': " .. gsub(table.concat(p, ", "), "ŕ", "R"))
end
return (gsub(table.concat(output_text, ""), "^\n(.)", "%1"))
end
return export