Returns the IPA phonetic transcription for a given word in White Hmong.

Powers {{mww-pron}}.


local export = {}

local m_IPA = require("Module:IPA")
local lang = require("Module:languages").getByCode("mww")

local vowels = {
    -- Oral vowels
	["a"] = "a", ["e"] = "e", ["i"] = "i", ["o"] = "ɒ", ["u"] = "u", ["w"] = "ɨ",
	-- Nasal vowels
	["ee"] = "ẽ", ["oo"] = "ɒ̃",
	-- Diphthongs
	["ai"] = "ai̯", ["au"] = "au̯", ["aw"] = "aɨ̯", ["ia"] = "iə̯", ["ua"] = "uə̯",
	[""] = "",
}

local consonants = {
	-- Voiced stops
	["d"] = "d", ["dh"] = "dʱ",
	-- Voiceless stops
	["p"] = "p", ["t"] = "t", ["r"] = "ʈ", ["c"] = "c", ["k"] = "k", ["q"] = "q",
	-- Aspirated consonants
	["ph"] = "pʰ", ["th"] = "tʰ", ["rh"] = "ʈʰ", ["ch"] = "cʰ", ["kh"] = "kʰ", ["qh"] = "qʰ", 
	-- Nasals
	["m"] = "m", ["n"] = "n", ["ny"] = "ɲ",
	-- Aspirated nasals
	["hm"] = "m̥", ["hn"] = "n̥", ["hny"] = "ɲ̊",
	-- Fricatives
	["f"] = "f", ["v"] = "v", ["s"] = "ʂ", ["x"] = "s", ["xy"] = "ç", ["z"] = "ʐ", ["y"] = "ʝ",
	-- Affricates
	["ts"] = "t͡ʂ", ["tx"] = "t͡s",
	-- Aspirated affricates 
	["tsh"] = "t͡ʂʰ", ["txh"] = "t͡sʰ",
	-- Palatalized allophones
	["xy*"] = "ɕ", ["txy"] = "t͡ɕ", ["txhy"] = "t͡ɕʰ", ["ntxy"] = "ⁿd͡ʑ", ["ntxhy"] = "ⁿt͡ɕʰ",
	-- Aspirate
	["h"] = "h",
	-- Laterals
	["l"] = "l", ["ml"] = "mˡ", ["pl"] = "pˡ",
	-- Aspirated laterals
	["hl"] = "l̥",[ "hml"] = "m̥ˡ", ["plh"] = "pˡʰ",
	-- Pre-nasalized stops
	["np"] = "ᵐb", ["nt"] = "ⁿd", ["nr"] = "ᶯɖ", ["nc"] = "ᶮɟ", ["nk"] = "ᵑɡ", ["nq"] = "ᶰɢ",
	-- Aspirated pre-nasalized stops
	["nph"] = "ᵐpʰ", ["nth"] = "ⁿtʰ", ["nrh"] = "ᶯʈʰ", ["nch"] = "ᶮcʰ", ["nkh"] = "ᵑkʰ", ["nqh"] = "ᶰqʰ",
	-- Pre-nasalized laterals
	["npl"] = "ᵐbˡ",
	-- Aspirated pre-nasalized laterals
	["nplh"] = "ᵐpˡʰ",
	-- Pre-nasalized affricates
	["nts"] = "ᶯd͡ʐ", ["ntx"] = "ⁿd͡z",
	-- Aspirated pre-nasalized affricate
	["ntsh"] = "ᶯt͡ʂʰ", ["ntxh"] = "ⁿt͡sʰ",
	-- None
	[""] = "ʔ"
}

local tones = {
	["b"] = "˥", ["j"] = "˥˧", ["v"] = "˧˦", [""] = "˧",
	["s"] = "˩", ["g"] = "˧˩̤", ["m"] = "˩̰", ["d"] = "˨˩˧",
}

-- Applies morphophonological rules
local function apply_morph(c, v)
	if v == "i" or v == "e" or v == "ia" then
		if c == "x" or c == "xy" then
			c = "xy*"
		elseif c == "tx" or c == "txh" or c == "ntx" or c == "ntxh" then
			c = c .. "y"
		end
	end
	return c
end

-- Parses a string of words and maps every letter or combination of letters into an IPA equivalent
local function parse(s)
	local ipa = ""
	s = s:lower()

	for syl in mw.text.gsplit(s, "[ %.%-]") do
		local c, v, t = syl:match("([cdfghklmnpqrstvxyz]*)([aeiouw]+n?)([bjvsgmd]?)")
		c = apply_morph(c, v)
		if ipa == "" then
			if pcall(function() ipa = consonants[c] .. vowels[v] .. tones[t] end) then do end else return "" end
		else
			if pcall(function() ipa = ipa .. "." .. consonants[c] .. vowels[v] .. tones[t] end) then do end else return "" end
		end
	end
	return ipa
end

function export.show(frame)
	local params = {
		[1] = {alias_of = 'w'},
		w = {default = mw.title.getCurrentTitle().text}
	}
	
	local args = require("Module:parameters").process(frame:getParent().args, params)
	local IPA_args = {{pron = '/' .. parse(args.w) .. '/'}}
	return '* ' .. m_IPA.format_IPA_full { lang = lang, items = IPA_args }
end

return export