Module:qlu-pron

From Linguifex
Revision as of 16:52, 23 January 2025 by Sware (talk | contribs)
Jump to navigation Jump to search


This module is still on development.

This module generates IPA pronunciation for Luthic words. Backend to {{qlu-IPA}}.


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("qlu")
local m_table = require("Module:table")
local m_IPA = require("Module:IPA")
local c = require("Module:languages/data").chars

local export = {}

local voiced = "mnɲŋbdɡβvzðɣʣʤlʎrɹɾʁʒʥǵ"
local voiceless = "ptʈkɸfsθʃxʦʧʨḱ"
local consonants = "[" .. voiced .. voiceless .. "ʷːjw]"
local front = "iĭïeêɛɪæyʏøœ"
local back = "uoɔʊʌɑɒ"
local vowels = "[aɐ" .. front .. back .. "ːjw]"

local function laxen(v)
	local otc = {}
	local switch = {["e"] = "i", ["i"] = "ɪ", ["u"] = "ʊ"}
		 
	for vc in gmatch(v, ".") do
		if switch[vc] then vc = gsub(vc, vc, switch[vc]) end
		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 = {
	-- vowel digraphs
	{"ăe", "ɛ" .. c.breve}, {"âe", "ɛ" .. c.circ}, {"ae", "ɛ"},
	{"ău", "ɔ" .. c.breve}, {"âu", "ɔ" .. c.circ}, {"au", "ɔ"},
	{"ĕi", "ĭ"}, {"ei", "i"},
	
	{"ch", "k"}, 
	{"sc([eêiĭï])", "ʃ%1"}, {"c([eêiĭï])", "ʧ%1"},
	{"g([ckqg])", "ŋ%1"}, {"g([eêiĭï])", "ʤ%1"}, {"gh", "g"},
	{"c", "k"}, {"ŋʤ", "dʤ"},
	
	{"ŋgü", "gǵ"}, {"gu(" .. vowels .. ")", "ǵ%1"},
	{"gl([iĭï])", "ʎ%1"}, {"gn([iĭï])", "ɲ%1"},
	
	{"ts", "ʦ"}, {"ph", "ɸ"}, {"th", "ʈ"}, --{"h", ""},
	{"qu?", "ḱ"}, {"þ", "θ"},
	
	{"%-", ""},
}

local phonetic_rules = {

}

local last_rules = {
	-- Escaped characters
	{"ʤ", "d͡ʒ"}, {"ʧ", "t͡ʃ"}, {"ʦ", "t͡s"}, {"ʣ", "d͡z"},
	{"ḱ", "kʷ"}, {"ǵ", "ɡʷ"}, {"ʈ", "t"},
}

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

function export.crux(term, outputs)
	term = mw.ustring.lower(term)
	
	for _, rule in ipairs(first_rules) do
		term = gsub(term, rule[1], rule[2])
	end
	
	term = syllabify(term)
	
	local phonemic = term
	--[[for _, rule in ipairs(phonemic_rules) do
		phonemic = gsub(phonemic, rule[1], rule[2])
	end]]
	
	local phonetic = phonemic
	--[[for _, rule in ipairs(phonetic_rules) do
		phonetic = gsub(phonetic, rule[1], rule[2])
	end]]
	
	term = gsub(term, "·", ".")
	term = gsub(term, "%.%.", ".")
	
	for _, rule in ipairs(last_rules) do
		phonemic = gsub(phonemic, rule[1], rule[2])
		phonetic = gsub(phonetic, rule[1], rule[2])
	end

	if outputs == "phonemic" then
		return phonemic
	elseif not outputs or outputs == "phonetic" then
		return phonetic
	elseif outputs == "test" then
		return "/" .. phonemic .. "/ [" .. phonetic .. "]"
	end
	
	return phonetic
end

function separate_word(term)
	local result = {}
	
	for word in gsplit(term, " ") do
		table.insert(result, export.crux(word))
	end
	
	return table.concat(result, " ")
end

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

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

	return "* " .. m_IPA.format_IPA_full({lang = lang, items = IPA_args})
end

return export