模块:Format link

WikiBot留言 | 贡献2026年6月24日 (三) 23:58的版本 (创建 Distinguish(zhwiki 版,NSPN→NAMESPACE))
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
--------------------------------------------------------------------------------
-- 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 mError -- lazily initialise [[Module:Error]]
local yesno -- lazily initialise [[Module:Yesno]]

local p = {}

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

local function getArgs(frame)
	mArguments = require('Module:Arguments')
	return mArguments.getArgs(frame, {parentOnly = true})
end

local function removeInitialColon(s)
	return s:match('^:?(.*)')
end

local function parseLink(link)
	link = removeInitialColon(link)
	local prePipe, display = link:match('^(.-)|(.*)$')
	link = prePipe or link
	local preHash, postHash = link:match('^(.-)#(.*)$')
	local page
	if not preHash then
		page = link
	elseif preHash ~= '' then
		page = preHash
	end
	local section
	if postHash and postHash ~= '' then
		section = postHash
	end
	return {
		link = link,
		page = page,
		section = section,
		display = display,
	}
end

local function formatDisplay(parsed)
	local page = parsed.page
	local section = parsed.section
	if (not section) then
		return page
	elseif (not page) then
		return mw.ustring.format('\u00a7 %s', section)
	else
		return mw.ustring.format('%s \u00a7 %s', page, section)
	end
end

local function missingArgError(target)
	mError = require('Module:Error')
	return mError.error{message =
		'错误:link或target参数缺失([[' .. target .. '#错误|帮助]])'
	}
end

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

function p.formatLink(frame)
	yesno = require('Module:Yesno')
	local args = getArgs(frame)
	local link = args[1] or args.link
	local target = args[3] or args.target
	if not (link or target) then
		return missingArgError('Template:Format link')
	end

	return p._formatLink{
		link = link,
		display = args[2] or args.display,
		target = target,
		categorizeMissing = args.categorizemissing
	}
end

function p._formatLink(options)
	checkType('_formatLink', 1, options, 'table')
	local function check(key, expectedType)
		checkTypeForNamedArg(
			'_formatLink', key, options[key], expectedType or 'string', true
		)
	end
	check('link')
	check('display')
	check('target')
	check('categorizeMissing')

	if options.link == '' then options.link = nil end
	if options.target == '' then options.target = nil end
	if not (options.link or options.target) then
		return missingArgError('Module:Format link')
	end

	if options.link and options.link:match('<span class="ilh-') then
		return options.link
	end

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

	if not display then display = formatDisplay(parsed, options) end

	if options.target then
		if options.target:match('<span class="ilh-') then
			return options.target
		end
		local parsedTarget = parseLink(options.target)
		parsed.link = parsedTarget.link
		parsed.page = parsedTarget.page
	end

	if catMissing and (mw.ustring.len(catMissing) > 0) then
		local title = nil
		if parsed.page then title = mw.title.new(parsed.page) end
		if title and (not title.isExternal) then
			local success, exists = pcall(function() return title.exists end)
			if success and not exists then
				category = mw.ustring.format('[[Category:%s]]', catMissing)
			end
		end
	end

	if parsed.link == display then
		return mw.ustring.format('[[:%s]]%s', parsed.link, category)
	else
		return mw.ustring.format('[[:%s|%s]]%s', parsed.link, display, category)
	end
end

function p.formatPages(options, pages)
	local ret = {}
	for i, page in ipairs(pages) do
		ret[i] = p._formatLink{
			link = page,
			categorizeMissing = options.categorizeMissing
		}
	end
	return ret
end

return p