Module:lfv-IPA

Revision as of 21:24, 26 August 2023 by TheNightAvl (talk | contribs)
local export = {}
local getArgs = require('Module:Arguments').getArgs

-- DATA --

local data = {
	["a"] = "a",
	["e"] = "e",
	["ê"] = "ɛ",
	["i"] = "i",
	["o"] = "o",
	["ô"] = "ɔ",
	["ø"] = "ø",
	["u"] = "ø",
	["y"] = "y",
	
	["b"] = "b",
	["d"] = "d",
	["ð"] = "ð",
	["f"] = "f",
	["g"] = "ɡ",
	["ǧ"] = "ɣ",
	["h"] = "x",
	["j"] = "j",
	["k"] = "k",
	["l"] = "l",
	["lj"] = "ʎ",
	["m"] = "m",
	["n"] = "n",
	["nj"] = "ɲ",
	["ñ"] = "ŋ",
	["p"] = "p",
	["r"] = "r",
	["s"] = "s",
	["š"] = "ʃ",
	["t"] = "t",
	["þ"] = "θ",
	["v"] = "v",
	["w"] = "w",
	["ŵ"] = "ɥ",
	["z"] = "z",
	["ž"] = "ʒ",
	
	["hl"] = "l̥",
	["hlj"] = "ʎ̥",
	["hm"] = "m̥",
	["hn"] = "n̥",
	["hnj"] = "ɲ̊",
	["hñ"] = "ŋ̊",
	["hr"] = "r̥",

	["llj"] = "ʎʎ",
	["nnj"] = "ɲɲ",

	["lhl"] = "l̥l̥",
	["lhlj"] = "ʎʎ",
	["mhm"] = "mm",
	["nhn"] = "nn",
	["nhnj"] = "ɲɲ",
	["ñhñ"] = "ŋŋ",
	["rhr"] = "rr",
	
	[" "] = " ",
	["."] = "|",
}
data[","] = data["."]

local vowel = {
	["a"] = true,
	["e"] = true,
	["ɛ"] = true,
	["i"] = true,
	["o"] = true,
	["ɔ"] = true,
	["ø"] = true,
	["u"] = true,
	["y"] = true,
}

local intervocalic_voicing = {
	["ʎ̥"] = "ʎʎ",
	["m̥"] = "mm",
	["n̥"] = "nn",
	["ɲ̊"] = "ɲɲ",
	["ŋ̊"] = "ŋŋ",
	["r̥"] = "rr",
}

function generate_IPA(word)

	local working_IPA = {}
	
	-- base generation -- 
	while #word > 0 do
		if data[mw.ustring.sub(word, 1, 4)] then
			table.insert(working_IPA, data[mw.ustring.sub(word, 1, 4)])
			word = mw.ustring.sub(word, 5)
		elseif data[mw.ustring.sub(word, 1, 3)] then
			table.insert(working_IPA, data[mw.ustring.sub(word, 1, 3)])
			word = mw.ustring.sub(word, 4)
		elseif data[mw.ustring.sub(word, 1, 2)] then
			table.insert(working_IPA, data[mw.ustring.sub(word, 1, 2)])
			word = mw.ustring.sub(word, 3)
		elseif data[mw.ustring.sub(word, 1, 1)] then
			table.insert(working_IPA, data[mw.ustring.sub(word, 1, 1)])
			word = mw.ustring.sub(word, 2)
		elseif data[mw.ustring.sub(word, 1, 1)] == "·" then
			word = mw.ustring.sub(word, 2)
		else
			error("The character '" .. mw.ustring.sub(word, 1, 1) .. "' is not recognised.")
		end
	end
	
	-- resolve consonants --
	
	local i = 1
	
	while working_IPA[i] do
	
		local p_prev = working_IPA[i-1]
		local p_current = working_IPA[i]
		local p_next = working_IPA[i+1]
		
		local function p_resolve(phone)
			working_IPA[i] = phone
		end
		
		if vowel[p_prev] and intervocalic_voicing[p_current] ~= nil and vowel[p_next] then
			p_resolve(intervocalic_voicing[p_current])
		end
		
		i = i + 1
	end
	
	return table.concat(working_IPA)
	
end

function export.generate(frame)
	local args = getArgs(frame)
	local outputIPA = args[1]
	
	local parameters = {}
	local p = 2
	
	-- mw.log("——— Parameters ———")
	while args[p] do
		parameters[args[p]] = true
		-- mw.log(args[p] .. " = true")
		p = p + 1
	end
	
	outputIPA = mw.ustring.gsub(outputIPA, "(%&nbsp%;)", " ")
	outputIPA = generate_IPA(outputIPA)
		
	local nolarge = ""
	if parameters["nolarge"] then
		nolarge = " nolarge"
	end
	if parameters["phon"] and parameters["format"] then
		outputIPA = "<span class=\"IPA" .. nolarge .. "\">[" .. outputIPA .. "]</span>"
	elseif parameters["format"] then
		outputIPA = "<span class=\"IPA" .. nolarge .. "\">/" .. outputIPA .. "/</span>"
	end
	
	-- mw.log(outputIPA)
	return outputIPA
	
end

return export

--[[
Debug console test string:
=p.generate(mw.getCurrentFrame():newChild{title="whatever",args={"alhlen"}})
]]