Module:hsn-pron

local m_str_utils = require("Module:string utilities")

local sub = m_str_utils.sub local find = m_str_utils.find local match = m_str_utils.match

local export = {}

local initialConv = { ["b"] = "p", ["p"] = "pʰ", ["m"] = "m", ["f"] = "ɸ", ["d"] = "t", ["t"] = "tʰ", ["l"] = "l", ["z"] = "t͡s", ["c"] = "t͡sʰ", ["s"] = "s", ["zh"] = "ʈ͡ʂ", ["ch"] = "ʈ͡ʂʰ", ["sh"] = "ʂ", ["r"] = "ʐ", ["j"] = "t͡ɕ", ["q"] = "t͡ɕʰ", ["x"] = "ɕ", ["ny"] = "n̠ʲ", ["g"] = "k", ["k"] = "kʰ", ["ng"] = "ŋ", ["h"] = "x", [""] = "" }

local finalConv = { ["r"] = "z̩", ["rr"] = "ʐ̩", ["i"] = "i", ["u"] = "u", ["y"] = "y", ["a"] = "a̠", ["ia"] = "i̯a̠", ["ua"] = "u̯a̠", ["ya"] = "y̯a̠", ["o"] = "o", ["io"] = "i̯o", ["e"] = "ɤ̞", ["ue"] = "u̯ɤ̞", ["ai"] = "ai̯", ["uai"] = "u̯ai̯", ["yai"] = "y̯ai̯", ["ei"] = "e̞i̯", ["uei"] = "u̯e̞i̯", ["yei"] = "y̯e̞i̯", ["au"] = "ɒu̯", ["iau"] = "i̯ɒu̯", ["ou"] = "əu̯", ["iou"] = "i̯əu̯", ["ie"] = "i̯e̞", ["ye"] = "y̯e̞", ["onn"] = "õ", ["enn"] = "ə̃", ["ienn"] = "i̯ẽ", ["yenn"] = "y̯ẽ", ["en"] = "ən", ["un"] = "u̯ən", ["in"] = "in", ["yn"] = "yn", ["an"] = "an", ["ian"] = "i̯æn", ["uan"] = "u̯an", ["yan"] = "y̯æn", ["ong"] = "ʊŋ", ["iong"] = "i̯ʊŋ", ["m"] = "m̩", ["n"] = "n̩", }

local toneConv = { ["1"] = "³³", ["2"] = "¹³", ["3"] = "⁴¹", ["4"] = "⁴⁵", ["5"] = "²¹", ["6"] = "²⁴", ["7"] = "³",	["5-ts"] = "²¹⁻¹¹", ["6-high"] = "²⁴⁻⁴⁴", ["6-low"] = "²⁴⁻²²", ["6*"] = "²⁴", [""] = "" }

function export.ipa(text, style) if type(text) == "table" then text = text.args[1] end local result = {} for word in mw.text.gsplit(text, "/") do		local syllables = mw.text.split(word, " ") local ipa, tone = {}, {} for index, syllable in ipairs(syllables) do			local initial, final initial = syllable:match("^([bpmfdtlnzcsrjqxgkh]?([hgy]?))") if initial:match("^.y") and initial ~= "ny" then initial = sub(initial, 1, 1) elseif initial == "y" then initial = "" end final = syllable:match("^" .. initial .. "([^1-7%*]*)") if final == "" then final = initial initial = "" end if (find(initial, "^[zcs]h$") and find(final, "^i")) or (find(initial, "^[jqx]$") and find(final, "^[aeou]")) or (find(final, "^r$") and not (initial == "" or find(initial, "^[zcs]h?$"))) or (find(final, "^u") and not (initial == "" or find(initial, "^[bpfgk]$"))) or (find(final, "^y") and not (initial == "" or initial == "ny" or find(initial, "^[jqx]$"))) then error("Invalid input \"" .. syllable .. "\": initial " .. initial .. " cannot go with final " .. final .. ".") end tone[index] = syllable:match("[1-7%*]+$") or (index ~= 1 and "7" or "") if style == "new" then initial = initial:gsub("([zcs])h", "%1") if final:match("^i") then initial = initial:gsub("[zcs]$", { ["z"] = "j", ["c"] = "q", ["s"] = "x" }) end final = final:gsub("(i?ong)", { ["iong"] = "in", ["ong"] = "en" }) end initial = initialConv[initial] or error(("Unrecognised initial: \"%s\""):format(initial)) if (initial == "" or match(initial, "[ʂʐ]")) and final == "r" then final = "rr" end final = finalConv[final] or error(("Unrecognised final: \"%s\""):format(final)) if initial == "l" and ((final ~= "ən" and not final:match("^[ii]") and match(final, "[ŋ̃n]")) or final:match("^[ii].*̃")) then initial = "l̃" end if tone[index] == "5" and #syllables > 1 then tone[index] = "5-ts" elseif tone[index] == "6" then if match(tone[index-1] or "", "[126]") then tone[index] = "6-high" elseif match(tone[index-1] or "", "[345]") then tone[index] = "6-low" end end tone[index] = toneConv[tone[index]] or error(("Unrecognised tone: \"%s\""):format(tone[index])) ipa[index] = initial .. final .. tone[index] end table.insert(result, table.concat(ipa, " ")) end return table.concat(result, "/, /") end

function export.rom(text) return (text		:gsub("/", " / ")		:gsub("([%d-]+)", "%1")) end

function export.stylediff(text) if match(text, "[zcs]h") or match(text, "[zcs]i") or match(text, "i?ong") then return true end return false end

return export