Module:an-pron

Hello, you have come here looking for the meaning of the word Module:an-pron. In DICTIOUS you will not only get to know all the dictionary meanings for the word Module:an-pron, but we will also tell you about its etymology, its characteristics and you will know how to say Module:an-pron in singular and plural. Everything you need to know about the word Module:an-pron you have here. The definition of the word Module:an-pron will help you to be more precise and correct when speaking or writing your texts. Knowing the definition ofModule:an-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:an-pr, see there for usage.


--Adapted from ] by ]

local export = {}

-- Standard MediaWiki module dependencies
local m_IPA = require("Module:IPA")
local m_table = require("Module:table")
local m_audio -- Lazily required
local m_put_utils = require("Module:parse utilities")
local links_module = require("Module:links")
local parameters_module = require("Module:parameters") 
local pron_qualifier_module -- Lazily required
local references_module -- Lazily required    
local rhymes_module -- Lazily required          
local hyphenation_module -- Lazily required  
local homophones_module -- Lazily required      

local force_cat = false -- for testing

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

-- ustring aliases
local u = mw.ustring.char
local rfind = mw.ustring.find
-- local rsubn_mw = mw.ustring.gsub 
local rmatch = mw.ustring.match
local rsplit = mw.text.split
local ulower = mw.ustring.lower
local uupper = mw.ustring.upper
local usub = mw.ustring.sub
local ulen = mw.ustring.len
local unfd = mw.ustring.toNFD
local unfc = mw.ustring.toNFC
local ustring = mw.ustring 
local ugsub = mw.ustring.gsub 

local AC = u(0x0301) 
local GR = u(0x0300) 
local CFLEX = u(0x0302)
local TILDE = u(0x0303)
local DIA = u(0x0308) 

local SYLDIV = u(0xFFF0) 
local vowel = "aeiouüyAEIOUÜY" 
local V = "" 
local accent = AC .. GR .. CFLEX
local accent_c = ""
local stress = AC .. GR
local stress_c = ""
local ipa_stress = "ˈˌ"
local ipa_stress_c = ""
local sylsep = "%-." .. SYLDIV 
local sylsep_c = ""
local wordsep = "# "
local separator_not_wordsep = accent .. ipa_stress .. sylsep
local separator = separator_not_wordsep .. wordsep
local separator_c = ""
local C = "" 
local C_NOT_H = "" 
local C_OR_WORDSEP = "" 
local T = "" 

local unstressed_words = m_table.listToSet({ 
	"o", "ro", "a", "ra", "os", "as", "ros", "ras", 
    "un", "una", "uns", "unas", 
    "de", "a", "en", "con", "por", "per", "pa", "ta", 
    "y", "e", "u", 
    "que", 
    "me", "te", "se", "lo", "la", "li", "nos", "vos", "los", "las", "lis",
    "en", "ne", "bi", "hi"
})

local function rsub(term, foo, bar)
	local retval = ugsub(term, foo, bar)
	return retval
end

local function rsubb(term, foo, bar)
	local retval, nsubs = ugsub(term, foo, bar)
	return retval, nsubs > 0
end

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

local function decompose(text)
	text = unfd(text)
	text = rsub(text, ".", {
		 = "ñ",
		 = "Ñ",
		 = "ü",
		 = "Ü",
	})
	return text
end

local function split_on_comma_func(term)
	if not term then return nil end
	if not m_put_utils then m_put_utils = require("Module:parse utilities") end
	if term:find(",%s") then
		return m_put_utils.split_on_comma(term)
	elseif term:find(",") then
		return rsplit(term, ",") 
	else
		return {term}
	end
end

local function convert_to_raw_text(text)
	text = rsub(text, "<.->", "")
	if not links_module then links_module = require("Module:links") end
	if text:find("%[%[") then
		text = links_module.remove_links(text) 
	end
	return text
end

local function textual_len(text)
	return ulen(convert_to_raw_text(text))
end

local function syllabify_from_spelling_or_pronun(text, is_spelling)
	text = rsub_repeatedly(text, "(" .. V .. accent_c .. "*)(" .. C_NOT_H .. V .. ")", "%1.%2")
	text = rsub_repeatedly(text, "(" .. V .. accent_c .. "*" .. C .. "+)(" .. C .. V .. ")", "%1.%2")
	local cluster_r = is_spelling and "rɾ" or "ɾ"
	text = rsub(text, "()%.()", ".%1%2")
	text = ugsub(text, "d%.()", ".d%1") 
	text = rsub(text, "()%.h", ".%1h")
	text = rsub(text, "r%.r", ".rr") 
	text = rsub(text, "t%.z", ".tz")
	text = rsub_repeatedly(text, "(" .. accent_c .. "*)(h?)", "%1.%2")
	text = rsub_repeatedly(text, "(" .. accent_c .. "*)(h?" .. V .. stress_c .. ")", "%1.%2")
	text = rsub(text, "(" .. stress_c .. ")(h?)", "%1.%2")
	text = rsub_repeatedly(text, "(" .. stress_c .. ")(h?" .. V .. stress_c .. ")", "%1.%2")
	text = rsub_repeatedly(text, "(" .. accent_c .. "*)(h?i)", "%1.%2")
	text = rsub_repeatedly(text, "(" .. accent_c .. "*)(h?u)", "%1.%2")
	return text
end

