Module:sjd-IPA

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

This module implements {{sjd-IPA}}.


local export = {}

local m_IPA = require("Module:IPA")
local lang = require("Module:languages").getByCode("sjd")
local rsub = mw.ustring.gsub
local rlower = mw.ustring.lower
local u = require("Module:string/char")

local macron = mw.ustring.char(0x0304)

local V = "[aɒeɛiuo]ː?" -- vowels
local C = "[bvɡdžzjklʎmnɲŋprstfxhʃɕ]ʲ?" -- consonants

local phon = {
	-- consonants
	["б"]="b",	["в"]="v",	["г"]="ɡ",	["д"]="d",	["ж"]="ʒ",	["з"]="z",
	["й"]="j",	["ҋ"]="j̥",	["ј"]="j̥",	["һ"]="h",	["'"]="h",	["к"]="k",
	["л"]="l",	["ӆ"]="l̥",	["м"]="m",	["ӎ"]="m̥",	["н"]="n",	["ӊ"]="n̥",
	["ӈ"]="ŋ",	["п"]="p",	["р"]="r",	["ҏ"]="r̥",	["с"]="s",	["т"]="t",
	["ф"]="f",	["х"]="x",	["ц"]="ts",	["ч"]="tʃ",	["ш"]="ʃ",	["щ"]="ɕ",
	-- vowels
	["оа"]="ɒ",	["а"]="a",	["и"]="i",	["о"]="o",	["у"]="u",	["ӯ"]="uː",
	["э"]="ɛ",	["ы"]="ɨ",	["ъ"]="j",  ["ӣ"]="iː",
}

