Module:sa-pronunc

Hello, you have come here looking for the meaning of the word Module:sa-pronunc. In DICTIOUS you will not only get to know all the dictionary meanings for the word Module:sa-pronunc, but we will also tell you about its etymology, its characteristics and you will know how to say Module:sa-pronunc in singular and plural. Everything you need to know about the word Module:sa-pronunc you have here. The definition of the word Module:sa-pronunc will help you to be more precise and correct when speaking or writing your texts. Knowing the definition ofModule:sa-pronunc, as well as those of other words, enriches your vocabulary and provides you with more and better linguistic resources.

Powers {{sa-IPA}}.


local export = {}

local u = require("Module:string/char")
local gsub = mw.ustring.gsub
local match = mw.ustring.match

local ACUTE     = u(0x0301)
local COARTIC   = u(0x0361)
local DENTAL    = u(0x032A)
local FLAP      = u(0x0306)
local NORELEASE = u(0x031A)
local SYLLABIC  = u(0x0329)
local NASAL     = u(0x0303)

local m_IPA = require("Module:IPA")
local lang = require("Module:languages").getByCode("sa")
local m_a = require("Module:accent qualifier")

local consonants = {
	 = "k",  = "ɡ",  = "kʰ",  = "ɡʱ",  = "ŋ",
	 = "t͡ɕ",  = "d͡ʑ",  = "t͡ɕʰ",  = "d͡ʑʱ",  = "ɲ",
	 = "t",  = "d",  = "tʰ",  = "dʱ",  = "n",
	 = "ʈ",  = "ɖ",  = "ʈʰ",  = "ɖʱ",  = "ɳ",
	 = "p",  = "b",  = "pʰ",  = "bʱ",  = "m",
	 = "j",  = "ɾ",  = "l",  = "ʋ",  = "ɭ̆",  --  = "ɭ̆ʱ",
	 = "ɕ",  = "ʂ",  = "s",  = "ɦ",
}

local diacritics = {
	 = "ɑː",  = "i",  = "iː",  = "u",  = "uː",  = "r̩",  = "r̩ː",
	 = "l̩",  = "l̩ː",  = "ɐj",  = "ɑːj",  = "ɐw",  = "ɑːw",  = "",
}

local vowel_list = {
	 = true,  = true,  = true,  = true,  = true,  = true,  = true,  = true,
	 = true,  = true,  = true,  = true,  = true,  = true, 
}

local stop_list = {
	 = true,  = true,  = true,  = true,
	 = true,  = true,  = true,  = true,
	 = true,  = true,  = true,  = true,
	 = true,  = true,  = true,  = true, 
	 = true,  = true,  = true,  = true,
}

local consonant_sonority = {
	-- voiceless stops and affricates
	 = 1,  = 1,
	 = 1,  = 1,
	 = 1,  = 1,
	 = 1,  = 1,
	 = 1,  = 1,
	-- voiceless fricatives
	 = 2,  = 2,  = 2,  = 2,  = 2,  = 2,
	-- voiced stops and affricates
	 = 3,  = 3,
	 = 3,  = 3,
	 = 3,  = 3,
	 = 3,  = 3,
	 = 3,  = 3,
	-- voiced fricatives
	 = 4,
	-- nasals
	 = 5,  = 5,  = 5,  = 5,  = 5,  = 5,  = 5,
	-- flaps
	 = 6,
	-- laterals
	 = 7,  = 7,  = 7,
	-- glides
	 = 8,  = 8,
}

local tt = {
	-- vowels
	 = "ɐ",  = "ɑː",  = "i",  = "iː",  = "u",  = "uː",  = "r̩",  = "r̩ː",
	 = "l̩",  = "l̩ː",  = "ɐj",  = "ɑːj",  = "ɐw",  = "ɑːw", 
	-- visarga    
	 = "h",
	-- chandrabindu
	 = "m̐",
	-- anusvara
	 = "ṃ",
	-- avagraha
	 = "",
    --Vedic extensions
     = "x",  = "ɸ",
}

