Module:vi-pron

local export = {}

local m_str_utils = require("Module:string utilities") local IPA_module = "Module:IPA" local parse_utilities_module = "Module:parse utilities"

local lang = require("Module:languages").getByCode("vi")

local ugcodepoint = m_str_utils.gcodepoint local rsubn = m_str_utils.gsub local rsplit = m_str_utils.split local ulen = m_str_utils.len local ulower = m_str_utils.lower local rmatch = m_str_utils.match local usub = m_str_utils.sub local toNFC = mw.ustring.toNFC local toNFD = mw.ustring.toNFD local u = m_str_utils.char

local function rsub(str, from, to) return (rsubn(str, from, to)) end

local function track(page) require("Module:debug/track")("vi-pron/" .. page) return true end

local function split_on_comma(term) if not term then return nil end if term:find(",%s") then return require(parse_utilities_module).split_on_comma(term) elseif term:find(",") then return rsplit(term, ",") else return {term} end end

--àằầèềìòồờùừỳ áắấéếíóốớúứý ảẳẩẻểỉỏổởủửỷ ãẵẫẽễĩõỗỡũữỹ ạặậẹệịọộợụựỵ local tone_diacritics = { [u(0x0300)] = 2, -- grave accent = ◌̀ [u(0x0301)] = 3, -- acute accent = ◌́ [u(0x0309)] = 4, -- hook above = ◌̉ [u(0x0303)] = 5, -- tilde = ◌̃ [u(0x0323)] = 6, -- dot under = ◌̣ }

local tone_contour = { ["hn"] = { [1] = "˧˧", [2] = "˨˩", ["3a"] = "˧˦", [3] = "˧˦", [4] = "˧˩", [5] = "˦ˀ˥", [6] = "˧˨ʔ" }, ["hue"] = { [1] = "˧˧", [2] = "˦˩", ["3a"] = "˦˧˥", [3] = "˨˩˦", [4] = "˧˨", [5] = "˧˨", [6] = "˨˩ʔ" }, ["hcmc"] = { [1] = "˧˧", [2] = "˨˩", ["3a"] = "˦˥", [3] = "˦˥", [4] = "˨˩˦", [5] = "˨˩˦", [6] = "˨˩˨" }, }

local initial_ipa = { ["b"] = { "ʔɓ", "ʔɓ", "ʔɓ" }, ["c"] = { "k", "k", "k" }, ["ch"] = { "t͡ɕ", "t͡ɕ", "c" }, ["d"] = { "z", "j", "j" }, ["đ"] = { "ʔɗ", "ʔɗ", "ʔɗ" }, ["g"] = { "ɣ", "ɣ", "ɣ" }, ["gh"] = { "ɣ", "ɣ", "ɣ" }, ["gi"] = { "z", "j", "j" }, ["gy"] = { "z", "j", "j" }, ["h"] = { "h", "h", "h" }, ["k"] = { "k", "k", "k" }, ["kh"] = { "x", "kʰ", "kʰ" }, ["l"] = { "l", "l", "l" }, ["m"] = { "m", "m", "m" }, ["n"] = { "n", "n", "n" }, ["ng"] = { "ŋ", "ŋ", "ŋ" }, ["ngh"] = { "ŋ", "ŋ", "ŋ" }, ["nh"] = { "ɲ", "ɲ", "ɲ" }, ["p"] = { "p", "p", "p" }, -- foreign ["ph"] = { "f", "f", "f" }, ["q"] = { "k", "k", "k" }, ["qu"] = { "kw", "kw", "w" }, ["r"] = { "z", "ʐ", "ɹ" }, ["ŕ"] = { "ɹ", "ɹ", "ɹ" }, ["s"] = { "s", "ʂ", "ʂ" }, ["t"] = { "t", "t", "t" }, ["th"] = { "tʰ", "tʰ", "tʰ" }, ["tr"] = { "t͡ɕ", "ʈ", "ʈ" }, ["v"] = { "v", "v", "v" }, ["x"] = { "s", "s", "s" }, ["z"] = { "z", "z", "z" }, [""] = { "ʔ", "ʔ", "ʔ" }, ["-"] = { "", "", "" }, }