local function phonemic(text)
	text = rlower(text)
	
	-- general phonology
	text = rsub(text, u(0x0301), "ˈ")
	text = rsub(text, u(0x0300), "ˌ")
	text = rsub(text, ".", phon)
	
	-- palatalization
	text = mw.ustring.gsub(text, "([Nn])%1ь", "ɲː")
	text = mw.ustring.gsub(text, "([Nn])ь", "ɲ")
	text = mw.ustring.gsub(text, "([bvɡdʒzkll̥mm̥nŋprr̥stfxһʒʃ])ь", "%1ʲ")
	text = mw.ustring.gsub(text, "([bvɡdʒzklmnn̥ŋprstfxһʒʃ])ҍ", "%1ʲ")
		-- Some consonants are affected if the preceding one is palatalized:
	text = mw.ustring.gsub(text, "([bɡdvlmnŋɲps])ʲ([vlnprst])", "%1ʲ%2ʲ")
	text = mw.ustring.gsub(text, "h([ptk])ʲ", "hʲ%1ʲ")
	text = mw.ustring.gsub(text, "xxʲ([ptk])", "xxʲ%1ʲ")
	
	text = mw.ustring.gsub(text, "([bdɡ])([ptk])ʲ", "%1ʲ%2ʲ") --semi-voiced geminates bp, dt, gk
		-- n,d,t preceding "semi-soft" ӓ and ӭ
	text = mw.ustring.gsub(text, "([NnDdTt])%1ӓ", "%1ːʲa")
	text = mw.ustring.gsub(text, "([NnDdTt])ӓ", "%1ʲa")
	text = mw.ustring.gsub(text, "([NnDdTt])%1ӭ", "%1ːʲɛ")
	text = mw.ustring.gsub(text, "([NnDdTt])ӭ", "%1ʲɛ")
		-- palatal н/ɲ + vowels
	text = mw.ustring.gsub(text, "([Nn])%1я", "ɲːa")
	text = mw.ustring.gsub(text, "([Nn])я", "ɲa")
	text = mw.ustring.gsub(text, "([Nn])%1е", "ɲːe")
	text = mw.ustring.gsub(text, "([Nn])е", "ɲe")
	text = mw.ustring.gsub(text, "([Nn])%1ё", "ɲːo")
	text = mw.ustring.gsub(text, "([Nn])ё", "ɲo")
	text = mw.ustring.gsub(text, "([Nn])%1и", "ɲːi")
	text = mw.ustring.gsub(text, "([Nn])и", "ɲi")
	text = mw.ustring.gsub(text, "([Nn])%1у", "ɲːu")
	text = mw.ustring.gsub(text, "([Nn])ю", "ɲu")
	
	text = mw.ustring.gsub(text, "llʲj", "ʎː") -- palatal ʎ
	text = mw.ustring.gsub(text, "lʲj", "ʎ")
	text = mw.ustring.gsub(text, "llʲ", "lʲː") -- palatalized l
	text = mw.ustring.gsub(text, "ll", "lː")
	
	-- consonant-ъ-consonant (creates a syllable boundary, e.g. "соа̄рнънэ"; check if there should be an extra-short vowel instead)
	text = mw.ustring.gsub(text, "([bvlmnst])j%1", "%1.%1") -- CjC → C.C
	
	-- j + vowels
		--е̄/е
	text = mw.ustring.gsub(text, "^" .. "([Ее])" .. macron, "ji̯e") -- initial е̄
	text = mw.ustring.gsub(text, "(" .. C .. ")([Ее])" .. macron, "%1i̯e") -- е̄ following a consonant
	text = mw.ustring.gsub(text, "^" .. "([Ее])", "je")
	text = mw.ustring.gsub(text, "jе", "jje")	-- replaces cyrillic е after j with je
	text = mw.ustring.gsub(text, "(" .. C .. ")([Ее])", "%1ʲe")
		--я̄/я
	text = mw.ustring.gsub(text, "^" .. "([Яя])" .. macron, "je̯a")
	text = mw.ustring.gsub(text, "([Яя])" .. macron, "e̯a")
	text = mw.ustring.gsub(text, "^" .. "([Яя])", "ja")
	text = mw.ustring.gsub(text, "([Яя])", "ʲa")
		-- ӣ, ё, ю̄, ю
	text = mw.ustring.gsub(text, "^" .. "([Ӣӣ])", "jiː")
	text = mw.ustring.gsub(text, "^" .. "([Ёё])", "jo")
	text = mw.ustring.gsub(text, "([Ёё])", "ʲo")
	text = mw.ustring.gsub(text, "^" .. "([Юю])" .. macron, "juː")
	text = mw.ustring.gsub(text, "^" .. "([Юю])", "ju")
	text = mw.ustring.gsub(text, "([Юю])", "ʲu")
	
	-- stress (1)
	text = mw.ustring.gsub(text, "(" .. V .. "ː?" .. macron .. "?)([ˈˌ])", "%2%1")
	
	-- long vowels
	text = rsub(text, "([aɒeɛiuo])̄" .. macron, "%1ː")
	text = rsub(text, "([iu])M", "%1ː")
	-- long consonants
	text = mw.ustring.gsub(text, "([bvɡdʒzjklmnŋprstfxʃɕ])%1ʲ", "%1ʲː")
	text = mw.ustring.gsub(text, "([bvɡdʒzjklmnŋprstfxʃɕ])%1", "%1ː")
	text = mw.ustring.gsub(text, "(j̥)%1", "%1ː")
	text = mw.ustring.gsub(text, "(l̥)%1", "%1ː")
	text = mw.ustring.gsub(text, "(m̥)%1", "%1ː")	
	text = mw.ustring.gsub(text, "(n̥)%1", "%1ː")
	text = mw.ustring.gsub(text, "(r̥)%1", "%1ː")	
	
	-- bringing everything into the proper form
	-- affricates
	text = rsub(text, "ts", "t͡s")
	text = rsub(text, "t͡st͡s", "t͡sː")
	text = rsub(text, "t͡sʲt͡sʲ", "t͡sʲː")
	text = rsub(text, "tʃ", "t͡ʃʲ")
	text = rsub(text, "t͡ʃʲt͡ʃʲ", "t͡ʃʲː")
	text = rsub(text, "dz", "d͡z")
	text = rsub(text, "dž", "d͡ʒ")
	text = rsub(text, "dʒʲ", "d͡ʒʲ")
	--- semi-voiced
	text = rsub(text, "bp", "b̥͡p")
	text = rsub(text, "gk", "g̥͡k")
	text = rsub(text, "dt", "d̥͡t")
	text = rsub(text, "bʲpʲ", "b̥͡pʲ")
	text = rsub(text, "gʲkʲ", "g̥͡k")
	text = rsub(text, "dʲtʲ", "d̥͡tʲ")
	-- diphtongs
	text = rsub(text, "ua", "u̯a")
	text = rsub(text, "uɛ", "u̯ɛ")
	text = rsub(text, "uo", "u̯o")
	
	-- fixing possible mistakes
	text = rsub(text, "oa", "ɒ") -- oa → ɒ
	text = rsub(text, "oa" .. macron, "ɒː")
	text = rsub(text, "е", "e") -- replacing the remaining cyrillic е's with latin
	text = rsub(text, "(".. macron ..")", "ː") -- replacing possible remaining macrons
	text = rsub(text, "ːʲ", "ʲː")
	text = rsub(text, "jʲ", "j")
	text = rsub(text, "ɲʲ", "ɲ")
	text = rsub(text, "ʎʲ", "ʎ")
	text = rsub(text, "lʲʲ", "ʎː")
	text = rsub(text, "tʲs", "t͡s")
	
	-- stress (2)
	text = rsub(text, "(" .. V .. ")(" .. C .. ")([ˈˌ])", "%1%3%2")
	text = rsub(text, "(" .. V .. C .. "+)(" .. C .. ")([ˈˌ])", "%1%3%2")
	
	if mw.ustring.find(text, "ˈ") == nil then
		text = "ˈ" .. text
		text = rsub(text, "-", "ˌ")
	end
	
	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) .. "/" })
	end
	
	return m_IPA.format_IPA_full { lang = lang, items = IPA_results }
end

return export