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.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 = { 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 = "Princess Zelda", },			{				description = "Piped link", args = { "Princess Zelda", "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 ]], },		},	},	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" }, },			{				desciprtion = "Does not escape file links or category links", args = { " and "}, },			{				description = "Escapes visible file and category links", args = { "Category:Link, Zelda, and File:SS Blessed Butterfly Icon.png"}, },		},	},	stripCategories = { params = { {				name = "wikitext", description = "A string of wiki markup", },		},		returns = { {				description = "The string of wiki markup with all the category links removed (not including visual links to category description pages)", wikitext = true, },			{				description = "A Lua table of the names of all categories removed, with the  namespace", },		},		cases = { {				args = {""} },			{				description = "Does not affect visual links to category description pages", args = {"Category:Link and Category:Princess Zelda"} }		}	} }

return p