local function syllabify_from_spelling(text)
	text = decompose(text)
	local TEMP_I = u(0xFFF1); local TEMP_U = u(0xFFF2); local TEMP_Y_CONS = u(0xFFF3)
	local TEMP_QU = u(0xFFF4); local TEMP_QU_CAPS = u(0xFFF5); local TEMP_GU = u(0xFFF6)
	local TEMP_GU_CAPS = u(0xFFF7); local TEMP_H = u(0xFFF8); local TEMP_NY = u(0xFFF9)
	local TEMP_NY_CAPS = u(0xFFFA); local TEMP_LL = u(0xFFFB); local TEMP_LL_CAPS = u(0xFFFC)

	text = rsub(text, "ny", TEMP_NY); text = rsub(text, "Ny", TEMP_NY_CAPS)
	text = rsub(text, "ll", TEMP_LL); text = rsub(text, "Ll", TEMP_LL_CAPS)
	text = ugsub(text, "", SYLDIV) 
	text = rsub(text, "y(" .. V .. ")", TEMP_Y_CONS .. "%1") 
	text = ugsub(text, "^(es)h", "%1" .. TEMP_H) 
	text = ugsub(text, "(es)h", "%1" .. TEMP_H) 
	text = rsub(text, "qu(" .. V .. ")", TEMP_QU .. "%1"); text = rsub(text, "Qu(" .. V .. ")", TEMP_QU_CAPS .. "%1")
	text = rsub(text, "gu(" .. V .. ")", TEMP_GU .. "%1"); text = rsub(text, "Gu(" .. V .. ")", TEMP_GU_CAPS .. "%1")

	local vowel_to_glide_temp = {  = TEMP_I,  = TEMP_U }
	text = rsub_repeatedly(text, "(.*" .. V .. accent_c .. "*)(h?)()(" .. V .. ")",
		function (v1, h, iu, v2) return v1 .. "." .. h .. vowel_to_glide_temp .. v2 end
	)
	text = syllabify_from_spelling_or_pronun(text, "is spelling")

	text = ugsub(text, SYLDIV, "."); text = ugsub(text, TEMP_I, "i"); text = ugsub(text, TEMP_U, "u")
	text = ugsub(text, TEMP_Y_CONS, "y"); text = ugsub(text, TEMP_QU, "qu"); text = ugsub(text, TEMP_QU_CAPS, "Qu")
	text = ugsub(text, TEMP_GU, "gu"); text = ugsub(text, TEMP_GU_CAPS, "Gu"); text = ugsub(text, TEMP_H, "h")
	text = ugsub(text, TEMP_NY, "ny"); text = ugsub(text, TEMP_NY_CAPS, "Ny")
	text = ugsub(text, TEMP_LL, "ll"); text = ugsub(text, TEMP_LL_CAPS, "Ll")
	text = unfc(text)
	return text
end

-- Generate the IPA of a given respelling
function export.IPA(text)
	-- start at FFF1 because FFF0 is used for SYLDIV
	local TEMP_Y = u(0xFFF1)
	local TEMP_W = u(0xFFF2)

	text = ulower(text or mw.title.getCurrentTitle().text)
	-- decompose everything but ñ and ü
	text = decompose(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)

	-- Make prefixes unstressed unless they have an explicit stress marker; also make certain
	-- monosyllabic words (e.g. ], ], ], ], etc.) without stress marks be
	-- unstressed.
	local words = rsplit(text, " ")
	for i, word in ipairs(words) do
		if rfind(word, "%-$") and not rfind(word, accent_c) or unstressed_words then
			-- add CFLEX to the last vowel not the first one, or we will mess up 'que' by
			-- adding the CFLEX after the 'u'
			words = rsub(word, "^(.*" .. V .. ")", "%1" .. CFLEX)
		end
	end
	text = table.concat(words, " ")
	-- Convert hyphens to spaces, to handle ], ], etc; with the exception of verbal clitics (with the temporary symbol @)
	text = rsub(text, "-se", "@se")
	text = rsub(text, "-te", "@te")
	text = rsub(text, "-me", "@me")
	text = rsub(text, "-tos", "@tos")
	text = rsub(text, "-vos", "@vos")
	text = rsub(text, "-nos", "@nos")
	text = rsub(text, "-mos", "@mos")
	text = rsub(text, "-lo", "@lo")
	text = rsub(text, "-el", "@el")
	text = rsub(text, "-los", "@los")
	text = rsub(text, "-es", "@es")
	text = rsub(text, "-la", "@la")
	text = rsub(text, "-las", "@las")
	text = rsub(text, "-le", "@le")
	text = rsub(text, "-li", "@li")
	text = rsub(text, "-les", "@les")
	text = rsub(text, "-lis", "@lis")
	text = rsub(text, "-en", "@en")
	text = rsub(text, "-ne", "@ne")
	text = rsub(text, "-i", "@i")
	text = rsub(text, "-bi", "@bi")

	text = rsub(text, "%-", " ")
	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, " ", "# #") .. "##"

	--glides
	text = rsub(text, "#y" .. CFLEX, "#i" .. CFLEX) -- conjunction
	text = rsub(text, "ny", "ɲ")
	text = rsub(text, "y", "ʝ")
	text = rsub(text, "hi()", "ʝ%1")

	-- handle certain combinations; sh handling needs to go before x handling to avoid issues with ]
	text = rsub(text, "ch", "ĉ") --not the real sound
	text = rsub(text, "ll", "ʎ")
	text = rsub(text, "#ps", "#s") -- ]
	text = rsub(text, "x", "ʃ")
	
	--c, g, q
	text = rsub(text, "c()", "θ%1")
	text = rsub(text, "z", "θ")
	text = rsub(text, "g()", "x%1")
	text = rsub(text, "gu()", "g%1")
	text = rsub(text, "gü()", "gu%1")
	text = rsub(text, "qü()", "ku%1")
	text = rsub(text, "ng()", "n%1") -- TODO is this really needed?
	text = rsub(text, "qu()", "k%1")
	text = rsub(text, "q", "k") -- ]
	text = rsub(text, "()iʃ", "%1Iʃ")

	-- map various consonants to their phoneme equivalent
	text = rsub(text, "", {="k", ="x", ="ɲ", ="ɾ", ="b"})

	--pronunciation of <r>/<rr>
	text = rsub(text, "ɾɾ", "r")
	text = rsub(text, "()ɾ", "%1r")
	text = rsub(text, "ɾ#", "R#")
	text = rsub(text, "ɾ%-", "R-")

	-- voiceless stop to voiced before obstruent or nasal (see Basic Grammar of Aragonese)
	local voice_stop = {  = "b",  = "d",  = "g" }
	text = rsub(text, "()(" .. separator_c .. "*" .. T .. ")",
		function(stop, after) return voice_stop .. after end)
	text = rsub(text, "!", "t")

	text = rsub(text, "n(*)", "m%1")

	-- remove silent h and · before syllable division
	text = rsub(text, "h", "")
	text = rsub(text, "·", ".")
	
	-- convert i/u between vowels to glide
	local vowel_to_glide = {  = "j",  = "w" }
	text = rsub_repeatedly(text, "(.*" .. V .. accent_c .. "*h?)()(" .. V .. ")",
		function (v1, iu, v2) return v1 .. vowel_to_glide .. v2 end
	)

	--syllable division
	text = syllabify_from_spelling_or_pronun(text, false)

	--diphthongs; do not include TEMP_Y here
	text = rsub(text, "i()", "j%1")
	text = rsub(text, "u()", "w%1")

	local accent_to_stress_mark = {  = "ˈ",  = "ˌ",  = "" }

	local function accent_word(word, syllables)
		-- Now stress the word. If any accent exists in the word (including ^ indicating an unaccented word),
		-- put the stress mark(s) at the beginning of the indicated syllable(s). Otherwise, apply the default
		-- stress rule.
		if rfind(word, accent_c) then
			for i = 1, #syllables do
				syllables = rsub(syllables, "^(.*)(" .. accent_c .. ")(.*)$",
					function(pre, accent, post) return accent_to_stress_mark .. pre .. post end
				)
			end
		else
			-- Default stress rule. Words without vowels (e.g. IPA foot boundaries) don't get stress.
			if #syllables > 1 and (rfind(word, "#") or rfind(word, C .. "#")) or #syllables == 1 and rfind(word, V) then
				syllables = "ˈ" .. syllables
			elseif #syllables > 1 and rfind(word, "") then
				syllables = "ˈ" .. syllables
			elseif #syllables > 1 then
				syllables = "ˈ" .. syllables
			end
		end
	end

	local words = rsplit(text, " ")
	for j, word in ipairs(words) do
		-- accentuation
		local syllables = rsplit(word, "%.")

		if rfind(word, "ment#") then
			local mente_syllables
			-- Words ends in -ment (converted above to mént); add a stress to the preceding portion
			mente_syllables = {}
			mente_syllables = table.remove(syllables)
			mente_syllables = table.remove(syllables)
			accent_word(table.concat(syllables, "."), syllables)
			accent_word(table.concat(mente_syllables, "."), mente_syllables)
			table.insert(syllables, mente_syllables)
			table.insert(syllables, mente_syllables)
		else
			accent_word(word, syllables)
		end

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

	text = table.concat(words, " ")
	text = rsub(text, "%-", "")
	-- suppress syllable mark before IPA stress indicator
	text = rsub(text, "%.(" .. ipa_stress_c .. ")", "%1")
	--make all primary stresses but the last one be secondary
	text = rsub_repeatedly(text, "ˈ(.+)ˈ", "ˌ%1ˈ")

	--other conversions, silent letters
	text = rsub(text, "R", "(ɾ)")
	text = rsub(text, "tθ#", "θ#")
	text = rsub(text, "()t#", "%1#")
	text = rsub(text, "nd#", "n#")
	text = rsub(text, "ɾs#", "s#")

	--semivowel symbols
	text = rsub(text, "()", "%1̯")
	text = rsub(text, "()", "%1̯")
	
	--value of conjunction <y>
	text = rsub(text, "(*)#i#(*)", "%1#ʝ#‿%2")
	text = rsub(text, "i̯(*)#i#(*)", "i̯%1#ʝ#‿%2")
	text = rsub(text, "u̯(*)#i#(*)", "u̯%1#ʝ#‿%2")
	text = rsub(text, "#i#(*)", "#j#‿%1")
	text = rsub(text, "(*)#i#", "%1‿#i̯#")

	-- convert fake symbols to real ones
	local final_conversions =  {
		 = "t͡ʃ", -- fake "ch" to real "ch"
		 = "ɡ", -- U+0067 LATIN SMALL LETTER G → U+0261 LATIN SMALL LETTER SCRIPT G
		 = "(i̯)",
	}
	text = rsub(text, "", final_conversions)

	-- remove # symbols at word and text boundaries
	text = rsub(text, "#", "")
	text = rsub(text, "‿ ", "‿")
	text = rsub(text, " ‿", "‿")
	text = rsub(text, "()‿ˈ", "ˈ%1‿")
	text = rsub(text, "()‿ˌ", "ˌ%1‿")

	text = unfc(text)

	local ret = {
		text = text,
	}
	return ret
