มอดูล:IPA

require('strict')
local p = {}
local function multiFind(s, patterns, init)
	local i, j = mw.ustring.find(s, patterns1, init)
	for n = 2, #patterns do
		local i2, j2 = mw.ustring.find(s, patternsn, init)
		if i2 and (not i or i2 %1')
end
local function wrapAtSpacesSafely(s)
	local patterns = {
		'%%^%|-%s^%|-|', -- Piped links
		'-%s^>->' -- HTML tags
	}
	s = mw.ustring.gsub(s, '%%(^%|-%s^%|-)%%', '%1') -- Pipe all links
	local t = {}
	local init
	while true do
		local i, j = multiFind(s, patterns, init)
		if not i then
			break
		end
		local pre = wrapAtSpaces(mw.ustring.sub(s, init, i - 1)) -- What precedes the match
		table.insert(t, pre)
		table.insert(t, mw.ustring.sub(s, i, j)) -- The match
		init = j + 1
	end
	local post = wrapAtSpaces(mw.ustring.sub(s, init)) -- What follows the last match
	table.insert(t, post)
	return table.concat(t)
end
local function checkNamespace(isDebug)
	return isDebug or require('Module:Category handler').main({ true })
end
local function renderCats(cats, isDebug)
	if not cats1 or not checkNamespace(isDebug) then
		return 
	end
	local t = {}
	for _, v in ipairs(cats) do
		table.insert(t, string.format(
			'%sCategory:%s',
			isDebug and ':' or ,
			v
		))
	end
	return table.concat(t)
end
local function resolveSynonym(s)
	return mw.loadData('Module:Lang/ISO 639 synonyms')s or s
end
local function getLangName(code, link)
	return require('Module:Lang')._name_from_tag({
		code,
		link = link,
		-- Without linking, "" gets expanded in some contexts
		template = 'IPA'
	})
end
local function linkLang(name, target, link)
	return link == 'yes' and string.format(
		'%s',
		target or name .. ' language',
		name
	) or name
end
function p._main(args)
	local ret, cats = {}, {}
	local isDebug = args.debug == 'yes'
	local s, langCode, isPrivate, fullLangCode
	
	-- Guide-linking mode
	if args2 and args2 ~=  then
		local data = mw.loadData('Module:IPA/data')
		local isGeneric = args.generic == 'yes'
		s = args2
		
		-- Split tag into language and region codes
		langCode = args1:gsub('%-.*', ):lower()
		langCode = resolveSynonym(langCode)
		local regionCode = args1:match('%-(.+)')
		local langData = data.langslangCode or {}
		if regionCode then
			isPrivate = regionCode:sub(1, 2) == 'x-'
			if not isPrivate then
				regionCode = regionCode:upper()
			end
			if langData.dialects and langData.dialectsregionCode then
				-- Overwrite language data with the dialect's
				local newLangData = {}
				for k, v in pairs(langData) do
					if k ~= 'dialects' then
						newLangDatak = v
					end
				end
				local dialectData = langData.dialectsregionCode
				if dialectData.aliasOf then
					-- Use the canonical region code
					regionCode = dialectData.aliasOf
					dialectData = langData.dialectsregionCode
				end
				-- Lowercase IANA variant
				if dialectData.isVariant then
					regionCode = regionCode:lower()
				end
				for k, v in pairs(dialectData) do
					newLangDatak = v
				end
				langData = newLangData
			else
				isGeneric = true
			end
			fullLangCode = langCode .. '-' .. regionCode
		else
			fullLangCode = langCode
		end
		
		local langName = langData.name
			and linkLang(langData.name, langData.link, args.link)
			or getLangName(fullLangCode, args.link)
		if langName:sub(1, 5) == '<span' then
			-- Module:Lang has returned an error
			return langName .. renderCats({ 'IPA template errors' }, isDebug)
		end
		if args.cat ~= 'no' then
			local catLangName = args.link == 'yes'
				and mw.ustring.match(langName, '(^%%+)%%$')
				or langName
			table.insert(cats, string.format('หน้าที่มีสัทอักษรสากลภาษา%s ', catLangName))
		end
		
		-- Label
		local label = args.label
		if not label then
			local labelCode = args3 and args3:lower()
				or langData.defaultLabelCode
			if labelCode ==  then
				label = 
			else
				local langText
				if langData.text then
					langText = linkLang(
						langData.text,
						mw.ustring.match(langName, '^%%(%+)'),
						args.link
					)
				else
					langText = mw.ustring.gsub(
						langName,
						'^%%((+) languages)%%$',
						'%2'
					)
					langText = mw.ustring.gsub(
						langText,
						' languages(%?%?)$',
						'%1'
					)
				end
				if labelCode and data.labelslabelCode then
					label = data.labelslabelCode:format(langText)
				else
					label = data.defaultLabel:format(langText)
				end
			end
		end
		if label and label ~=  then
			local span = mw.html.create('span')
				:addClass('IPA-label')
				:wikitext(label)
			if args.small ~= 'no' then
				span:addClass('IPA-label-small')
				table.insert(ret, mw.getCurrentFrame():extensionTag({
					name = 'templatestyles',
					args = { src = 'Module:IPA/styles.css' }
				}))
			end
			table.insert(ret, tostring(span) .. ' ')
		end
		
		-- Brackets
		s = (not isGeneric and langData.format or '%s'):format(s)
		
		-- Link to key
		local key = not isGeneric and langData.key or data.defaultKey
		s = string.format('%s', key, s)
	else
		-- Basic mode
		s = args1
		if args.cat ~= 'no' then
			table.insert(cats, 'หน้าที่มีสัทอักษรสากลไม่ระบุภาษา')
		end
	end
	
	-- Transcription
	do
		local lang = isPrivate and langCode or fullLangCode or
			args.lang ~=  and args.lang or 'und'
		local span = mw.html.create('span')
			:addClass('IPA')
			:addClass(args.class)
			:attr('lang', lang .. '-Latn-fonipa')
		-- wrap=all: Do nothing
		-- wrap=none: Never break
		-- Otherwise: Break at spaces only
		if args.wrap ~= 'all' then
			span:addClass('nowrap')
			if args.wrap ~= 'none' then
				s = wrapAtSpacesSafely(s)
			end
		end
		if (not args2 or args2 == ) and args.tooltip ~=  then
			local tooltip = args.tooltip or
				'เสียงอ่านในสัทอักษรสากล'
			span:attr('title', tooltip)
		end
		s = tostring(span:wikitext(s))
		table.insert(ret, s)
	end
	
	-- Audio
	local audio = args.audio ~=  and args.audio or args4 ~=  and args4
	if audio then
		local button = mw.getCurrentFrame():expandTemplate({
			title = 'Audio',
			args = { audio,  }
		})
		table.insert(ret, ' ' .. button)
		table.insert(cats, 'Pages including recorded pronunciations')
	end
	
	-- Categories
	table.insert(ret, renderCats(cats, isDebug))
	
	return table.concat(ret)
end
function p.main(frame)
	local args = frame:getParent().args
	if not args1 then
		return 
	end
	for i, v in ipairs(args) do
		argsi = mw.text.trim(v)
	end
	return p._main(args)
end
return p