Module:zlw-ocs-pronunciation

local export = {}

local m_IPA = require("Module:IPA") local m_table = require("Module:table") local lang = require("Module:languages").getByCode("zlw-ocs")

local U = mw.ustring.char local rsub = mw.ustring.gsub local rlower = mw.ustring.lower local rfind = mw.ustring.find

local raised = U(0x031D) local syllabic = U(0x0329) local consonants = "bdcɟfɡɣxjkɫlmnɲprstʋzʒʃɲʲ" local sconsonants = "bdcɟfɡɣxjkɫmnɲpstʋzʒʃɲʲ" local C = "[" .. consonants .. "]" local sC = "[" .. sconsonants .. "]" local vowels = "aɛiɨou" local V = "[" .. vowels .. "]" local voiceless_consonant = "ptsʃckxf" local voiced_consonant = "bdzʒɟɡɣʋ" local syllabic_consonant = "[mnrlɫ]" .. syllabic

local function track(page) require("Module:debug").track("zlw-ocs-IPA/" .. page) return true end

local function rsub_repeatedly(term, foo, bar) while true do		local new_term = rsub(term, foo, bar) if new_term == term then return term end term = new_term end end local digraphs = { ["ch"] = "x", ["dž"] = "d͡ʒ", ["ie"] = "i̯ɛː", }

local devoicing = { ["d͡z"] = "t͡s", ["d͡ʒ"] = "t͡ʃ", ["b"] = "p", ["d"] = "t", ["z"] = "s", ["ʒ"] = "ʃ", ["ɣ"] = "x", ["g"] = "k", ["ʋ"] = "f", ["ɟ"] = "c", }

local voicing = { ["t͡s"] = "d͡z", ["t͡ʃ"] = "d͡ʒ", ["p"] = "b", ["t"] = "d", ["s"] = "z", ["ʃ"] = "ʒ", ["x"] = "ɣ", ["k"] = "ɡ", ["f"] = "ʋ", ["c"] = "ɟ", }

local function voice_backward(sound, following) return voicing[sound] .. following end

local function devoice_backward(sound, following) return devoicing[sound] .. following end

local function voice_forward(preceding, sound) return preceding .. voicing[sound] end

local function devoice_forward(preceding, sound) return preceding .. devoicing[sound] end

local function final_devoicing(sound, following) return devoicing[sound] .. following .. "#"	end

local function flatmap(items, fun) local new = {} for _, item in ipairs(items) do		local results = fun(item) mw.logObject(results, "results") for _, result in ipairs(results) do			table.insert(new, result) end mw.logObject(new, "new") end return new end

local phon = { ["a"] = "a", ["á"] = "aː", ["b"] = "b", ["b́"] = "bʲ", ["c"] = "t͡s", ["č"] = "t͡ʃ", ["ć"] = "cʲ", ["d"] = "d", ["ď"] = "ɟ", ["e"] = "ɛ", ["é"] = "ɛː", ["ě"] = "i̯ɛ", ["f"] = "f", ["f́"] = "fʲ", ["g"] = "ɡ", ["h"] = "ɣ", ["i"] = "i", ["í"] = "iː", ["j"] = "j", ["k"] = "k", ["l"] = "l", ["ľ"] = "ʎ", ["ł"] = "ɫ", ["m"] = "m", ["ḿ"] = "mʲ", ["n"] = "n", ["ň"] = "ɲ", ["o"] = "o", ["ó"] = "oː", ["p"] = "p", ["ṕ"] = "pʲ", ["r"] = "r", ["ř"] = "r"..raised, ["s"] = "s", ["š"] = "ʃ", ["ś"] = "sʲ", ["t"] = "t", ["ť"] = "c", ["u"] = "u", ["ú"] = "uː", ["v"] = "ʋ", ["v́"] = "ʋʲ", ["y"] = "ɨ", ["ý"] = "ɨː", ["z"] = "z", ["ž"] = "ʒ", ["ź"] = "zʲ", [":"] = "ː", ["?"] = "ʔ" }

function export.phonemic(text, post) text = rlower(text)

text = rsub(text, " | ", "# | #") text = "##" .. rsub(text, " ", "# #") .. "##"

-- basic phonology for digraph, replacement in pairs(digraphs) do		text = rsub(text, digraph, replacement) end text = rsub(text, ".", phon) text = rsub(text, "l([aɨou])", "ɫ%1") text = rsub(text, "l#", "ɫ#") text = rsub(text, "(l)(" .. C .. ")", "ɫ%2") text = rsub(text, "ʎ", "l") -- palatalisation text = rsub(text, "ni", "ɲi") text = rsub(text, "ti", "ci") text = rsub(text, "di", "ɟi") text = rsub(text, "(" .. C .. ")([rlɫ])#", "%0"..syllabic.."#") text = rsub(text, "(" .. C .. ")([rlɫ])(" .. C .. ")", "%1%2"..syllabic.."%3") text = rsub(text, "(" .. sC .. ")([mn])#", "%0"..syllabic.."#") text = rsub(text, "(" .. sC .. ")([mn])(" .. sC .. ")", "%1%2"..syllabic.."%3")

text = rsub(text, "([" .. voiceless_consonant .. "])r̝", "%1r̝̊") text = rsub(text, "'", "ˈ") text = rsub(text, "-", ""); -- suffixes text = rsub(text, "^ˈ%-", "-") if not rfind(text, " ") then text = rsub(text, text, "ˈ" .. text) end

local variants = {text}

