Module:eu-pron

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

This module is not to be directly used. It is used by Template:eu-IPA, see there for usage. Template:eu-pr uses Module:eu-pron/new.


-- Based on ] by: Benwing
-- Adapted by Santi2222

local export = {}

local m_IPA = require("Module:IPA")
local m_str_utils = require("Module:string utilities")

local lang = require("Module:languages").getByCode("eu")

local u = m_str_utils.char
local rsubn = m_str_utils.gsub
local rsplit = m_str_utils.split
local toNFC = mw.ustring.toNFC
local toNFD = mw.ustring.toNFD
local ulower = m_str_utils.lower
local ulen = m_str_utils.len

local TILDE = u(0x0303) -- tilde =  ̃

local vowel = "aeiou" -- vowel;
local V = ""
local W = "" -- glide
local separator = "# ."
local separator_c = ""
local C = "" -- consonant

-- version of rsubn() that discards all but the first return value
local function rsub(term, foo, bar)
	local retval = rsubn(term, foo, bar)
	return retval
end

-- version of rsubn() that returns a 2nd argument boolean indicating whether
-- a substitution was made.
local function rsubb(term, foo, bar)
	local retval, nsubs = rsubn(term, foo, bar)
	return retval, nsubs > 0
end

-- apply rsub() repeatedly until no change
local function rsub_repeatedly(term, foo, bar)
	while true do
		local new_term = rsub(term, foo, bar)
		if new_term == term then
			return term
		end
		term = new_term
	end
end

-- style == one of the following:
-- "northern_style": lack of palatalization, /h/, <j> = /j/
-- "southern_style": palatalization, lack of /h/, <j> = /x/

