Module:kilta-pron: Difference between revisions

From Linguifex
Jump to navigation Jump to search
No edit summary
No edit summary
Line 13: Line 13:
local m_IPA = require("Module:IPA")
local m_IPA = require("Module:IPA")


local consonants = "[pβmtsnɾlʧkxʷqƕᵷʤɡbvdː]"
local consonants = "[pβmtsnɾlʧkxʷqhyʤɡbvdː]"
local vowels = "[aeiouáéíóúəïüʔ]"
local vowels = "[aeiouáéíóúəïüʔ]"


Line 37: Line 37:
local phonemic_rules = {
local phonemic_rules = {
{"%-$", ""}, {"%-", " "},
{"%-$", ""}, {"%-", " "},
{"hw", "ƕ"}, {"kw", "q"}, {"ch", "ʧ"}, {"au", "ü"}, {"ai", "ï"},
{"h", "x"}, {"hw", "h"}, {"kw", "q"}, {"ch", "ʧ"}, {"au", "ü"}, {"ai", "ï"},
{"v", "β"}, {"r", "ɾ"}, {"h", "x"},
{"v", "β"}, {"r", "ɾ"},  
{"ë", "ə"}, {"ëë+", "əː"}, --
{"ë", "ə"}, {"ëë+", "əː"}, --
Line 49: Line 49:
{"a(ː?·?ˈ?)([nm])", "æ%1%2"},
{"a(ː?·?ˈ?)([nm])", "æ%1%2"},
{"n(ː?·?ˈ?)([kxqƕ])", "ŋ%1%2"},
{"n(ː?·?ˈ?)([kxqƕ])", "ŋ%1%2"},
{"([nm])·k", "%1·ɡ"}, {"([nm])·q", "%1·ᵷ"}, {"([nm])·p", "%1·b"}, {"([nm])·ʧ", "%1·ʤ"},
{"([nm])·k", "%1·ɡ"}, {"([nm])·q", "%1·y"}, {"([nm])·p", "%1·b"}, {"([nm])·ʧ", "%1·ʤ"},
{"([nm])·t", "%1·d"},  
{"([nm])·t", "%1·d"},  
{"([nm])(ː?·?ˈ?)β", "%1%2b"},
{"([nm])(ː?·?ˈ?)β", "%1%2b"},
Line 57: Line 57:


local last_rules = {
local last_rules = {
{"q", "kʷ"}, {"ƕ", "xʷ"}, {"", "ɡʷ"},
{"q", "kʷ"}, {"h", "xʷ"}, {"y", "ɡʷ"},
{"ʧ", "t͡ʃ"},
{"ʧ", "t͡ʃ"},
{"ʤ", "d͡ʒ"},
{"ʤ", "d͡ʒ"},

Revision as of 21:38, 20 April 2024

Documentation for this module may be created at Module:kilta-pron/doc

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 gsplit = mw.text.gsplit

local A = u(0x0301) -- COMBINING ACUTE
local D = u(0x0308) -- COMBINING DIAERESIS

local lang = require("Module:languages").getByCode("kilta")
local m_IPA = require("Module:IPA")

local consonants = "[pβmtsnɾlʧkxʷqhyʤɡbvdː]"
local vowels = "[aeiouáéíóúəïüʔ]"

local export = {}

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 function split (input, sep)
    if sep == nil then sep = "%s" end
    
    local t = {}
    for str in gmatch(input, "([^" .. sep .. "]+)") do
		table.insert(t, str)
    end
    
    return t
end

local phonemic_rules = {
	{"%-$", ""}, {"%-", " "},
	{"h", "x"}, {"hw", "h"}, {"kw", "q"}, {"ch", "ʧ"}, {"au", "ü"}, {"ai", "ï"},
	
	{"v", "β"}, {"r", "ɾ"}, 
	{"ë", "ə"}, {"ëë+", "əː"}, --
	
	{"kq", "qː"}, {"(" .. consonants .. ")(" .. consonants .. ")",
		function(c1,c2) return same(c1,c2) and c1 .. "ː" or c1 .. c2 end},
}

local phonetic_rules = {
	{"a(ː?·?ˈ?)([nm])", "æ%1%2"},
	{"n(ː?·?ˈ?)([kxqƕ])", "ŋ%1%2"},
	{"([nm])·k", "%1·ɡ"}, {"([nm])·q", "%1·y"}, {"([nm])·p", "%1·b"}, {"([nm])·ʧ", "%1·ʤ"},
	{"([nm])·t", "%1·d"}, 
	{"([nm])(ː?·?ˈ?)β", "%1%2b"},
	{"β([ie])", "v%1"},
	{"^(ˈ?)(" .. vowels .. ")", "%1ʔ%2"},
}

local last_rules = {
	{"q", "kʷ"}, {"h", "xʷ"}, {"y", "ɡʷ"},
	{"ʧ", "t͡ʃ"},
	{"ʤ", "d͡ʒ"},
	{"ü", "au̯"},
	{"ï", "ai̯"},
	{"[·%.]ˈ", "ˈ"}, {"·", "."}, {"([áéíóú])", function(v) return mw.ustring.toNFD(v):gsub(A, "ː") end},
}

local function syllabify(term)
	local iskolan = term == "kolaːn"
	local syllable = "(" .. consonants .. "*" .. vowels .. consonants .. "-)"
	term = term:gsub("(" .. consonants .. ")ː", "%1·%1")
	term = term:gsub("q·q", "k·q")
	term = term:gsub(syllable, "·%1·")
	term = term:gsub("^·", "")
	term = term:gsub("·$", "")
	term = term:gsub("·+", "·")
	
	term = term:gsub("·([nlɾs])([pβmtʧkxʷqƕː])", "%1·%2")
	term = term:gsub("·([tmnlɾs])$", "%1")
	term = term:gsub("·(" .. consonants .. ")·", "%1·")
	
	local syllables = split(term, "·")
	if iskolan then
		syllables[#syllables] = "ˈ" .. syllables[#syllables] -- ultimate stress
	elseif #syllables > 1 then
		syllables[#syllables - 1] = "ˈ" .. syllables[#syllables - 1] -- penultimate stress
	else
		error("debug: " .. #syllables)
	end
	
	return table.concat(syllables, "·")
end

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

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

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

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

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

return export