local function flatmap_and_sub_pre(from, to1, to2) variants = flatmap(			variants,			function(item)				if rfind(item, from) then					local retval = {rsub_repeatedly(item, from, to1)}					if to2 then						m_table.insertIfNot(retval, rsub_repeatedly(item, from, to2))					end					return retval				else					return {item}				end			end		) end if post ~= nil then if args.desc == "no" then else if args.desc ~= nil then desc = args.desc desc = rlower(desc) desc = rsub(desc, " | ", "# | #") desc = "##" .. rsub(desc, " ", "# #") .. "##"

-- basic phonology for digraph, replacement in pairs(digraphs) do		desc = rsub(desc, digraph, replacement) end desc = rsub(desc, ".", phon) desc = rsub(desc, "l([aɨou])", "ɫ%1") text = rsub(text, "l#", "ɫ#") text = rsub(text, "(l)(" .. C .. ")", "ɫ%2") text = rsub(text, "ʎ", "l") -- palatalisation desc = rsub(desc, "ni", "ɲi") desc = rsub(desc, "ti", "ci") desc = rsub(desc, "di", "ɟi")

desc = rsub(desc, "(" .. C .. ")([rlɫ])#", "%0"..syllabic.."#") desc = rsub(desc, "(" .. sC .. ")([mn])#", "%0"..syllabic.."#") desc = rsub(desc, "'", "ˈ") desc = rsub(desc, "-", "") -- suffixes desc = rsub(desc, "^ˈ%-", "-") if not rfind(desc, " ") then desc = rsub(desc, desc, "ˈ" .. desc) end

variants = {desc} end text = flatmap_and_sub_pre("(" .. C .. ")([rlɫ])(" .. C .. ")", "%1%2"..syllabic.."%3") text = flatmap_and_sub_pre("(" .. sC .. ")([mn])(" .. sC .. ")", "%1%2"..syllabic.."%3") text = flatmap_and_sub_pre("([" .. voiced_consonant .. "])([r̝]?)#", final_devoicing) text = flatmap_and_sub_pre("v([" .. voiceless_consonant .. "])", "f%1") text = flatmap_and_sub_pre("f([" .. voiced_consonant .. "])", "v%1")

text = flatmap_and_sub_pre("([" .. voiced_consonant .. "])([f])", voice_forward) text = flatmap_and_sub_pre("([" .. voiceless_consonant .. "])([v])", devoice_forward)

text = flatmap_and_sub_pre("d͡z([" .. voiceless_consonant .. "])", "t͡s%1") text = flatmap_and_sub_pre("t͡s([bdzʒɟɡɣ])", "d͡z%1") text = flatmap_and_sub_pre("d͡ʒ([" .. voiceless_consonant .. "])", "t͡ʃ%1") text = flatmap_and_sub_pre("t͡ʃ([bdzʒɟɡɣ])", "d͡ʒ%1") text = flatmap_and_sub_pre("([" .. voiced_consonant .. "])([" .. voiceless_consonant .. "])", devoice_backward) text = flatmap_and_sub_pre("([" .. voiceless_consonant .. "])([bdzʒɟɡɣ])", voice_backward)

flatmap_and_sub_pre("-", "") flatmap_and_sub_pre("ɨː", "iː", "ɛj") flatmap_and_sub_pre("ɨ", "i") flatmap_and_sub_pre("lu", "li") flatmap_and_sub_pre("ɫ", "l") flatmap_and_sub_pre("ʲu", "i") flatmap_and_sub_pre("([sz])ʲ", "%1") flatmap_and_sub_pre("ʲ", "j") flatmap_and_sub_pre("([ʒʃjɟcɲ])u", "%1i") flatmap_and_sub_pre("t͡su", "t͡si") flatmap_and_sub_pre("(r"..raised..")u", "%1i") flatmap_and_sub_pre("oː", "u̯o") flatmap_and_sub_pre("uː", "ou̯") flatmap_and_sub_pre("ie", "iː") flatmap_and_sub_pre("ʋ", "v") flatmap_and_sub_pre("i̯ɛː", "iː") flatmap_and_sub_pre("([bpfvm])i̯", "%1j") flatmap_and_sub_pre("([ʒʃj])ɛː", "%1iː") flatmap_and_sub_pre("(r"..raised..")ɛː", "%1iː") flatmap_and_sub_pre("ɣ", "ɦ") flatmap_and_sub_pre("i̯", "") flatmap_and_sub_pre("r̝#", "r̝̊") flatmap_and_sub_pre("r̝([" .. voiceless_consonant .. "])", "r̝̊%1") end end flatmap_and_sub_pre("#", "")

return variants end

function export.IPA(frame) local terms = {}

args = frame:getParent.args local currentTitle = mw.title.getCurrentTitle.text

for _, term in ipairs(args) do		if term == currentTitle then track("redundant") end table.insert(terms, term) end

if #terms == 0 then terms = {currentTitle} end

local results1, results2 = {}, {}

for _, term in ipairs(terms) do		local variantsPre = export.phonemic(term) for _, variant in ipairs(variantsPre) do table.insert(results1, {pron = "/" .. variant .. "/"}) end local variantsPost = export.phonemic(term, true) for _, variant in ipairs(variantsPost) do table.insert(results2, {pron = "/" .. variant .. "/"}) end end

if args.desc == "no" then results1[1].qualifiers = {"13th CE"}

return "*" .. m_IPA.format_IPA_full { lang = lang, items = results1 } else results1[1].qualifiers = {"13th CE"} results2[1].qualifiers = {"15th CE"}

return "*" .. m_IPA.format_IPA_full { lang = lang, items = results1 } .. "\n*" .. m_IPA.format_IPA_full { lang = lang, items = results2 } end end

return export