Module:qay-pron: Difference between revisions

From Linguifex
Jump to navigation Jump to search
No edit summary
No edit summary
Line 14: Line 14:
local export = {}
local export = {}


local consonants = "[mpbvwθntdszlrɾŋɴhɥṛ]"
local consonants = "[pbmvstdnrɾljkɡŋhxçʤʧ]"
local NONSYLLABIC = u(0x032F) -- non-syllabic, combining inverted breve below
local DIPHTHONG = u(0x035C) -- double articulation, combining double breve below
local front = "ie"
local front = "ie"
local back = "ou"
local back = "ou"
local vowels = "[a" .. front .. back .. "]"
local vowels = "[a" .. front .. back .. "ː]"
-- ʤʧ


local function open_to_closed(v)
local function open_to_closed(v)
Line 32: Line 29:
return table.concat(otc)
return table.concat(otc)
end
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 shared_rules = {
{"n[kg]", {["nk"] = "ŋk", ["ng"] = "ŋ"}}, {"c", "ʧ"}, {"j", "ʤ"}, {"y", "j"}, {"g", "ɡ"},
-- Long vowels
{"ā", "aː"},  {"ē", "eː"}, {"ī", "iː"}, {"ō", "oː"}, {"ū", "uː"},
}


local phonemic_rules = {
local phonemic_rules = {
{"ng", "ŋ"}, {"y", "j"}, {"g", "ɡ"}, {"([tkdɡ])j", "%1ʲ"}, {"ā", ""}, {"ē", "eː"}, {"ī", "iː"}, {"ō", "oː"}, {"ū", "uː"},
{"([tkdɡ])j", "%1ʲ"}, {"(" .. consonants .. consonants .. ")", function(c1, c2) return same(c1,c2) and c1 or c1 .. c2 end},
}
}


local phonetic_rules = {
local phonetic_rules = {
{"ng", "ŋ"}, {"y", "j"}, {"g", "ɡ"}, {"nk", "ŋk"}, {"([^nŋ])[tk]j", "%1ʧ"}, {"([^nŋ])[dɡ]j", "%1ʤ"}, {"r", "ɾ"}, {"h([" .. front .. "])", "ç%1"},
{"([^nŋ])[tk]j", "%1ʧ"}, {"([^nŋ])[dɡ]j", "%1ʤ"}, {"r", "ɾ"},
{"h([" .. back .. "])", "x%1"}, {"ā", "aː"},  {"ē", "eː"}, {"ī", "iː"}, {"ō", "oː"}, {"ū", "uː"}, {"a", "ä"},
{"h([" .. front .. "])", "ç%1"}, {"h([" .. back .. "])", "x%1"},  
--{"(" consonants .. vowel)", ""},
}
}


