Jump to content

Module:niv-IPA

From Wiktionary, the free dictionary


local export = {}

--[=[

Author: saph (User:Saph668)

Implements {{niv-IPA}}.

To-do:
1. Fix coda р̌ in palatalisation. (e.g. [[меӄр̌]])

]=]--

local m_IPA = require("Module:IPA")
local lang = require("Module:languages").getByCode("niv")
local m_para = require("Module:parameters")
local m_a = require("Module:accent qualifier")

local rsub = mw.ustring.gsub
local rlower = mw.ustring.lower

local hacek = "\204\140"
local length = "\203\144"
local devoice = "\204\165"
local raise = "\203\148"

local correspondences = {
    ["а"]='a', ["в"]='v', ["е"]='je',
    ["ё"]='jo', ["г"]='ɡ', ["д"]='d',
    ["и"]='i', ["й"]='j', ["к"]='k', 
    ["л"]='l', ["м"]='m', ["н"]='n', 
    ["о"]='o', ["п"]='p', ["р"]='r',
    ["с"]='s', ["т"]='t', ["у"]='u', 
    ["ф"]='f', ["х"]='x', ["ы"]='ɤ',
    ["э"]='e', ["ю"]='ju', ["я"]='ja', 
    ["з"]='z', ["б"]='b', ["ъ"]='',
    ["ғ"]='ɣ', ["ӻ"]='ʁ', ["ӷ"]='ɢ',
    ["ӈ"]='ŋ', ["ӽ"]='χ', ["ч"]='cʰ',
    ["ӄ"]='q', ["ӿ"]='h', ["ў"]='w',
}

local vowel = "[aeiouɤ]"
local C = "[mnŋptkqbdɡPTKQfsxχhvzɣʁlwRrl]"
local fv = "[fsxχhvzɣʁaeiouɤ]"
local pv = "[ptckqPTCKQaeiouɤ]"

local function palatalise(text)
	text = rsub(text, "[яёюьи]", {
        ['я'] = 'jа', ['ё'] = 'jо',
        ['ю'] = 'ju', ['ь'] = 'j',
        ['и'] = "ji"
    })
	return text
end

local function pron(text)
	text = rlower(text)
	text = palatalise(text)
    text = rsub(text, ".", correspondences)
	text = text:gsub("nj", "ɲ")
	    :gsub("dj", "ɟ")
	    :gsub("tj", "c")
	    :gsub(hacek, devoice)
	text = rsub(text, "[’ʼ]", "ʰ")
    return text:gsub("j([ei])", "%1")
end

local function toIPA(text)
	text = text:gsub("\'", "")
	    :gsub("—", "")
	    :gsub(",", "‿")
	    :gsub("ⁿ", "")
	return text
end

local function phon(text)
	-- universal phonetic pronunciation
	local mutation_u = {
		["p"] = 'v', ["t"] = 'r', ["c"] = 'z',
		["k"] = 'ɣ', ["q"] = 'ʁ'
	}
	local mutation_a = {
		["pʰ"] = 'f', ["tʰ"] = 'r' .. devoice, ["cʰ"] = 's',
		["kʰ"] = 'x', ["qʰ"] = 'χ'
	}
	local voicing = {
		["p"] = 'b', ["t"] = 'd', ["c"] = 'ɟ', 
		["k"] = 'ɡ', ["q"] = 'ɢ'
	}
	text = pron(text)
	text = text:gsub(".", correspondences)
		:gsub("(" .. vowel .. ")f(" .. vowel .. ")", "%1v%2")
		:gsub("(" .. vowel .. ")s(" .. vowel .. ")", "%1z%2")
		:gsub("\'", "ˈ")
		:gsub("—", "\203\144")
	for u,v in pairs(voicing) do
		text = text:gsub("([mnɲŋⁿ])," .. u, "%1," .. v)
	end
    for u,v in pairs(mutation_a) do
		text = text:gsub("(" .. pv .. ")," .. u, "%1,}" .. v)
			:gsub("(" .. fv .. ")," .. v, "%1,}" .. u)
    end
    for u,v in pairs(mutation_u) do
		text = text:gsub("(" .. pv .. ")," .. u, "%1,}" .. v)
			:gsub("(" .. fv .. ")," .. v, "%1,}" .. u)
    end
	text = text:gsub("}", "")
		:gsub(",", "‿ˈ")
		:gsub("a" .. length, "i")
		:gsub("r" .. devoice, "r" .. devoice .. raise)
	return text
end

local function yphon(text)
	-- phonetic pronunciation among younger speakers
	text = phon(text)
	text = rsub(text, "^(" .. C .. ")(ʰ?)(" .. devoice .. "?)(" .. raise .. "?)([ʼ’]?)([ie])(" .. C .. "?)(" .. C .. "?)(" .. C .. "?)$",
		"%1%2%3%4ʲ%5%6%7%8") -- palatalise monosyllabic heavy words w /i/ or /e/ nucleus
	return text
end

