Module:qay-pron

From Linguifex
Revision as of 16:40, 24 June 2022 by Sware (talk | contribs)
Jump to navigation Jump to search


local sub = mw.ustring.sub
local find = mw.ustring.find
local gmatch = mw.ustring.gmatch
local gsub = mw.ustring.gsub
local match = mw.ustring.match
local u = mw.ustring.char
local split = mw.text.split
local gsplit = mw.text.gsplit

local lang = require("Module:languages").getByCode("qay")
local m_table = require("Module:table")
local m_IPA = require("Module:IPA")

local export = {}

local consonants = "[pbmvstdnrɾlkɡŋhxçʤʧjwçx]"
local front = "iɪeɛ"
local back = "oɔu"
local vowels = "[a" .. front .. back .. "ː´]"

local function laxen(v)
	local otc = {}
	local switch = {["e"] = "ɛ", ["i"] = "ɪ", ["o"] = "ɔ", ["u"] = "ʊ", ["a"] = "a", ["ː"] = "ː", ["´"] = "´"}
		 
	for vc in gmatch(v, ".") do
		vc = gsub(vc, vc, switch[vc])
		table.insert(otc, vc)
	end
	return table.concat(otc)
end

local function same(foo, bar)
	foo, bar = mw.ustring.toNFD(foo), mw.ustring.toNFD(bar) -- decompose diacritics
	foo, bar = match(foo, "^."), match(bar, "^.") -- sort out the letter
	return foo == bar and true or false
end

local first_rules = {
	{"n(·?)([kg])", "ŋ%1%2"}, {"ŋg", "ŋ"}, {"c", "ʧ"}, {"j", "ʤ"}, {"y", "j"}, {"g", "ɡ"}, 
	-- Long vowels
	{"ā", "aː"},  {"ē", "eː"}, {"ī", "iː"}, {"ō", "oː"}, {"ū", "uː"},
	-- Diphthongs
	{"au", "aʊ"}, {"[uʊ]ji", "wi"}, {"h?u([aeiouɛɪɔʊ])", "w%1"},
}

local phonetic_rules = {
	{"ˈ·", "ˈ"}, {"·ˈ", "ˈ"}, {"´", ""},
	
	{"h([" .. front .. "])", "ç%1"}, {"h([" .. back .. "])", "x%1"},
	{"([^nŋ]·)[tk]j", "%1ʧ"}, {"([^nŋ]·)[dɡ]j", "%1ʤ"}, {"r", "ɾ"}, {"k([·ˈ])w", "%1kw"}, {"s([·ˈ])j", "%1sj"},
	
	-- Lax vowels in closed syllables
	{"([·ˈ])(" .. consonants .. "?)(" .. vowels .. "*)(" .. consonants .. ")", function(st,c1,v,c2) return st .. c1 .. laxen(v) .. c2 end},
	{"^(" .. consonants .. "?)(" .. vowels .. "*)(" .. consonants .. ")$", function(c1,v,c2) return c1 .. laxen(v) .. c2 end},
	{"(" .. consonants .. ")(" .. vowels .. "*)(" .. consonants .. consonants .. ")", function(c1,v,c23) return c1 .. laxen(v) .. c23 end},
	
	-- Doubled consonants are reduced to one
	{"(" .. consonants .. ")(·?ˈ?)(" .. consonants .. ")", function(c1, st, c2) return same(c1,c2) and st .. c1 or c1 .. st .. c2 end},
	{"jj", "j"},
	
	-- Diphthongs
	{"(" .. vowels .. ")j$", "%1ɪ"},
	
	{"(·" .. consonants .. ")e$", "%1ə"}, {"a", "ä"},
}

local function syllabify(term)
	term = gsub(term, "(" .. consonants .. "*)(" .. vowels .. "*)", "%1%2·")
	term = gsub(term, "··", "·"); term = gsub(term, "·$", ""); term = gsub(term, "^·", "")
	term = gsub(term, "·(" .. consonants .. ")(" .. consonants .. ")(" .. vowels .. "*)", "%1·%2%3")
	term = gsub(term, "·(" .. consonants .. ")$", "%1")
	term = gsub(term, "·(" .. consonants .. ")·", "%1·")
	term = gsub(term, "(" .. consonants .. ")·(" .. consonants .. ")([pbmvstdnrɾlkɡŋhxçʤʧçx])", "%1%2·%3")
	
	local syllables = split(term, "·")
	
	if #syllables ~= 1 then
		for i, syll in ipairs(syllables) do
			if match(syll, "´") or match(syll, "ː") then
				table.insert(syllables, i, "ˈ")
				return table.concat(syllables, "·")
			elseif match(term, "ŋ$") or match(syllables[#syllables], "[aɛɪɔʊ][ɪʊ]") then
				table.insert(syllables, #syllables, "ˈ")
				--syllables[#syllables-1] = gsub(syllables[#syllables-1], "ˈ", "")
				return table.concat(syllables, "·")
			else
				table.insert(syllables, #syllables-1, "ˈ")
				return table.concat(syllables, "·")
			end
		end
	end
	
	return table.concat(syllables, "·")
end

function export.crux(term)
	term = mw.ustring.lower(term)
	
	for _, rule in ipairs(first_rules) do
		term = gsub(term, rule[1], rule[2])
	end
	
	term = syllabify(term)
	
	for _, micrule in ipairs(phonetic_rules) do
		term = gsub(term, micrule[1], micrule[2])
	end
	
	term = gsub(term, "·", ".")
	
	return term
end

function export.show(frame)
	local parent_args = frame:getParent().args
	local params = {
		[1] = { default = mw.title.getCurrentTitle().nsText == 'Template' and "ankyu" or mw.title.getCurrentTitle().text },
	}
	local args = require("Module:parameters").process(parent_args, params)
	local term = args[1]

	local IPA_args = {}
	local phonetic = export.crux(term)
	table.insert(IPA_args, {pron = '[' .. phonetic .. ']'})

	return "* " .. m_IPA.format_IPA_full(lang, IPA_args)
end

return export