Anonymous
×
Create a new article
Write your page title here:
We currently have 97 articles on The Dream Shrine. Type your article name above or click on one of the titles below and start writing!



The Dream Shrine

Documentation for this module may be created at Module:UtilsMarkup/Link/doc

local p = {}
local h = {}

local utilsMarkup = require("Module:UtilsMarkup/Format")
local utilsPage = require("Module:UtilsPage")
local utilsString = require("Module:UtilsString")
local utilsTable = require("Module:UtilsTable")

function p.anchor(id, display)
	return string.format('<span id="%s">[[#%s|%s]]</span>', id, id, display or id)
end

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

function p.categories(categoryNames)
	local categoryLinks = utilsTable.map(categoryNames, p.category)
	return table.concat(categoryLinks)
end

function p.containsLink(wikitext, external)
	return wikitext ~= nil and not not wikitext:find("%[%[.*%]%]")
end

function p.file(name, options)
	options = options or {}
	local size = options.size
	local link = options.link
	local caption = options.caption
	local class = options.class
	local noBacklink = options.noBacklink
	
	if not utilsString.startsWith(name, "File:") then
		name = "File:" .. name
	end
	if link and noBacklink then
		link = utilsPage.fullUrl(link)
	end
	local linkParts = utilsTable.compact({
		name,
		size,
		link and "link="..link,
		class and "class="..class,
		caption,
	})
	local fileLink = "[[" .. table.concat(linkParts, "|") .. "]]"
	return fileLink
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)
	local linkParts = utilsString.trim(link, "][")
	local pipe = string.find(linkParts, "|")
	local page = string.sub(linkParts, 1, pipe and pipe - 1)
	local display = pipe and string.sub(linkParts, pipe + 1)
	local startsWithColon = utilsString.startsWith(page, ":")
	page = string.gsub(page, "^:", "")
	local title = mw.title.new(page)
	if not title or title.interwiki ~= "" or not startsWithColon and (title.nsText == "Category" or title.nsText == "File") then
		return link
	end
	return p.link(page, display or page, true)
end

-- 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 url = utilsPage.fullUrl(link)
		local externalLink = h.externalLink(url, text or link)
		local formattedLink = utilsMarkup.class("plainlinks", externalLink)
		return formattedLink
	end
	local title = mw.title.new(link) or 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|%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.sectionLink(page, section, display)
	local target = page
	if section then
		target = target .. "#" .. section
	end
	return p.link(target, display)
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:")
		if not utilsTable.keyOf(categories, categoryLink) then
			table.insert(categories, categoryLink)
		end
	end
	return string.gsub(wikitext, categoryPattern, ""), categories
end

function p.Schemas() 
	return {
		anchor = {
			id = {
				type = "string",
				required = true,
			},
			display = {
				type = "string",	
			},
		},
		link = {
			page = {
				type = "string",
				required = true,
				desc = "The link target. Can be the name of a page on the wiki or an external URL.",
			},
			display = {
				type = "string",
				default = "page",
				desc = "The text to display for the link.",
			},
			noBacklink = {
				type = "boolean",
				desc = [[
					When <code>true</code>, renders an internal link such that it does not register on the]] .. " [[Special:WhatLinksHere]] " .. [[of the target page.
					
					'''Use only when certain that the page exists'''.  This method cannot render red-links (i.e. distinguish non-existent pages).
				]],
			},
		},
		sectionLink = {
			page = {
				type = "string",
				required = true,
				desc = "The name of a wiki page to target.",
			},
			section = {
				type = "string",
				desc = "The name of the page section to target.",
			},
			display = {
				type = "string",
				default = "page",
				desc = "The text to display for the link.",
			},
		},
		file = {
			name = {
				type = "string",
				required = true,
				desc = "A file name, with or without the <code>File:</code> prefix.",
			},
			options = {
				type = "record",
				properties = {
					{
						name = "size",
						type = "string",
						desc = "Image size in pixels.",
					},
					{
						name = "link",
						type = "string",
						desc = "Name of a page on the wiki or an external URL for the image thumbnail to link to.",
					},
					{
						name = "caption",
						type = "string",
						desc = "[https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img Alt text] for the image.",
					},
					{
						name = "class",
						type = "string",
						desc = "Sets the HTML classes of the image element.",
					},
					{
						name = "noBacklink",
						type = "boolean",
						desc = "When <code>true</code>, the <code>link</code> property is rendered 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.",
					}
				}
			},
		},
		category = {
			name = {
				type = "string",
				required = true,
				desc = "The name of the category to link to (with or without namespace prefix).",
			},
			sortKey = {
				type = "string",
				desc = "A custom {{mediawiki|Help:Categories#Sort_key|sort key}} for the category entry.",
			}
		},
		categories = {
			names = {
				type = "array",
				required = true,
				items = { type = "string" },
				desc = "An array of category names, with or without the namespace prefix.",
			}
		},
		killBacklinks = {
			wikitext = {
				type = "string",
				required = true,
				desc = "A string of wiki markup.",
			},
		},
		stripCategories = {
			wikitext = {
				type = "string",
				required = true,
				desc = "A string of wiki markup.",
			},
		}
	}