local function write_stress(term)
local function syllabify(term, pos)
--[=[local pattern = "(" .. consonants .. "*".. vowels .. "*" .. consonants .. "-)"
term = gsub(term, "(" .. consonants .. "*)(" .. vowels .. "*)", "%1%2·")
local weight = {}
term = gsub(term, "··", "·"); term = gsub(term, "·$", "")
term = gsub(term, pattern, "·%1")
term = gsub(term, "·(" .. consonants .. ")(" .. consonants .. ")(" .. vowels .. "*)", "%1·%2%3")
term = gsub(term, "", "")
term = gsub(term, "·$", "")
term = gsub(term, "·(" .. consonants .. ")·", "·%1")
term = gsub(term, "·(" .. consonants .. ")$", "%1")
term = gsub(term, "·(" .. consonants .. ")$", "%1")
term = gsub(term, "·(" .. consonants .. ")(" .. consonants .. ")", "%1·%2") 
term = gsub(term, "·(" .. consonants .. ")·", "%1·")
term = gsub(term, "([ptkbdɡ])·([rlṛsz])", "·%1%2")
term = gsub(term, "·(" .. consonants .. "?" .. consonants .. ")$", "%1")
local syllables = split(term, "·")
local syll = split(term, "·"); local noa = {}
if from_module then return #syllables end -- allow other modules to know the number of syllables
local monosyll = {["n"] = "ˈ", ["pron"] = "", ["particle"] = "(ˈ)", ["prep"] = "(ˈ)", ["conj"] = "(ˈ)"}
if #syllables == 1 then return table.concat(syllables) end -- account for monosyllables
if #syll ~= 1 then
for i, syllable in ipairs(syllables) do
if match(term, "[áéíóúĄ]") then
if match(syllable, "[áéíóúý]") then -- if the user inputted manual stress, ignore all the rest
for _, s in ipairs(syll) do
table.insert(syllables, i, "ˈ")
s = remove_acute(s, match(s, "[áéíóúĄ]") and true or false)
return table.concat(syllables)
table.insert(noa, s)
end
end
if match(syllable, consonants .. "$") or match(syllable, "ː$") then weight[i] = "h"
else
elseif match(syllable, NONSYLLABIC .. "$") then weight[i] = "h"
syll[#syll - 1] = "ˈ" .. syll[#syll - 1]
else weight[i] = "l"
end
end
end
end
 
local a, p = weight[#weight-2], weight[#weight-1]
return table.concat(#noa > 1 and noa or syll, "·")
if p == nil then table.insert(syllables, #syllables, "ˈ")
elseif a == nil then table.insert(syllables, #syllables-1, "ˈ")
elseif p == "l" and a == "h" then table.insert(syllables, #syllables-2, "ˈ")
elseif (p == "l" and a == "l") or (p == "h") then table.insert(syllables, #syllables-1, "ˈ")
else table.insert(syllables, #syllables-1, "ˈ") end
return table.concat(syllables)]=]
return term
end
end


function export.phonemic(term)
function export.phonemic(term)
term = mw.ustring.lower(term)
term = mw.ustring.lower(term)
for _, rule in ipairs(shared_rules) do
term = gsub(term, rule[1], rule[2])
end
for _, micrule in ipairs(phonemic_rules) do
for _, micrule in ipairs(phonemic_rules) do
Line 93: Line 97:
function export.phonetic(term)
function export.phonetic(term)
term = mw.ustring.lower(term)
term = mw.ustring.lower(term)
for _, rule in ipairs(shared_rules) do
term = gsub(term, rule[1], rule[2])
end
for _, ticrule in ipairs(phonetic_rules) do
for _, ticrule in ipairs(phonetic_rules) do
term = gsub(term, ticrule[1], ticrule[2])
term = gsub(term, ticrule[1], ticrule[2])
end
end
term = gsub(term, "a", "ä")
return write_stress(term)
return write_stress(term)

Revision as of 21:36, 20 June 2022



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ɾljkɡŋhxçʤʧ]"
local front = "ie"
local back = "ou"
local vowels = "[a" .. front .. back .. "ː]"

local function open_to_closed(v)
	local otc = {}
	local switch = {["e"] = "ɛ", ["i"] = "ɪ", ["ɔ"] = "ɔ", ["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 shared_rules = {
	{"n[kg]", {["nk"] = "ŋk", ["ng"] = "ŋ"}}, {"c", "ʧ"}, {"j", "ʤ"}, {"y", "j"}, {"g", "ɡ"}, 
	-- Long vowels
	{"ā", "aː"},  {"ē", "eː"}, {"ī", "iː"}, {"ō", "oː"}, {"ū", "uː"},
	
}

local phonemic_rules = {
	{"([tkdɡ])j", "%1ʲ"}, {"(" .. consonants .. consonants .. ")", function(c1, c2) return same(c1,c2) and c1 or c1 .. c2 end},
}

local phonetic_rules = {
	{"([^nŋ])[tk]j", "%1ʧ"}, {"([^nŋ])[dɡ]j", "%1ʤ"}, {"r", "ɾ"},
	{"h([" .. front .. "])", "ç%1"}, {"h([" .. back .. "])", "x%1"}, 
	--{"(" consonants .. vowel)", ""},
	
	
	
}

local function syllabify(term, pos)
	term = gsub(term, "(" .. consonants .. "*)(" .. vowels .. "*)", "%1%2·")
	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·")
	
	local syll = split(term, "·"); local noa = {}
	
	local monosyll = {["n"] = "ˈ", ["pron"] = "", ["particle"] = "(ˈ)", ["prep"] = "(ˈ)", ["conj"] = "(ˈ)"}
	
	if #syll ~= 1 then
		if match(term, "[áéíóúĄ]") then
			for _, s in ipairs(syll) do
				s = remove_acute(s, match(s, "[áéíóúĄ]") and true or false)
				table.insert(noa, s)
			end
		else
			syll[#syll - 1] = "ˈ" .. syll[#syll - 1]
		end
	end

	return table.concat(#noa > 1 and noa or syll, "·")
end

function export.phonemic(term)
	term = mw.ustring.lower(term)
	
	for _, rule in ipairs(shared_rules) do
		term = gsub(term, rule[1], rule[2])
	end
	
	for _, micrule in ipairs(phonemic_rules) do
		term = gsub(term, micrule[1], micrule[2])
	end
	
	return write_stress(term)
end

function export.phonetic(term)
	term = mw.ustring.lower(term)
	
	for _, rule in ipairs(shared_rules) do
		term = gsub(term, rule[1], rule[2])
	end
	
	for _, ticrule in ipairs(phonetic_rules) do
		term = gsub(term, ticrule[1], ticrule[2])	
	end
	
	term = gsub(term, "a", "ä")
	
	return write_stress(term)
end

--[=[
local function IPA_span(items)
	local bits = {}
	for _, item in ipairs(items) do
		local bit = "<span style=\"font-size:110%;font-family:Gentium,'DejaVu Sans','Segoe UI',sans-serif>" .. item.pron .. "</span>"
		table.insert(bits, bit)
	end
	return table.concat(bits)
end

local function format_IPA(items)
	return "[[w:IPA chart|IPA]]<sup>([[IPA for High Valyrian|key]])</sup>:&#32;" .. IPA_span(items)
end

function line_format(pronunciation, register)
	local IPA_args = {}
	for _, arg in ipairs(args[1]) do
		local phonemic = export.phonemic(arg)
		local phonetic = export.phonetic(arg)
		table.insert(IPA_args, {pron = '/' .. phonemic .. '/'})
		if phonemic ~= phonetic then
			table.insert(IPA_args, {pron = '[' .. phonetic .. ']'})
		end
	end
end

function separate_word(term, b)
	local result = {}
	
	for word in gsplit(term, " ") do
		if b then table.insert(result, export.antique_crux(word))
		else table.insert(result, export.crux(word)) end
	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 "ankyu" or mw.title.getCurrentTitle().text },
	}
	local args = require("Module:parameters").process(parent_args, params)
	local term = args[1]

	local IPA_args = {}
	local phonemic = export.phonemic(term)
	local phonetic = export.phonetic(term)
	table.insert(IPA_args, {pron = '/' .. phonemic .. '/'})
	if phonemic ~= phonetic then
		table.insert(IPA_args, {pron = '[' .. phonetic .. ']'})
	end

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

return export