Modulo:It-pronunciation

Da Dialetto Metaurense.
⧼vector-jumptonavigation⧽ ⧼vector-jumptosearch⧽

La documentazione per questo modulo può essere creata in Modulo:It-pronunciation/man

local export = {}
local k=" "
local stress = "ˈ"
local long = "ː"
local acute_or_grave = "[" .. mw.ustring.char(0x300, 0x301) .. "]"
local vowels = "æaeɛioɔu"
local vowel = "[" .. vowels .. "]"
local not_vowel = "[^" .. vowels .. "]"
local front = "[eɛij]"
local fronted = mw.ustring.char(0x031F)

local full_affricates = { ["ʦ"] = "t͡s", ["ʣ"] = "d͡z", ["ʧ"] = "t͡ʃ", ["ʤ"] = "d͡ʒ" }

-- ʦ, ʣ, ʧ, ʤ used for
-- t͡s, d͡z, t͡ʃ, d͡ʒ in body of function.

-- voiced_z must be a table of integer indices, a boolean, or nil.
function export.to_phonemic(word, voiced_z, single_character_affricates)
	word = mw.ustring.lower(word)
	if mw.ustring.find(word,"sč") then
          word = mw.ustring.toNFC(word)
	--sč at the end of a word is /ʃ/
          word = word:gsub("sč","ʃ")
        end
        if mw.ustring.find(word,"č") then
          word = mw.ustring.toNFC(word)
	--sč at the end of a word is /ʧ/
          word = word:gsub("č","ʧ")
        end
        if mw.ustring.find(word,"â") then
         word = mw.ustring.toNFC(word)
	 --â at the end of a word is /a/
         if mw.ustring.match(word,"â.")==nil then
           word=word:gsub("â","a ")
         else
         word=word:gsub("â","a")
         end
        end
        if mw.ustring.find(word,"ğ") then
          word = mw.ustring.toNFC(word)
	--ğ at the end of a word is /ʤ/
          word = word:gsub("ğ","ʤ")    
        end

	-- Decompose combining characters: for instance, è → e + ◌̀
	local decomposed = mw.ustring.toNFD(word)
	local all_z_voiced
	if type(voiced_z) == "boolean" then
		all_z_voiced = voiced_z
		voiced_z = nil
	else
		require "libraryUtil".checkTypeMulti("to_IPA", 2, voiced_z,
			{ "table", "boolean", "nil" })
	end
	
	-- Transcriptions must contain an acute or grave, to indicate stress
	-- This does not handle phrases containing more than one stressed word.
	-- Default to penultimate stress rather than throw error?
	
        if not mw.ustring.find(decomposed, acute_or_grave) then
	      -- Allow monosyllabic unstressed words.
	     --local vowel_count = select(2, decomposed:gsub("[æaeiou]", "%1"))
            --if vowel_count ~= 1 then
            transcriptio=mw.ustring.sub(decomposed,-1)
            if transcriptio == 'a' then 
             decomposed = mw.ustring.gsub(decomposed,"(" .. vowel .. ")(" .. not_vowel .. "*" .. vowel .. not_vowel .."*)$","%1" ..  mw.ustring.char(0x301) .. "%2")
             --end
              elseif transcriptio =='e' then 
              decomposed = mw.ustring.gsub(decomposed,"(" .. vowel .. ")(" .. not_vowel .. "*" .. vowel .. not_vowel .."*)$","%1" ..  mw.ustring.char(0x301) .. "%2")
             elseif transcriptio =='o' then 
              decomposed = mw.ustring.gsub(decomposed,"(" .. vowel .. ")(" .. not_vowel .. "*" .. vowel .. not_vowel .."*)$","%1" ..  mw.ustring.char(0x301) .. "%2")
             elseif transcriptio =='i' then 
              decomposed = mw.ustring.gsub(decomposed,"(" .. vowel .. ")(" .. not_vowel .. "*" .. vowel .. not_vowel .."*)$","%1" ..  mw.ustring.char(0x301) .. "%2")
             else
            
              decomposed=mw.ustring.gsub(decomposed,"(".. vowel ..")(" .. not_vowel .. "*)$",'%1' ..mw.ustring.char(0x301).. '%2')
         
	     end

       end
	
	local transcription = decomposed
        
	-- Handle è, ò. \204\128 is the UTF-8 encoding of the combining grave accent.
	transcription = transcription:gsub("([eo])(\204\128)",
		function (vowel, accent)
			return ({ e = "ɛ", o = "ɔ" })[vowel] .. accent
		end) -- e or o followed by grave
	
	-- ci, gi + vowel
	-- Do ci, gi + e, é, è sometimes contain /j/?
	transcription = mw.ustring.gsub(transcription,
		"([cg])([cg]?)i(" .. vowel .. ")",
		function (consonant, double, vowel)
			local out_consonant
			if consonant == "c" then
				out_consonant = "ʧ"
			else
				out_consonant = "ʤ"
			end
			
			if double ~= "" then
				if double ~= consonant then
					error("Invalid sequence " .. first .. double .. ".")
				end
				
				out_consonant = out_consonant .. out_consonant
			end
			
			return out_consonant .. vowel
		end)
	
	-- Handle gl and gn.
	-- Have to do the gsub twice, in case the matches to the pattern overlap,
	-- as in gnagnà.
	for i = 1, 2 do
		transcription = mw.ustring.gsub(transcription,
			"(g[nl])(.?)(.?)",
			function (digraph, after1, after2)
				local consonant
				if digraph == "gn" then
					consonant = "ɲ"
				
				-- gli is /ʎi/, or /ʎ/ before a vowel
				elseif after1 == "i" then
					consonant = "ʎ"
					if after2 ~= "" and vowels:find(after2) then
						after1 = ""
					end
				end
				
				if consonant then
					return consonant .. after1 .. after2
				end
			end)
	end


	-- Handle other cases of c, g.
	transcription = mw.ustring.gsub(transcription,
		"(([cg])([cg]?)(h?)(.?))",
		function (consonant, first, double, second, next)
			-- Don't allow the combinations cg, gc.
			-- Or do something else?
			if double ~= "" and double ~= first then
				error("Invalid sequence " .. first .. double .. ".")
			end
			
			-- c, g is soft before e, i.
			local consonant
			if (next == "e" or next == "ɛ" or next == "i") and second ~= "h" then
                        
				if first == 'c' then
					consonant = "ʧ"
				else
					consonant = "ʤ"
				end
			else
				if first == "c" then
					consonant = "k"
				else
					consonant = "ɡ"
				end
			end
			
			if double ~= "" then
				consonant = consonant .. consonant
			end
			
			return consonant .. next
		end)
	
	-- ⟨qu⟩ represents /kw/.
	transcription = transcription:gsub("qu", "kw")
	
	-- u or i (without accent) before another vowel is a semivowel.
	-- ci, gi + vowel, gli, qu must be dealt with beforehand.
	transcription = mw.ustring.gsub(transcription,
		"([iu])(" .. vowel .. ")",
		function (semivowel, vowel)
			if semivowel == "i" then
				semivowel = "j"
			else
				semivowel = "w"
			end
			
			return semivowel .. vowel
		end)
	
	local z_index = 0
	-- sc before e, i is /ʃ/, doubled between vowels.
	transcription = transcription
		:gsub("sʧ", "ʃ")

	-- ⟨z⟩ represents /t͡s/ or /d͡z/; no way to determine which.
	-- For now, /t͡s/ is the default.
		:gsub("()(z+)",
			function (index, z)
				local length = #z
				if length > 2 then
					error("Too many z's!")
				else
					z_index = z_index + 1
					local z_pronunciation
					if voiced_z and require "Module:table".contains(voiced_z, z_index)
							or all_z_voiced then
						z_pronunciation = "ʣ"
					else
						z_pronunciation = "ʦ"
					end
					-- double z in nazione
					if length == 1 and transcription:sub(index + 1, index + 1) == "j" then
						length = 2
					end
					return z_pronunciation:rep(length)
				end
			end)
	
	-- Replace acute and grave with stress mark.
	transcription = mw.ustring.gsub(transcription,
		"(" .. vowel .. ")" .. acute_or_grave, stress .. "%1")
	
	-- Single ⟨s⟩ between vowels is /z/.
	transcription = mw.ustring.gsub(transcription,
		"(.)s(.)",
		function (before, after)
			if vowels:find(before) and vowels:find(after) then
				return before .. "z" .. after
			end -- else return s
		end)
	-- n a fine parola ha diversa pronuncia
        transcriptio=mw.ustring.sub(transcription,-1)
           if transcriptio=='n' then 
             transcription=transcription..' '
             transcription=mw.ustring.gsub(transcription,'n ','ŋ')
        end
	-- After a vowel, /ʃ ʎ ɲ/ are doubled.
	-- [[w:Italian phonology]] says word-internally, [[w:Help:IPA/Italian]] says
	-- after a vowel.
	transcription = mw.ustring.gsub(transcription, "(.)([ʃʎɲ])",
		function (before, palatal)
			if vowels:find(before) then
				return before .. palatal .. palatal
			end
		end)
	
	-- Move stress before syllable onset, and add syllable breaks.
	-- This rule may need refinement.
	transcription = mw.ustring.gsub(transcription,
		"()(" .. not_vowel .. "?)([^" .. vowels .. stress .. "]*)(" .. stress
			.. "?)(" .. vowel .. ")",
		function (position, first, rest, syllable_divider, vowel)
			-- beginning of word, that is, at the moment, beginning of string
			if position == 1 then
				return syllable_divider .. first .. rest .. vowel
			end
			
			if syllable_divider == "" then
				syllable_divider = "."
			end
			
			if rest == "" then
				return syllable_divider .. first .. vowel
			else
				return first .. syllable_divider .. rest .. vowel
			end
		end)
	
	if not single_character_affricates then
		transcription = mw.ustring.gsub(transcription, "[ʦʣʧʤ]", full_affricates)
	end
	
	return transcription