local mvi_initial_ipa = { ["ꞗ"] = "β", ["Ꞗ"] = "β", ["b"] = "ɓ", ["c"] = "k", ["ch"] = "c", ["d"] = "ð", ["đ"] = "ɗ", ["g"] = "ɣ", ["gh"] = "ɣ", ["gi"] = "ʝ", ["h"] = "h", ["k"] = "k", ["kh"] = "kʰ", ["l"] = "l", ["m"] = "m", ["n"] = "n", ["ng"] = "ŋ", ["ngh"] = "ŋ", ["nh"] = "ɲ", ["p"] = "p", ["ph"] = "pʰ", ["r"] = "ɹ", ["s"] = "ʂ", ["t"] = "t", ["th"] = "tʰ", ["tr"] = "ʈ", ["v"] = "w", ["x"] = "ɕ", }

local final_ipa = { ["a"] = { "aː", "aː", "aː" }, ["ac"] = { "aːk̚", "aːk̚", "aːk̚" }, ["ach"] = { "ajk̟̚", "at̚", "at̚" }, ["ai"] = { "aːj", "aːj", "aːj" }, ["am"] = { "aːm", "aːm", "aːm" }, ["an"] = { "aːn", "aːŋ", "aːŋ" }, ["ań"] = { "aːn", "aːn", "aːn" }, ["ang"] = { "aːŋ", "aːŋ", "aːŋ" }, ["anh"] = { "ajŋ̟", "ɛɲ", "an" }, ["ao"] = { "aːw", "aːw", "aːw" }, ["ao᷄"] = { "awŋ͡m", "", "" }, ["ap"] = { "aːp̚", "aːp̚", "aːp̚" }, ["at"] = { "aːt̚", "aːk̚", "aːk̚" }, ["au"] = { "aw", "aw", "a(ː)w" }, ["ay"] = { "aj", "aj", "a(ː)j" }, ["ăc"] = { "ak̚", "ak̚", "ak̚" }, ["ăm"] = { "am", "am", "am" }, ["ăn"] = { "an", "aŋ", "aŋ" }, ["ăng"] = { "aŋ", "aŋ", "aŋ" }, ["ăp"] = { "ap̚", "ap̚", "ap̚" }, ["ăt"] = { "at̚", "ak̚", "ak̚" }, ["â"] = { "ə", "ə", "ə" }, ["âc"] = { "ək̚", "ək̚", "ək̚" }, ["âm"] = { "əm", "əm", "əm" }, ["ân"] = { "ən", "əŋ", "əŋ" }, ["âng"] = { "əŋ", "əŋ", "əŋ" }, ["âp"] = { "əp̚", "əp̚", "əp̚" }, ["ât"] = { "ət̚", "ək̚", "ək̚" }, ["âu"] = { "əw", "əw", "əw" }, ["ây"] = { "əj", "əj", "əj" }, ["e"] = { "ɛ", "ɛ", "ɛ" }, ["ec"] = { "ɛk̚", "ɛk̚", "ɛk̚" }, ["em"] = { "ɛm", "ɛm", "ɛm" }, ["en"] = { "ɛn", "ɛŋ", "ɛŋ" }, ["eń"] = { "ɛn", "ɛn", "ɛn" }, ["eng"] = { "ɛŋ", "ɛŋ", "ɛŋ" }, ["eo"] = { "ɛw", "ɛw", "ɛw" }, ["ep"] = { "ɛp̚", "ɛp̚", "ɛp̚" }, ["et"] = { "ɛt̚", "ɛt̚", "ɛk̚" }, ["ê"] = { "e", "ej", "ej" }, ["êc"] = { "ek̚", "ek̚", "ek̚" }, ["êch"] = { "əjk̟̚", "et̚", "əːt̚" }, ["êm"] = { "em", "em", "em" }, ["ên"] = { "en", "en", "əːn" }, ["êng"] = { "eŋ", "eŋ", "eŋ" }, ["ênh"] = { "əjŋ̟", "en", "əːn" }, ["êp"] = { "ep̚", "ep̚", "ep̚" }, ["êt"] = { "et̚", "et̚", "əːt̚" }, ["êu"] = { "ew", "ew", "ew" }, ["i"] = { "i", "ɪj", "ɪj" }, ["ia"] = { "iə", "iə", "iə" }, ["ic"] = { "ïk̟̚", "ïk̟̚", "ïk̟̚" }, ["ich"] = { "ïk̟̚", "ɨt̚", "ɨt̚" }, ["iêc"] = { "iək̚", "iək̚", "iək̚" }, ["iêm"] = { "iəm", "iəm", "im" }, ["iên"] = { "iən", "iəŋ", "iəŋ" }, ["iêng"] = { "iəŋ", "iəŋ", "iəŋ" }, ["iêp"] = { "iəp̚", "iəp̚", "ip̚" }, ["iêt"] = { "iət̚", "iək̚", "iək̚" }, ["iêu"] = { "iəw", "iw", "iw" }, ["im"] = { "im", "im", "im" }, ["in"] = { "in", "in", "ɨn" }, ["inh"] = { "ïŋ", "ɨn", "ɨn" }, ["ip"] = { "ip̚", "ip̚", "ip̚" }, ["it"] = { "it̚", "it̚", "ɨt̚" }, ["iu"] = { "iw", "iw", "iw" }, ["o"] = { "ɔ", "ɔ", "ɔ" }, ["oa"] = { "waː", "waː", "waː" }, ["oac"] = { "waːk̚", "waːk̚", "waːk̚" }, ["oach"] = { "wajk̟̚", "wat̚", "wat̚" }, ["oai"] = { "waːj", "waːj", "waːj" }, ["oam"] = { "waːm", "waːm", "waːm" }, ["oan"] = { "waːn", "waːŋ", "waːŋ" }, ["oang"] = { "waːŋ", "waːŋ", "waːŋ" }, ["oanh"] = { "wajŋ̟", "wɛɲ", "wan" }, ["oao"] = { "waːw", "waːw", "waːw" }, ["oap"] = { "waːp̚", "waːp̚", "waːp̚" }, ["oat"] = { "waːt̚", "waːk̚", "waːk̚" }, ["oay"] = { "waj", "waj", "waj" }, ["oă"] = { "wa", "wa", "wa" }, ["oăc"] = { "wak̚", "wak̚", "wak̚" }, ["oăm"] = { "wam", "wam", "wam" }, ["oăn"] = { "wan", "waŋ", "waŋ" }, ["oăng"] = { "waŋ", "waŋ", "waŋ" }, ["oăt"] = { "wat̚", "wak̚", "wak̚" }, ["oc"] = { "awk͡p̚", "awk͡p̚", "awk͡p̚" }, ["oe"] = { "wɛ", "wɛ", "wɛ" }, ["oem"] = { "wɛm", "wɛm", "wɛm" }, ["oen"] = { "wɛn", "wɛŋ", "wɛŋ" }, ["oeo"] = { "wɛw", "wɛw", "wɛw" }, ["oet"] = { "wɛt̚", "wɛk̚", "wɛk̚" }, ["oi"] = { "ɔj", "ɔj", "ɔj" }, ["om"] = { "ɔm", "ɔm", "ɔm" }, ["on"] = { "ɔn", "ɔŋ", "ɔŋ" }, ["ong"] = { "awŋ͡m", "awŋ͡m", "awŋ͡m" }, ["ooc"] = { "ɔk̚", "ɔk̚", "ɔk̚" }, ["oong"] = { "ɔŋ", "ɔŋ͡m", "ɔŋ" }, ["op"] = { "ɔp̚", "ɔp̚", "ɔp̚" }, ["ot"] = { "ɔt̚", "ɔk̚", "ɔk̚" }, ["ô"] = { "o", "ow", "ow" }, ["ôc"] = { "əwk͡p̚", "əwk͡p̚", "əwk͡p̚" }, ["ôi"] = { "oj", "oj", "oj" }, ["ôm"] = { "om", "om", "om" }, ["ôn"] = { "on", "oŋ", "oŋ" }, ["ôń"] = { "on", "on", "on" }, ["ông"] = { "əwŋ͡m", "əwŋ͡m", "əwŋ͡m" }, ["ôôc"] = { "ok̚", "ok̚", "ok̚" }, ["ôông"] = { "oŋ", "oŋ", "oŋ" }, ["ôp"] = { "op̚", "op̚", "op̚" }, ["ôt"] = { "ot̚", "ok̚", "ok̚" }, ["ơ"] = { "əː", "əː", "əː" }, ["ơi"] = { "əːj", "əːj", "əːj" }, ["ơm"] = { "əːm", "əːm", "əːm" }, ["ơn"] = { "əːn", "əːŋ", "əːŋ" }, ["ơng"] = { "əːŋ", "əːŋ", "əːŋ" }, ["ơp"] = { "əːp̚", "əːp̚", "əːp̚" }, ["ơt"] = { "əːt̚", "əːk̚", "əːk̚" }, ["u"] = { "u", "ʊw", "ʊw" }, ["ua"] = { "uə", "uə", "uə" }, ["uac"] = { "waːk̚", "waːk̚", "waːk̚" }, ["uach"] = { "wajk̟̚", "wat̚", "wat̚" }, ["uai"] = { "waːj", "waːj", "waːj" }, ["uan"] = { "waːn", "waːŋ", "waːŋ" }, ["uang"] = { "waːŋ", "waːŋ", "waːŋ" }, ["uanh"] = { "wajŋ̟", "wɛɲ", "wan" }, ["uao"] = { "waːw", "waːw", "waːw" }, ["uap"] = { "waːp̚", "waːp̚", "waːp̚" }, ["uat"] = { "waːt̚", "waːk̚", "waːk̚" }, ["uau"] = { "waw", "waw", "wa(ː)w" }, ["uay"] = { "waj", "waj", "waj" }, ["uă"] = { "wa", "wa", "wa" }, ["uăc"] = { "wak̚", "wak̚", "wak̚" }, ["uăm"] = { "wam", "wam", "wam" }, ["uăn"] = { "wan", "waŋ", "waŋ" }, ["uăng"] = { "waŋ", "waŋ", "waŋ" }, ["uăp"] = { "wap̚", "wap̚", "wap̚" }, ["uăt"] = { "wat̚", "wak̚", "wak̚" }, ["uâ"] = { "wə", "wə", "wə" }, ["uâc"] = { "wək̚", "wək̚", "wək̚" }, ["uân"] = { "wən", "wəŋ", "wəŋ" }, ["uâng"] = { "wəŋ", "wəŋ", "wəŋ" }, ["uât"] = { "wət̚", "wək̚", "wək̚" }, ["uây"] = { "wəj", "wəj", "wəj" }, ["uc"] = { "ʊwk͡p̚", "ʊwk͡p̚", "ʊwk͡p̚" }, ["ue"] = { "wɛ", "wɛ", "wɛ" }, ["uen"] = { "wɛn", "wɛŋ", "wɛŋ" }, ["ueo"] = { "wɛw", "wɛw", "wɛw" }, ["uep"] = { "wɛp̚", "wɛp̚", "wɛp̚" }, ["uet"] = { "wɛt̚", "wɛt̚", "wɛt̚" }, ["uê"] = { "we", "wej", "wej" }, ["uêch"] = { "wəjk̟̚", "wet̚", "wəːt̚" }, ["uên"] = { "wen", "wen", "wəːn" }, ["uênh"] = { "wəjŋ̟", "wen", "wəːn" }, ["uêt"] = { "wet̚", "wet̚", "wəːt̚" }, ["uêu"] = { "weu", "weu", "wew" }, ["ui"] = { "uj", "uj", "uj" }, ["uin"] = { "win", "win", "wɨn" }, ["uit"] = { "wit̚", "wit̚", "wit̚" }, ["um"] = { "um", "um", "ʊm" }, ["un"] = { "un", "un", "ʊwŋ͡m" }, ["ung"] = { "ʊwŋ͡m", "ʊwŋ͡m", "ʊwŋ͡m" }, ["unh"] = { "ujŋ̟", "un", "uwn" }, ["uo"] = { "wɔ", "wɔ", "wɔ" }, ["uô"] = { "uə", "uə", "uə" }, ["uôc"] = { "uək̚", "uək̚", "uək̚" }, ["uôi"] = { "uəj", "uj", "uj" }, ["uôm"] = { "uəm", "uəm", "uəm" }, ["uôn"] = { "uən", "uəŋ", "uəŋ" }, ["uông"] = { "uəŋ", "uəŋ", "uəŋ" }, ["uôt"] = { "uət̚", "uək̚", "uək̚" }, ["uơ"] = { "wəː", "wəː", "wəː" }, ["uơi"] = { "wəːj", "wəːj", "wəːj" }, ["uơn"] = { "wəːn", "wəːŋ", "wəːŋ" }, ["uơt"] = { "wəːt̚", "wəːk̚", "wəːk̚" }, ["up"] = { "up̚", "up̚", "ʊp̚" }, ["ut"] = { "ut̚", "ʊk̚", "ʊk͡p̚" }, ["uy"] = { "wi", "wɪj", "wɪj" }, ["uya"] = { "wiə", "wiə", "wiə" }, ["uych"] = { "wïk̟̚", "wɨk̟̚", "wɨt̚" }, ["uyn"] = { "win", "win", "wɨn" }, ["uich"] = { "wïk̟̚", "wɨk̟̚", "wɨt̚" }, ["uyê"] = { "wiə", "wiə", "wiə" }, ["uyên"] = { "wiən", "wiəŋ", "wiəŋ" }, ["uyênh"] = { "wiəŋ̟", "wiən", "wən" }, ["uyêt"] = { "wiət̚", "wiək̚", "wiək̚" }, ["uynh"] = { "wïŋ̟", "wɨn", "wɨn" }, ["uyp"] = { "wip̚", "wip̚", "wip̚" }, ["uyt"] = { "wit̚", "wɨt̚", "wɨt̚" }, ["uyu"] = { "wiw", "wiw", "wiw" }, ["ư"] = { "ɨ", "ɨ", "ɨ" }, ["ưa"] = { "ɨə", "ɨə", "ɨə" }, ["ưc"] = { "ɨk̚", "ɨk̚", "ɨk̚" }, ["ưi"] = { "ɨj", "ɨj", "ɨj" }, ["ưm"] = { "ɨm", "ɨm", "ɨm" }, ["ưn"] = { "ɨn", "ɨŋ", "ɨŋ" }, ["ưng"] = { "ɨŋ", "ɨŋ", "ɨŋ" }, ["ươc"] = { "ɨək̚", "ɨək̚", "ɨək̚" }, ["ươi"] = { "ɨəj", "ɨj", "ɨj" }, ["ươm"] = { "ɨəm", "ɨəm", "ɨəm" }, ["ươn"] = { "ɨən", "ɨəŋ", "ɨəŋ" }, ["ương"] = { "ɨəŋ", "ɨəŋ", "ɨəŋ" }, ["ươp"] = { "ɨəp̚", "ɨəp̚", "ɨəp̚" }, ["ươt"] = { "ɨət̚", "ɨək̚", "ɨək̚" }, ["ươu"] = { "iəw", "ɨəw", "ɨəw" }, ["ưt"] = { "ɨt̚", "ɨk̚", "ɨk̚" }, ["ưu"] = { "iw", "ɨw", "ɨw" }, ["y"] = { "i", "ɪj", "ɪj" }, ["yêc"] = { "iək̚", "iək̚", "iək̚" }, ["yêm"] = { "iəm", "iəm", "iəm" }, ["yên"] = { "iən", "iəŋ", "iəŋ" }, ["yêng"] = { "iəŋ", "iəŋ", "iəŋ" }, ["yêp"] = { "iəp̚", "iəp̚", "iəp̚" }, ["yêt"] = { "iət̚", "iək̚", "iək̚" }, ["yêu"] = { "iəw", "iw", "iw" }, }

