local export = {}
local PAGENAME = mw.title.getCurrentTitle().text
local find = mw.ustring.find
local sub = mw.ustring.sub
local gsub = mw.ustring.gsub
local rhyme
local lang = require("Module:languages").getByCode("lo")
-- for easier processing
local pre = {
[1] = { "ຫງ", "" }, -- faux hng
[2] = { "ຫ[ຍຽ]", "" }, -- faux hny
[3] = { "ຫນ", "ໜ" },
[4] = { "ຫມ", "ໝ" },
[5] = { "ຫ[ຣລຼ]", "" }, -- faux hl
[6] = { "ຫວ", "" }, -- faux hw
[7] = {"([ເແໂໃໄ])([ກ-ຮໜໝ][ຣລວຼ]?)", "%2%1"},
[8] = {"(.*)([່້໊໋])(.*)", "%1%3%2"},
}
local initials = {
["ກ"] = "k", ["ຂ"] = "kʰ", ["ຄ"] = "kʰ", [""] = "ŋ", ["ງ"] = "ŋ",
["ຈ"] = "t͡ɕ", ["ສ"] = "s", ["ຊ"] = "s", [""] = "ɲ", ["ຍ"] = "ɲ",
["ດ"] = "d", ["ຕ"] = "t", ["ຖ"] = "tʰ", ["ທ"] = "tʰ", ["ໜ"] = "n", ["ນ"] = "n",
["ບ"] = "b", ["ປ"] = "p", ["ຜ"] = "pʰ", ["ພ"] = "pʰ",
["ຝ"] = "f", ["ຟ"] = "f", ["ໝ"] = "m", ["ມ"] = "m",
["ຢ"] = "j", ["ຣ"] = "l", [""] = "l", ["ລ"] = "l",
[""] = "ʋ", ["ວ"] = "ʋ", ["ຫ"] = "h", ["ຮ"] = "h", ["ອ"] = "ʔ",
["ກວ"] = "kʷ", ["ຂວ"] = "kʷʰ", ["ຄວ"] = "kʷʰ", ["ງວ"] = "ŋʷ",
["ຈວ"] = "t͡ɕʷ", ["ສວ"] = "sʷ", ["ຊວ"] = "sʷ",
["ຖວ"] = "tʷʰ", ["ທວ"] = "tʷʰ", ["ລວ"] = "lʷ", ["ອວ"] = "ʔʷ", ["ຮວ"] = "hʷ",
}
local vowels = {
[""] = "#",
["ະ"] = "aʔ", ["ັ"] = "a", ["າ"] = "aː",
["ິ*"] = "iʔ", ["ິ"] = "i", ["ີ"] = "iː",
["ຶ*"] = "ɯʔ", ["ຶ"] = "ɯ", ["ື"] = "ɯː",
["ຸ*"] = "uʔ", ["ຸ"] = "u", ["ູ"] = "uː",
["ເະ"] = "eʔ", ["ເັ"] = "e", ["ເ"] = "eː",
["ແະ"] = "ɛʔ", ["ແັ"] = "ɛ", ["ແ"] = "ɛː",
["ໂະ"] = "oʔ", ["ົ"] = "o", ["ໂ"] = "oː",
["ເາະ"] = "ɔʔ", ["ັອ"] = "ɔ", ["ອ"] = "ɔː", ["ໍ"] = "ɔː",
["ເິ*"] = "ɤʔ", ["ເິ"] = "ɤ", ["ເີ"] = "ɤː",
["ົວະ"] = "uə̯ʔ", ["ົວ"] = "uːə̯", ["ວ"] = "uːə̯", ["'ວ"] = "uːə̯",
["ເັຍ"] = "iə̯ʔ", ["ເັຽະ"] = "iə̯ʔ", ["ັຽ"] = "iə̯",
["ເຍ"] = "iːə̯", ["ເັຽ"] = "iːə̯", ["ຽ"] = "iːə̯", ["'ຍ"] = "iːə̯", ["'ຽ"] = "iːə̯",
["ເຶອ*"] = "ɯə̯ʔ", ["ເຶອ"] = "ɯə̯", ["ເືອ"] = "ɯːə̯",
["ຳ"] = "am", ["ໃ"] = "aɰ", ["ໄ"] = "aj", ["ເົາ"] = "aw",
}
local finals = {
[""] = "", ["ກ"] = "k̚", ["ດ"] = "t̚", ["ບ"] = "p̚",
["ງ"] = "ŋ", ["ນ"] = "n", ["ມ"] = "m",
["ຍ"] = "j", ["ຽ"] = "j", ["ວ"] = "w", ["ສ"] = "s",
--force final
["+ກ"] = "k̚", ["+ດ"] = "t̚", ["+ບ"] = "p̚",
["+ງ"] = "ŋ", ["+ນ"] = "n", ["+ມ"] = "m",
["+ຍ"] = "j", ["+ວ"] = "w", ["+ສ"] = "s",
}
-- เวียงจันทน์
local vt_unmarked_tones = { -- M,L,H
live = { "˩(˧)", "˧˥", "˩(˧)" },
dead_short = { "˧˥", "˧", "˧˥" },
dead_long = { "˧˩", "˥˨", "˧˩" },
}
local vt_marked_tones = { -- M,L,H
["່"] = { "˧", "˧", "˧" },
["້"] = { "˥˨", "˥˨", "˧˩" },
["໊"] = { "˧˥", "˧˥", "˧˥" },
["໋"] = { "˩˧", "˩˧", "˩˧" },
}
-- หลวงพระบาง
local lp_unmarked_tones = { -- M,L,H
live = { "˩˨", "˩˨", "˥˧˧" },
dead_short = { "˩˨", "˧˨", "˩˨" },
dead_long = { "˥˥˨", "˧˦", "˥˥˨" },
}
local lp_marked_tones = { -- M,L,H
["່"] = { "˧˨", "˧˨", "˧˨" },
["້"] = { "˧˦", "˧˦", "˥˥˨" },
["໊"] = { "˧˦", "˧˦", "˧˦" },
["໋"] = { "˩˨", "˩˨", "˩˨" },
}
function export.show(frame)
local accents = {"เวียงจันทน์", "หลวงพระบาง"}
local output = {}
for _,accent in ipairs(accents) do
table.insert(output, toIPA(frame, accent))
end
-- reduced hyphenation (FIXME: Use the standard module)
table.insert(output, "* การแบ่งพยางค์: <span class='Laoo lo-reading' lang='lo'>" .. (frame:getParent().args[1] or PAGENAME) .. "</span>")
-- global var trick (FIXME: YUCK, clean this up)
local rhymes
if rhyme == "aɰ" then
rhymes = {{rhyme = "aj"}, {rhyme = rhyme}}
elseif rhyme and not find(rhyme, "^#") then
rhymes = {{rhyme = rhyme}}
end
table.insert(output, "* " .. require("Module:rhymes").format_rhymes {
lang = lang,
rhymes = rhymes,
})
return table.concat(output, "\n")
end
function toIPA(frame, accent)
local args = frame:getParent().args
local text = args[1] or PAGENAME -- supports only one pronunciation
local debug = args["d"] or nil
local unmarked_tones, marked_tones
if accent == "เวียงจันทน์" then
unmarked_tones, marked_tones = vt_unmarked_tones, vt_marked_tones
text = gsub(text, "ໃ", "ໄ")
elseif accent == "หลวงพระบาง" then
unmarked_tones, marked_tones = lp_unmarked_tones, lp_marked_tones
else
error("The accent " .. accent .. " is not accepted.")
end
local ipa = {}
for syl in mw.text.gsplit(text, "[ %.%-]") do
for _, v in ipairs(pre) do
syl = mw.ustring.gsub(syl, v[1], v[2])
end
local i, v, f, t = mw.ustring.match(syl, "^([ກ-ຮໜໝ][ຣລວຼ]?)('?[ະ-ູົ-ໄໍຍວອຽ]*)(%+?[ກດບງນມຍຽວສ]?)([່້໊໋]?)$")
if find(i, ".[ຣລຼ]$") then
error("The -ຣ-, -ລ- medials are either unpronounced or disyllabic. Please respell.")
end
if find(i, "^[ກຈດຕບປຢອ]ວ?$") then -- middle class
tn = 1
elseif find(i, "^[ຄຊທພຟຮງຍນມຣລວ]ວ?$") then -- low class
tn = 2
else --high class
tn = 3
end
if find(i, ".ວ$") then
if v == "" then
i = sub(i, 1, -2)
v = "ວ"
elseif v == "ຍ" then
i = sub(i, 1, -2)
v = "ວ"
f = "ຍ"
elseif v == "າ" then -- Cwaa > Cuua
i = sub(i, 1, -2)
v = "ວ"
elseif v == "າຍ" then -- Cwaa > Cuua
i = sub(i, 1, -2)
v = "ວ"
f = "ຍ"
end
end
if find(v, "ວ$") and v ~= "ົວ" and v ~= "ວ" and v ~= "'ວ" then
v = sub(v, 1, -2)
f = "ວ"
end
if find(v, "ຍ$") and v ~= "ເຍ" and v ~= "ເັຍ" and v ~= "'ຍ" then
v = sub(v, 1, -2)
f = "ຍ"
end
if find(v, "ຽ$") and v ~= "ັຽ" and v ~= "ເັຽ" and v ~= "ຽ" and v ~= "'ຽ" then
v = sub(v, 1, -2)
f = "ຍ"
end
if f == "" and (v == "ິ" or v == "ຶ" or v == "ຸ" or v == "ເິ" or v == "ເຶອ") then
v = v .. "*" -- added ʔ
end
if t ~= "" then
tm = marked_tones[t]
else
dead = (find(f, "%+?[ກດບ]") or find(vowels[v], "ʔ$"))
long = find(vowels[v], "ː")
tm = unmarked_tones[(dead and (long and "dead_long" or "dead_short") or "live")]
end
if debug then
table.insert(ipa, "["..(i or "-").."]["..(v or "-").."]["..(f or "-").."]["..(t or "-").."]")
else
table.insert(ipa, initials[i] .. vowels[v] .. finals[f] .. tm[tn])
rhyme = vowels[v] .. finals[f] -- It becomes rhyme after the last iteration
end
end
local ipa_final = table.concat(ipa, ".")
ipa_final = gsub(ipa_final, "a(ʔ[˥-˩]+)%.", "a(%1).")
ipa_final = "[" .. ipa_final .. "]"
return "* " .. require("Module:IPA").format_IPA_full {
lang = lang,
items = {{pron = ipa_final}},
a = {accent},
} .. (#ipa > 0 and require("Module:utilities").format_categories({"ศัพท์ภาษาลาวที่มี " .. #ipa .. " พยางค์"}, lang) or "")
end
return export