Module:Format link: Difference between revisions

From escforumwiki
Jump to navigation Jump to search
en>Nihiltres
(Copied function removeInitialColon from Module:Hatnote)
en>Nihiltres
(Integrate improvements from Module:Hatnote/sandbox, in particular use of mw.ustring by Izno and my own categoryMissing stuff)
Line 106: Line 106:
italicizePage = yesno(args.italicizepage),
italicizePage = yesno(args.italicizepage),
italicizeSection = yesno(args.italicizesection),
italicizeSection = yesno(args.italicizesection),
categorizeMissing = args.categorizemissing
}
}
end
end
Line 132: Line 133:
options.italicizeSection,
options.italicizeSection,
'boolean',
'boolean',
true
)
checkTypeForNamedArg(
'_formatLink',
'categorizeMissing',
options.categorizeMissing,
'string',
true
true
)
)
Line 137: Line 145:
local parsed = parseLink(options.link)
local parsed = parseLink(options.link)
local display = options.display or parsed.display
local display = options.display or parsed.display
local catMissing = options.categorizeMissing
local category = ''
 
--Test if page exists if a diagnostic category is specified
if catMissing and (mw.ustring.len(catMissing) > 0) then
if not mw.title.new(parsed.page).exists then
category = mw.ustring.format('[[Category:%s]]', catMissing)
end
end
 
-- Deal with the case where we don't have to pipe the link
-- Deal with the case where we don't have to pipe the link
if not display and not parsed.section and not options.italicizePage then
if not display and not parsed.section and not options.italicizePage then
return string.format('[[:%s]]', parsed.link)
return mw.ustring.format('[[:%s]]%s', parsed.link, category)
end
end
Line 148: Line 165:
local section = maybeItalicize(parsed.section, options.italicizeSection)
local section = maybeItalicize(parsed.section, options.italicizeSection)
if not page then
if not page then
display = string.format('§ %s', section)
display = mw.ustring.format('§ %s', section)
elseif section then
elseif section then
display = string.format('%s § %s', page, section)
display = mw.ustring.format('%s § %s', page, section)
else
else
display = page
display = page
Line 156: Line 173:
end
end
return string.format('[[:%s|%s]]', parsed.link, display)
return mw.ustring.format('[[:%s|%s]]%s', parsed.link, display, category)
end
end


return p
return p

Revision as of 22:06, 19 December 2021

Documentation for this module may be created at Module:Format link/doc

--------------------------------------------------------------------------------
-- 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 "#". Used in
-- the {{format link}} template.
--------------------------------------------------------------------------------
local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local checkTypeForNamedArg = libraryUtil.checkTypeForNamedArg
local mArguments -- lazily initialise [[Module:Arguments]]
local yesno -- lazily initialise [[Module:Yesno]]

local p = {}

--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------

local function getArgs(frame)
	-- Fetches the arguments from the parent frame. Whitespace is trimmed and
	-- blanks are removed.
	mArguments = require('Module:Arguments')
	return mArguments.getArgs(frame, {parentOnly = true})
end

local function removeInitialColon(s)
	-- Removes the initial colon from a string, if present.
	return s:match('^:?(.*)')
end

local function italicize(s)
	-- Italicize a string.
	return '<i>' .. s .. '</i>'
end

local function maybeItalicize(s, shouldItalicize)
	-- italicize s if s is a string and the shouldItalicize parameter is true.
	if s and shouldItalicize then
		return italicize(s)
	else
		return s
	end
end

local function parseLink(link)
	-- Parse a link and return a table with the link's components.
	-- These components are:
	-- - link: the link, stripped of any initial colon (always present)
	-- - page: the page name (always present)
	-- - section: the page name (may be nil)
	-- - display: the display text, if manually entered after a pipe (may be nil)
	link = removeInitialColon(link)

	-- Find whether a faux display value has been added with the {{!}} magic
	-- word.
	local prePipe, display = link:match('^(.-)|(.*)$')
	link = prePipe or link

	-- Find the page, if it exists.
	-- For links like [[#Bar]], the page will be nil.
	local preHash, postHash = link:match('^(.-)#(.*)$')
	local page
	if not preHash then
		-- We have a link like [[Foo]].
		page = link
	elseif preHash ~= '' then
		-- We have a link like [[Foo#Bar]].
		page = preHash
	end

	-- Find the section, if it exists.
	local section
	if postHash and postHash ~= '' then
		section = postHash
	end
	
	return {
		link = link,
		page = page,
		section = section,
		display = display,
	}
end

--------------------------------------------------------------------------------
-- Main functions
--------------------------------------------------------------------------------

function p.formatLink(frame)
	-- The formatLink export function, for use in templates.
	yesno = require('Module:Yesno')
	local args = getArgs(frame)
	local link = args[1]
	if not link then
		return p.makeWikitextError(
			'no link specified',
			'Template:Format link#Errors',
			args.category
		)
	end
	return p._formatLink{
		link = link,
		display = args[2],
		italicizePage = yesno(args.italicizepage),
		italicizeSection = yesno(args.italicizesection),
		categorizeMissing = args.categorizemissing
	}
end

function p._formatLink(options)
	-- The formatLink export function, for use in modules.
	checkType('_formatLink', 1, options, 'table')
	checkTypeForNamedArg('_formatLink', 'link', options.link, 'string', false)
	checkTypeForNamedArg(
		'_formatLink',
		'display',
		options.display,
		'string',
		true
	)
	checkTypeForNamedArg(
		'_formatLink',
		'italicizePage',
		options.italicizePage,
		'boolean',
		true
	)
	checkTypeForNamedArg(
		'_formatLink',
		'italicizeSection',
		options.italicizeSection,
		'boolean',
		true
	)
	checkTypeForNamedArg(
		'_formatLink',
		'categorizeMissing',
		options.categorizeMissing,
		'string',
		true
	)

	local parsed = parseLink(options.link)
	local display = options.display or parsed.display
	local catMissing = options.categorizeMissing
	local category = ''

	--Test if page exists if a diagnostic category is specified
	if catMissing and (mw.ustring.len(catMissing) > 0) then
		if not mw.title.new(parsed.page).exists then
			category = mw.ustring.format('[[Category:%s]]', catMissing)
		end
	end

	-- Deal with the case where we don't have to pipe the link
	if not display and not parsed.section and not options.italicizePage then
		return mw.ustring.format('[[:%s]]%s', parsed.link, category)
	end
	
	-- Find the display text for piped links
	if not display then
		local page = maybeItalicize(parsed.page, options.italicizePage)
		local section = maybeItalicize(parsed.section, options.italicizeSection)
		if not page then
			display = mw.ustring.format('§&nbsp;%s', section)
		elseif section then
			display = mw.ustring.format('%s §&nbsp;%s', page, section)
		else
			display = page
		end
	end
	
	return mw.ustring.format('[[:%s|%s]]%s', parsed.link, display, category)
end

return p