-- This module implements টেমপ্লেট:IPAc-en.  local data = mw.loadData('মডিউল:IPAc-en/তথ্য') local p = {}  -- Global container for tracking categories local categoryHandler = require('মডিউল:বিষয়শ্রেণী পরিচালনাকারী').main local categories = {}  -- Trims whitespace from a string local function trim(s) 	return s:match('^%s*(.-)%s*$') end  -- This implements টেমপ্লেট:Nowrap. local function makeNowrapSpan(s) 	local span = mw.html.create('span') 		:addClass('nowrap') 		:wikitext(s) 	return tostring(span) end  local function makePronunciationText(id) 	id = id and string.lower(trim(id)) 	if id and id ~=  and data.pronunciation[id] then 		return data.pronunciation[id].text 	end end  -- This adds a tooltip icon to a label. It implements টেমপ্লেট:H:title. local function makeTooltip(label, tooltip) 	local span = mw.html.create('span') 		:attr('title', tooltip) 		:wikitext(label) 	return tostring(span) end  local function formatPhonemeGroup(phonemes) 	if #phonemes > 0 then 		local span = mw.html.create('span') 			:css('border-bottom', '1px dotted') 			:wikitext(table.concat(phonemes)) 		return tostring(span) 	else 		return  	end end  local function renderCategories() 	local ret = 	ret = categoryHandler{ 		[1] = 'yes', -- Add categories in these namespaces 		main = 1, 		wikipedia = 1, 		file = 1, 		template = 1, 		help = 1, 		category = 1, 		portal = 1, 		book = 1, 		draft = 1, 		module = 1, 	} 	 	if ret == 'yes' then 		ret = {} 		for cat in pairs(categories) do 			table.insert(ret, string.format('বিষয়শ্রেণী:%s', cat)) 		end 		table.sort(ret) 		ret = table.concat(ret) 	else 		ret =  	end 	return ret end  function p._main(args) 	local ret = {} 	local i = 0 -- Keeps track of numbered args  	-- Pronunciation 	do 		local pron = {} 		while true do 			i = i + 1 			local pronItem = makePronunciationText(args[i]) 			if pronItem then 				pron[#pron + 1] = pronItem 				pron[#pron + 1] = ' ' 			else 				break 			end 		end 		if #pron > 0 then 			ret[#ret + 1] = string.format( 				'%s', 				table.concat(pron) 			) 		end 	end  	-- Phonemes 	do 		-- Loop through the numbered args, separating them into phoneme groups 		-- and separator strings (both called "words" for convenience). We only 		-- underline the phoneme groups, not the separators. 		local words = {} 		words[#words + 1] = '/' -- Opening slash 		i = i - 1 -- Set up i again as it was changed in the pronunciation loop 		local id 		repeat 			local phonemes = {} 			local isWordEnd = false 			while not isWordEnd do 				i = i + 1 				id = args[i] 				id = id and trim(id) 				if not id then 					isWordEnd = true 					words[#words + 1] = formatPhonemeGroup(phonemes) 				elseif id ~=  then 					local t = data.phonemes[id] 					if not t then 						-- We were passed an invalid id. 						isWordEnd = true 						categories["Ill-ফরম্যাটেড IPAc-en ট্রান্সক্লুশন"] = true 						words[#words + 1] = formatPhonemeGroup(phonemes) 						words[#words + 1] = makeTooltip( 							string.format( 								"[অসমর্থিত ইনপুট: '%s']", 								id 								), 							'অপরিচিত প্রতীক' 						) 					elseif not t.label then 						-- The data module contains bad data, so throw an error. 						error(string.format( 							"'% s' এর জন্য কোন লেবেল আইডি পাওয়া যায়নি", 							tostring(id) 						)) 					elseif t.tooltip then 						-- We are dealing with a regular phoneme. 						phonemes[#phonemes + 1] = makeTooltip( 							t.label, 							t.tooltip 						) 					else 						-- We are dealing with a separator. 						isWordEnd = true 						words[#words + 1] = formatPhonemeGroup(phonemes) 						words[#words + 1] = t.label						 					end 				end 			end 		until not id 		words[#words + 1] = '/' -- Closing slash  		-- Wrap the words in a link to IPA help. 		local span = mw.html.create('span') 			-- Suppress Navigation popups and Page Previews (aka Hovercards) 			:addClass('IPA nopopups noexcerpt') 			:wikitext(string.format( 				'%s', 				table.concat(words) 			)) 		 		ret[#ret + 1] = tostring(span) 	end 	 	-- Audio link 	do 		local file = args.audio and trim(args.audio) 		if file and file ~=  then 			if args[1] and string.lower(trim(args[1])) == 'uk' then 				categories["নিবন্ধসমূহ রেকর্ডকৃত উচ্চারণ (যুক্তরাজ্যের ইংরেজি) ধারণ করছে"] = true 			elseif args[1] and string.lower(trim(args[1])) == 'us' then 				categories["নিবন্ধসমূহ রেকর্ডকৃত উচ্চারণ (মার্কিন ইংরেজি) ধারণ করছে"] = true 			else 				categories["নিবন্ধসমূহ রেকর্ডকৃত উচ্চারণ (ইংরেজি) ধারণ করছে"] = true 			end 			 			ret[#ret + 1] = mw.getCurrentFrame():expandTemplate{ 				title = 'টেমপ্লেট:আধ্বব অডিও সংযোগ', args = { file } } 		end 	end 	 	-- Nowrap and categories 	ret = makeNowrapSpan(table.concat(ret)) .. renderCategories()  	-- Reset the categories table in case we are run again. 	categories = {}  	return ret end  function p.main(frame) 	return p._main(frame:getParent().args) end  return p