local export = {}
local m_string_utils = require("Module:string utilities")
local gsub = m_string_utils.gsub
local gsplit = mw.text.gsplit
local match = m_string_utils.match
local lower = m_string_utils.lower
local toNFC = mw.ustring.toNFC
local toNFD = mw.ustring.toNFD
local initial_ipa = {
["b"] = "p", ["p"] = "pʰ", ["m"] = "m",
["d"] = "t", ["t"] = "tʰ", ["n"] = "n", ["l"] = "l",
["c"] = "t͡s", ["ch"] = "t͡sʰ", ["s"] = "s",
["g"] = "k", ["k"] = "kʰ", ["ng"] = "ŋ", ["h"] = "x",
[""] = "",
}
local final_ipa = {
["i"] = "i", ["u"] = "u", ["ṳ"] = "y",
["a"] = "a", ["ia"] = "ia", ["ua"] = "ua",
["a̤"] = "ɛ", ["ie"] = "iɛ", ["uoi"] = "uɛ", ["ṳe"] = "yɛ",
["o̤"] = "ɔ", ["io̤"] = "iɔ",
["e"] = "e", ["e̤"] = "œ", ["o"] = "o",
["ai"] = "ai", ["uai"] = "uai",
["au"] = "au", ["iau"] = "iau",
["iu"] = "iu",
["ing"] = "iŋ", ["uing"] = "uiŋ", ["ṳing"] = "yiŋ",
["ang"] = "aŋ", ["iang"] = "iaŋ", ["uang"] = "uaŋ",
["o̤ng"] = "ɔŋ", ["ong"] = "ɔŋ", ["io̤ng"] = "iɔŋ", ["iong"] = "iɔŋ", ["uo̤ng"] = "uɔŋ",
["eng"] = "eiŋ", --missing /ieiŋ/
["e̤ng"] = "œyŋ",
["aing"] = "aiŋ", ["uaing"] = "uaiŋ",
}
local tone_marks = "[́̂̌̿̄̆̀]"
local tone_from_mark = {
["́"] = 1, --陰平 (acute)
["̂"] = 3, --陽平 (circumflex)
["̌"] = 2, --上 (caron)
["̿"] = 3, --陰去 (double overline)
["̄"] = 4, --陽去 (macron)
["̆"] = 5, --陰入 (breve)
["̀"] = 6, --陽入 (grave)
}
local tone_value = {
[1] = "⁵⁴", --陰平
[2] = "²¹", --上
[3] = "³³", --陰去
[4] = "⁵⁵", --陽去
[5] = "²⁴", --陰入
[6] = "⁴²", --陽入
}
--[=[
Given a syllable, return tone value of the syllable's tone and the syllable without the tone mark
]=]
local function get_tone_value(syllable)
if match(syllable, "̄̄") then -- check for double macron
local corrected = gsub(syllable, "̄̄", "̿")
error("Please change " .. syllable .. " to " .. corrected .. ".")
end
local tone = match(syllable, tone_marks)
if tone then
return tone_value[tone_from_mark[tone]], gsub(syllable, tone, "")
else
error("No tone detected.")
end
end
function export.rom(text)
return (text
:gsub("/", " / ")
:gsub(">([^> %-]+)", "<sup>→%1</sup>"))
end
function export.ipa(text)
text = toNFD(lower(text))
local words_ipa = {}
for word in gsplit(text, "/") do
word = gsub(word, " ", "-")
local syllables_ipa = {}
for syllable in gsplit(word, "-") do
syllable = match(syllable, ">(.*)$") or syllable
local initial, final, tone_value
tone_value, syllable = get_tone_value(syllable)
initial, final = match(syllable, "^([bpmdtnlcsk]?[gh]?)([aeioung̤]+)$")
initial, final = toNFC(initial), toNFC(final)
initial, final = initial_ipa[initial], final_ipa[final]
table.insert(syllables_ipa, initial..final..tone_value)
end
table.insert(words_ipa, table.concat(syllables_ipa, " "))
end
return "/" .. table.concat(words_ipa, "/, /") .. "/"
end
return export