local function ophon(text)
	-- phonetic pronunciation among older speakers
	-- empty for now
	-- text = phon(text)
	-- return text
end

local function fphon(text)
	-- phonetic pronunciation in fast speech
	text = phon(text)
	local boundary = "\226\128\191\203\136"
	local voicing = {
		["f"] = "v", ["s"] = "z"
	}
	local spirantisation = {
		["k"] = 'x', ["q"] = 'χ'
	}
	text = text:gsub("r\204\165\203\148", "R")
	text = rsub(text, "(" .. vowel .. ")" .. "([ɣrʁ])" .. "([rl])", "%1\203\144" .. "" .. "%3")
	text = text:gsub("R", "r\204\165\203\148")
	for u,v in pairs(voicing) do
		text = rsub(text, u .. boundary .. "([mnŋvzɣʁljwrl])", v .. boundary .. "%1")
	end
	for u,v in pairs(spirantisation) do
    	text = text:gsub(u .. boundary .. "([xχʁ])", v .. boundary .. "%1")
    end
	return text
end

function export.make(frame)
	local args = m_para.process(frame:getParent().args, {
	    [1] = { list = true, default = mw.loadData("Module:headword/data").pagename },
	})
    local results = {}
    local results_y = {}
    local results_o = {}
    local results_f = {}
    for i, term in ipairs(args[1]) do
        local phonemic = {}
        local phonetic = {}
        local yphonetic = {}
        -- local ophonetic = {}
        local fphonetic = {}
        local words = mw.text.split(term, ".", true)
        phonemic[i] = pron(words[i])
        phonetic[i] = phon(words[i])
        yphonetic[i] = yphon(words[i])
        -- ophonetic[i] = ophon(words[i])
        fphonetic[i] = fphon(words[i])
        phonemic = table.concat(phonemic, " ")
        phonetic = table.concat(phonetic, " ")
        yphonetic = table.concat(yphonetic, " ")
        -- ophonetic = table.concat(ophonetic, " ")
        fphonetic = table.concat(fphonetic, " ")
        phonemic = toIPA(phonemic)
        phonetic = toIPA(phonetic)
        yphonetic = toIPA(yphonetic)
        -- ophonetic = toIPA(ophonetic)
        fphonetic = toIPA(fphonetic)
        table.insert(results, { pron = "/" .. phonemic .. "/" })
        if phonetic ~= phonemic and rsub(phonetic, "ˈ", "") ~= phonemic then
        	if not phonetic:match("ˈ") then
        		phonetic = rsub(phonetic, "^", "ˈ")
        	end
        	if not yphonetic:match("ˈ") then
        		yphonetic = rsub(yphonetic, "^", "ˈ")
	        end
	        -- if not ophonetic:match("ˈ") then
	        --	ophonetic = rsub(ophonetic, "^", "ˈ")
	        -- end
	        if not fphonetic:match("ˈ") then
	        	fphonetic = rsub(fphonetic, "^", "ˈ")
	        end
        	table.insert(results, { pron = "[" .. phonetic .. "]" })
        end
        if yphonetic ~= phonetic and rsub(yphonetic, "ˈ", "") ~= phonemic then
        	table.insert(results_y, { pron = "[" .. yphonetic .. "]" })
        end
        -- if ophonetic ~= phonetic and rsub(ophonetic, "ˈ", "") ~= phonemic then
        --	table.insert(results_o, { pron = "[" .. ophonetic .. "]" })
        -- end
        if fphonetic ~= phonetic and rsub(fphonetic, "ˈ", "") ~= phonemic then
        	table.insert(results_f, { pron = "[" .. fphonetic .. "]" })
        end
    end
    
	local show = 
		"*" .. m_IPA.format_IPA_full { lang = lang, items = results }
    
	local hide = show .. "\n"

	local sections = {}
	
	if #results_y > 0 then
	    table.insert(sections, m_a.format_qualifiers(lang, {"younger speakers"}) .. " " .. m_IPA.format_IPA_full { lang = lang, items = results_y })
	end
	
	-- if #results_o > 0 then
	--    table.insert(sections, m_a.format_qualifiers(lang, {"older speakers"}) .. " " .. m_IPA.format_IPA_full { lang = lang, items = results_o })
	-- end
	
	if #results_f > 0 then
	    table.insert(sections, m_a.format_qualifiers(lang, {"in faster speech"}) .. " " .. m_IPA.format_IPA_full { lang = lang, items = results_f })
	end
	
	if #sections > 0 then
	    hide = hide .. "**" .. table.concat(sections, "\n**")
	end
		
	if hide == show .. "\n" then
	    return show
	else
	    return '\n<div class="vsSwitcher" data-toggle-category="pronunciations">'
	        .. '<span class="vsToggleElement"></span>'
	        .. '<div class="vsShow">\n'
	        .. show
	        .. '\n</div><div class="vsHide">\n'
	        .. hide
	        .. '</div></div>\n<span></span>'
end
end

return export