Module:gn-IPA

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


local export = {}

local PAGENAME = mw.title.getCurrentTitle().text

-- single characters that map to IPA sounds   
local phonetic_chars_map = {
	["ch"] = "ʃ",
	["f"] = "f",
	["g"] = "ɰ",
	["g̃"] = "ɰ̃",
	["h"] = "h",
	["j"] = "d͡ʒ",
	["k"] = "k",
	["l"] = "l",
	["m"] = "m",
	["mb"] = "ᵐb",
	["n"] = "n",
	["nd"] = "ⁿd",
	["ng"] = "ᵑɡ",
	["nt"] = "ⁿt",
	["ñ"] = "ɲ",
	["p"] = "p",
	["r"] = "ɾ",
	["s"] = "s",
	["t"] = "t",
	["v"] = "ʋ",
	["'"] = "ʔ",
	["a"] = "a",
	["ã"] = "ã",
	["e"] = "e",	
	["ẽ"] = "e",
	["i"] = "i",
	["ĩ"] = "ĩ",
	["o"] = "o",
	["õ"] = "õ",
	["u"] = "u",
	["ũ"] = "ũ",
	["y"] = "ɨ",
	["ỹ"] = "ɨ̃",
}

-- character sequences of two that map to IPA sounds
local phonetic_2chars_map = {
		{ 'rr', 'r' },
}

function export.word_to_IPA(word)
	word = mw.ustring.lower(word)

	local phonetic = word

	-- generating the stress
	phonetic = mw.ustring.gsub(phonetic, "%S+", function(word)
		-- Do not add a stress mark for monosyllabic words. Check to see if the word contains only a single instance of [aeiouyãẽĩõũỹ]+.
		local numberOfVowels = select(2, mw.ustring.gsub(word, "[aeiouyãẽĩõũỹ]", "%0"))
	
		-- If polysyllabic, add IPA stress mark using the following rules. The stress mainly falls on the last syllable. 
		--In some cases the stress is not on the last syllable. In such cases the stressed vowel
		-- is marked by an acute accent <՛>. So:
		--      1) Find the vowel followed by <՛>․ If none, jump to step 2. Else check if it is the first vowel of the word.
		--         If true, put the IPA stress at the beginning, else do step 3.
		--      2) Find the last vowel, i.e. [aeiouyãẽĩõũỹ],
		--      3) If the IPA symbol preceding it is [aeiouyãẽĩõũỹ], i.e. a vowel, put the stress symbol between them, 
		--         if it is NOT [aeiouyãẽĩõũỹ], i.e. it is a consonant, 
		--         put the stress before that consonant.
		if numberOfVowels > 1 then
			local rcount
			word, rcount = mw.ustring.gsub(word, "([^ aeiouyãẽĩõũỹ]*[aeiouyãẽĩõũỹ])՛", "ˈ%1")
			if rcount == 0 then
				word = mw.ustring.gsub(word, "([^ aeiouyãẽĩõũỹ]*[aeiouyãẽĩõũỹ][^ aeiouyãẽĩõũỹ]*)$", "ˈ%1")
				word = mw.ustring.gsub(word, "([^ aeiouyãẽĩõũỹ]*[aeiouyãẽĩõũỹ]?[aeiouyãẽĩõũỹ][^ aeiouyãẽĩõũỹ]*ə[^ aeiouyãẽĩõũỹ]*)$", "ˈ%1")
			end
			-- Including () in the second and third sets will only work
			-- if () never encloses a vowel.
			word = mw.ustring.gsub(word, "([aeiouyãẽĩõũỹ])ˈ([^ aeiouyãẽĩõũỹ()]+)([^ aeiouyãẽĩõũỹˈ()])", "%1%2ˈ%3")
			word = mw.ustring.gsub(word, "(.)͡ˈ", "ˈ%1͡")
			return word
		end
	end)

	return phonetic
end

function export.pronunciation(frame)
	local params = {
		[1] = {default = PAGENAME}
	}
	local args, unrecognized_args = require("Module:parameters").process(frame:getParent().args, params, true)
	local pron = export.word_to_IPA(args[1])
	local lang = require("Module:languages").getByCode("gn")
	local items = {{pron = "/" .. pron .. "/"}}
	return require("Module:IPA").format_IPA_full { lang = lang, items = items }
end
 
return export