Module:et-IPA

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

This module implements {{et-IPA}}.


local find = mw.ustring.find
local gsub = mw.ustring.gsub
local glen = mw.ustring.len
local u = require("Module:string/char")

local export = {}

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

local A = u(0x002A) 		-- halflength marker (asterisk)
local C = "[mnptkvfsʃhlrjʒz]"			-- consonants
local D = u(0x0308)		-- centralisation marker (diaeresis)
local L = "[ˑː]" 						-- length markers
local R = u(0x0325)		-- voicelessness marker (ring below)
local S = u(0x032F) 		-- diphthong marker
local T = u(0x031E)		-- lowering marker (downtack)
local V = "[ɑeiouæɤøy][ˑː]?" .. D .. "?" .. T .. "?"
local W = "[ɑeiouæɤøy]?[ˑː]?" .. D .. "?" .. T .. "?" .. S .. "?"
local X = "[mnptkvfsʃhɦlrjʒzˑːʲ" .. R .. "]"

local lowerc = {
	["A"]="a",	["B"]="b",	["D"]="d",	["E"]="e",	["F"]="f",	["G"]="g",
	["H"]="h",	["I"]="i",	["J"]="j",	["K"]="k",	["L"]="l",	["M"]="m",
	["N"]="n",	["O"]="o",	["P"]="p",	["R"]="r",	["S"]="s",	["T"]="t",
	["U"]="u",	["V"]="v",	["Z"]="z",	["Ä"]="ä",	["Ü"]="ü",	["Ö"]="ö",
	["Š"]="š",	["Ž"]="ž",	["Õ"]="õ",
}

local phon = {
	-- consonants
	["b"]="b̥",	["d"]="d̥",	["g"]="ɡ̊",
	["p"]="p", ["t"]="t", ["k"]="k",
	["v"]="v",	["ž"]="ʒ̊", ["z"]="z̥",
	["f"]="f",	["š"]="ʃ",
	["'"]="ʲ",
	-- vowels
	["a"]="ɑ",	["e"]="e",	["i"]="i",
	["o"]="o",	["u"]="u",	["ä"]="æ",
	["õ"]="ɤ",	["ö"]="ø",	["ü"]="y",
}

local function phonemic(text)
	text = gsub(text, '.', lowerc)
	-- general phonology
	text = gsub(text, '.', phon)
	-- long consonants
	text = gsub(text, "([pkt])" .. A, "%1")
	text = gsub(text, "(" .. C .. ")" .. L .. "?%1", "%1ː")
	text = gsub(text, "(" .. C .. ")" .. L .. "?" .. A, "%1ˑ")
	-- palatalised long consonants
	text = gsub(text, "(" .. C .. ")(" .. L .. ")ʲ", "%1ʲ%2")
	-- long vowels
	text = gsub(text, "(" .. V .. ")%1", "%1ː")
	text = gsub(text, "(" .. V .. ")" .. A, "%1ˑ")
	-- üüV
	text = gsub(text, "y" .. L .. "(" .. V .. ")", "yiːj%1")
	-- diphthongs
	text = gsub(text, "([ɑeiouɤ])([ɑeiou])", "%1%2" .. S)
	text = gsub(text, "æ([eiou])", "æ%1" .. S)
	text = gsub(text, "ø([ɑei])", "ø%1" .. S)
	text = gsub(text, "y([ɑeio])", "y%1" .. S)
	-- stress
	if find(text, "ˈ") == nil then
		text = "ˈ" .. text
	end
	if find(text, "ˌ") == nil then
		text = gsub(text, "+", "ˌ")
	end
	text = gsub(text, "(" .. L .. ")" .. L, "%1")
	
	return text
end

local function phonetic(text)
	text = gsub(text, '.', lowerc)
	-- velar nasal
	text = gsub(text, "n%f[kg]", "ŋ")
	-- glide insertion
	text = gsub(text, "(" .. V .. ")i(" .. V .. ")", "%1ij%2")
	text = gsub(text, "(" .. V .. ")u(" .. V .. ")", "%1uw%2")
	-- flash forward to after phonemic transcription
	text = phonemic(text)
	-- palatalisation
	text = gsub(text, "([ndtslz]" .. R .. "?)([ːˑ]?[ij])", "%1ʲ%2")
	-- optional initial h-
	text = gsub(text, "^ˈh", "ˈ(h)")
	-- h-voicing
	text = gsub(text, "(" .. V .. S .. "?[ˈˌ]?)h(" .. V .. ")", "%1ɦ%2")
	-- long gemination
	text = gsub(text, "(" .. V .. ")ː([ptk])(" .. V .. ")", "%1ː%2ː%3")
	-- short gemination
	text = gsub(text, "(" .. V .. S .. "?)([ptkfš]ʲ?)(" .. V .. ")", "%1%2ˑ%3")
	text = gsub(text, "([ptk]ʲ?)$", "%1ˑ")
	text = gsub(text, "([ptk]ʲ?)([ptkf])", "%1ˑ%2")
	text = gsub(text, "([bpdtɡkshfʃzʒ]" .. R .. "?" .. L .. "?)([ptk]ʲ?)ˑ", "%1%2")
	-- final devoicing
	text = gsub(text, "([ths]ʲ?)([mnrvl])$", "%1ˑ%2" .. R)
	-- vowel articulation
	text = gsub(text, "e$", "e" .. T)
	text = gsub(text, "jɑ", "jɑ" .. D)
	text = gsub(text, "ɑj", "ɑ" .. D .. "j")
	text = gsub(text, "ju", "ju" .. D)
	text = gsub(text, "uj", "u" .. D .. "j")
	-- secondary stress
	local i = 1
	local n = gsub(text, X, "")
	n = glen(n)
	while i <= n do
		text = gsub(text, "([ˈˌ]" .. X .. "*" .. V .. W .. X .. "*" .. V .. W .. X .. "*)(" .. V .. W .. X .. "*" .. V .. ")", "%1S%2")
		text = gsub(text, "([ˈˌ]" .. X .. "*" .. V .. W .. X .. "*" .. V .. W .. X .. "*)(" .. V .. W .. "[ptk][ːˑ]?)$", "%1S%2")
		text = gsub(text, "([ˈˌ]" .. X .. "*" .. V .. W .. X .. "*" .. V .. W .. X .. "*)(" .. V .. W .. "[ptk][ːˑ]?)ˌ", "%1S%2")
		i = i + 1
	end
	text = gsub(text, "(" .. C .. R .. "?ʲ?)S(" .. V .. ")", "ˌ%1%2")
	text = gsub(text, "(" .. C .. "ʲ?)ːS(" .. V .. ")", "%1ˌ%1%2")
	text = gsub(text, "(" .. C .. "ʲ?)ˑS(" .. V .. ")", "%1̚ˌ%1%2")
	text = gsub(text, "S", "ˌ")
	
	return text
end

function export.IPA(frame)
	local words = {}
	
	for _, word in ipairs(frame:getParent().args) do
		table.insert(words, word)
	end
	
	if #words == 0 then
		words = {mw.title.getCurrentTitle().text}
	end
	
	local IPA_results = {}
	
	for _, word in ipairs(words) do
		table.insert(IPA_results, { pron = "/" .. phonemic(word) .. "/" })
		table.insert(IPA_results, { pron = "[" .. phonetic(word) .. "]" })
	end
	
	return m_IPA.format_IPA_full { lang = lang, items = IPA_results }
end

return export