local varieties = { ["hn"] = { "Hà Nội", 1 }, ["hue"] = { "Huế", 2 }, ["hcmc"] = { "Hồ Chí Minh City", 3 }, }

local hcmc_opt_w = { ["ch"] = true, ["d"] = true, ["l"] = true, ["s"] = true, ["t"] = true, ["th"] = true, ["tr"] = true, ["x"] = true, }

local variations = { ["hn"] = { { "^ɹ", "z" }, { " ɹ", " z" } }, ["hue"] = { { "z", "j" }, { "ʂ", "s" }, { "kʰ", "x" }, { "awŋ͡m", "ɔŋ" } }, ["hcmc"] = { { "ʂ", "s" }, { "v", "j" }, { "kʰ", "x" }, { "z", "j" } }, }

function export.ipa(frame) local respellings = {} local variety_respellings = {} local output = {} for variety, _ in pairs(varieties) do		output[variety] = {} end local output_text = {} local iparams = { ["mvi"] = {type = "boolean"}, }	local iargs = require("Module:parameters").process(frame.args, iparams)

local params = { [1] = {list = true}, ["hn"] = {}, ["hue"] = {}, ["hcmc"] = {}, ["pagename"] = {}, -- for testing or documentation }	local args = require("Module:parameters").process(frame:getParent.args, params)