end

local function generate_term_pronunciation_variants(term_text, pagename_val_unused, parse_err_func_unused, frame_args)
    local variants = {}
    local standard_ipa_obj = export.IPA(term_text)
    local standard_ipa_str = standard_ipa_obj.text

    local standard_variant_label = nil -- Default label for the standard IPA

    local ben_param_value = frame_args and frame_args.ben
    local benasque_ipa_to_add
    local add_benasque_line_flag = true

    -- Determine benasque_ipa_to_add and add_benasque_line_flag
    if ben_param_value then
        local lower_ben_param = ulower(ben_param_value)
        if lower_ben_param == "0" then
            add_benasque_line_flag = false
        elseif ben_param_value ~= "" then
            local ipa_result_from_ben_override = export.IPA(ben_param_value)
            local ipa_from_ben_form_override = ipa_result_from_ben_override.text
            if rfind(ipa_from_ben_form_override, "θ") then
                benasque_ipa_to_add = ugsub(ipa_from_ben_form_override, "θ", "s")
            else
                benasque_ipa_to_add = ipa_from_ben_form_override
            end
        else -- ben_param_value is "" (empty string)
            if rfind(standard_ipa_str, "θ") then
                benasque_ipa_to_add = ugsub(standard_ipa_str, "θ", "s")
            else
                add_benasque_line_flag = false
            end
        end
    else -- ben_param_value is nil
        if rfind(standard_ipa_str, "θ") then
            benasque_ipa_to_add = ugsub(standard_ipa_str, "θ", "s")
        else
            add_benasque_line_flag = false
        end
    end

    if add_benasque_line_flag and benasque_ipa_to_add then
        -- A Benasquese variant will be added. Label the standard IPA accordingly.
        -- standard_variant_label = "(Most dialects)"
        table.insert(variants, { ipa = standard_ipa_str, label = standard_variant_label })
        table.insert(variants, {
            ipa = benasque_ipa_to_add,
            label = "]"
        })
    else
        -- No Benasquese variant to add (or it was suppressed). Add only the standard IPA.
        -- standard_variant_label will be nil here, unless overridden by other q parameters later.
        table.insert(variants, { ipa = standard_ipa_str, label = standard_variant_label })
    end

    return variants, standard_ipa_str
end

local function express_all_styles(dodialect_func_param_with_args)
	local ret_data_struct = { pronun = {}, expressed_styles = {} }
	dodialect_func_param_with_args(ret_data_struct) 
	table.insert(ret_data_struct.expressed_styles, { styles = {{pronun = ret_data_struct.pronun, tag = nil}} })
	return ret_data_struct
end

local function format_all_styles(list_of_pron_variant_lists_for_term_group, format_style_func_ref, p_args_formatting)
	if list_of_pron_variant_lists_for_term_group and #list_of_pron_variant_lists_for_term_group > 0 then
		return format_style_func_ref(nil, list_of_pron_variant_lists_for_term_group, true, p_args_formatting)
	end
	return "", 0 
end

