Module:qay-pron: Difference between revisions

From Linguifex
Jump to navigation Jump to search
No edit summary
No edit summary
 
(135 intermediate revisions by the same user not shown)
Line 14: Line 14:
local export = {}
local export = {}


local palatal = "ɲʎɟj"
local consonants = "[pbmvstdnrɾlkɡŋhxçʤʧjwçx2]"
local velar = "kɡxɣ"
local front = "iɪeɛ"
local uvular = "q"
local back = "oɔuʊ"
local consonants = "[mpbvwθntdszlrɾŋɴhɥṛ" .. palatal .. velar .. uvular .. "]"
local vowels = "[a" .. front .. back .. "ː´2]"
local NONSYLLABIC = u(0x032F) -- non-syllabic, combining inverted breve below
local DIPHTHONG = u(0x035C) -- double articulation, combining double breve below
local vowels = "[aeiouyáéíóúýàèìòùỳː" .. NONSYLLABIC .. DIPHTHONG .. "]"


local phonemic_rules = {
local function laxen(v)
{"([tkdg])y", "&1ʲ"},
local otc = {}
}
local switch = {["e"] = "ɛ", ["i"] = "ɪ", ["o"] = "ɔ", ["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 phonetic_rules = {
local function same(foo, bar)
{"[tk]y", "ʧ"}, {"[dg]y", "ʤ"}
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 deacuter = {
local first_rules = {
["á"] = "a", ["é"] = "e", ["í"] = "i", ["ó"] = "o", ["ú"] = "u", ["ý"] = "y",
{"n(·?)([kg])", "ŋ%1%2"}, {"ŋg", "ŋ"}, {"c", "ʧ"}, {"j", "ʤ"}, {"y", "j"}, {"g", "ɡ"}, {"%-", ""},
-- Long vowels
{"ā", "aː"},  {"ē", ""}, {"ī", ""}, {"ō", ""}, {"ū", ""},
-- Diphthongs
{"au", ""}, {"[uʊ]ji", "wi"}, {"h?u([aeiouɛɪɔʊ])", "w%1"},
}
}


local function write_stress(term)
local phonetic_rules = {
--[=[local pattern = "(" .. consonants .. "*".. vowels .. "*" .. consonants .. "-)"
{"([ˈˌ])·", "%1"}, {"·([ˈˌ])", "%1"}, {"ˈˌ", "ˌ"}, {"·ˈ´·", "ˈ"},
local weight = {}
term = gsub(term, pattern, "·%1")
term = gsub(term, "^·", "")
term = gsub(term, "·$", "")
term = gsub(term, "·(" .. consonants .. ")·", "·%1")
term = gsub(term, "·(" .. consonants .. ")$", "%1")
term = gsub(term, "·(" .. consonants .. ")(" .. consonants .. ")", "%1·%2"
term = gsub(term, "([ptkbdɡ])·([rlṛsz])", "·%1%2")
term = gsub(term, "·(" .. consonants .. "?" .. consonants .. ")$", "%1")
local syllables = split(term, "·")
{"h([" .. front .. "])", "ç%1"}, {"h([" .. back .. "])", "x%1"},
{"([^nŋ]·)[tk]j", "%1ʧ"}, {"([^nŋ]·)[dɡ]j", "%1ʤ"}, {"r", "ɾ"}, {"k([·ˈ])w", "%1kw"}, {"s([·ˈ])j", "%1sj"},
if from_module then return #syllables end -- allow other modules to know the number of syllables
-- 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},
if #syllables == 1 then return table.concat(syllables) end -- account for monosyllables
-- Doubled consonants are reduced to one
for i, syllable in ipairs(syllables) do
{"(" .. consonants .. ")(·?ˈ?)(" .. consonants .. ")", function(c1, st, c2) return same(c1,c2) and st .. c1 or c1 .. st .. c2 end},
if match(syllable, "[áéíóúý]") then -- if the user inputted manual stress, ignore all the rest
{"jj", "j"},
table.insert(syllables, i, "ˈ")
return table.concat(syllables)
end
if match(syllable, consonants .. "$") or match(syllable, "ː$") then weight[i] = "h"
elseif match(syllable, NONSYLLABIC .. "$") then weight[i] = "h"
else weight[i] = "l"
end
end
local a, p = weight[#weight-2], weight[#weight-1]
-- Diphthongs
if p == nil then table.insert(syllables, #syllables, "ˈ")
{"(" .. vowels .. ")j$", "%1ɪ"},
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)]=]
{"(·" .. consonants .. ")e$", "%1ə"}, {"a", "ä"},
return term
{"ʤ", "d͡ʒ"}, {"ʧ", "t͡ʃ"},
end
}


function export.phonemic(term)
local function syllabify(word)
term = mw.ustring.lower(term)
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, "·");
for _, micrule in ipairs(phonemic_rules) do
if #syllables ~= 1 then
term = gsub(term, micrule[1], micrule[2])
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
end
return write_stress(term)
return table.concat(syllables, "·")
end
end


function export.phonetic(term)
function export.crux(term)
term = mw.ustring.lower(term)
term = mw.ustring.lower(term)
for _, ticrule in ipairs(phonetic_rules) do
for _, rule in ipairs(first_rules) do
term = gsub(term, ticrule[1], ticrule[2])
term = gsub(term, rule[1], rule[2])
end
end
return write_stress(term)
term = syllabify(term)
end
 
for _, rule in ipairs(phonetic_rules) do
--[=[
term = gsub(term, rule[1], rule[2])
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
end
return table.concat(bits)
term = gsub(term, "·", ".")
term = gsub(term, "%.%.", ".")
return term
end
end


local function format_IPA(items)
function separate_word(term)
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 = {}
local result = {}
for word in gsplit(term, " ") do
for word in gsplit(term, " ") do
if b then table.insert(result, export.antique_crux(word))
table.insert(result, export.crux(word))
else table.insert(result, export.crux(word)) end
end
end
return table.concat(result, " ")
return table.concat(result, " ")
end
end
]=]


function export.show(frame)
function export.show(frame)
Line 140: Line 148:


local IPA_args = {}
local IPA_args = {}
local phonemic = export.phonemic(term)
local phonetic = separate_word(term)
local phonetic = export.phonetic(term)
table.insert(IPA_args, {pron = '[' .. phonetic .. ']'})
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)
return "* " .. m_IPA.format_IPA_full({lang = lang, items = IPA_args})
end
end


return export
return export

Latest revision as of 15:07, 7 August 2024



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çx2]"
local front = "iɪeɛ"
local back = "oɔuʊ"
local vowels = "[a" .. front .. back .. "ː´2]"

local function laxen(v)
	local otc = {}
	local switch = {["e"] = "ɛ", ["i"] = "ɪ", ["o"] = "ɔ", ["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 = {
	{"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 = {
	{"([ˈˌ])·", "%1"}, {"·([ˈˌ])", "%1"}, {"ˈˌ", "ˌ"}, {"·ˈ´·", "ˈ"},
	
	{"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", "ä"},
	{"ʤ", "d͡ʒ"}, {"ʧ", "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)
	term = mw.ustring.lower(term)
	
	for _, rule in ipairs(first_rules) do
		term = gsub(term, rule[1], rule[2])
	end
	
	term = syllabify(term)
	
	for _, rule in ipairs(phonetic_rules) do
		term = gsub(term, rule[1], rule[2])
	end
	
	term = gsub(term, "·", ".")
	term = gsub(term, "%.%.", ".")
	
	return term
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 "ankyu" 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