Перайсьці да зьместу

Модуль:Фармат спасылкі

Зьвесткі зь Вікіпэдыі — вольнай энцыкляпэдыі
--------------------------------------------------------------------------------
-- Фармат спасылкі
--
-- Стварае вікі-спасылку з дадзенай спасылкі й адлюстроўвае значэньні. Спасылкі экрануюцца
-- двукроп’ямі, калі неабходна, і спасылкі на разьдзелы выяўляюцца і адлюстроўваюцца
-- разьдзяляльнікам «§» замест стандартнага сымбаля MediaWiki «#». Выкарыстоўваецца ў
-- шаблёне {{Фармат спасылкі}}.
--------------------------------------------------------------------------------
local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local checkTypeForNamedArg = libraryUtil.checkTypeForNamedArg
local mArguments -- лянівая ініцыялізацыя [[Модуль:Аргумэнты]]
local mError -- лянівая ініцыялізацыя [[Модуль:Памылка]]
local yesno -- лянівая ініцыялізацыя [[Модуль:ТакНе]]

local p = {}

--------------------------------------------------------------------------------
-- Дапаможныя функцыі
--------------------------------------------------------------------------------

local function getArgs(frame)
	-- Атрымлівае аргумэнты з бацькоўскага фрэйма. Прагалы выдаляюцца й
	-- прыбіраюцца.
	mArguments = require('Модуль:Аргумэнты')
	return mArguments.getArgs(frame, {parentOnly = true})
end

local function removeInitialColon(s)
	-- Выдаляе пачатковае двукроп’е з радка, калі яно ёсьць.
	return s:match('^:?(.*)')
end

local function maybeItalicize(s, shouldItalicize)
	-- Вылучае курсівам s, калі s — радок і парамэтар shouldItalicize мае значэньне true.
	if s and shouldItalicize then
		return '<i>' .. s .. '</i>'
	else
		return s
	end
end

local function parseLink(link)
	-- Разьбірае спасылку і вяртае табліцу з кампанеэнтамі спасылкі.
	-- Гэтыя кампанэнты:
	-- - спасылка: спасылка без пачатковага двукроп’я (заўсёды прысутнічае)
	-- - старонка: назва старонкі (заўсёды прысутнічае)
	-- - разьдзел (сэкцыя): назва старонкі (можа быць нуль)
	-- - паказаць тэкст, калі ён уведзены ўручную пасьля вэртыкальнай лініі (можа быць нуль)
	link = removeInitialColon(link)

	-- Высьветліць, ці было дададзена фальшывае значэньне адлюстраваньня з дапамогай {{!}} магічнага
	-- слова.
	local prePipe, display = link:match('^(.-)|(.*)$')
	link = prePipe or link

	-- Знайсьці старонку, калі яна існуе.
	-- Для спасылак тыпу [[#Bar]], старонка будзе нуль.
	local preHash, postHash = link:match('^(.-)#(.*)$')
	local page
	if not preHash then
		-- Спасылка тыпу [[Foo]].
		page = link
	elseif preHash ~= '' then
		-- Спасылка тыпу [[Foo#Bar]].
		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, options)
	-- Фарматуе радок адлюстраваньня на аснове разабранай табліцы спасылак (якая адпавядае
	-- вываду parseLink) і табліца опцыяў (якая адпавядае ўваходным опцыям для
	-- _formatLink).
	local page = maybeItalicize(parsed.page, options.italicizePage)
	local section = maybeItalicize(parsed.section, options.italicizeSection)
	if (not section) then
		return page
	elseif (not page) then
		return mw.ustring.format('§&nbsp;%s', section)
	else
		return mw.ustring.format('%s §&nbsp;%s', page, section)
	end
end

local function missingArgError(target)
	mError = require('Модуль:Памылка')
	return mError.error{message =
		'Памылка: не пазначаная спасылка альбо мэта! ([[' .. target .. '#Памылкі|дапамога]])'
	}
end

--------------------------------------------------------------------------------
-- Асноўныя функцыі
--------------------------------------------------------------------------------

function p.formatLink(frame)
	-- formatLink экспартуе функцыю для выкарыстаньня ў шаблёнах.
	yesno = require('Модуль:ТакНе')
	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('Шаблён:Фармат спасылкі')
	end

	return p._formatLink{
		link = link,
		display = args[2] or args.display,
		target = target,
		italicizePage = yesno(args.italicizepage),
		italicizeSection = yesno(args.italicizesection),
		categorizeMissing = args.categorizemissing
	}
end

function p._formatLink(options)
	-- formatLink экспартуе функцыю для выкарыстаньня ў модулях.
	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('italicizePage', 'boolean')
	check('italicizeSection', 'boolean')
	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('Модуль:Фармат спасылкі')
	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
		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('[[Катэгорыя:%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)
	-- Фарматуе масіў старонак, выкарыстоўваючы formatLink і зададзеную табліцу опцыяў,
	-- і вяртае яго як масіў. Нулявыя значэньні не дапускаюцца
	local ret = {}
	for i, page in ipairs(pages) do
		ret[i] = p._formatLink{
			link = page,
			categorizeMissing = options.categorizeMissing,
			italicizePage = options.italicizePage,
			italicizeSection = options.italicizeSection
		}
	end
	return ret
end

return p