This module page is not ready for use.
This module page may not work properly, because it has not been completed and is being kept for tests and improvement. Its arguments, functions and results may change without warning.

It is advisable not to use this module as of yet. You may edit this page or discuss possible changes.


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