Module:IPA explained

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, jend

local function wrapAtSpaces(s) return mw.ustring.gsub(s, '(%s+)', '

%1')end

local function wrapAtSpacesSafely(s) local patterns = 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').mainend

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('', isDebug and ':' or , v )) end return table.concat(t)end

local function resolveSynonym(s) return mw.loadData('Module:Lang/ISO 639 synonyms')[s] or send

local function getLangName(code, link) return require('Module:Lang')._name_from_tagend

local function linkLang(name, target, link) return link

'yes' and string.format('%s', target or name .. ' language', name ) or nameend

function p._main(args) local ret, cats =, local isDebug = args.debug

'yes' local s, langCode, isPrivate, fullLangCode -- 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] -- Split tag into language and region codes langCode = args[1]:gsub('%-.*', ):lower langCode = resolveSynonym(langCode) local regionCode = args[1]:match('%-(.+)') local langData = data.langs[langCode] or if regionCode then isPrivate = regionCode:sub(1, 2)

'x-' 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 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 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)

'