Module documentation

Lua library for managing title strings.

isInterwiki

isInterwiki(String prefix, bool onlyInterlang = false): bool

Checks wether prefix is a valid interwiki prefix. I.e. wether the prefix is registered in mw.site.interwikiMap()

If onlyInterlang is true, it will only check for language prefixes ('en', 'pt'…), excluding website prefixes ('commons', 'wikiquote'…).

Returns true if prefix is a registered interwiki prefix, false else.

isInterlangPrefix

isInterlangPrefix(String prefix): bool

Checks wether prefix is a valid interlanguage prefix. I.e. wether the prefix is registered in mw.site.interwikiMap() and is known by mw.language.isKnownLanguageTag().

Equivalent to isInterwiki(prefix, true).

Returns true if prefix is a registered interlanguage prefix, false else.

isNamespace

isNamespace(String prefix): bool

Checks wether the prefix is a valid namespace prefix on Meta. I.e. wether the prefix is registered in mw.site.namespaces

Returns true if prefix is a registered interwiki prefix, false else.

langToWiki

langToWiki(String lang): String|bool

Gives a valid interwiki prefix for the requested language code.

Most interwiki prefixes are actually language codes, but some language code match with another interwiki. E.g. 'pt-br' language code matches with 'pt' interwiki prefix.

Returns the interwiki prefix related to the given language if possible, or false if none is known.

splitPrefixedTitle

splitPrefixedTitle(String title): String, String

Split title into two parts: interwiki prefixes and page title.

Returns 2 strings:

  • first one is all prefixes which are recognized as interwikis, joined with colon
  • second one is the rest of the given string
myLangLink(String pageLink): String

Prefixes page name with Special:MyLanguage.

Parameter

  • pageLink: Page name, eventually prefixed with interwiki prefixes and namespace.

Return

Returns name of page which links to given page link in user language.

-- == Titlelib.lua == --
local p = {}

--[[ Checks wether the given String is a valid interwiki prefix.

	I.e. wether the prefix is registered in mw.site.interwikiMap()
	
	@param onlyInterlang bool Wether to look only for interlang wiki prefix.
	False by default.
	
	@return true if str is a registered interwiki prefix, false else
]]
function p.isInterwiki(str, onlyInterlang)
	if not onlyInterlang then onlyInterlang = false end
	str = mw.ustring.lower(str) --prefixes are stored as lower case
	
	if mw.site.interwikiMap()[str] then -- `str` is in interwikiMap
		-- When requested, ensures `str` is a valid language code
		return not onlyInterlang or mw.language.isKnownLanguageTag(str)
	end
	
	return false -- `str` is not in interwikiMap
end

--[[ Checks wether the given String is a valid interlang wiki prefix.

	I.e. wether the prefix is registered in mw.site.interwikiMap() and is a
	known language code.
	
	@param str String the prefix to check for.
	
	@return true if str is a registered interlang prefix, false else.
]]
function p.isInterlangPrefix(str)
	return p.isInterwiki(str, true)
end

--[[ Checks wether the given String is a valid namespace prefix on Meta.

	I.e. wether the prefix is registered in mw.site.namespaces
	
	@return true if str is a registered interwiki prefix, false else
]]
function p.isNamespace(str)
	str = mw.ustring.lower(str)
	for i, details in pairs(mw.site.namespaces) do
		if str == mw.ustring.lower(details.name)
			or str == mw.ustring.lower(details.canonicalName)
			or (details.aliases[1] and str == mw.ustring.lower(details.aliases[1]))
			--on Meta there is no more than 1 alias; else we should use
			--table.contains(aliases, str)
		then
			return true
		end
	end
	
	return false
end

--[[ Split given title into two parts: interwiki prefixes and page title
	@Return table containing 2 strings:
		* first one is all prefixes which are recognized as interwikis, joined
		with colon
		* second one is the rest of the given string
]]
function p.splitPrefixedTitle(linkStr)
	if not mw.ustring.find(linkStr, ':') then --if there is no colon in title
		return ':', linkStr --that means there is no prefix
	end
	
	local linkTable = mw.text.split(linkStr, ':', true)
	
	local outwikiPart = '' --interwiki prefixes and language code
	local inwikiPart = '' --page name, including namespace prefix
	
	local hasGotLastInterwikiPrefix = false
	local hasInterwikiPrefix = false
	
	for i, linkPart in ipairs(linkTable) do
		if linkPart == '' then
		elseif hasGotLastInterwikiPrefix or p.isNamespace(linkPart) then
			hasGotLastInterwikiPrefix = true
			inwikiPart = inwikiPart .. ':' .. linkPart
		elseif p.isInterlangPrefix(linkPart) then
			outwikiPart = outwikiPart .. ':' .. linkPart
			hasGotLastInterwikiPrefix = true
		elseif not hasInterwikiPrefix and p.isInterwiki(linkPart) then
			outwikiPart = outwikiPart .. ':' .. linkPart
			hasInterwikiPrefix = true
		else
			hasGotLastInterwikiPrefix = true
			inwikiPart = linkPart
		end
	end
	
	return outwikiPart .. ':', inwikiPart