end

function p.Documentation() 
	return {
		anchor = {
			params = {"id", "display"},
			returns = "A link that refers to itself. Useful for linking to specific sections of a page without necessarily using headings.",
			cases = {
				{
					args = {"foo"},
					expect = '<span id="foo">[[#foo|foo]]</span>',
				},
				{
					args = {"bar", "Bar"},
					expect = '<span id="bar">[[#bar|Bar]]</span>',
				},
				{
					args = {"foo bar"},
					expect = '<span id="foo bar">[[#foo bar|foo bar]]</span>',
				},
			},
		},
		link = {
			params = {"page", "display", "noBacklink"},
			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 = {
				{
					desc = "Internal link",
					args = { "Princess Zelda" },
					expect = "[[Princess Zelda]]",
				},
				{
					desc = "Piped link",
					args = { "Princess Zelda", "Zelda" },
					expect = "[[Princess Zelda|Zelda]]",
				},
				{
					desc = "Category link",
					args = { "Category:Items" },
					expect = "[[:Category:Items]]",
				},
				{
					desc = "Category link without prefix",
					args = { "Category:Items", "" },
					expect = "[[:Category:Items|Items]]",
				},
				{
					desc = "Category link with display text",
					args = { "Category:Items in Breath of the Wild", "Items in ''Breath of the Wild''" },
					expect = "[[:Category:Items in Breath of the Wild|Items in ''Breath of the Wild'']]",
				},
				{
					desc = "File link (to file description)",
					args = { "File:MM Deku Butler Artwork.png" },
					expect = "[[:File:MM Deku Butler Artwork.png]]",
				},
				{
					desc = "External link",
					args = { "https://www.mariowiki.com/Thwomp", "Thwomp" },
					expect = "[https://www.mariowiki.com/Thwomp Thwomp]",
				},
				{
					desc = "Looks like an internal link, but it's actually an external link. This is to avoid [[Special:WhatLinksHere]]",
					args = { "Princess Zelda", "Zelda", true },
					expect = [[<span class="plainlinks">[//zeldawiki.wiki/Princess_Zelda Zelda]</span>]],
				},
				{
					-- Doing red links here would require checking page existence, which requires a database read and is considered an "expensive function" by MediaWiki
					-- Given how often this function can be called on any given page, it's probably best to avoid this
					desc = "When <code>noBacklink</code> is set to <code>true</code>, red links are not rendered for pages which do not exist, for performance reasons.",
					args = { "Flippityfloppityfloo", nil, true },
					expect = [[<span class="plainlinks">[//zeldawiki.wiki/Flippityfloppityfloo Flippityfloppityfloo]</span>]],
				},
			},
		},
		sectionLink = {
			params = {"page", "section", "display"},
			returns = "A string of wikitext rendering a section link.",
			cases = {
				{
					args = {"Link", "Ocarina of Time", "Hero of Time"},
					expect = "[[Link#Ocarina of Time|Hero of Time]]",
				},
				{
					args = {"Link", nil, "Hero of Time"},
					expect = "[[Link|Hero of Time]]",
				},
				{
					args = {"Link", ""},
					expect = "[[Link#]]",
				},
			},
		},
		file = {
			params = {"name", "options"},
			returns = "A <code>string</code> of wikitext that renders a thumbnail for the file.",
			cases = {
				{
					args = { "File:ALttP Ganon Sprite.png" },
					expect = "[[File:ALttP Ganon Sprite.png]]",
				},
				{
					args = { "ALttP Ganon Sprite.png", {
						link = "",
						caption = "Ganon"
					}},
					expect = "[[File:ALttP Ganon Sprite.png|link=|Ganon]]",
				},
				{
					args = { "File:TWW Great Fairy Figurine Model.png", {
						link = "Great Fairy",
						size = "100px",
					}},
					expect = "[[File:TWW Great Fairy Figurine Model.png|100px|link=Great Fairy]]",
				},
				{
					args = { "File:TWW Great Fairy Figurine Model.png", {
						link = "Great Fairy",
						size = "100px",
						noBacklink = true,
					}},
					expect = "[[File:TWW Great Fairy Figurine Model.png|100px|link=//zeldawiki.wiki/Great_Fairy]]",
				},
				{
					args = { "File:TWW Great Fairy Figurine Model.png", {
						link = "Great Fairy",
						size = "100px",
						class = "notpageimage",
					}},
					expect = "[[File:TWW Great Fairy Figurine Model.png|100px|link=Great Fairy|class=notpageimage]]",
				},
			},
		},
		category = {
			params = {"name", "sortKey"},
			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 <code>link</code>.",
			cases = {
				outputOnly = true,
				{
					desc = "Category link from category name",
					args = { "Items" },
					expect = "[[Category:Items]]"
				},
				{
					desc = "Category link from category name with namespace prefix",
					args = { "Category:Items" },
					expect = "[[Category:Items]]",
				},
				{
					desc = "Category link with sort key",
					args = { "Items", "*" },
					expect = "[[Category:Items|*]]",
				},
			},
		},
		categories = {
			params = {"names"},
			returns = "A concatenated string of category links.",
			cases = {
				outputOnly = true,
				{
					args = { {"Link", "Category:Zelda", "Category:Ganon"} },
					expect = "[[Category:Link]][[Category:Zelda]][[Category:Ganon]]"
				},
				{
					args = { {} },
					expect = ""
				},
			},
		},
		containsLink = {
			params = {"wikitext"},
			returns = "Given a string of wikitext, returns <code>true</code> if it contains an internal or interwiki link, false otherwise.",
			cases = {
				{
					args = {"There is a [[Link]]"},
					expect = true,
				},
				{
					args = {"[Link] is not a link but rather an indication of replaced words in a quote."},
					expect = false,
				},
			},
		},
		killBacklinks = {
			params = {"wikitext"},
			returns = "The same wikitext but with all the internal links formatted as external links, to avoid additions to [[Special:WhatLinksHere]].",
			cases = {
				{
					-- See "link" function for peformance reasons
					-- It might still be possible for us to support red links here if the performance requirements aren't as stringent as the "link" function
					-- There doesn't seem to be a pressing need at the moment, though
					desc = "Escapes basic article links - unfortunately non-existent pages are not rendered as red links for performance reasons",
					args = { "[[Link]], [[Princess Zelda|Zelda]], and [[Jean-Guy Rubber Boots]]" },
					expect = '<span class="plainlinks">[//zeldawiki.wiki/Link Link]</span>, <span class="plainlinks">[//zeldawiki.wiki/Princess_Zelda Zelda]</span>, and <span class="plainlinks">[//zeldawiki.wiki/Jean-Guy_Rubber_Boots Jean-Guy Rubber Boots]</span>'
				},
				{
					desc = "Does not escape file links or category links",
					args = { "[[Category:Link]] and [[File:SS Blessed Butterfly Icon.png]]"},
					expect = "[[Category:Link]] and [[File:SS Blessed Butterfly Icon.png]]"
				},
				{
					desc = "Escapes visible file and category links",
					args = { "[[:Category:Link]], [[:Category:Princess Zelda|Zelda]], and [[:File:SS Blessed Butterfly Icon.png]]"},
					expect = 
						'<span class="plainlinks">[//zeldawiki.wiki/Category:Link Category:Link]</span>, '
						.. '<span class="plainlinks">[//zeldawiki.wiki/Category:Princess_Zelda Zelda]</span>, '
						.. 'and <span class="plainlinks">[//zeldawiki.wiki/File:SS_Blessed_Butterfly_Icon.png File:SS Blessed Butterfly Icon.png]</span>'
				},
				{
					desc = "Does not affect interwiki links",
					args = { "[[metroidwiki:Chozo|Chozo]]" },
					expect = "[[metroidwiki:Chozo|Chozo]]"
				}
			},
		},
		stripCategories = {
			params = {"wikitext"},
			returns = {
				 "The string of wiki markup with all the category links removed (not including visual links to category description pages).",
				 "A <code>table</code> array of direct links to the removed categories.",
			},
			cases = {
				outputOnly = true,
				{
					desc = "Basic use case",
					args = {"<[[Category:Link]][[Category:Princess Zelda]][[Category:Link]]>"},
					expect = {
						"<>",
						{"[[:Category:Link]]", "[[:Category:Princess Zelda]]"},
					},
				},
				{
					desc = "Does not affect visual links to category description pages",
					args = {"[[:Category:Link]] and [[:Category:Princess Zelda]]"},
					expect = {
						"[[:Category:Link]] and [[:Category:Princess Zelda]]",
						{},
					}
				}
			}
		}
	}
end

return p