end

function export.to_phonetic(word, voiced_z)
	local phonetic = export.to_phonemic(word, voiced_z)
	
	-- Vowels longer in stressed, open, non-word-final syllables.
	phonetic = mw.ustring.gsub(phonetic,
		"(" .. stress .. not_vowel .. "*" .. vowel .. ")(.?)",
		function (before, after)
			if after ~= ""
					and (vowels .. "."):find(after) then
				return before .. long .. after
			end
		end)
	
	-- Imperfect: doesn't convert geminated k, g properly.
	phonetic = mw.ustring.gsub(phonetic,
		"([kg])(" .. front .. ")",
		"%1" .. fronted .. "%2")
		:gsub("a", "a")
		:gsub("n", "n̺") -- Converts n before a consonant, which is incorrect.
	
	return phonetic
end

function export.show(frame)
	local m_IPA = require "Module:IPA"
	
	local word, voiced_z
	if type(frame) == "table" then
		local args = require "Module:parameters".process(
			frame:getParent().args,
			{
				[1] = {},
				voiced = {}, -- series of numbers, or boolean
			})
		
		word = args[1]
		if args.voiced then
			local count = 0
			voiced_z = require "Module:fun".map(
				function (item)
					count = count + 1
					return tonumber(item)
						or count == 1 and require "Module:yesno"(item) -- Rejects false values.
						or error("Invalid input '" .. item .."' in |voiced= parameter. "
							.. "Expected number.")
				end,
				mw.text.split(args.voiced, "%s*,%s*"))
			if not voiced_z[2] and type(voiced_z[1]) == "boolean" then
				voiced_z = voiced_z[1]
			end
		end
	else
		word = frame
	end
		
	if not word then
		word = mw.title.getCurrentTitle().text
	end
	
	local transcription = "[" .. export.to_phonetic(word, voiced_z) .. "]"
	
	return m_IPA.format_IPA_full(
		require "Module:languages".getByCode "it",
		{ { pron = transcription } })
end

return export