Documentation for this module may be created at ਮੌਡਿਊਲ:shortcut box/doc

local require_when_needed = require("Module:require when needed")

local format_categories = require_when_needed("Module:utilities", "format_categories")
local get_template_invocation_name = require_when_needed("Module:template parser", "getTemplateInvocationName")
local html_create = mw.html.create
local insert = table.insert
local process_params = require_when_needed("Module:parameters", "process")
local tostring = tostring

local current_title = mw.title.getCurrentTitle()

-- Generate the correct target for incoming redirects to the location of the shortcut box.
local namespace, target, documentation = current_title.namespace, current_title.prefixedText
-- If in the template or module namespace, make `target` point to the template/module, not any documentation subpage.
if namespace == 10 or namespace == 828 then
	target, documentation = target:gsub("(.[\128-\191]*)/documentation$", "%1")
	documentation = documentation == 1
else
	-- Otherwise, point to the current section, or the page if at the top.
	local current_section = require("Module:pages").get_current_section()
	if current_section ~= 0 then -- Section 0 is everything before the first heading.
		local headings, i = {}, 0
		for heading in require("Module:template parser").find_headings(current_title:getContent()) do
			i = i + 1
			headings[i] = heading
			if heading.section == current_section then
				-- Once the current section has been found, validate headings in reverse order until a valid one is found.
				local anchor
				repeat
					anchor = headings[i]:get_anchor()
					i = i - 1
				until anchor ~= nil or i == 0
				-- Generate the fragment.
				target = target .. (anchor == nil and "" or "#" .. anchor:gsub("_", " "))
				break
			end
		end
	end
end

local namespace_abbreviations = {
	[4] = "WT",
	[14] = "CAT",
	[100] = "AP",
	[110] = "WS",
	[118] = "RC",
	[828] = "MOD",
}

local export = {}

local function generate_shortcut(title, br_open, display, br_close, demo)
	local redlink = not title:getContent()
	
	local query = {}
	if redlink then
		query.action = "edit"
		query.redlink = true
		if not demo then
			query.preloadtext = "#REDIRECT [[" .. target .. "]]"
		end
	else
		query.redirect = "no"
	end
	
	local tag = html_create("code")
		:wikitext(br_open .. "[" .. tostring(title:fullUrl(query)) .. " ")
	
	if redlink then
		display = html_create("span")
			:addClass("redlink")
			:wikitext(display)
	end
	
	tag = tag:node(display)
		:wikitext("]".. br_close)
		
	if demo then
		return tag
	end
	
	local redirect = title.redirectTarget
	
	-- Check the target is correct.
	if redirect and redirect.fullText == target then
		return tag
	end
	
	-- If not, flag for attention.
	tag:addClass("attentionseeking")
	
	return tag, true
end

local function handle_shortcut(title, demo)
	local namespace = title.namespace
	if namespace == 10 then
		-- The "Template:" prefix will still be needed in rare situations, so abbreviate it to "T:".
		return generate_shortcut(title, "{{", get_template_invocation_name(title):gsub("^Template:", "T:"), "}}", demo)
	end
	local prefix = namespace_abbreviations[namespace] or title.nsText
	local text = prefix ~= "" and (prefix .. ":" .. title.text) or title.text
	return generate_shortcut(title, "", text, "", demo)
end

-- Takes `list`, an array of title objects, and returns a shortcut box.
function export.format_shortcuts(list, temp, nocat, demo)
	local div = html_create("div")
		:addClass("noprint")
		:addClass("plainlinks")
		:addClass("shortcut-box")
		:wikitext(("%s[[Wiktionary:Shortcut|%shortcut%s]]:"):format(
			temp and "Temporary " or "",
			temp and "s" or "S",
			list[2] and "s" or ""
		))
	
	local attn
	for _, shortcut in ipairs(list) do
		div:tag("br")
		local shortcut, iattn = handle_shortcut(shortcut, demo)
		div:node(shortcut)
		attn = attn or iattn
	end
	
	local categories
	if not nocat then
		categories = {}
		if attn then
			insert(categories, "Shortcut boxes needing attention")
		end
		-- Don't categorise documentation subpages as having shortcuts.
		if not documentation then
			insert(categories, "Wiktionary pages with shortcuts")
		end
		categories = format_categories(categories, nil, "-", nil, true)
	end
	
	return tostring(div) .. (categories or "")
end

function export.shortcut_t(frame)
	local boolean = {type = "boolean"}
	local params = {
		[1] = {required = true, type = "title", list = true},
		["demo"] = {type = "boolean", demo = true},
		["nocat"] = boolean,
		["temp"] = boolean,
	}
	local args = process_params(frame:getParent().args, params)
	return export.format_shortcuts(args[1], args.temp, args.nocat, args.demo)
end

return export