local function dodialect_pronun(args_for_dialect_pron, ret_data_for_dialect, top_level_args)
    ret_data_for_dialect.pronun = {} 
    for i, term_obj in ipairs(args_for_dialect_pron.terms) do
        local current_term_text = term_obj.term 
        local pagename_for_ipa = args_for_dialect_pron.pagename or current_term_text 
        
        local variants_for_this_term, standard_ipa_str_for_other_uses = 
            generate_term_pronunciation_variants(current_term_text, pagename_for_ipa, args_for_dialect_pron.parse_err, top_level_args)
        
        local mIPA_items_for_this_term = {}
        for _, variant in ipairs(variants_for_this_term) do -- 'variant' is {ipa = "...", label = "..."}
            
            -- Initialize with general per-term display properties
            local current_item_q = term_obj.q   -- User-defined qualifiers before IPA (from <q:...>)
            local current_item_qq = term_obj.qq -- User-defined qualifiers after IPA (from <qq:...>)
            local current_item_a = term_obj.a
            local current_item_aa = term_obj.aa
            local current_item_refs = nil -- Specifically handle refs below

            if variant.label then
                -- This is one of our automatically generated labeled variants (e.g., Benasquese).
                -- Its label should go into 'qq' (qualifier after), overriding any user <qq:...>.
                current_item_qq = {variant.label}
                
                -- For these auto-labeled lines, suppress other per-term display annotations
                -- to keep the output clean and focused on the dialectal variant.
                current_item_a = nil
                current_item_aa = nil
                -- Refs are also typically for the main entry, not repeated for each dialect line here.
                -- current_item_refs remains nil as it's handled below (will not be set if variant.label exists)

            end

            -- Handle references: populate 'refs' only if there's no specific variant.label 
            -- (i.e., it's a base pronunciation) AND the term_obj has references.
            -- This maintains the original logic where refs were cleared if variant.label was present.
            if not variant.label and term_obj.ref then 
                if not references_module then references_module = require("Module:references") end
                local collected_refs = {}
                if type(term_obj.ref) == "table" then
                    for _, refspec_str in ipairs(term_obj.ref) do
                        local parsed_refs_from_spec = references_module.parse_references(refspec_str) 
                        for _, single_ref_obj in ipairs(parsed_refs_from_spec) do
                            table.insert(collected_refs, single_ref_obj)
                        end
                    end
                end
                if #collected_refs > 0 then
                    current_item_refs = collected_refs
                end
            end

            local item = {
                phonemic = variant.ipa, 
                q = current_item_q,   -- Qualifiers from <q:...> always appear before
                qq = current_item_qq, -- Dialect label (if any) or <qq:...> appears after
                a = current_item_a, 
                aa = current_item_aa,
                refs = current_item_refs
            }
            table.insert(mIPA_items_for_this_term, item)
        end
        ret_data_for_dialect.pronun = mIPA_items_for_this_term
        
        if term_obj then 
            term_obj.pronun = { pronun = { phonemic = standard_ipa_str_for_other_uses } }
        end
    end
end

local function generate_pronun(parsed_resp_group_obj, top_level_args) 
	local function dodialect_pronun_wrapper(ret_data_wrapper)
		dodialect_pronun(parsed_resp_group_obj, ret_data_wrapper, top_level_args)
	end

	local ret_data_from_express = express_all_styles(dodialect_pronun_wrapper)
	
local function format_style(tag_style_group_unused, list_of_mIPA_items_for_terms, is_first_style_group_flag, p_args_formatting_options)
        local final_formatted_text_parts_for_all_terms_in_group = {}
        local total_approx_len_for_group = 0

        for term_idx, mIPA_items_for_this_term in ipairs(list_of_mIPA_items_for_terms) do
            -- mIPA_items_for_this_term is a list of pronunciation objects for the current term.
            -- e.g., { std_variant_details, benasque_variant_details }

            local combined_text_for_len_calc_for_this_term = {} -- For length calculation
            local formatted_content_for_each_variant = {} -- Store formatted content of each variant (IPA + qualifiers)

            -- Step 1: Get the formatted content for each variant
            for variant_idx, pron_object_item in ipairs(mIPA_items_for_this_term) do
                local phonemic_val = pron_object_item.phonemic or ""
                local current_pron_str = "/" .. (phonemic_val:gsub("%.", "")) .. "/"
                
                local single_item_list_for_mIPA_call = {
                    { 
                        pron = current_pron_str,
                        q = pron_object_item.q,
                        qq = pron_object_item.qq,
                        a = pron_object_item.a,
                        aa = pron_object_item.aa,
                        refs = pron_object_item.refs
                    }
                }

                local mIPA_options_for_single_variant = {
                    lang = lang,
                    items = single_item_list_for_mIPA_call,
                    no_cat = force_cat 
                }
                
                table.insert(formatted_content_for_each_variant, m_IPA.format_IPA_full(mIPA_options_for_single_variant))

                -- Update text for length calculation
                if pron_object_item.q then
                    for _, q_val_item in ipairs(pron_object_item.q) do
                        table.insert(combined_text_for_len_calc_for_this_term, q_val_item)
                    end
                end
                table.insert(combined_text_for_len_calc_for_this_term, current_pron_str)
                if variant_idx < #mIPA_items_for_this_term then
                    table.insert(combined_text_for_len_calc_for_this_term, " ") 
                end
            end

            -- Step 2: Assemble the final lines, each with its own bullet, and apply pre/post text
            local final_bulleted_lines_for_this_term = {}
            local base_bullet_string = ustring.rep("*", p_args_formatting_options.bullets or 1) .. " "

            for i, variant_content_string in ipairs(formatted_content_for_each_variant) do
                local line_parts = {}
                table.insert(line_parts, base_bullet_string)

                -- Apply 'pre' text to the first variant line of the first term in the group
                if i == 1 and term_idx == 1 and is_first_style_group_flag and p_args_formatting_options.pre then
                    table.insert(line_parts, p_args_formatting_options.pre .. " ")
                end
                
                table.insert(line_parts, variant_content_string)

                -- Apply 'post' text to the last variant line of the first term in the group
                if i == #formatted_content_for_each_variant and term_idx == 1 and is_first_style_group_flag and p_args_formatting_options.post then
                    table.insert(line_parts, " " .. p_args_formatting_options.post)
                end
                
                table.insert(final_bulleted_lines_for_this_term, table.concat(line_parts))
            end
            
            -- Join these fully-formed, bulleted lines with a newline character.
            local complete_ipa_block_for_this_term = table.concat(final_bulleted_lines_for_this_term, "\n")
            
            table.insert(final_formatted_text_parts_for_all_terms_in_group, complete_ipa_block_for_this_term)
            
            total_approx_len_for_group = total_approx_len_for_group + textual_len(table.concat(combined_text_for_len_calc_for_this_term))
        end
        
        return table.concat(final_formatted_text_parts_for_all_terms_in_group, ", "), total_approx_len_for_group
    end
	
	if ret_data_from_express.expressed_styles and 
	   ret_data_from_express.expressed_styles and 
	   ret_data_from_express.expressed_styles.styles and
	   ret_data_from_express.expressed_styles.styles then
		ret_data_from_express.text, ret_data_from_express.text_len = format_all_styles(
			ret_data_from_express.expressed_styles.styles.pronun, 
			format_style,
			parsed_resp_group_obj 
		)
	else
		ret_data_from_express.text = "(Error: Pronunciation data structure issue in generate_pronun)"
		ret_data_from_express.text_len = 0
		mw.log("Module:an-pron ERROR: ret_data_from_express.expressed_styles structure not as expected in generate_pronun.")
	end
	return ret_data_from_express
end

-- Simplified parse_respelling as raw input is no longer specially handled
local function parse_respelling(respelling_text, pagename_val, parse_err_func, top_level_args_unused_here)
    if respelling_text == "+" then
        if not pagename_val or pagename_val == "" then
            parse_err_func("Cannot use '+' for respelling as page name is not available.")
            return { term = "" , raw = false, q = {"(Error: No pagename for '+')"}}
        end
        respelling_text = pagename_val
    end
    return {term = respelling_text, raw = false} 
end

local function get_num_syl_from_phonemic(phonemic_str)
    if not phonemic_str or phonemic_str == "" then return 0 end
    phonemic_str = rsub(phonemic_str, "|", " ")
    local words_list = rsplit(phonemic_str, " +")
    local total_syllables = 0
    for i, single_word in ipairs(words_list) do
        single_word = rsub(single_word, "(.)(.)", "%1.%2")
        single_word = rsub(single_word, "", "")
        total_syllables = total_syllables + ulen(rsub(single_word, "", "")) + 1
    end
    return total_syllables > 0 and total_syllables or 1
end

local function convert_phonemic_to_rhyme(phonemic_str)
    return rsub(rsub(phonemic_str, ".*", ""), "^*", ""):gsub("", ""):gsub("t͡ʃ", "tʃ")
end

local function split_syllabified_spelling(spelling_str)
    return rsplit(spelling_str, "%.")
end

local function align_syllabification_to_spelling(syllab_str, spelling_str)
    local result_chars = {}
    local syll_chars_list = rsplit(decompose(syllab_str), "")
    local spelling_chars_list = rsplit(decompose(spelling_str), "")
    local i_syll = 1
    local j_spell = 1
    while i_syll <= #syll_chars_list or j_spell <= #spelling_chars_list do
        local char_i = syll_chars_list
        local char_j = spelling_chars_list
        if char_i == char_j then
            table.insert(result_chars, char_i)
            i_syll = i_syll + 1
            j_spell = j_spell + 1
        elseif char_i == "." then
            table.insert(result_chars, char_i)
            i_syll = i_syll + 1
        elseif char_i == AC or char_i == GR or char_i == CFLEX then
            i_syll = i_syll + 1 
        elseif char_j == AC or char_j == GR or char_j == CFLEX then 
            j_spell = j_spell + 1
        else
            return nil 
        end
    end
    if i_syll <= #syll_chars_list or j_spell <= #spelling_chars_list then 
        return nil 
    end
    return unfc(table.concat(result_chars))
end

local function generate_hyph_obj(term_str)
    return {syllabification = term_str, hyph = split_syllabified_spelling(term_str)}
end

local function word_has_vowels(word_str)
    return rfind(word_str, V)
end

local function all_words_have_vowels(term_str)
    local words_list = rsplit(decompose(term_str), "")
    for _, single_word in ipairs(words_list) do
        if single_word ~= "" and not word_has_vowels(single_word) then
            return false
        end
    end
    return true
end

local function should_generate_rhyme_from_respelling(term_str)
    local words_list = rsplit(decompose(term_str), " +")
    return #words_list == 1 and
        not words_list:find("%.%-%..") and
        not words_list:find("%-$") and
        not (words_list:find("^%-") and words_list:find(CFLEX)) and
        word_has_vowels(words_list)
end

local function should_generate_rhyme_from_ipa(ipa_str)
    return not ipa_str:find("%s") and word_has_vowels(decompose(ipa_str))
end

local function dodialect_specified_rhymes(rhymes_list, hyphs_list, parsed_respelling_groups_list_arg, rhyme_ret_table)
    rhyme_ret_table.pronun = rhyme_ret_table.pronun or {}
    for _, rhyme_obj in ipairs(rhymes_list) do
        local num_syl_val = rhyme_obj.num_syl
        local no_num_syl_flag = false

        if not num_syl_val or #num_syl_val == 0 then
            num_syl_val = {}
            if hyphs_list and #hyphs_list > 0 then
                for _, hyph_item in ipairs(hyphs_list) do
                    if hyph_item.syllabification and should_generate_rhyme_from_respelling(hyph_item.syllabification) then
                        local this_syl_count = 1 + ulen(rsub(hyph_item.syllabification, "", ""))
                        m_table.insertIfNot(num_syl_val, this_syl_count)
                    else
                        no_num_syl_flag = true; break
                    end
                end
            else
                no_num_syl_flag = true
            end
            if no_num_syl_flag or #num_syl_val == 0 then num_syl_val = nil end
        end

        if not no_num_syl_flag and (not num_syl_val or #num_syl_val == 0) then
            num_syl_val = {}
            for _, parsed_item in ipairs(parsed_respelling_groups_list_arg) do
                for _, term_obj_item_wrapper in ipairs(parsed_item.terms or {}) do
                    local term_obj_item = (type(term_obj_item_wrapper) == "table" and term_obj_item_wrapper) or term_obj_item_wrapper
                    local std_ipa_for_rhyme
                    if term_obj_item.raw then
                         std_ipa_for_rhyme = term_obj_item.raw_phonemic
                    elseif term_obj_item.term then 
                         local ipa_result = export.IPA(term_obj_item.term)
                         std_ipa_for_rhyme = ipa_result.text 
                    end

                    if std_ipa_for_rhyme and type(std_ipa_for_rhyme) == "string" then
                        if not should_generate_rhyme_from_ipa(std_ipa_for_rhyme) then
                            no_num_syl_flag = true; break
                        end
                        local this_syl_count = get_num_syl_from_phonemic(std_ipa_for_rhyme)
                        m_table.insertIfNot(num_syl_val, this_syl_count)
                    else
                        no_num_syl_flag = true; break
                    end
                end
                if no_num_syl_flag then break end
            end
            if no_num_syl_flag or #num_syl_val == 0 then num_syl_val = nil end
        end

        table.insert(rhyme_ret_table.pronun, {
            rhyme = rhyme_obj.rhyme,
            num_syl = num_syl_val,
            qualifiers = rhyme_obj.qualifiers,
        })
    end
end

local function parse_rhyme(arg_str, parse_err_func)
	local function gen_obj(term_str, p_err) return {rhyme = term_str} end
	local p_mods = {
		s = {
			item_dest = "num_syl",
			convert = function(val_str, p_err)
				local ns_list = rsplit(val_str, ",")
				for i_val, ns_val in ipairs(ns_list) do
					if not ns_val:find("^+$") then
						p_err("Number of syllables '" .. ns_val .. "' should be numeric")
					end
					ns_list = tonumber(ns_val)
				end
				return ns_list
			end,
		},
	}
	return parse_pron_modifier(arg_str, parse_err_func, gen_obj, p_mods)
end

local function parse_hyph(arg_str, parse_err_func)
	local p_mods = {}
	return parse_pron_modifier(arg_str, parse_err_func, generate_hyph_obj, p_mods)
end

local function parse_homophone(arg_str, parse_err_func)
	local function gen_obj(term_str, p_err) return {term = term_str} end
	local p_mods = {
		t = { item_dest = "gloss" },
		gloss = {item_dest = "gloss"},
		pos = {}, alt = {}, lit = {}, id = {},
		g = { item_dest = "genders", convert = function(val) return rsplit(val, ",") end },
	}
	return parse_pron_modifier(arg_str, parse_err_func, gen_obj, p_mods)
end

local function generate_audio_obj(audio_arg_str, parse_err_func) 
	local file_part, gloss_part
	if audio_arg_str:find("#") then
		file_part, gloss_part = audio_arg_str:match("^(.-)%s*#%s*(.*)$")
	elseif audio_arg_str:find(";") then
		file_part, gloss_part = audio_arg_str:match("^(.-)%s*;%s*(.*)$")
	end

	if not file_part then
		file_part = audio_arg_str
		gloss_part = "Audio" 
	elseif gloss_part == "" then 
		gloss_part = "Audio"
	end
	return {file = file_part, gloss = gloss_part}
end

local function parse_audio(arg_str, parse_err_func)
	local p_mods = {}
	return parse_pron_modifier(arg_str, parse_err_func, generate_audio_obj, p_mods, "no split on comma")
end

-- External entry point for {{an-pr}} or {{an-IPA}}.
function export.show_pr(frame)
    if not parameters_module then parameters_module = require("Module:parameters") end
    if not m_put_utils then m_put_utils = require("Module:parse utilities") end 
    if not m_audio then m_audio = require("Module:audio") end
    if not hyphenation_module then hyphenation_module = require("Module:hyphenation") end
    if not homophones_module then homophones_module = require("Module:homophones") end
    if not rhymes_module then rhymes_module = require("Module:rhymes") end
    if not m_table then m_table = require("Module:table") end
    if not ustring then ustring = mw.ustring end

    local params_spec = {
         = {list = true, default = "+"}, 
         = {default = nil},          
         = {type = "string", default = nil},
         = {type = "string", default = nil},
         = {type = "string", default = nil},
         = {list = true, default = nil},
         = {type = "string", default = nil}, 
         = {list = true, default = nil},
         = {list = true, default = nil},
         = {list = true, default = nil},
         = {list = true, default = nil},
         = {list = true, default = nil}
    }
    
    local effective_args_table 
    if frame:getParent() and frame:getParent().args then
        effective_args_table = frame:getParent().args
    elseif frame.args then 
        effective_args_table = frame.args
    else
        effective_args_table = {} 
    end
    
    local args_processed = parameters_module.process(effective_args_table, params_spec)
    
    local pagename_val = args_processed.pagename or mw.title.getCurrentTitle().subpageText or mw.title.getCurrentTitle().text or ""
    local respelling_input_list = args_processed 
    
    local parsed_respelling_groups_list = {}

    local function overall_parse_err_callback(error_msg, arg_name_str, original_val_str)
        error(error_msg .. ": " .. arg_name_str .. "= " .. original_val_str)
    end

    local overall_rhyme_parsed_data = args_processed.rhyme and
        parse_rhyme(args_processed.rhyme, function(msg) overall_parse_err_callback(msg, "rhyme", args_processed.rhyme) end) or nil
    local overall_hyph_parsed_data = args_processed.hyph and
        parse_hyph(args_processed.hyph, function(msg) overall_parse_err_callback(msg, "hyph", args_processed.hyph) end) or nil
    local overall_hmp_parsed_data = args_processed.hmp and
        parse_homophone(args_processed.hmp, function(msg) overall_parse_err_callback(msg, "hmp", args_processed.hmp) end) or nil
    local overall_audio_parsed_data
    if args_processed.audio and #args_processed.audio > 0 then
        overall_audio_parsed_data = {}
        for _, audio_str_item in ipairs(args_processed.audio) do
            local parsed_audio_items_list = parse_audio(audio_str_item, function(msg) overall_parse_err_callback(msg, "audio", audio_str_item) end)
            for _, pa_obj_item in ipairs(parsed_audio_items_list) do
                table.insert(overall_audio_parsed_data, pa_obj_item)
            end
        end
    end

    for i_resp, respelling_str_item in ipairs(respelling_input_list) do
        if respelling_str_item:find("<") then
            local inline_mods_spec = {
                pre = { overall = true }, post = { overall = true },
                bullets = {
                    overall = true,
                    convert = function(b_val, p_err)
                        if not b_val:find("^+$") then p_err("Modifier 'bullets' needs a number, saw '" .. b_val .. "'") end
                        return tonumber(b_val)
                    end,
                },
                rhyme = { overall = true, store = "insert-flattened", convert = parse_rhyme },
                hyph = { overall = true, store = "insert-flattened", convert = parse_hyph },
                hmp = { overall = true, store = "insert-flattened", convert = parse_homophone },
                audio = { overall = true, store = "insert-flattened", convert = parse_audio },
                ref = { store = "insert" }, q = { store = "insert" }, qq = { store = "insert" },
                a = { store = "insert" }, aa = { store = "insert" },
            }
            local parsed_group_container = m_put_utils.parse_inline_modifiers(respelling_str_item, {
                paramname = "respelling group " .. i_resp,
                param_mods = inline_mods_spec,
                generate_obj = function(term_val, p_err) 
                    return parse_respelling(term_val, pagename_val, p_err, args_processed) 
                end,
                splitchar = ",",
                outer_container = { terms = {}, audio = {}, rhyme = {}, hyph = {}, hmp = {} }
            })
            if not parsed_group_container.bullets then parsed_group_container.bullets = 1 end
            table.insert(parsed_respelling_groups_list, parsed_group_container)
        else
            local term_obj_list_for_group = {}
            local function current_term_parse_err_callback(error_msg)
                error(error_msg .. " for respelling string: '" .. respelling_str_item .. "'")
            end
            for _, term_part_val in ipairs(split_on_comma_func(respelling_str_item)) do
                table.insert(term_obj_list_for_group, parse_respelling(term_part_val, pagename_val, current_term_parse_err_callback, args_processed))
            end
            table.insert(parsed_respelling_groups_list, {
                terms = term_obj_list_for_group, 
                audio = {}, rhyme = {}, hyph = {}, hmp = {},
                bullets = 1,
                pagename = pagename_val, 
                parse_err = current_term_parse_err_callback 
            })
        end
    end

    if not (overall_hyph_parsed_data and #overall_hyph_parsed_data > 0) then
        if respelling_input_list and #respelling_input_list == 1 and respelling_input_list == "+" then
            if pagename_val and pagename_val ~= "" and all_words_have_vowels(pagename_val) then
                local syllabified_pagename = syllabify_from_spelling(pagename_val)
                if syllabified_pagename then
                    overall_hyph_parsed_data = {generate_hyph_obj(syllabified_pagename)}
                end
            end
        end
    end

    for resp_group_idx, resp_group_data in ipairs(parsed_respelling_groups_list) do
        resp_group_data.pronun_display_details = generate_pronun(resp_group_data, args_processed)

        if #resp_group_data.hyph == 0 and not (overall_hyph_parsed_data and #overall_hyph_parsed_data > 0) then
             if resp_group_data.terms and #resp_group_data.terms > 0 then
                local first_term_obj_for_hyph_wrapper = resp_group_data.terms 
                local first_term_obj_for_hyph = (type(first_term_obj_for_hyph_wrapper) == "table" and first_term_obj_for_hyph_wrapper) or first_term_obj_for_hyph_wrapper

                if first_term_obj_for_hyph and not first_term_obj_for_hyph.raw and 
                   first_term_obj_for_hyph.term and first_term_obj_for_hyph.term ~= "" and 
                   all_words_have_vowels(first_term_obj_for_hyph.term) then
                    local syllabified_term_str = syllabify_from_spelling(first_term_obj_for_hyph.term)
                    if syllabified_term_str then 
                        m_table.insertIfNot(resp_group_data.hyph, generate_hyph_obj(syllabified_term_str))
                    end
                end
            end
        end
        
        local no_auto_rhyme_flag = false
        if resp_group_data.terms then
            for term_idx, term_obj_wrapper in ipairs(resp_group_data.terms) do
                local term_obj_for_rhyme_check = (type(term_obj_wrapper) == "table" and term_obj_wrapper) or term_obj_wrapper
                local ipa_to_check_for_rhyme
                if term_obj_for_rhyme_check.raw then
                    ipa_to_check_for_rhyme = term_obj_for_rhyme_check.raw_phonemic
                elseif resp_group_data.pronun_display_details and 
                       resp_group_data.pronun_display_details.pronun and 
                       resp_group_data.pronun_display_details.pronun and 
                       #resp_group_data.pronun_display_details.pronun > 0 then 
                    ipa_to_check_for_rhyme = resp_group_data.pronun_display_details.pronun.phonemic 
                end
                
                if not ipa_to_check_for_rhyme or not should_generate_rhyme_from_ipa(ipa_to_check_for_rhyme) then
                    no_auto_rhyme_flag = true; break
                end
            end
        else
            no_auto_rhyme_flag = true 
        end

        if #resp_group_data.rhyme == 0 and not overall_rhyme_parsed_data and not no_auto_rhyme_flag then
            local rhyme_ret_for_group_auto = { pronun = {} }
            if resp_group_data.terms then 
                for term_idx_auto, term_obj_wrapper_auto in ipairs(resp_group_data.terms) do
                    local term_obj_for_rhyme_auto = (type(term_obj_wrapper_auto) == "table" and term_obj_wrapper_auto) or term_obj_wrapper_auto
                    local std_ipa_for_rhyme_auto
                    if term_obj_for_rhyme_auto.raw then
                        std_ipa_for_rhyme_auto = term_obj_for_rhyme_auto.raw_phonemic
                    elseif resp_group_data.pronun_display_details and 
                           resp_group_data.pronun_display_details.pronun and 
                           resp_group_data.pronun_display_details.pronun and
                           #resp_group_data.pronun_display_details.pronun > 0 then
                        std_ipa_for_rhyme_auto = resp_group_data.pronun_display_details.pronun.phonemic
                    end

                    if std_ipa_for_rhyme_auto then
                        local num_syl_val = get_num_syl_from_phonemic(std_ipa_for_rhyme_auto)
                        local rhyme_str = convert_phonemic_to_rhyme(std_ipa_for_rhyme_auto)
                        local saw_rhyme_already = false
                        for _, existing_rhyme_obj in ipairs(rhyme_ret_for_group_auto.pronun) do
                            if existing_rhyme_obj.rhyme == rhyme_str then
                                saw_rhyme_already = true
                                m_table.insertIfNot(existing_rhyme_obj.num_syl, num_syl_val)
                                break
                            end
                        end
                        if not saw_rhyme_already then
                            table.insert(rhyme_ret_for_group_auto.pronun, { rhyme = rhyme_str, num_syl = {num_syl_val} })
                        end
                    end
                end
            end
            if #rhyme_ret_for_group_auto.pronun > 0 then
                resp_group_data.rhyme = rhyme_ret_for_group_auto.pronun
            end
        elseif #resp_group_data.rhyme > 0 then
            local temp_rhyme_ret = { pronun = {} } 
            dodialect_specified_rhymes(resp_group_data.rhyme, resp_group_data.hyph or {}, {resp_group_data}, temp_rhyme_ret)
            resp_group_data.rhyme = temp_rhyme_ret.pronun
        end
    end

    local first_hyph_data_display, first_hmp_data_display, first_audio_data_display, first_rhyme_data_display
    local all_hyph_groups_eq_display, all_hmp_groups_eq_display, all_audio_groups_eq_display, all_rhyme_groups_eq_display = true, true, true, true

    if #parsed_respelling_groups_list > 0 then
        first_hyph_data_display = parsed_respelling_groups_list.hyph
        first_hmp_data_display = parsed_respelling_groups_list.hmp
        first_audio_data_display = parsed_respelling_groups_list.audio
        first_rhyme_data_display = parsed_respelling_groups_list.rhyme

        if #parsed_respelling_groups_list > 1 then
            for i_grp = 2, #parsed_respelling_groups_list do
                if not m_table.deepEquals(parsed_respelling_groups_list.hyph, first_hyph_data_display) then all_hyph_groups_eq_display = false end
                if not m_table.deepEquals(parsed_respelling_groups_list.hmp, first_hmp_data_display) then all_hmp_groups_eq_display = false end
                if not m_table.deepEquals(parsed_respelling_groups_list.audio, first_audio_data_display) then all_audio_groups_eq_display = false end
                if not m_table.deepEquals(parsed_respelling_groups_list.rhyme, first_rhyme_data_display) then all_rhyme_groups_eq_display = false end
            end
        end
    else
        all_hyph_groups_eq_display, all_hmp_groups_eq_display, all_audio_groups_eq_display, all_rhyme_groups_eq_display = false, false, false, false
    end

    local output_text_parts = {}
    local min_num_bullets_val = math.huge 

    for j_grp, resp_group_data in ipairs(parsed_respelling_groups_list) do
        local current_grp_bullets = resp_group_data.bullets or 1
        if current_grp_bullets < min_num_bullets_val then min_num_bullets_val = current_grp_bullets end

        if j_grp > 1 then table.insert(output_text_parts, "\n") end
        if resp_group_data.pre then table.insert(output_text_parts, resp_group_data.pre .. " ") end

        if resp_group_data.pronun_display_details and resp_group_data.pronun_display_details.text then
            table.insert(output_text_parts, resp_group_data.pronun_display_details.text)
        else
            local err_msg_pron = "(Pronunciation formatting error for group " .. j_grp .. ")"
            table.insert(output_text_parts, ustring.rep("*", current_grp_bullets) .. " " .. err_msg_pron)
        end

        if resp_group_data.post then table.insert(output_text_parts, " " .. resp_group_data.post) end

        local accessory_bullet_lvl = current_grp_bullets + (#parsed_respelling_groups_list > 1 and 1 or 0)

        if not all_audio_groups_eq_display and not overall_audio_parsed_data and resp_group_data.audio and #resp_group_data.audio > 0 then
            for _, audio_obj_item in ipairs(resp_group_data.audio) do
                table.insert(output_text_parts, "\n" .. ustring.rep("*", accessory_bullet_lvl) .. " " .. m_audio.format_audio(audio_obj_item))
            end
        end
        if not all_hyph_groups_eq_display and not overall_hyph_parsed_data and resp_group_data.hyph and #resp_group_data.hyph > 0 then
             table.insert(output_text_parts, "\n" .. ustring.rep("*", accessory_bullet_lvl) .. " " .. hyphenation_module.format_hyphenations{ lang = lang, hyphs = resp_group_data.hyph, caption = "Syllabification" })
        end
        if not all_hmp_groups_eq_display and not overall_hmp_parsed_data and resp_group_data.hmp and #resp_group_data.hmp > 0 then
            table.insert(output_text_parts, "\n" .. ustring.rep("*", accessory_bullet_lvl) .. " " .. homophones_module.format_homophones{ lang = lang, homophones = resp_group_data.hmp })
        end
        if not all_rhyme_groups_eq_display and not overall_rhyme_parsed_data and resp_group_data.rhyme and #resp_group_data.rhyme > 0 then
             table.insert(output_text_parts, "\n" .. ustring.rep("*", accessory_bullet_lvl) .. " " .. rhymes_module.format_rhymes{ lang = lang, rhymes = resp_group_data.rhyme, caption = "Rhymes" })
        end
    end

    local overall_display_bullet_lvl_final_val = min_num_bullets_val == math.huge and 1 or min_num_bullets_val

    if overall_audio_parsed_data and #overall_audio_parsed_data > 0 then
        for _, audio_overall_item in ipairs(overall_audio_parsed_data) do
            table.insert(output_text_parts, "\n" .. ustring.rep("*", overall_display_bullet_lvl_final_val) .. " " .. m_audio.format_audio(audio_overall_item))
        end
    elseif all_audio_groups_eq_display and first_audio_data_display and #first_audio_data_display > 0 then
         for _, audio_first_grp_item in ipairs(first_audio_data_display) do
            table.insert(output_text_parts, "\n" .. ustring.rep("*", overall_display_bullet_lvl_final_val) .. " " .. m_audio.format_audio(audio_first_grp_item))
         end
    end

    if overall_hyph_parsed_data and #overall_hyph_parsed_data > 0 then
        table.insert(output_text_parts, "\n" .. ustring.rep("*", overall_display_bullet_lvl_final_val) .. " " .. hyphenation_module.format_hyphenations{ lang = lang, hyphs = overall_hyph_parsed_data, caption = "Syllabification" })
    elseif all_hyph_groups_eq_display and first_hyph_data_display and #first_hyph_data_display > 0 then
        table.insert(output_text_parts, "\n" .. ustring.rep("*", overall_display_bullet_lvl_final_val) .. " " .. hyphenation_module.format_hyphenations{ lang = lang, hyphs = first_hyph_data_display, caption = "Syllabification" })
    end

    if overall_hmp_parsed_data and #overall_hmp_parsed_data > 0 then
         table.insert(output_text_parts, "\n" .. ustring.rep("*", overall_display_bullet_lvl_final_val) .. " " .. homophones_module.format_homophones{ lang = lang, homophones = overall_hmp_parsed_data })
    elseif all_hmp_groups_eq_display and first_hmp_data_display and #first_hmp_data_display > 0 then
        table.insert(output_text_parts, "\n" .. string.rep("*", overall_display_bullet_lvl_final_val) .. " " .. homophones_module.format_homophones{ lang = lang, homophones = first_hmp_data_display })
    end

    if overall_rhyme_parsed_data and #overall_rhyme_parsed_data > 0 then
        local overall_rhyme_output_final = { pronun = {} } 
        local all_hyphs_for_overall_rhyme = overall_hyph_parsed_data or (all_hyph_groups_eq_display and first_hyph_data_display) or {}
        
        dodialect_specified_rhymes(overall_rhyme_parsed_data, all_hyphs_for_overall_rhyme, parsed_respelling_groups_list, overall_rhyme_output_final)
        if overall_rhyme_output_final.pronun and #overall_rhyme_output_final.pronun > 0 then
            table.insert(output_text_parts, "\n" .. ustring.rep("*", overall_display_bullet_lvl_final_val) .. " " .. rhymes_module.format_rhymes{ lang = lang, rhymes = overall_rhyme_output_final.pronun, caption = "Rhymes" })
        end
    elseif all_rhyme_groups_eq_display and first_rhyme_data_display and #first_rhyme_data_display > 0 then
        table.insert(output_text_parts, "\n" .. ustring.rep("*", overall_display_bullet_lvl_final_val) .. " " .. rhymes_module.format_rhymes{ lang = lang, rhymes = first_rhyme_data_display, caption = "Rhymes" })
    end
    
    if #output_text_parts == 0 and #respelling_input_list > 0 and respelling_input_list == "+" and (pagename_val == "" or not pagename_val) then
        return "<strong class=\"error\">Module:an-pron: No page name available for default pronunciation ('+'). Please specify a term or use on a content page.</strong>"
    end

    return table.concat(output_text_parts)
end -- End of export.show_pr

return export