-- This module stores functions that are shared between [[Module:UserLinks]] -- and [[Module:UserLinks/extra]].   -- Load data and define often-used variables local cfg = mw.loadData('Module:UserLinks/config') local namespaces = mw.site.namespaces   -- Lazily initialise modules that we may or may not need local mCategoryHandler   -- Define namespaces for which links need to be escaped with the colon trick. -- See [[w:en:Help:Colon trick]]. local colonNamespaces = { 	[6] = true, -- File 	[14] = true, -- Category }   local p = {}   function p.maybeLoadModule(s) 	-- Attempts to load the module s. If it succeeds, returns the module; 	-- otherwise, returns false. 	local success, mdl = pcall(require, s) 	if success then 		return mdl 	else 		return false 	end end   function p.raiseError(message, section, level) 	-- Raises an error using the Lua error function. The error message is 	-- designed to be caught with pcall and then passed to p.makeWikitextError. 	-- The section, if specified, is the section name on a help page that gives 	-- help to users about that particular error. 	if section then 		message = message .. '|' .. section 	end 	if not level or level == 0 then 		level = 0 	else 		level = level + 1 	end 	error(message, level) end   function p.makeWikitextError(encodedMessage, demo) 	local errorMessage, section = mw.ustring.match(encodedMessage, '^(.-)|(.*)$') 	errorMessage = errorMessage or encodedMessage   	-- If not a demo, get the error category link and pass it through 	-- [[Module:Category handler]]'s blacklist. 	local category 	if not demo then 		category = string.format( 			'[[%s:%s]]', 			namespaces[14].name, 			p.message('error-config-category') 		) 		mCategoryHandler = p.maybeLoadModule('Module:Category handler') 		if mCategoryHandler then 			-- Categorise all namespaces, but not blacklisted pages. 			category = mCategoryHandler.main{all = category} 		end 	end 	category = category or ''   	-- Format the error message and the section link. 	local formattedError 	if section then 		formattedError = p.message( 			'error-config-message-help', 			errorMessage, 			section 		) 	else 		formattedError = p.message( 			'error-config-message-nohelp', 			errorMessage 		) 	end   	-- Return the error message and the category inside html error tags. 	return string.format( 		'<strong class="error">%s</strong>%s', 		formattedError, 		category 	) end   local function formatPage(interwiki, namespace, page) 	-- Formats an interwiki, a namespace and a page into a wikilink-ready 	-- string. The interwiki and namespace are optional. If a namespace is 	-- specified, it should be a valid key to mw.site.namespaces. The page 	-- parameter is required. 	local ret = {} 	interwiki = interwiki or '' 	if interwiki ~= '' or colonNamespaces[namespace] then 		ret[#ret + 1] = ':' 	end 	ret[#ret + 1] = interwiki 	if interwiki ~= '' then 		ret[#ret + 1] = ':' 	end 	if namespace then 		local nsTable = namespaces[namespace] 		if not nsTable then 			error('"' .. tostring(namespace) .. '" is not a valid namespace key', 2) 		end 		ret[#ret + 1] = nsTable.name 		if namespace ~= 0 then 			ret[#ret + 1] = ':' 		end 	end 	ret[#ret + 1] = page 	return table.concat(ret) end   local function formatDisplay(s) 	-- Replaces spaces in a string with "&nbsp;" to make sure they don't wrap. 	-- Don't replace anything if we are substing, as we generally don't want 	-- to use "&nbsp;" in that case. 	if mw.isSubsting() then 		return s 	else 		return s:gsub(' ', '&nbsp;') 	end end   function p.makeWikilink(interwiki, namespace, page, display) 	-- Creates a wikilink. The interwiki, namespace and display parameters are 	-- optional. If a namespace parameter is specified it must be a valid key 	-- to mw.site.namespaces. 	local formattedPage = formatPage(interwiki, namespace, page) 	if display then 		display = formatDisplay(display) 		return string.format('[[%s|%s]]', formattedPage, display) 	else 		return string.format('[[%s]]', formattedPage) 	end end   local function formatUrlLink(url, display) 	-- Formats a URL link with an optional display parameter. 	if display then 		display = formatDisplay(display) 		return string.format('[%s %s]', url, display) 	else 		return string.format('[%s]', url) 	end end   function p.makeUrlLink(s, display) 	local url = tostring(mw.uri.new(s)) 	return require('Module:URL')._url(url, display) end   function p.makeFullUrlLink(interwiki, namespace, page, query, display) 	local formattedPage = formatPage(interwiki, namespace, page) 	return require('Module:Fullurl')._fullurl2(formattedPage, query, display) end   function p.message(key, ...) 	-- Returns the message with the given key from [[Module:UserLinks/config]]. 	-- Extra parameters are substituted in the message for keys $1, $2, $3, etc. 	local msg = cfg[key] 	if not msg then 		p.raiseError( 			'No message found with key "' .. tostring(key) .. '"', 			'No message found', 			2 		) 	end 	local noArgs = select('#', ...) 	if noArgs < 1 then 		return msg 	else 		local msg = mw.message.newRawMessage(msg, ...) 		return msg:plain() 	end end   return p