local accent_vowel = {
	 = "ɐ́",  = "ɑ́ː",  = "í",  = "íː",  = "ú",  = "úː",  = "ŕ̩",  = "ŕ̩ː",
	 = "ĺ̩",  = "ĺ̩ː",  = "ɐ́j",  = "ɑ́ːj",  = "ɐ́w",  = "ɑ́ːw", 
}

local function shift_to_codas(syllables)
	-- shift codas to previous syllable using the Weerasinghe-Wasala-Gamage method 
	local to_move = 0
	for i, syll in ipairs(syllables) do
		if i == 1 then
			-- no need to shift to coda if in the first syllable
		elseif #syll < 3 then
			-- coda movement only needed for onset clusters of 2 or more
		elseif #syll == 3 then
			-- V.CCV => VC.CV
			to_move = 1
		elseif #syll == 4 then
			if syll == "ɾ" or syll == "j" or (stop_list] and stop_list]) then
				-- V.CCrV or V.CCyV => VC.CrV or VC.CyV
				-- if the first two consonants are stops, VC.CCV
				to_move = 1
			else
				-- V.CCCV => VCC.CV
				to_move = 2
			end
		else
			-- 4 consonants or more
			if syll == "ɾ" or syll == "j" then
				to_move = #syll - 3
			else
				-- find index of consonant of least sonority
				to_move = #syll - 1
				local min_son = consonant_sonority]
				for i = (#syll - 1), 1, -1 do
					if consonant_sonority] < min_son then
						to_move = i
						min_son = consonant_sonority]
					end
				end
			end
		end
	
		while to_move > 0 do
			table.insert(syllables, table.remove(syllables, 1))
			to_move = to_move - 1
		end
	end
	return syllables
end

local function syllabify(remainder, accent)
	local syllables = {}
	local syll = {}
	
	while #remainder > 0 do
		local phoneme = table.remove(remainder, 1)
		
		if vowel_list then
			table.insert(syll, phoneme)
			table.insert(syllables, syll)
			syll = {}
		else
			table.insert(syll, phoneme)
		end
	end
	-- store whatever consonants remain
	local final_cons = syll
	
	-- Vedic pitch accent
	if accent ~= nil and accent <= #syllables then
		syll = syllables
		syllables = accent_vowel]
	end
	
	syllables = shift_to_codas(syllables)
	
	-- it is not necessary to include 'l' in the pattern for short vowels as it doesn't occur as a vowel in syllable coda and as consonantal 'l' would then be erroneously included
	local short_vowel_patt = "^" .. SYLLABIC .. "?" .. ACUTE .. "?$"

	-- Classic stress accent
	local num_sylls = #syllables
	if num_sylls == 2 then
		table.insert(syllables, 1, 'ˈ')
	elseif num_sylls == 3 then
		-- if the final segment of the second syllable is not a short vowel, stress the second syllable
		if match(syllables], short_vowel_patt) == nil then
			table.insert(syllables, 1, 'ˈ')
		-- else stress the third
		else
			table.insert(syllables, 1, 'ˈ')
		end
	elseif num_sylls >= 4 then
		if match(syllables], short_vowel_patt) == nil then
			table.insert(syllables, 1, 'ˈ')
		elseif match(syllables], short_vowel_patt) == nil then
			table.insert(syllables, 1, 'ˈ')
		else
			table.insert(syllables, 1, 'ˈ')
		end
	end

	-- If there are phonemes left, then the word ends in a consonant
	-- Add them to the last syllable
	for _, phoneme in ipairs(final_cons) do
		table.insert(syllables, phoneme)
	end
	
	for i, _ in ipairs(syllables) do
		syllables = table.concat(syllables, "")
	end
	
	return table.concat(syllables, ".")
end

local anu_to_nasals = {
	 = "ŋ",  = "ŋ",
	 = "ɲ",  = "ɲ",
	 = "n",  = "n",
	 = "ɳ",  = "ɳ",
	 = "m",  = "m",
}