function export.IPA(text, style, phonetic)

	local northern = style == "northern_style"
	local n_diff = false

	text = ulower(text or mw.title.getCurrentTitle().text)
	-- decompose everything but ñ
	text = toNFD(text)
	text = rsub(text, ".", {
		 = "ñ",
	})
	-- convert commas and en/en dashes to IPA foot boundaries
	text = rsub(text, "%s*%s*", " | ")
	-- question mark or exclamation point in the middle of a sentence -> IPA foot boundary
	text = rsub(text, "()%s*%s*()", "%1 | %2")

	-- canonicalize multiple spaces and remove leading and trailing spaces
	local function canon_spaces(text)
		text = rsub(text, "%s+", " ")
		text = rsub(text, "^ ", "")
		text = rsub(text, " $", "")
		return text
	end

	text = canon_spaces(text)

	-- Convert hyphens to spaces
	text = rsub(text, "%-", " ")
	-- canonicalize multiple spaces again, which may have been introduced by hyphens
	text = canon_spaces(text)
	-- now eliminate punctuation
	text = rsub(text, "", "")
	-- put # at word beginning and end and double ## at text/foot boundary beginning/end
	text = rsub(text, " | ", "# | #")
	text = "##" .. rsub(text, " ", "# #") .. "##"

	--cases in which <j> is always /x/ (requires respelling)
	text = rsubb(text, "kh", "X")

	--determining whether "h" denotes a phoneme, or the lack of palatalization, palatalization when needed
	text = rsub(text, "nh", "N")
	text = rsub(text, "lh", "L")

	text = rsub(text, "()il(*)", (northern and "%1ił%2" or "%1ĺ%2"))
	text = rsub(text, "()in(*)", (northern and "%1iň%2" or "%1ń%2"))

	text = rsub(text, "uin(*)", (northern and "uiň%1" or "uiń%1"))
	text = rsub(text, "uil(*)", (northern and "uił%1" or "uiĺ%1"))

	text = rsub(text, "il(*)", (northern and "ił%1" or "iĺ%1"))
	text = rsub(text, "in(*)", (northern and "iň%1" or "iń%1"))

	if text:find("") then
		n_diff = true
	end

	text = rsub(text, "ĺ", "ʎ")
	text = rsub(text, "ń", "ɲ")
	text = rsub(text, "N", "n")
	text = rsub(text, "L", "l")
	text = rsub(text, "ň", "n")
	text = rsub(text, "ł", "l")

	--c, g, q
	text = rsub(text, "ng()", "n%1") -- ], ], etc.
	text = rsub(text, "q", "k") -- ], ], ], ], etc.
	text = rsub(text, "c", "k") -- ], etc.

	--alphabet-to-phoneme
	text = rsub(text, "tx", "C") --not the real sound
	text = rsub(text, "tz", "Ś") --not the real sound
	text = rsub(text, "ts", "S") --not the real sound
	text = rsubb(text, "ll", "ʎ")
	text = rsubb(text, "dd", "ɟ")
	text = rsubb(text, "tt", "c")
	text = rsub(text, "x", "ʃ")
	text = rsub(text, "#p()", "#%1") -- ], ]
	text = rsub(text, "",
			{  = "ɡ",  = "ɲ",  = "b",  = "ś" })

	--/x/ sound
	text = rsubb(text, "j", (northern and "J" or "x"))
	if text:find("") then
		n_diff = true
	end
	text = rsub(text, "J", "j")

	--cases in which <j> is always /j/ (requires respelling)
	text = rsubb(text, "y", "j")

	-- trilled r (in all cases except between vowels)
	text = rsub(text, "()r()", "%1ɾ%2")
	text = rsub(text, "()r()", "%1ɾ%2") -- it has to be applied twice in order to handle VrVrV sequences
	text = rsub(text, "rr", "r")

	text = rsub(text, "n(*)", "m%1")
	
	-- lack of /h/ in Southern dialects
	text = rsub(text, "aha", (northern and "aha" or "a"))
	text = rsub(text, "ehe", (northern and "ehe" or "e"))
	text = rsub(text, "ihi", (northern and "ihi" or "i"))
	text = rsub(text, "oho", (northern and "oho" or "o"))
	text = rsub(text, "uhu", (northern and "uhu" or "u"))
	text = rsub(text, "h", (northern and "h" or ""))
	
	----------------------
	--syllable division
	
	-- i and u between vowels -> i. and u.
	text = rsub_repeatedly(text, "ui", "U") --this dipthong requires special treatment
	
	local vowel_to_glide = {  = "i.",  = "u." }
	text = rsub_repeatedly(text, "(" .. V .. "*)()(" .. V .. ")",
			function(v1, iu, v2)
				return v1 .. vowel_to_glide .. v2
			end
	)
	text = rsub_repeatedly(text, "U", "ui")
	
	text = rsub_repeatedly(text, "(" .. V .. ")(" .. C .. W .. "?" .. V .. ")", "%1.%2")
	text = rsub_repeatedly(text, "(" .. V .. C .. ")(" .. C .. V .. ")", "%1.%2")
	text = rsub_repeatedly(text, "(" .. V .. C .. ")(" .. C .. C .. V .. ")", "%1.%2")
	text = rsub_repeatedly(text, "(" .. V .. C .. C .. ")(" .. C .. C .. V .. ")", "%1.%2")
	text = rsub(text, "()%.()", ".%1%2")
	text = rsub_repeatedly(text, "(" .. C .. ")%.s(" .. C .. ")", "%1s.%2")
	-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	text = rsub_repeatedly(text, "(" .. ")ui", "%1u.i")
	text = rsub_repeatedly(text, "(" .. ")()", "%1.%2")
	text = rsub_repeatedly(text, "ii", "i.i")
	text = rsub_repeatedly(text, "(" .. ")u", "%1.u")

	local words = rsplit(text, " ")
	for j, word in ipairs(words) do

		local syllables = rsplit(word, "%.")

		-- Vowels are nasalized if followed by nasal in same syllable.
		if phonetic then
			for i = 1, #syllables do
				-- first check for two vowels (veinte)
				syllables = rsub(syllables, "(" .. V .. ")(" .. V .. ")()",
						"%1" .. TILDE .. "%2" .. TILDE .. "%3")
				-- then for one vowel
				syllables = rsub(syllables, "(" .. V .. ")()", "%1" .. TILDE .. "%2")
			end
		end

		-- Reconstruct the word.
		words = table.concat(syllables, phonetic and "." or "")
	end

	text = table.concat(words, " ")

	--phonetic transcription
	if phonetic then
		-- s, z, f before voiced consonants
		local voiced = "mnɲbdɟɡʎl"
		local r = "ɾr"
		local tovoiced = {
			 = "z̺",
			 = "z̻",
		}
		local function voice(sound, following)
			return tovoiced .. following
		end
		text = rsub(text, "()(" .. separator_c .. "*)", voice)

		-- fricative vs. stop allophones; first convert stops to fricatives, then back to stops
		-- after nasals and sometimes after l
		local stop_to_fricative = {  = "β",  = "ð",  = "ɣ" }
		local fricative_to_stop = {  = "b",  = "d",  = "ɡ" }
		text = rsub(text, "", stop_to_fricative)
		text = rsub(text, "(" .. separator_c .. "*)()",
				function(nasal, fricative)
					return nasal .. fricative_to_stop
				end
		)
		text = rsub(text, "(" .. separator_c .. "*)()",
				function(nasal_l, fricative)
					return nasal_l .. fricative_to_stop
				end
		)
		text = rsub(text, "##β", "##b")
		text = rsub(text, "##ð", "##d")
		text = rsub(text, "##ɣ", "##ɡ")

		text = rsub(text, "", {  = "t̪",  = "d̪" })

		-- nasal assimilation before consonants
		local labiodental, dentialveolar, alveolopalatal, palatal, velar = "ɱ", "n̪", "nʲ", "ɲ", "ŋ"
		local nasal_assimilation = {
			 = labiodental,
			 = dentialveolar,  = dentialveolar,
			 = alveolopalatal,
			 = alveolopalatal,
			 = palatal,  = palatal,  = palatal,  = palatal,
			 = velar,  = velar,  = velar,
		}
		text = rsub(text, "n(" .. separator_c .. "*)(.)",
				function(stress, following)
					return (nasal_assimilation or "n") .. stress .. following
				end
		)

		-- lateral assimilation before consonants
		text = rsub(text, "l(" .. separator_c .. "*)(.)",
				function(stress, following)
					local l = "l"
					if following == "t" or following == "d" then
						-- dentialveolar
						l = "l̪"
					elseif following == "C" or following == "ʃ" then
						-- alveolopalatal
						l = "lʲ"
					elseif following == "ɟ" or following == "c" or following == "j" then
						-- alveolopalatal
						l = "ʎ"
					end
					return l .. stress .. following
				end)

		-- voiced fricatives are actually approximants
		text = rsub(text, "()", "%1̞")

		-- northern /h/ is usually 
		text = rsub(text, "h", "ɦ")
	end

	--semivowels
	text = rsub(text, "()" .. TILDE .. "()", "%1" .. TILDE .. "%2̯")
	text = rsub(text, "()" .. TILDE .. "()", "%1" .. TILDE .. "%2̯")
	text = rsub(text, "()", "%1̯")
	text = rsub(text, "()", "%1̯")
	text = rsub(text, "u̯i̯", "u̯i") --correct the mistake appeareing in words with aui, eui
	
	if phonetic then
		-- /e/ and /o/ are actually lowered
		text = rsub(text, "", {  = "e̞",  = "o̞" })
	end
	
	-- convert fake symbols to real ones
	local final_conversions = {
		 = "t͡s̺",
		 = "t͡s̻",
		 = "s̺",
		 = "s̻",
		 = "t͡ʃ",
		 = "x"
	}
	text = rsub(text, "", final_conversions)

	-- remove # symbols at word and text boundaries
	text = rsub(text, "#", "")
	text = toNFC(text)

	local ret = {
		text = text,
		northern_different = n_diff,
	}

	return ret