end

--[[ Gives the interwiki prefix for a given language code or database project id.
	E.g. langToWiki("de-formal") will return 'de'.

	Currently, doesn’t provide any fallback.
	
	@param lang String Language code or database project identifier (project
	code on Wikidata).
	
	@Return String|bool Related interwiki prefix (without colon), or false if
	there is none.
	
	@Seealso T253387
]]
function p.langToWiki(lang)
	lang = lang:gsub('_', '-') --DB-prefixes use `_` instead of `-`
	local exceptions = {
--		['lang-code']	= 'interwiki-prefix'
		
		['ady-cyrl']	= 'ady',
		['aeb']			= 'ar',
		['aeb-arab']	= 'ar',
		['aeb-latn']	= 'ar',
		['arq']			= 'ar',
		['ban-bali']	= 'ban',
		['be-x-old']	= 'be-tarask',		-- Both work
		['bho']			= 'bh',
		['crh-latn']	= 'crh',
		['crh-cyrl']	= 'crh',
		['de-at']		= 'de',
		['de-ch']		= 'de',
		['de-formal']	= 'de',
		['egl']			= 'eml',
		['en-ca']		= 'en',
		['en-gb']		= 'en',
		['es-419']		= 'es',
		['es-formal']	= 'es',
		['frc']			= 'fr',
		['gan-hans']	= 'gan',
		['gan-hant']	= 'gan',
		['gom-deva']	= 'gom',
		['gom-latn']	= 'gom',
		['gsw']			= 'als',
		['hif-latn']	= 'hif',
		['hu-formal']	= 'hu',
		['hsn']			= 'zh',
		['ike']			= 'iu',
		['ike-cans']	= 'iu',
		['ike-latn']	= 'iu',
		['kbd-cyrl']	= 'kbd',
		['kk-arab']		= 'kk',
		['kk-cn']		= 'kk',
		['kk-cyrl']		= 'kk',
		['kk-kz']		= 'kk',
		['kk-latn']		= 'kk',
		['kk-tr']		= 'kk',
		['ko-kp']		= 'ko',
		['ks-arab']		= 'ks',
		['ks-deva']		= 'ks',
		['ku-arab']		= 'ku',
		['ks-latn']		= 'ku',
		['lzh']			= 'zh-classical',	-- Both work
		['ms-arab']		= 'ms',
		['nan']			= 'zh-min-nan',		-- Both work
		['nb']			= 'no',				-- Both work
		['nl-informal']	= 'nl',
		['mo']			= 'ro',				-- Both work
		['pt-br']		= 'pt',
		['rgn']			= 'eml',
		['rup']			= 'roa-rup',
		['sgs']			= 'bat-smg',
		['shi-latn']	= 'shi',
		['shi-tfng']	= 'shi',
		['shy-latn']	= 'shy',			-- Wikipedia in Incubator
		['skr-arab']	= 'skr',
		['se-fi']		= 'se',
		['se-no']		= 'se',
		['se-se']		= 'se',
		['sr-ec']		= 'sr',
		['sr-el']		= 'sr',
		['tg-cyrl']		= 'tg',
		['tg-latn']		= 'tg',
		['tt-cyrl']		= 'tt',
		['tt-latn']		= 'tt',
		['ug-arab']		= 'ug',
		['ug-latn']		= 'ug',
		['uz-cyrl']		= 'uz',
		['uz-latn']		= 'uz',
		['vro']			= 'fiu-vro',
		['yue']			= 'zh-yue',			-- Both work
		['zh-cn']		= 'zh',
		['zh-hans']		= 'zh',
		['zh-hant']		= 'zh',
		['zh-hk']		= 'zh',
		['zh-mo']		= 'zh',
		['zh-my']		= 'zh',
		['zh-sg']		= 'zh',
		['zh-tw']		= 'zh',				-- Both work
	}
	if exceptions[lang] then
		return exceptions[lang]
	elseif p.isInterlangPrefix(lang) then
		return lang
	else --given string is not a valid interlang prefix
		return false
		-- We may consider returning first fallback language code, if it is a
		-- valid non-English interwiki.
	end
end

--[[ Prefixes page name with Special:MyLanguage.
	
	@param pageLink String Page name, eventually prefixed with
	interwiki prefixes and namespace.
	
	@return String Name of page which links to given page link
	in user language.
]]
function p.myLangLink(pageLink)
	local outPrefix, pageName = p.splitPrefixedTitle(pageLink)
	return outPrefix .. 'Special:MyLanguage/' .. pageName
end

return p