local function anusvara(text)
	text = gsub(text, "ṃ$", "m")
	text = gsub(
		text,
		"ṃ(?)()(?)(?)",
		function(div, cons, mark, fric)
			return anu_to_nasals .. div .. cons .. mark .. fric
		end
	)
	text = gsub(
		text,
		"()(" .. SYLLABIC .. "?)(" .. ACUTE .. "?)(ː?)(?)ṃ",
		"%1%2" .. NASAL .. "%3%4%5"
	)
	text = gsub(text, "ṃ", "ɴ")
	return text
end

local function convert_word(word, accent)
	local chars = {}
	local t = {}
	
	gsub(word, ".", function(c) table.insert(chars, c) end)
	
	for i, c in ipairs(chars) do
		if consonants then
			table.insert(t, consonants)
			if not diacritics] then
				table.insert(t, "ɐ")
			end
		elseif c == "्" then
			-- do nothing
		elseif diacritics then
			table.insert(t, diacritics)
		elseif tt then
			table.insert(t, tt)
		end
	end
	
	word = syllabify(t, accent)
	
	word = gsub(word, "%.ˈ", "ˈ")
	
	-- correction for ळ्ह = ɭ̆ʱ
	word = gsub(word, "ɭ̆(?)ɦ", "%1ɭ̆ʱ")
	
	-- chandrabindu
	word = gsub(
		word,
		"()(" .. SYLLABIC .. "?)(" .. ACUTE .. "?)(ː?)(?)m̐",
		"%1%2" .. NASAL .. "%3%4%5"
	)
	return word
end

local function convert_words(words, accents)
	local result = {}
	
	local word_num = 1
	for word in mw.text.gsplit(words, " ") do
		table.insert(result, convert_word(word, accents))
		word_num = word_num + 1
	end
	
	text = table.concat(result, " ")
	
	return text
end

local function phon_procs(text)
	-- Anusvāra
	text = anusvara(text)
	
	return text
end

local function abhinidhana_phonemic(text)
	--de-aspirate and de-affricate before stops
	text = gsub(
		text,
		"()(" .. DENTAL .. "?)?(?)()",
		"%1%2%3%4"
	)
	text = gsub(
		text,
		"()" .. COARTIC .. "?(?)()",
		"%1%2%3"
	)
	return text
end

local function abhinidhana_phonetic(text)
	text = gsub(
		text,
		"()(" .. DENTAL .. "?)(?)()",
		"%1%2" .. NORELEASE .. "%3%4"
	)
	return text
end

local superscript = {
	 = "ɐ̆",
	 = "ɑ̆",
	 = "ĕ",
	 = "ŏ",
	 = "ĭ",
	 = "ŭ",
}