local pagename = args.pagename or mw.loadData("Module:headword/data").pagename

local function canonicalize_respelling(respelling) if respelling:find("^raw:") then return {raw = (respelling:gsub("^raw:", ""))} else if respelling == "+" then respelling = pagename end return {respelling = rsub(rsub(ulower(respelling), "%-", " "), ",", "")} end end

local mvi = iargs.mvi local raw_respellings = args[1] if not raw_respellings[1] then raw_respellings = {"+"} end for _, raw_respelling in ipairs(raw_respellings) do		table.insert(respellings, canonicalize_respelling(raw_respelling)) end for variety, _ in pairs(varieties) do		if args[variety] == "-" or (mvi and (variety == "hue" or variety == "hcmc")) then variety_respellings[variety] = false elseif args[variety] then local variety_raw_respellings = split_on_comma(args[variety]) variety_respellings[variety] = {} for _, raw_respelling in ipairs(variety_raw_respellings) do				table.insert(variety_respellings[variety], canonicalize_respelling(raw_respelling)) end end end

for variety, location in pairs(varieties) do		if variety_respellings[variety] == false then -- skip variety output[variety] = false else local var_respellings = variety_respellings[variety] or respellings for i, spec in ipairs(var_respellings) do				local pronunciation = {} if spec.raw then table.insert(output[variety], spec.raw) else for syllable in mw.text.gsplit(spec.respelling, " ", true) do						local ipa = {} local initial, final, tone = nil, nil, nil tone = 1 syllable = toNFD(syllable) syllable = rsub(syllable, "([nr]́)", toNFC)