end

-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function export.show(frame)
	local params = {
		 = {},
		 = {},
		 = {},
		 = {},
		 = {},
		 = { type = "number", default = 1 },
	}
	local parargs = frame:getParent().args
	local args = require("Module:parameters").process(parargs, params)
	local phonemic = {}
	local phonetic = {}
	local expressed_styles = {}
	local text = args or mw.title.getCurrentTitle().text
	local function dostyle(style)
		phonemic = export.IPA(text, style, false)
		phonetic = export.IPA(text, style, true)
	end
	local function express_style(hidden_tag, tag, style)
		if not phonemic then
			dostyle(style)
		end
		local new_style = {
			tag = tag,
			phonemic = phonemic,
			phonetic = phonetic,
		}
		for _, hidden_tag_style in ipairs(expressed_styles) do
			if hidden_tag_style.tag == hidden_tag then
				table.insert(hidden_tag_style.styles, new_style)
				return
			end
		end
		table.insert(expressed_styles, {
			tag = hidden_tag,
			styles = { new_style },
		})
	end
	dostyle("northern_style")
	local northern_different = phonemic.northern_different
	if not northern_different then
		express_style(false, false, "southern_style")
	else
		express_style("Southern", "Southern", "southern_style")
		express_style("Northern", "Northern", "northern_style")
	end

	-- If only one style group, don't indicate the style.
	if #expressed_styles == 1 then
		expressed_styles.tag = false
		if #expressed_styles.styles == 1 then
			expressed_styles.styles.tag = false
		end
	end

	local lines = {}

	local function format_style(tag, expressed_style, is_first)
		local pronunciations = {}
		table.insert(pronunciations, {
			pron = "/" .. expressed_style.phonemic.text .. "/",
			qualifiers = tag and { tag } or nil,
		})
		table.insert(pronunciations, {
			pron = "",
		})
		local bullet = string.rep("*", args.bullets) .. " "
		local pre = is_first and args.pre and args.pre .. " " or ""
		local post = is_first and (args.ref or "") .. (args.post and " " .. args.post or "") or ""
		local formatted = bullet .. pre .. m_IPA.format_IPA_full { lang = lang, items = pronunciations } .. post
		local formatted_for_len = bullet .. pre .. "IPA(key): " .. (tag and "(" .. tag .. ") " or "") ..
				"/" .. expressed_style.phonemic.text .. "/, " .. post
		return formatted, formatted_for_len
	end

	for i, style_group in ipairs(expressed_styles) do
		if #style_group.styles == 1 then
			style_group.formatted, style_group.formatted_for_len = format_style(style_group.styles.tag, style_group.styles, i == 1)
		else
			style_group.formatted, style_group.formatted_for_len = format_style(style_group.tag, style_group.styles, i == 1)
			for j, style in ipairs(style_group.styles) do
				style.formatted, style.formatted_for_len = format_style(style.tag, style, i == 1 and j == 1)
			end
		end
	end

	local maxlen = 0
	for _, style_group in ipairs(expressed_styles) do
		local this_len = ulen(style_group.formatted_for_len)
		if #style_group.styles > 1 then
			for _, style in ipairs(style_group.styles) do
				this_len = math.max(this_len, ulen(style.formatted_for_len))
			end
		end
		maxlen = math.max(maxlen, this_len)
	end

	for _, style_group in ipairs(expressed_styles) do
		if #style_group.styles == 1 then
			table.insert(lines, style_group.formatted)
		else
			local inline = '\n<div class="vsShow" style="display:none">\n' .. style_group.formatted .. "</div>"
			local full_prons = {}
			for _, style in ipairs(style_group.styles) do
				table.insert(full_prons, style.formatted)
			end
			local full = '\n<div class="vsHide">\n' .. table.concat(full_prons, "\n") .. "</div>"
			local em_length = math.floor(maxlen * 0.68) -- from ]
			table.insert(lines, '<div class="vsSwitcher" data-toggle-category="pronunciations" style="width: ' .. em_length .. 'em; max-width:100%;"><span class="vsToggleElement" style="float: right;">&nbsp;</span>' .. inline .. full .. "</div>")
		end
	end

	return table.concat(lines, "\n")
end

return export