local function make_dialects(text)
	local dialects = {}
	
	text = abhinidhana_phonemic(text)

	-- Rigvedic Sanskrit
	local rig_phnm = text
	rig_phnm = gsub(rig_phnm, "^ˈ", "")
	rig_phnm = gsub(rig_phnm, "ˈ", ".")
	rig_phnm = gsub(rig_phnm, " %.", " ")
	
	local rig_phnt = abhinidhana_phonetic(rig_phnm)
	-- visarga alternation
	rig_phnt = gsub(rig_phnt, "h(?)()", "ɸ%1%2")
	rig_phnt = gsub(rig_phnt, "h(?)()", "x%1%2")
	-- nasalized semivowels
	rig_phnt = gsub(
		rig_phnt,
		"()(" .. DENTAL .. "?)(?)()(?)(ʱ?)",
		"%4%5" .. NASAL .. "%3%4%5%6"
	)
	
	dialects = {
		label = "Vedic",
		phonemic = rig_phnm,
		phonetic = rig_phnt,
	}
	
	-- Classical Sanskrit
	local cla_phnm = text
	cla_phnm = gsub(cla_phnm, "", { = "e",  = "o",  = "i",  = "u",  = "",  = "r"})
	cla_phnm = gsub(cla_phnm, "ɐ(" .. NASAL .. "?)j", "e%1ː")
	cla_phnm = gsub(cla_phnm, "ɐ(" .. NASAL .. "?)w", "o%1ː")
	cla_phnm = gsub(cla_phnm, "ɑ(" .. NASAL .. "?)ː()", "ɑ%1%2")
	
	-- Add dental diacritic to t, d, tʰ, dʱ, n, l, s.
	cla_phnm = gsub(
	    cla_phnm,
	    "(" .. COARTIC .. "??)(?)",
	    function(base_consonant, aspiration)
	        if base_consonant == "t" or base_consonant == "d" then
	            return base_consonant .. DENTAL .. aspiration
	        end
	    end
    )
	cla_phnm = gsub(cla_phnm, NASAL .. "?()", "%1" .. DENTAL)
	
	local cla_phnt = abhinidhana_phonetic(cla_phnm)
	-- cla_pron = gsub(cla_pron, "r̩(" .. NASAL .. "?)(" .. ACUTE .. "?)(ː?)", "ɾi%1%2%3")
	-- cla_pron = gsub(cla_pron, "l̩(" .. NASAL .. "?)(" .. ACUTE .. "?)(ː?)", "l̪i%1%2%3")
	
	cla_phnt = gsub(
		cla_phnt,
		"()(" .. NASAL .. "?)(ː?)(?)h$",
		function (vow, nas, length, glide)
			return vow .. nas .. length .. glide .. "h" .. superscript
		end
	)
	cla_phnt = gsub(
		cla_phnt,
		"()(" .. NASAL .. "?)(ː?)(?)h ",
		function (vow, nas, length, glide)
			return vow .. nas .. length .. glide .. "h" .. superscript .. " "
		end
	)
	
	dialects = {
		label = "Classical Sanskrit",
		phonemic = cla_phnm,
		phonetic = cla_phnt,
	}
	
	return dialects
end

local function make_table(dialects, novedic, noclassical)
	local dial_types = {'rig', 'cla'}
	
	if novedic then
		table.remove(dial_types, 1)
	end
	
	if noclassical then
		table.remove(dial_types, 2)
	end
	
	if #dial_types == 1 then
		local dial = dial_types
		local IPA_args = {{pron = '/' .. dialects.phonemic .. '/'}}
		if dialects.phonemic ~= dialects.phonetic then
			table.insert(IPA_args, {pron = '.phonetic .. ']'})
		end
		return table.concat{
			'\n* ',
			m_a.format_qualifiers(lang, {dialects.label}),
			' ',
			m_IPA.format_IPA_full { lang = lang, items = IPA_args },
		}
	else
		
		local inline_args = {{pron = '/' .. dialects.cla.phonemic .. '/'}}
		
		if dialects.cla.phonemic ~= dialects.cla.phonetic then
			table.insert(inline_args, {pron = ''})
		end
		
		local full = {}
		for _, dial in ipairs(dial_types) do
			local full_args = {{pron = '/' .. dialects.phonemic .. '/'}}
			if dialects.phonemic ~= dialects.phonetic then
				table.insert(full_args, {pron = '.phonetic ..']'})
			end
			table.insert(full, table.concat{
				'\n* ',
				m_a.format_qualifiers(lang, {dialects.label}),
				' ',
				m_IPA.format_IPA_full { lang = lang, items = full_args },
			})
		end
		
		return table.concat(full, "")
	end
end

function export.show(frame)
	local params = {
		 = {alias_of = 'w'},
		w = {default = mw.title.getCurrentTitle().text},
		a = {list = true, allow_holes = true, type = 'number'},
		novedic = {type = 'boolean'},
		noclassical = {type = 'boolean'}
	}
	
	local args = require("Module:parameters").process(frame:getParent().args, params)
	
	local text = convert_words(args.w, args.a)
	
	text = phon_procs(text)
	
	local dialects = make_dialects(text)
	
	return make_table(dialects, args.novedic, args.noclassical)
end

return export