--                                                                            --
-- This module produces hatnote links and links to related articles. It       --
-- implements the {{rellink}} and {{hatnote}} meta-templates, and a few of includes    ---- the more popular templates they depend on, including {{main}},             ---- {{see also}}, {{further}} and {{details}}helper functions for other Lua modules to format hatnote links.                                            --
--------------------------------------------------------------------------------
local mTableTools libraryUtil = require('Module:TableToolslibraryUtil')local checkType = libraryUtil.checkTypelocal mArguments = require('-- lazily initialise [[Module:Arguments')]] local p = {}
--------------------------------------------------------------------------------
-- Argument processingHelper functions
--------------------------------------------------------------------------------
--[[local function getArgs(frame)	-- The p table is for functions to be returned Fetches the arguments from #invoke, and for functions-- to be used from other Lua modulesthe parent frame. The f table Whitespace is for functions acting as a-- bridge between #invoke functions trimmed and Lua module functions. #invoke functions	-- blanks are connected to f table functions through the makeInvokeFunction functionremoved.-- Functions for use from other Lua modules have names beginning with an	mArguments = require('Module:Arguments')-- underscore	return mArguments. --]]local pgetArgs(frame, f {parentOnly = {}, {true})end
local function makeInvokeFunctionremoveInitialColon(funcs)	-- Removes the initial colon from a string, if present.	return functions:match('^:?(frame)		local args = mArguments.getArgs(frame, {parentOnly = true}*)		return func(args')	end
end
---------------------------------------------------------------------------------- Helper functions-------------------------------------------------------------------------------- local function findNamespaceIdp._findNamespaceId(link, removeColon)
	-- Finds the namespace id (namespace number) of a link or a pagename. This
	-- function will not work if the link is enclosed in double brackets. If the
	-- removeColon parameter is set to true, the function will remove initial
	-- colons from the link.
	checkType('_findNamespaceId', 1, link, 'string')
	checkType('_findNamespaceId', 2, removeColon, 'boolean', true)
	if removeColon then
		link = removeInitialColon(link:match('^:?(.*)')
	end
	local namespace = link:match('^(.-):')
end
local function formatLinkp._formatPages(link, display...)	-- Makes Formats a wikilink from the given link list of pages using formatLink and display valuesreturns it as an array. Links areNil	-- escaped with colons if necessaryvalues are not allowed.	local pages = {...}	local ret = {}	for i, and links to sections are detectedpage in ipairs(pages) do		ret[i] = p._formatLink(page)	end	return retend function p._formatPageTables(pages)	-- Takes a list of page/display tables and displayed with " § " returns it as a separator rather than the standardlist of	-- MediaWiki "#"formatted links. Nil values are not allowed.	checkType('_formatPageTables', 1, pages, 'table')	local links = {}	for i, t in ipairs(pages) do		local link = t[1]		local display = t[2]		links[i] = p._formatLink(link, display)	end	return linksend
function p._makeWikitextError(msg)
	-- Formats an error message to be returned to wikitext.
	checkType('_makeWikitextError', 1, msg, 'string')
	return string.format('<strong class="error">Error: %s.</strong>', msg)
end
 
--------------------------------------------------------------------------------
-- Format link
--
-- Makes a wikilink from the given link and display values. Links are escaped
-- with colons if necessary, and links to sections are detected and displayed
-- with " § " as a separator rather than the standard MediaWiki "#".
--------------------------------------------------------------------------------
 
function p.formatLink(frame)
	local args = getArgs(frame)
	local link = args[1]
	local display = args[2]
	if not link then
		return p._makeWikitextError('no link specified')
	end
	return p._formatLink(link, display)
end
 
function p._formatLink(link, display)
	-- Find whether we need to use the colon trick or not. We need to use the
	-- colon trick for categories and files, as otherwise category links
	-- categorise the page and file links display the file.
	checkType('_formatLink', 1, link = link:match, 'string')	checkType('^:?_formatLink', 2, display, 'string', true)	link = removeInitialColon(.*)'link) -- Remove initial colon if specified.	local namespace = findNamespaceIdp._findNamespaceId(link)
	local colon
	if namespace == 6 or namespace == 14 then
		return string.format('[[%s%s]]', colon, link)
	end
end
 
local function formatPages(...)
	-- Formats a list of pages using formatLink and returns it as an array. Nil
	-- values are not allowed.
	local pages = {...}
	local ret = {}
	for i, page in ipairs(pages) do
		ret[i] = formatLink(page)
	end
	return ret
end
 
local function formatPageTables(pages)
	-- Takes a list of page/display tables and returns it as a list of
	-- formatted links. Nil values are not allowed.
	local links = {}
	for i, t in ipairs(pages) do
		local link = t[1]
		local display = t[2]
		links[i] = formatLink(link, display)
	end
	return links
end
 
local function makeWikitextError(msg)
	-- Formats an error message to be returned to wikitext.
	return string.format('<strong class="error">Error: %s.</strong>', msg)
end
--------------------------------------------------------------------------------
function p._hatnotehatnote(sframe)	return string.format('<div classlocal args ="dablink">%s</div>', s)end function f.hatnotegetArgs(argsframe)
	local s = args[1]
	if not s then
		return makeWikitextErrorp._makeWikitextError('no text specified')
	end
	return p._hatnote(s)
end
function p.hatnote = makeInvokeFunction_hatnote(s)	checkType(f'_hatnote', 1, s, 'string')	return string.hatnoteformat('<div class="dablink">%s</div>', s)end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
function p._rellinkrellink(s, extraclassesframe)	if extraclasses then		extraclasses = ' ' .. extraclasses	else		extraclasses = ''	end	return string.format('<div classlocal args ="rellink%s">%s</div>', extraclasses, s)end function f.rellinkgetArgs(argsframe)
	local s = args[1]
	local extraclasses = args.extraclasses
	if not s then
		return makeWikitextErrorp._makeWikitextError('no text specified')
	end
	return p._rellink(s, extraclasses)
end
p.rellink = makeInvokeFunction(f.rellink) ---------------------------------------------------------------------------------- Details---- Produces a "For more details on this topic" link. the first parameter is the-- page linked to, and if the second parameter is present it is used instead-- of the "this topic" text.-------------------------------------------------------------------------------- function p._details_rellink(pages, topicextraclasses)	page = formatLinkcheckType(page)	topic = topic or 'this topic_rellink'	local text = string.format('For more details on %s, see %1, s.', topic, page)	local extraclasses = 'boilerplate seealsostring'	return p._rellink(text, extraclasses)end function f.details(args)	local page = args[1]	local topic = args[2]	if not page then		return makeWikitextErrorcheckType('no page specified_rellink')	end	return p._details(page, topic)end p.details = makeInvokeFunction(f.details) ---------------------------------------------------------------------------------- Further---- Produces a "Further information: a2, b and c" link. It accepts an unlimited-- number of positional parametersextraclasses, each of which is a page name.-------------------------------------------------------------------------------- function p._further(...)	local links = formatPages(...)	local text = 'Further information: string' .. mw.text.listToText(links)	return p._rellink(text)end function f.further(args)	local pages = mTableTools.compressSparseArray(args, true)	if #pages < 1 extraclasses then		return makeWikitextError(extraclasses = 'no pages specified')	end	return p._further(unpack(pages))end p.further = makeInvokeFunction(f.further) ---------------------------------------------------------------------------------- Main---- Produces a link to a main article or articles. If used in category or-- category talk space, produces "The main article for this category is xxx".-- Otherwise, produces "Main article: xxx". Accepts an unlimited number of-- page/display tables. Non-table inputs will result in an error. The first-- value in the table should be the page name. Omitting this will result in an-- error, except in the case of the first table, which uses the page name as a-- fallaback. The second value in the table is an optional display value for-- the link. If the first page name is not in mainspace, the output uses "page"-- instead of "article". If more than one page is specified, the function uses-- plural forms.-------------------------------------------------------------------------------- function p._main(...)	-- Get the list of pages. If no first page was specified we use the current	-- page name.	local pages = {...}	local currentTitle = mw.title.getCurrentTitle()	local firstPageTable = pages[1]	local firstPage	if firstPageTable then		firstPage = firstPageTable[1]extraclasses
	else
		firstPage extraclasses = currentTitle.text		firstPageTable = {firstPage}		pages[1] = firstPageTable''
	end
 	-- Find the pagetypereturn string.	local firstPageNs = findNamespaceIdformat(firstPage, true)	local pagetype = firstPageNs == 0 and 'article' or 'page' 	-- Make the formatted link text	local links <div class= formatPageTables(pages)	links = mw.text.listToText(links) 	-- Build the text.	local isPlural = #pages > 1	local currentNs = currentTitle.namespace	local isCategoryNamespace = currentNs - currentNs % 2 == 14	local stringToFormat	if isCategoryNamespace then		if isPlural then			stringToFormat = 'The main %ss for this'				.. ' [[Wikipedia:Categorization|category]] are "rellink%s'		else			stringToFormat = 'The main %s for this'				.. ' [[Wikipedia:Categorization|category]] is %s'		end	else		if isPlural then			stringToFormat = 'Main %ss: %s'		else			stringToFormat = 'Main %s: ">%s</div>'		end	end	local text = string.format(stringToFormat, pagetype, links) 	-- Pass the text to p._rellink.	local extraclasses = 'relarticle mainarticle'	return p._rellink(text, extraclassess)
end
 
function f.main(args)
	local pages = {}
	for k, v in pairs(args) do
		if type(k) == 'number' then
			local display = args['l' .. tostring(k)]
			local page = {v, display}
			pages[k] = page
		end
	end
	pages = mTableTools.compressSparseArray(pages)
	return p._main(unpack(pages))
end
 
p.main = makeInvokeFunction(f.main)
 
--------------------------------------------------------------------------------
-- See also
--
-- Produces a "See also: a, b and c" link. The first parameter is an optional
-- alternative for the "See also" text. The following parameters are an
-- unlimited number of page/display tables. The first entry in the table is the
-- page name, and the second entry in the table is the display text.
--------------------------------------------------------------------------------
 
function p._seealso(altphrase, ...)
	altphrase = altphrase or 'See also'
	local pages = {...}
	local links = formatPageTables(pages)
	links = mw.text.listToText(links)
	local text = altphrase .. ': ' .. links
	local extraclasses = 'boilerplate seealso'
	return p._rellink(text, extraclasses)
end
 
function f.seealso(args)
	local pages = {}
	for k, v in pairs(args) do
		if type(k) == 'number' then
			local numstring = tostring(k)
			local display = args['label ' .. numstring]
				or args['l' .. numstring]
			local page = {v, display}
			pages[k] = page
		end
	end
	pages = mTableTools.compressSparseArray(pages)
	if not pages[1] then
		return makeWikitextError(
			'[[Template:See also|'
				.. 'Template must be given at least one article name]]'
		)
	end
	local altphrase = args.altphrase
	return p._seealso(altphrase, unpack(pages))
end
 
p.seealso = makeInvokeFunction(f.seealso)
return p