for diac_pattern, tone_num in pairs(tone_diacritics) do							if rmatch(syllable, diac_pattern) then tone = tone_num break end end syllable = toNFC(rsub(syllable, "[̣̀́̉̃]", "")) if syllable == "gi" or syllable == "gin" then syllable = rsub(syllable, "gi", "gii") end initial = rmatch(syllable, "^g[ꞗꞖbcdđgklmnpqrŕstvx]+") or rmatch(syllable, "^(g[hiy])[^cmnpt]") or rmatch(syllable, "^g") or rmatch(syllable, "^[ꞗꞖbcdđghklmnpqrŕstvxz]+") or "" initial = (rmatch(syllable, "^giê.") and syllable ~= "giên") and "d" or initial initial = rmatch(syllable, "qu$") and "qu" or initial final = usub(syllable, ulen(initial) + 1, -1) local ipa, seq, detoned = {}, location[2], "" if mvi then if mvi_initial_ipa[initial] then table.insert(ipa, mvi_initial_ipa[initial]) else local initial_cluster = "" for cc in ugcodepoint(initial) do									local ch = u(cc) initial_cluster = initial_cluster .. mvi_initial_ipa[ch] end table.insert(ipa, initial_cluster) end elseif initial_ipa[initial] then table.insert(ipa, initial_ipa[initial][seq]) else local initial_cluster = "" initial = rsub(initial, "r$", "ŕ") for cc in ugcodepoint(initial) do								local ch = u(cc) initial_cluster = initial_cluster .. initial_ipa[ch][seq] end initial_cluster = rsub(initial_cluster, "([cgknpt]h)", function(digraph)								return initial_ipa[digraph][seq] end) table.insert(ipa, initial_cluster) end if final_ipa[final] then detoned = rsub(final_ipa[final][seq], "^([wu].+)", function(nucleus)								if initial .. final == "qua" then									nucleus = final_ipa["oa"][seq]								elseif initial .. final == "qui" then									nucleus = final_ipa["uy"][seq]								end								if variety == "hcmc" then									if initial == "q" then										nucleus = rsub(nucleus, "^u", "w")										end									if hcmc_opt_w[initial] then										nucleus = rsub(nucleus, "^w", "⁽ʷ⁾")									end								end								return nucleus end) table.insert(ipa, detoned) else error(("Unrecognised final: \"%s\""):format(final)) end if tone == 3 and rmatch(final, "[chmngpt]") then tone = "3a" end table.insert(ipa, tone_contour[variety][tone]) table.insert(pronunciation, table.concat(ipa, "")) end table.insert(output[variety], "[" .. table.concat(pronunciation, " ") .. "]") end end end end

