Module:UtilsMarkup/Link

local p = {} local h = {}

local format = require("Module:UtilsMarkup/Format").format local utilsDPL = require("Module:UtilsDPL") local utilsString = require("Module:UtilsString")

-- If backlink == false then this print an external link that looks like an internal one -- (useful for creating links that do not appear in Special:WhatLinksHere) function p.link(link, text, noBacklink) if not link then return "" end link = mw.text.trim(link) if link:find('http') then return h.externalLink(link, text) end if noBacklink then local pageExists = utilsDPL.pageExists(link) local url = tostring(mw.uri.fullUrl(link, { action = not pageExists and "edit" or nil, redlink = not pageExists and "1" or nil }))		local externalLink = h.externalLink(url, text or link) local formattedLink = format(externalLink, {			class = pageExists and "plainlinks" or "plainlinks new"		}) return formattedLink end local title = mw.title.new(link) if title.nsText == "File" or title.nsText == "Category" then link = ":" .. link if text == "" then text = title.text end end return h.internalLink(link, text) end

function h.internalLink(page, display) if not page then return "" end if not display then return ("%s"):format(page) end return ('%s'):format(page, display) end

function h.externalLink(page, display) if not page then return "" end if not display then return page end return ('[%s %s]'):format(page, display) end

function p.category(name, sortKey) if not utilsString.startsWith("Category:", name) then name = "Category:" .. name end return h.internalLink(name, sortKey) end

function p.killBacklinks(wikitext) local link = string.match(wikitext, "%[%^%*%]%]") if not link then return wikitext end local startPos, endPos = string.find(wikitext, link, 1, true) local before = string.sub(wikitext, 1, startPos -1) local after = string.sub(wikitext, endPos + 1) local externalLink = p.killBacklink(link) return before .. externalLink .. p.killBacklinks(after) end

function p.killBacklink(link) if utilsString.startsWith("[[Category:", link) then		return link	end	if utilsString.startsWith("[[File:", link) then		return link -- not dealing with this now, but it's doable	end	link = mw.text.trim(link, "][")	link = string.gsub(link, "^:", "")	local pipe = string.find(link, "|")	local page = string.sub(link, 1, pipe and pipe - 1)	local display = pipe and string.sub(link, pipe + 1)	return p.link(page, display, true) end

local categoryPattern = "%[%[Category:[^%]]*%]%]" function p.stripCategories(wikitext) local categories = {} for category in string.gmatch(wikitext, categoryPattern) do		local categoryWithoutSortKey = string.gsub(category, "|[^%]]*%]%]", "]]") local categoryLink = string.gsub(categoryWithoutSortKey, "Category", ":Category") table.insert(categories, categoryLink) end return string.gsub(wikitext, categoryPattern, ""), categories end

p.Documentation = { {		name = "link", params = { {				name = "page", description = "The link target. Can be a page on the wiki or an external URL.", },			{				optional = true, name = "display", description = "The text to display for the link. Defaults to " },			{				optional = true, name = "noBacklink", description = "When, renders an internal link such that it does not register on the Special:WhatLinksHere of the target page. " .. "It also does not register on Special:WantedPages if the page doesn't exist." },		},		returns = "A string of wikitext that evaluates to a link. Will display a red link if the target is an internal link to a page that doesn't exist.", cases = { {				description = "Internal link", args = { "Princess Zelda" }, expected = "Zelda",			},			{				description = "Category link",				args = { "Category:Items" },				expected = "Category:Items",			},			{				description = "Category link without prefix",				args = { "Category:Items", "" },				expected = "Items",			},			{				description = "Category link with display text",				args = { "Category:Items in Breath of the Wild", "Items in Breath of the Wild" },				expected = "Items in Breath of the Wild",			},			{				description = "File link (to file description)",				args = { "File:MM Deku Butler Artwork.png" },				expected = "File:MM Deku Butler Artwork.png",			},			{				description = "External link",				args = { "https://www.mariowiki.com/Thwomp", "Thwomp" },				expected = "Thwomp",			},			{				description = "Looks like an internal link, but it's actually an external link. This is to avoid Special:WhatLinksHere",				args = { "Princess Zelda", "Zelda", true },				expected = [[ Zelda ]],			},			{				description = "Looks like an internal red link, but it's actually an external link. This is to avoid Special:WantedPages",				args = { "Flippityfloppityfloo", "foobar", true },				expected = [[ foobar ]],			},		},	},	{		name = "category",		params = {			{				name = "name",				description = "The name of the category to link to (with or without namespace prefix)",			},			{				name = "sortkey",				description = "A custom ",				optional = true,			},		},		returns = "A category link—the kind that adds a category to a page. For the other kind that links to the actual category page, use .",		cases = {			{				description = "Category link from category name",				args = { "Items" },				expected = ""			},			{				description = "Category link from category name with namespace prefix",				args = { "Category:Items" },				expected = "",			},			{				description = "Category link with sort key",				args = { "Items", "*" },				expected = "",			},		},	},	{		name = "killBacklinks",		params = {			{				name = "wikitext",				description = "A string of wiki markup",			}		},		returns = "The same wikitext but with all the internal links formatted as external links, to avoid additions to Special:WhatLinksHere",		cases = {			{				description = "Escapes both normal links and red links",				args = { "Link, Zelda and Jean-Guy Rubber Boots" },			},			{				description = "Does not escape file links or category links",				args = { " and [[File:SS Blessed Butterfly Icon.png]]"},			},			{				description = "Escapes visible file and category links",				args = { "Category:Link, Zelda, and File:SS Blessed Butterfly Icon.png"},			},		},	},	{		name = "stripCategories",		params = {			{				name = "wikitext",				description = "A string of wiki markup",			},		},		returns = {			 "The string of wiki markup with all the category links removed (not including visual links to category description pages)",			 "A Lua table of the names of all categories removed, with the   namespace",		},		cases = {			{				description = "Basic use case",				args = {""}			},			{				description = "Does not affect visual links to category description pages",				args = {"Category:Link and Category:Princess Zelda"}			}		}	} }

return p