Module:IPA

require('strict')
local p = {}

local function multiFind(s, patterns, init)
	local i, j = mw.ustring.find(s, patterns[1], init)
	for n = 2, #patterns do
		local i2, j2 = mw.ustring.find(s, patterns[n], init)
		if i2 and (not i or i2 < i) then
			i, j = i2, j2
		end
	end
	return i, j
end

local function wrapAtSpaces(s)
	return mw.ustring.gsub(s, '(%s+)', '<span class="wrap">%1</span>')
end

local function wrapAtSpacesSafely(s)
	local patterns = {
		'%[%[[^%]|]-%s[^%]|]-|', -- Piped links
		'</?[A-Za-z][^>]-%s[^>]->' -- HTML tags
	}
	s = mw.ustring.gsub(s, '%[%[([^%]|]-%s[^%]|]-)%]%]', '[[%1|%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 cats[1] 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 splitTag(s)
	local langCode = s:gsub('%-.*', ''):lower()
	langCode = resolveSynonym(langCode)
	local regionCode = s:match('%-(.+)')
	local isPrivate = regionCode and regionCode:sub(1, 2) == 'x-'
	return langCode, regionCode, isPrivate
end

local function getLangName(code, link, raw)
	return require('Module:Lang')._name_from_tag({
		code,
		link = link,
		raw = raw,
		-- Without linking, "{{IPA}}" gets expanded in some contexts
		template = '[[Template:IPA|IPA]]'
	})
end

local function linkLang(name, target, link)
	return link == 'yes' and string.format(
		'[[%s|%s]]',
		target or name .. ' language',
		name
	) or name
end

function p._main(args)
	local ret, cats = {}, {}
	local isDebug = args.debug == 'yes'
	local s, langCode, regionCode, isPrivate
	
	-- Guide-linking mode
	if args[2] and args[2] ~= '' then
		local data = mw.loadData('Module:IPA/data')
		local isGeneric = args.generic == 'yes'
		s = args[2]
		langCode, regionCode, isPrivate = splitTag(args[1])
		local langData = data.langs[langCode] or {}
		if regionCode then
			if not isPrivate then
				regionCode = regionCode:upper()
			end
			if langData.dialects and langData.dialects[regionCode] then
				-- Overwrite language data with the dialect's
				local newLangData = {}
				for k, v in pairs(langData) do
					if k ~= 'dialects' then
						newLangData[k] = v
					end
				end
				local dialectData = langData.dialects[regionCode]
				if dialectData.aliasOf then
					-- Use the canonical region code
					regionCode = dialectData.aliasOf
					isPrivate = regionCode:sub(1, 2) == 'x-'
					dialectData = langData.dialects[regionCode]
				end
				-- Lowercase IANA variant
				if dialectData.isVariant then
					regionCode = regionCode:lower()
				end
				for k, v in pairs(dialectData) do
					newLangData[k] = v
				end
				langData = newLangData
			else
				isGeneric = true
			end
		end
		
		local fullLangCode = regionCode and langCode .. '-' .. regionCode
			or langCode
		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 = langData.name
				or getLangName(fullLangCode, nil, 'yes')
			if catLangName:sub(1, 5) == '<span' then
				-- Module:Lang has returned an error, but it's not fatal
				table.insert(cats, 'IPA template errors')
				mw.addWarning(catLangName)
			else
				table.insert(cats, string.format('Pages with %s IPA', catLangName))
			end
		end
		
		-- Label
		local label = args.label
		if not label then
			local labelCode = args[3] and args[3]: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)%]%]$',
						'[[%1|%2]]'
					)
					langText = mw.ustring.gsub(
						langText,
						' languages(%]?%]?)$',
						'%1'
					)
				end
				if labelCode and data.labels[labelCode] then
					label = data.labels[labelCode]: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 '&#91;%s&#93;'):format(s)
		
		-- Link to key
		local key = not isGeneric and langData.key or data.defaultKey
		s = string.format('[[%s|%s]]', key, s)
	else
		-- Basic mode
		s = args[1]
		if args.lang and args.lang ~= '' then
			langCode, regionCode, isPrivate = splitTag(args.lang)
		end
		if args.cat ~= 'no' then
			table.insert(cats, 'Pages with plain IPA')
		end
	end
	
	-- Transcription
	do
		local lang = (langCode or 'und') .. '-Latn'
		if not isPrivate and regionCode then
			lang = lang .. '-' .. regionCode
		end
		lang = lang .. '-fonipa'
		local span = mw.html.create('span')
			:addClass('IPA')
			:addClass(args.class)
			:attr('lang', lang)
		-- 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 args[2] or args[2] == '') and args.tooltip ~= '' then
			local tooltip = args.tooltip or
				'Representation in the International Phonetic Alphabet (IPA)'
			span:attr('title', tooltip)
		end
		s = tostring(span:wikitext(s))
		table.insert(ret, s)
	end
	
	-- Audio
	local audio = args.audio ~= '' and args.audio or args[4] ~= '' and args[4]
	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 args[1] then
		return ''
	end
	for i, v in ipairs(args) do
		args[i] = mw.text.trim(v)
	end
	return p._main(args)
end

return p

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.