for variety, location in pairs(varieties) do		if mvi and variety == "hn" then location[1] = "Đông Kinh" end if output[variety] ~= false then local ipa_items = {} for i, out in ipairs(output[variety]) do				if variety == "hcmc" then -- FIXME: Move this up to the pronunciation-computing loop. out = rsub(out, "[hk]w", "w") out = rsub(out, "ʔw", "(ʔ)w") end table.insert(ipa_items, {pron = out, separator = i == 1 and "" or ", "}) local alternative = out for _, variation in ipairs(variations[variety]) do					alternative = rsub(alternative, variation[1], variation[2]) end if alternative ~= out then table.insert(ipa_items, {pron = alternative, separator = " ~ "}) end end table.insert(output_text, location[2], "\n* " .. require("Module:IPA").format_IPA_full {				lang = lang,				a = {location[1]},				items = ipa_items,				separator = "",			}) else table.insert(output_text, location[2], "") end end local saw_raw = false local actual_respellings = {} for _, spec in ipairs(respellings) do		if spec.raw then saw_raw = true break else table.insert(actual_respellings, spec.respelling) end end if not saw_raw and table.concat(actual_respellings, "") ~= ulower(pagename) then table.insert(output_text, #output_text + 1, "\n* Phonetic spelling: " .. rsub(table.concat(actual_respellings, ", "), "ŕ", "R")) end return rsub(table.concat(output_text, ""), "^\n(.)", "%1") end

return export