<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.cern.ch/index.php?action=history&amp;feed=atom&amp;title=Module%3AIPA</id>
	<title>Module:IPA - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.cern.ch/index.php?action=history&amp;feed=atom&amp;title=Module%3AIPA"/>
	<link rel="alternate" type="text/html" href="https://wiki.cern.ch/index.php?title=Module:IPA&amp;action=history"/>
	<updated>2026-04-04T06:02:32Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.44.0</generator>
	<entry>
		<id>https://wiki.cern.ch/index.php?title=Module:IPA&amp;diff=7916&amp;oldid=prev</id>
		<title>Vigen: 1 revision imported from :wikipedia:Module:IPA</title>
		<link rel="alternate" type="text/html" href="https://wiki.cern.ch/index.php?title=Module:IPA&amp;diff=7916&amp;oldid=prev"/>
		<updated>2026-03-19T09:10:09Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported from &lt;a href=&quot;https://en.wikipedia.org/wiki/Module:IPA&quot; class=&quot;extiw&quot; title=&quot;wikipedia:Module:IPA&quot;&gt;wikipedia:Module:IPA&lt;/a&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 09:10, 19 March 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Vigen</name></author>
	</entry>
	<entry>
		<id>https://wiki.cern.ch/index.php?title=Module:IPA&amp;diff=7915&amp;oldid=prev</id>
		<title>wikipedia&gt;Nardog: bugfixes</title>
		<link rel="alternate" type="text/html" href="https://wiki.cern.ch/index.php?title=Module:IPA&amp;diff=7915&amp;oldid=prev"/>
		<updated>2024-12-27T10:23:34Z</updated>

		<summary type="html">&lt;p&gt;bugfixes&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;require(&amp;#039;strict&amp;#039;)&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
local function multiFind(s, patterns, init)&lt;br /&gt;
	local i, j = mw.ustring.find(s, patterns[1], init)&lt;br /&gt;
	for n = 2, #patterns do&lt;br /&gt;
		local i2, j2 = mw.ustring.find(s, patterns[n], init)&lt;br /&gt;
		if i2 and (not i or i2 &amp;lt; i) then&lt;br /&gt;
			i, j = i2, j2&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return i, j&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function wrapAtSpaces(s)&lt;br /&gt;
	return mw.ustring.gsub(s, &amp;#039;(%s+)&amp;#039;, &amp;#039;&amp;lt;span class=&amp;quot;wrap&amp;quot;&amp;gt;%1&amp;lt;/span&amp;gt;&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function wrapAtSpacesSafely(s)&lt;br /&gt;
	local patterns = {&lt;br /&gt;
		&amp;#039;%[%[[^%]|]-%s[^%]|]-|&amp;#039;, -- Piped links&lt;br /&gt;
		&amp;#039;&amp;lt;/?[A-Za-z][^&amp;gt;]-%s[^&amp;gt;]-&amp;gt;&amp;#039; -- HTML tags&lt;br /&gt;
	}&lt;br /&gt;
	s = mw.ustring.gsub(s, &amp;#039;%[%[([^%]|]-%s[^%]|]-)%]%]&amp;#039;, &amp;#039;[[%1|%1]]&amp;#039;) -- Pipe all links&lt;br /&gt;
	local t = {}&lt;br /&gt;
	local init&lt;br /&gt;
	while true do&lt;br /&gt;
		local i, j = multiFind(s, patterns, init)&lt;br /&gt;
		if not i then&lt;br /&gt;
			break&lt;br /&gt;
		end&lt;br /&gt;
		local pre = wrapAtSpaces(mw.ustring.sub(s, init, i - 1)) -- What precedes the match&lt;br /&gt;
		table.insert(t, pre)&lt;br /&gt;
		table.insert(t, mw.ustring.sub(s, i, j)) -- The match&lt;br /&gt;
		init = j + 1&lt;br /&gt;
	end&lt;br /&gt;
	local post = wrapAtSpaces(mw.ustring.sub(s, init)) -- What follows the last match&lt;br /&gt;
	table.insert(t, post)&lt;br /&gt;
	return table.concat(t)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function checkNamespace(isDebug)&lt;br /&gt;
	return isDebug or require(&amp;#039;Module:Category handler&amp;#039;).main({ true })&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderCats(cats, isDebug)&lt;br /&gt;
	if not cats[1] or not checkNamespace(isDebug) then&lt;br /&gt;
		return &amp;#039;&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	local t = {}&lt;br /&gt;
	for _, v in ipairs(cats) do&lt;br /&gt;
		table.insert(t, string.format(&lt;br /&gt;
			&amp;#039;[[%sCategory:%s]]&amp;#039;,&lt;br /&gt;
			isDebug and &amp;#039;:&amp;#039; or &amp;#039;&amp;#039;,&lt;br /&gt;
			v&lt;br /&gt;
		))&lt;br /&gt;
	end&lt;br /&gt;
	return table.concat(t)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function resolveSynonym(s)&lt;br /&gt;
	return mw.loadData(&amp;#039;Module:Lang/ISO 639 synonyms&amp;#039;)[s] or s&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function splitTag(s)&lt;br /&gt;
	local langCode = s:gsub(&amp;#039;%-.*&amp;#039;, &amp;#039;&amp;#039;):lower()&lt;br /&gt;
	langCode = resolveSynonym(langCode)&lt;br /&gt;
	local regionCode = s:match(&amp;#039;%-(.+)&amp;#039;)&lt;br /&gt;
	local isPrivate = regionCode and regionCode:sub(1, 2) == &amp;#039;x-&amp;#039;&lt;br /&gt;
	return langCode, regionCode, isPrivate&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getLangName(code, link, raw)&lt;br /&gt;
	return require(&amp;#039;Module:Lang&amp;#039;)._name_from_tag({&lt;br /&gt;
		code,&lt;br /&gt;
		link = link,&lt;br /&gt;
		raw = raw,&lt;br /&gt;
		-- Without linking, &amp;quot;{{IPA}}&amp;quot; gets expanded in some contexts&lt;br /&gt;
		template = &amp;#039;[[Template:IPA|IPA]]&amp;#039;&lt;br /&gt;
	})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function linkLang(name, target, link)&lt;br /&gt;
	return link == &amp;#039;yes&amp;#039; and string.format(&lt;br /&gt;
		&amp;#039;[[%s|%s]]&amp;#039;,&lt;br /&gt;
		target or name .. &amp;#039; language&amp;#039;,&lt;br /&gt;
		name&lt;br /&gt;
	) or name&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._main(args)&lt;br /&gt;
	local ret, cats = {}, {}&lt;br /&gt;
	local isDebug = args.debug == &amp;#039;yes&amp;#039;&lt;br /&gt;
	local s, langCode, regionCode, isPrivate&lt;br /&gt;
	&lt;br /&gt;
	-- Guide-linking mode&lt;br /&gt;
	if args[2] and args[2] ~= &amp;#039;&amp;#039; then&lt;br /&gt;
		local data = mw.loadData(&amp;#039;Module:IPA/data&amp;#039;)&lt;br /&gt;
		local isGeneric = args.generic == &amp;#039;yes&amp;#039;&lt;br /&gt;
		s = args[2]&lt;br /&gt;
		langCode, regionCode, isPrivate = splitTag(args[1])&lt;br /&gt;
		local langData = data.langs[langCode] or {}&lt;br /&gt;
		if regionCode then&lt;br /&gt;
			if not isPrivate then&lt;br /&gt;
				regionCode = regionCode:upper()&lt;br /&gt;
			end&lt;br /&gt;
			if langData.dialects and langData.dialects[regionCode] then&lt;br /&gt;
				-- Overwrite language data with the dialect&amp;#039;s&lt;br /&gt;
				local newLangData = {}&lt;br /&gt;
				for k, v in pairs(langData) do&lt;br /&gt;
					if k ~= &amp;#039;dialects&amp;#039; then&lt;br /&gt;
						newLangData[k] = v&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				local dialectData = langData.dialects[regionCode]&lt;br /&gt;
				if dialectData.aliasOf then&lt;br /&gt;
					-- Use the canonical region code&lt;br /&gt;
					regionCode = dialectData.aliasOf&lt;br /&gt;
					isPrivate = regionCode:sub(1, 2) == &amp;#039;x-&amp;#039;&lt;br /&gt;
					dialectData = langData.dialects[regionCode]&lt;br /&gt;
				end&lt;br /&gt;
				-- Lowercase IANA variant&lt;br /&gt;
				if dialectData.isVariant then&lt;br /&gt;
					regionCode = regionCode:lower()&lt;br /&gt;
				end&lt;br /&gt;
				for k, v in pairs(dialectData) do&lt;br /&gt;
					newLangData[k] = v&lt;br /&gt;
				end&lt;br /&gt;
				langData = newLangData&lt;br /&gt;
			else&lt;br /&gt;
				isGeneric = true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		local fullLangCode = regionCode and langCode .. &amp;#039;-&amp;#039; .. regionCode&lt;br /&gt;
			or langCode&lt;br /&gt;
		local langName = langData.name&lt;br /&gt;
			and linkLang(langData.name, langData.link, args.link)&lt;br /&gt;
			or getLangName(fullLangCode, args.link)&lt;br /&gt;
		if langName:sub(1, 5) == &amp;#039;&amp;lt;span&amp;#039; then&lt;br /&gt;
			-- Module:Lang has returned an error&lt;br /&gt;
			return langName .. renderCats({ &amp;#039;IPA template errors&amp;#039; }, isDebug)&lt;br /&gt;
		end&lt;br /&gt;
		if args.cat ~= &amp;#039;no&amp;#039; then&lt;br /&gt;
			local catLangName = langData.name&lt;br /&gt;
				or getLangName(fullLangCode, nil, &amp;#039;yes&amp;#039;)&lt;br /&gt;
			if catLangName:sub(1, 5) == &amp;#039;&amp;lt;span&amp;#039; then&lt;br /&gt;
				-- Module:Lang has returned an error, but it&amp;#039;s not fatal&lt;br /&gt;
				table.insert(cats, &amp;#039;IPA template errors&amp;#039;)&lt;br /&gt;
				mw.addWarning(catLangName)&lt;br /&gt;
			else&lt;br /&gt;
				table.insert(cats, string.format(&amp;#039;Pages with %s IPA&amp;#039;, catLangName))&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		-- Label&lt;br /&gt;
		local label = args.label&lt;br /&gt;
		if not label then&lt;br /&gt;
			local labelCode = args[3] and args[3]:lower()&lt;br /&gt;
				or langData.defaultLabelCode&lt;br /&gt;
			if labelCode == &amp;#039;&amp;#039; then&lt;br /&gt;
				label = &amp;#039;&amp;#039;&lt;br /&gt;
			else&lt;br /&gt;
				local langText&lt;br /&gt;
				if langData.text then&lt;br /&gt;
					langText = linkLang(&lt;br /&gt;
						langData.text,&lt;br /&gt;
						mw.ustring.match(langName, &amp;#039;^%[%[([^|%]]+)&amp;#039;),&lt;br /&gt;
						args.link&lt;br /&gt;
					)&lt;br /&gt;
				else&lt;br /&gt;
					langText = mw.ustring.gsub(&lt;br /&gt;
						langName,&lt;br /&gt;
						&amp;#039;^%[%[(([^|]+) languages)%]%]$&amp;#039;,&lt;br /&gt;
						&amp;#039;[[%1|%2]]&amp;#039;&lt;br /&gt;
					)&lt;br /&gt;
					langText = mw.ustring.gsub(&lt;br /&gt;
						langText,&lt;br /&gt;
						&amp;#039; languages(%]?%]?)$&amp;#039;,&lt;br /&gt;
						&amp;#039;%1&amp;#039;&lt;br /&gt;
					)&lt;br /&gt;
				end&lt;br /&gt;
				if labelCode and data.labels[labelCode] then&lt;br /&gt;
					label = data.labels[labelCode]:format(langText)&lt;br /&gt;
				else&lt;br /&gt;
					label = data.defaultLabel:format(langText)&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if label and label ~= &amp;#039;&amp;#039; then&lt;br /&gt;
			local span = mw.html.create(&amp;#039;span&amp;#039;)&lt;br /&gt;
				:addClass(&amp;#039;IPA-label&amp;#039;)&lt;br /&gt;
				:wikitext(label)&lt;br /&gt;
			if args.small ~= &amp;#039;no&amp;#039; then&lt;br /&gt;
				span:addClass(&amp;#039;IPA-label-small&amp;#039;)&lt;br /&gt;
				table.insert(ret, mw.getCurrentFrame():extensionTag({&lt;br /&gt;
					name = &amp;#039;templatestyles&amp;#039;,&lt;br /&gt;
					args = { src = &amp;#039;Module:IPA/styles.css&amp;#039; }&lt;br /&gt;
				}))&lt;br /&gt;
			end&lt;br /&gt;
			table.insert(ret, tostring(span) .. &amp;#039; &amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		-- Brackets&lt;br /&gt;
		s = (not isGeneric and langData.format or &amp;#039;&amp;amp;#91;%s&amp;amp;#93;&amp;#039;):format(s)&lt;br /&gt;
		&lt;br /&gt;
		-- Link to key&lt;br /&gt;
		local key = not isGeneric and langData.key or data.defaultKey&lt;br /&gt;
		s = string.format(&amp;#039;[[%s|%s]]&amp;#039;, key, s)&lt;br /&gt;
	else&lt;br /&gt;
		-- Basic mode&lt;br /&gt;
		s = args[1]&lt;br /&gt;
		if args.lang and args.lang ~= &amp;#039;&amp;#039; then&lt;br /&gt;
			langCode, regionCode, isPrivate = splitTag(args.lang)&lt;br /&gt;
		end&lt;br /&gt;
		if args.cat ~= &amp;#039;no&amp;#039; then&lt;br /&gt;
			table.insert(cats, &amp;#039;Pages with plain IPA&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Transcription&lt;br /&gt;
	do&lt;br /&gt;
		local lang = (langCode or &amp;#039;und&amp;#039;) .. &amp;#039;-Latn&amp;#039;&lt;br /&gt;
		if not isPrivate and regionCode then&lt;br /&gt;
			lang = lang .. &amp;#039;-&amp;#039; .. regionCode&lt;br /&gt;
		end&lt;br /&gt;
		lang = lang .. &amp;#039;-fonipa&amp;#039;&lt;br /&gt;
		local span = mw.html.create(&amp;#039;span&amp;#039;)&lt;br /&gt;
			:addClass(&amp;#039;IPA&amp;#039;)&lt;br /&gt;
			:addClass(args.class)&lt;br /&gt;
			:attr(&amp;#039;lang&amp;#039;, lang)&lt;br /&gt;
		-- wrap=all: Do nothing&lt;br /&gt;
		-- wrap=none: Never break&lt;br /&gt;
		-- Otherwise: Break at spaces only&lt;br /&gt;
		if args.wrap ~= &amp;#039;all&amp;#039; then&lt;br /&gt;
			span:addClass(&amp;#039;nowrap&amp;#039;)&lt;br /&gt;
			if args.wrap ~= &amp;#039;none&amp;#039; then&lt;br /&gt;
				s = wrapAtSpacesSafely(s)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if (not args[2] or args[2] == &amp;#039;&amp;#039;) and args.tooltip ~= &amp;#039;&amp;#039; then&lt;br /&gt;
			local tooltip = args.tooltip or&lt;br /&gt;
				&amp;#039;Representation in the International Phonetic Alphabet (IPA)&amp;#039;&lt;br /&gt;
			span:attr(&amp;#039;title&amp;#039;, tooltip)&lt;br /&gt;
		end&lt;br /&gt;
		s = tostring(span:wikitext(s))&lt;br /&gt;
		table.insert(ret, s)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Audio&lt;br /&gt;
	local audio = args.audio ~= &amp;#039;&amp;#039; and args.audio or args[4] ~= &amp;#039;&amp;#039; and args[4]&lt;br /&gt;
	if audio then&lt;br /&gt;
		local button = mw.getCurrentFrame():expandTemplate({&lt;br /&gt;
			title = &amp;#039;Audio&amp;#039;,&lt;br /&gt;
			args = { audio, &amp;#039;&amp;#039; }&lt;br /&gt;
		})&lt;br /&gt;
		table.insert(ret, &amp;#039; &amp;#039; .. button)&lt;br /&gt;
		table.insert(cats, &amp;#039;Pages including recorded pronunciations&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Categories&lt;br /&gt;
	table.insert(ret, renderCats(cats, isDebug))&lt;br /&gt;
	&lt;br /&gt;
	return table.concat(ret)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
	local args = frame:getParent().args&lt;br /&gt;
	if not args[1] then&lt;br /&gt;
		return &amp;#039;&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	for i, v in ipairs(args) do&lt;br /&gt;
		args[i] = mw.text.trim(v)&lt;br /&gt;
	end&lt;br /&gt;
	return p._main(args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>wikipedia&gt;Nardog</name></author>
	</entry>
</feed>