Module:User:Erutuon/ru-pronunciation

From Wiktionary, the free dictionary
Jump to navigation Jump to search

Testcases[edit]


local export = {}

local match = mw.ustring.match
local gsub = mw.ustring.gsub

local U = mw.ustring.char
local tie = U(0x361)
local acute = U(0x301)
local long = "ː"
local stress = "ˈ"

local correspondences = {
	["а"] = "a",
	["б"] = "b",
	["в"] = "v",
	["г"] = "g",
	["д"] = "d",
	["е"] = "ʲe",
	["ё"] = "ʲo",
	["ж"] = "ʐ",
	["з"] = "z",
	["и"] = "ʲi",
	["й"] = "j",
	["к"] = "k",
	["л"] = "l",
	["м"] = "m",
	["н"] = "n",
	["о"] = "o",
	["п"] = "p",
	["р"] = "r",
	["с"] = "s",
	["т"] = "t",
	["у"] = "u",
	["ф"] = "f",
	["х"] = "x",
	["ц"] = "t" .. tie .. "s",
	["ч"] = "t" .. tie .. "ɕ",
	["ш"] = "ʂ",
	["щ"] = "ɕ" .. long,
	["ъ"] = "'",
	["ы"] = "ɨ",
	["ь"] = "ʲ",
	["э"] = "e",
	["ю"] = "ʲu",
	["я"] = "ʲa",
	[acute] = stress,
}

local function tagIPA(IPA)
	return '<span class="IPA">/' .. IPA .. '/</span>'
end

function export.toIPA(word)
	local hasStress = match(word, acute)
	
	IPA = gsub(
		word,
		".",
		function(letter)
			return correspondences[letter] or letter
		end
	)
	
	local vowels = "aeiɨou"
	local vowel = "[" .. vowels .. "]"
	
	IPA = gsub(IPA, "([" .. vowels .. "ʲ])ʲ", "%1j")
	
	IPA = gsub(IPA, "([ʂʐɕ" .. long .. "?])ʲ", "%1")
	IPA = gsub(IPA, "(t" .. tie .. "s)ʲ", "%1")
	
	IPA = gsub(IPA, "([ʂʐ])i", "%1ɨ")
	IPA = gsub(IPA, "(t" .. tie .. "s)i", "%1ɨ")
	
	-- Reduce vowels.
	local reduction = {
		["e"] = "ɨ",
		["o"] = "a",
	}
	local iotated_reduction = {
		["a"] = "i",
		["e"] = "i",
		["o"] = "a",
	}
	
	if hasStress then
		local palatalization = "[ʲjɕ]?" .. long .. "?"
		
		IPA = gsub(
			IPA,
			"^(" .. vowel .. ")([^" .. stress .. "])",
			function (vowel, nextCharacter)
				return ( reduction[vowel] or vowel ) .. nextCharacter
			end
		)
		IPA = gsub(
			IPA,
			"(" .. palatalization .. ")(" .. vowel .. ")([^" .. stress .. "])",
			function (palatalization, vowel, nextCharacter)
				mw.log(word, palatalization, vowel, nextCharacter)
				if palatalization == "" then
					return ( reduction[vowel] or vowel ) .. nextCharacter
				else
					return palatalization .. ( iotated_reduction[vowel] or vowel ) .. nextCharacter
				end
			end
		)
		IPA = gsub(
			IPA,
			"(" .. palatalization .. ")(" .. vowel .. ")$",
			function (palatalization, vowel)
				if vowel ~= "e" then
					if palatalization == "" then
						return ( reduction[vowel] or vowel )
					else
						return palatalization .. ( iotated_reduction[vowel] or vowel )
					end
				end
			end
		)
	end
	
	-- Move stress mark before vowel.
	IPA = gsub(IPA, "([" .. vowels .. "])" .. stress, stress .. "%1")
	
	-- Move stress mark before consonants.
	while match(IPA, "[^" .. vowels .. "]" .. stress) do
		IPA = gsub(IPA, "([^" .. vowels .. "])" .. stress, stress .. "%1")
	end
	
	return IPA
end

function export.IPA(frame)
	local params = {
		[1] = {},
	}
	
	local args = require("Module:parameters").process(frame.args, params)
	
	local IPA = export.toIPA(args[1])
	
	return require("Module:links").full_link
		{
			term = args[1],
			lang = require("Module:languages").getByCode("ru"),
			sc = require("Module:scripts").getByCode("Cyrl")
		} ..
		" &mdash; " ..
		tagIPA(IPA)
end

return export