Модуль:Загаловак

З пляцоўкі Вікікрыніцы

Дакументацыю да гэтага модуля можна стварыць у Модуль:Загаловак/Дакументацыя

--[=[
Модуль для працы шаблёну {{Загаловак}}

It doesn't do everything yet, but over time it can accrete functions from
the template, which will become simpler and simpler until it's just an invoke.

Not implemented yet:
 * Categories (deprecated anyway)
 * Subpage checking
]=]

local p = {} --p азначае пакет
local yesno = require('Модуль:ТакНе')
local getArgs = require('Модуль:Аргумэнты').getArgs


-- узяць парамэтар „перапісаць_“ ці парамэтар „парамэтар“ у такім парадку
-- калі нічога няма, тады nil
function get_arg_or_override(args, param)
	if args["перапісаць_" .. param] then
		return args["перапісаць_" .. param]
	elseif args["override_" .. param] then
		return args["override_" .. param]
	elseif args[param] then
		return args[param]
	end
	
	return nil
end

-- вяртае true, калі сьпіс мае хоць адзін аргумэнт з значэньнем nil
-- (nil азначае адсутнасьць; пусты радок — гэта не адсутнасьць)
function any_arg_nil(args, list)
	for k,v in pairs(list) do
		if args[v] == nil then
			return true
		end
	end
	return false
end

-- вяртае true, калі сьпіс мае хоць адзін непусты аргумэнт або ня nil
-- (nil азначае адсутнасьць; пусты радок — гэта не адсутнасьць)
function has_any_arg(args, list)
	for k,v in pairs(list) do
		if args[v] ~= nil and args[v] ~= "" then
			return true
		end
	end
	return false
end

--[=[
Вяртае '1', калі ў шаблёне бракуе абавязковых парамэтраў
]=]
function p.has_missing_params(frame)
	local args = getArgs(frame, {
		removeBlanks = false
	})
	local required_args = {'назва', 'аўтар', 'папярэдні', 'наступны', 'анатацыі'}
	if any_arg_nil(args, required_args) then
		return '1'
	end
	return ''
end

-- Раскладае кожнае значэньне з табліцы ID:значэньні ва ўваходны элемэнт parent
function append_mf_values(parent, values)
	for k,v in pairs(values) do
		parent:tag("span")
			:attr("id", k)
			:wikitext(v)
	end
end

-- Стварае абгорткавы мікрафармат div
function construct_mf_wrapper(args)
	local mf_div =  mw.html.create("div")
	mf_div:addClass("ws-noexport")
	    :attr("id", "ws-data")
		:css({
			speak = "none"
		})
	
	-- хавае мікрафармат, калі не пазначана адваротнае
	if not (args["вывад_мікрафармату"] and yesno(args['вывад_мікрафармату'])) then
		mf_div:css("display", "none")
	end
	return mf_div
end

-- Зьбірае ўсе значэньні зьвестак мікрафармату з пададзеных аргумэнтаў
-- Вяртае табліцу мікрафармату ID:зьместу.
function collect_mf_data(args)
	-- тут зьібраюцца значэньні МФ
	local mf = {};

	mf["ws-article-id"] = mw.title.getCurrentTitle().id 
	
	-- дадаць назву
	if args["назва"] then
		mf["ws-title"] = args['назва']
	elseif args["title"] then
		mf["ws-title"] = args['title']

		-- калі ёсьць частка, то дадаць
		if args["частка"] then
			mf["ws-title"] = mf["ws-title"] .. " — " .. args["частка"]
		end
	end
	
	local author = get_arg_or_override(args, "суаўтар")
	if not author then
		author = get_arg_or_override(args, "аўтар_часткі")
	end
	if not author then
		author = get_arg_or_override(args, "аўтар")	
	end
	if author then
		mf['ws-author'] = author
	end
	
	local translator = get_arg_or_override(args, "перакладчык")
	if not translator then
		translator = get_arg_or_override(args, "пераклад")
	end
	if translator then
		mf['ws-translator'] = translator
	end
	
	local year = get_arg_or_override(args, "год")
	if not year then
		year = get_arg_or_override(args, "дата")
	end
	if year then
		mf['ws-year'] = year
	end
	
	if args['вокладка'] then
		mf['ws-cover'] = args['вокладка']	
	end
	
	return mf
end

--[=[
Канструюе для старонкі [[Даведка:Мікрафармат]].

Вось што ў форме:
<div id="ws-data" ...>
  <span id="ws-title">Тут назва…</span>
  ...
<div>
]=]
function p.microformat(frame)
	local args = getArgs(frame)

	local mf_div =  construct_mf_wrapper(args)
	local mf = collect_mf_data(args)

	append_mf_values(mf_div, mf)
	return tostring(mf_div)
end

function make_category_list(categories)
	local s = ""
	for k,v in pairs(categories) do
		s = s .. "[[Катэгорыя:" .. v .. "]]\n"
	end
	return s
end

--[=[
Вызначае яўнае фарматаваньне ў палёх кшталту „частка“ і „назва“
]=]
function explicit_formatting(str)
	return string.match(str, "'''?")
		or string.match(str, "<%s*/?%s*[iIbB]%s*>")
		-- дадавайце тут іншыя выпадкі
end

function check_non_existent_author_pages(args, param, categories)

	if args[param] then
		-- на некаторых старонках можа быць няслушны аўтар
		local special = false
		local lower_arg =  string.lower(args[param])
		if lower_arg == "невядомы" or lower_arg == "не пазначаны" then
			special = true
		end
		
		if not special then
			local target = mw.title.makeTitle("Аўтар", args[param])
			-- ёмістая функцыя!
			if not target or not target.exists then
				table.insert(categories, "Вікікрыніцы:Творы зь няіснымі старонкамі аўтараў")
			end
		end
	end
end

--[=[
Канструюе аўтаматычныя катэгорыі для назвы
]=]
function p.categories(frame)
	local args = getArgs(frame)
	
	local categories = {}
	local this_page = mw.title.getCurrentTitle();

	if args["перапісаць_аўтар"] then
		table.insert(categories, "Вікікрыніцы:Старонкі зь перапрызначанымі аўтарамі")
	end
	
	if this_page:inNamespaces(0, 114) then
		check_non_existent_author_pages(args, "аўтар", categories)
		check_non_existent_author_pages(args, "рэдактар", categories)
		check_non_existent_author_pages(args, "перакладчык", categories)
		check_non_existent_author_pages(args, "перакладчык_часткі", categories)
		check_non_existent_author_pages(args, "аўтар_часткі", categories)
		check_non_existent_author_pages(args, "суаўтар", categories)
	end
	
	if args["суаўтар"] or args["аўтар_часткі"] then
		table.insert(categories, "Вікікрыніцы:Старонкі з суаўтарамі")
	end
	
	if args["перапісаць_суаўтар"] or args["перапісаць_аўтар_часткі"] then
		table.insert(categories, "Вікікрыніцы:Старонкі зь перапрызначанымі суаўтарамі")
	end
	
	local author = get_arg_or_override(args, "аўтар")
	if author and (string.lower(author) == "невядомы") then
		table.insert(categories, "Ананімныя творы")
	end
	
	local editor = get_arg_or_override(args, "рэдактар")
	if editor then
		editor = string.lower(editor)
		if editor == "невядомы" or editor == "?" then
			table.insert(categories, "Творы зь невядомымі рэдактарамі")
		elseif editor == "не пазначаны" then
			table.insert(categories, "Творы зь непазначанымі рэдактарамі")
		end
	end
	
	local translator = get_arg_or_override(args, "перакладчык")
	if not translator then
		translator = get_arg_or_override(args, "пераклад")
	end
	if translator then
		translator = string.lower(translator)
		if translator == "невядомы" or translator == "не пазначаны" or translator == "?" then
			table.insert(categories, "Пераклады зь непазначанымі перакладчыкамі")
		elseif translator == "wikisource" and (this_page.baseText == this_page.text) then
			-- калі базавая старонка
			-- ?? чаму гэта ня робіць шаблён {{Пераклад}} ??
			table.insert(categories, "Пераклады Вікікрыніцы")
		end
	end

	if args["скарот"] then
		table.insert(categories, "Вікікрыніцы:Старонкі асноўнай прасторы са скаротамі")
	end
	
	if args["перапісаць_год"] then
		table.insert(categories, "Вікікрыніцы:Старонкі зь перапрызначанымі гадамі")
	end
	if args["бяз_году"] then
		table.insert(categories, "Вікікрыніцы:Старонкі з адключанымі гадамі")
	end
	if args["без_кат_году"] then
		table.insert(categories, "Вікікрыніцы:Старонкі з адключанымі катэгорыямі паводле гадоў")
	end
	
	if args["вокладка"] then
		table.insert(categories, "Вікікрыніцы:Старонкі з экспартаванай вокладкай")
	end
	
	-- праверкі нармальнасьці/службовыя на розных парамэтрах
	
	-- парамэтар „дазволіць_ручное_фарматаваньне“ адключае гэтую праверку
	if args["дазволіць_ручное_фарматаваньне"] == nil and args["дазволіць_хібнае_фарматаваньне"] == nil then

		if (args["назва"] and explicit_formatting(args['назва'])) or
		   (args["title"] and explicit_formatting(args['title']))
		then
			table.insert(categories, "Вікікрыніцы:Старонкі з ручным фарматаваньнем у загалоўках")
		end

		if args["частка"] and explicit_formatting(args['частка'])
		then
			table.insert(categories, "Вікікрыніцы:Старонкі з ручным фарматаваньнем у загалоўках")
		end
	end

	return make_category_list(categories)
end

--[=[
Генэруе магічнае слова {{DEFAULTSORT}} адпаведна парамэтру дапомнага сартаваньня
]=]
function p.defaultsort(frame)
	local args = getArgs(frame)
	
	local defsortKey = ''
	
	if args.defaultsort then
		defsortKey = args.defaultsort
	else
		-- у гэтым месцы можна было б аўтаматычна сканструяваць дапомнае сартаваньне
		-- абразаньнем пры патрэбе артыкляў A/An/The
	end
	
	-- калі знойдзены ці сканструяваны прыдатны ключ, ужыць яго
	if defsortKey ~= '' then
		return frame:preprocess{text = "{{DEFAULTSORT:" .. defsortKey .. "}}"}
	end
	
	-- інакш не рабіць нічога і выкарыстаць дапомны
	return ''
end

function get_plain_sister(frame, args, sister_args)
	local ps_args = {}
	for k,v in pairs(sister_args) do
		if args[v] then
			ps_args[v] = args[v]
		end
	end
	
	return frame:expandTemplate{title = "Зьвязаныя праекты", args = ps_args}
end

--[=[
Вяртае span назвы

> 
--]=]
function construct_title(args)
	local title = mw.html.create("span")
		:attr("id", "header_title_text")
		:css({
			["font-weight"] = "bold",
		})
		
	local s = ""
	if args["назва"] then
		title:wikitext(args["назва"])
	elseif args["title"] then
		title:wikitext(args["title"])
	else
		title:wikitext("Бяз назвы")
	end

	return title
end

--[=[
Канструюе поле назвы
]=]
function p.title(frame)
	local args = getArgs(frame)

	local title = construct_title(args)
	return tostring(title)
end

--[=[
Зьбірае span году
--]=]
function construct_year(frame, args)

	local year = mw.html.create("span")
		:attr("id", "header_year_text")
		
	if args["перапісаць_год"] then
		year:wikitext( '(' .. args["перапісаць_год"] .. ')' )
	else
		local year_args = {
			[1] = args["год"] or args["дата"],
			noprint = "0",
			nocat = "0",
		}
		
		if args["бяз_году"] then
			year_args['не_выводзіць'] = "1"
		end
		
		if args["неадназначнасьць"] and yesno(args['неадназначнасьць']) then
			-- не катэгарызаваць неадназначнасьці
			year_args['бязкат'] = "1"
		else
			if args["без_кат_году"] and yesno(args['без_кат_году']) then
				-- ручное адключэньне катэгарызацыі
				year_args['бязкат'] = "1"
			elseif mw.title.getCurrentTitle().isSubpage then
				-- катэгарызаваць толькі базавую старонку
				year_args['бязкат'] = "1"
			end
		end
		mw.logObject(year_args)
		year:wikitext(mw.text.trim(frame:expandTemplate{
			title = "Загаловак/год",
			args  = year_args
		}))
	end
	return year
end

--[=[
Зьбірае поле году
]=]	
function p.year(frame)
	local args = getArgs(frame)

	ret = ""
	if get_arg_or_override(args, "год") then
		ret = tostring(construct_year(frame, args))
	elseif get_arg_or_override(args, "дата") then
		ret = tostring(construct_year(frame, args))
	end

	return ret
end

function create_vcard(id, content, wrap_fn)
	local span = mw.html.create("span")
		:addClass("vcard")
		:css({
			['font-style'] = 'italic'
		})
		:attr("id", id)
	
	if wrap_fn then
		span:tag("span")
			:addClass("fn")
			:wikitext(content)
	else
		span:wikitext(content)
	end
	
	return span
end

function p.author(frame)
	local args = getArgs(frame)
	
	local param_name = "аўтар"
	local prefix = "Аўтар:"
	local id = "header_author_text"

	local s = ""
	local atext;
	
	local wrap_fn = true

	if args["перапісаць_" .. param_name] then
		s = s .. "<br/>"
		atext = args["перапісаць_" .. param_name]
	elseif args[param_name] then
		if args['частка'] then
			s = s .. "&#44;&#32;"
		else
			s = s .. "<br/>"
		end
		
		if string.lower(args[param_name]) == "невядомы" then
			atext = "Невядомы"
			wrap_fn = false
		else
			atext = "[[Аўтар:" .. args[param_name] .. "|" .. args[param_name] .. "]]"
		end
 		
		if args['частка'] then
			s = s .. "<i>" .. string.lower(prefix) .. "</i> "
		else
			s = s .. "<i>" .. prefix .. "</i> "
		end
	end
	
	local a_span = create_vcard(id, atext, wrap_fn)
	return s .. tostring(a_span)
end

function p.editor(frame)
	local args = getArgs(frame)

	local ed = get_arg_or_override(args, "рэдактар")

	-- рэдактараў няма
	if ed == nil then
		return ""
	end
	
	local have_authors = get_arg_or_override(args, "аўтар") ~= nil

	local s = " "
	if have_authors then
		s = ", "
	end
	
	if not have_authors and not args["частка"] then
		s = s .. "<br/>"
	end
	
	-- гэта трэба падчысьціць і праверыць перапісаць_рэдактар = невядомы|не пазначаны|?
	local special
	if ed == "?" or string.lower(ed) == "невядомы" then
		special = "рэдактар невядомы"
	elseif string.lower(ed) == "не пазначаны" then
		special = "рэдактар не пазначаны"
	elseif ed ~= nil then
		s = s .. "рэдактар"
	end
	
	s = "<i>" .. s .. "</i> "

	local etext
	local wrap_fn = true
	if args["перапісаць_рэдактар"] then
		etext = args["перапісаць_рэдактар"]
	elseif args["рэдактар"] then

		if special then
			etext = special
			wrap_fn = false
		else
			etext = "[[Аўтар:" .. args["рэдактар"] .. "|" .. args["рэдактар"] .. "]]"
		end
	end
	
	local span = create_vcard("header_editor_text", etext, true)
	return s .. tostring(span)
end

function p.translator(frame)
	local args = getArgs(frame)

	local tr = get_arg_or_override(args, "перакладчык")

	-- перакладчыка нямашака
	if tr == nil then
		return ""
	end

	local have_authors = get_arg_or_override(args, "аўтар") ~= nil
					  or get_arg_or_override(args, "author") ~= nil
	local have_editors = get_arg_or_override(args, "рэдактар") ~= nil

	local s = " "
	if have_authors or have_editors then
		s = ", "
	end
	
	if not have_authors
	   and not have_editors
	   and args["частка"] == nil
	then
		s = s .. "<br/>"
	end

	local special
	if tr == "?" or string.lower(tr) == "невядомы" then
		special = "перакладчык невядомы"
	elseif string.lower(tr) == "не пазначаны" then
		special = "перакладчык не пазначаны"
	elseif string.lower(tr) == "wikisource" then
		special = "перакладзена [[Вікікрыніцы:Пераклады|<span id=\"header_translator_text\">Вікікрыніцамі</span>]]"
	elseif tr ~= nil then
		s = s .. "перакладчык"
	end
	
	s = "<i>" .. s .. "</i> "

	local etext
	local wrap_fn = true
	if args["перапісаць_перакладчык"] then
		etext = args["перапісаць_перакладчык"]
	elseif args["перакладчык"] then
		if special then
			etext = special
			wrap_fn = false
		else
			etext = "[[Аўтар:" .. args["перакладчык"] .. "|" .. args["перакладчык"] .. "]]"
		end
	elseif args["пераклад"] then
		if special then
			etext = special
			wrap_fn = false
		else
			etext = "[[Аўтар:" .. args["пераклад"] .. "|" .. args["пераклад"] .. "]]"
		end
	end
	
	local span = create_vcard("header_translator_text", etext, true)
	return s .. tostring(span)
end

function p.section(frame)
	local args = getArgs(frame)
	
	if not args["частка"] then
		return
	end

	if args["частка"] then
		local s = "<br /><span id=\"header_section_text\">" .. args["частка"] .. "</span>"
	end

	-- тут існуюць сынонімы
	local trans = get_arg_or_override(args, "перакладчык_часткі")
	if trans == nil then
		trans = get_arg_or_override(args, "суперакладчык")
	end

	-- тут існуюць сынонімы
	local sec_author = get_arg_or_override(args, "аўтар_часткі")
	if sec_author == nil then
		sec_author = get_arg_or_override(args, "суаўтар")
	end
	
	-- першая частка перакладчык_часткі дадае перанос радку, бо калі будзе „перакладчык_часткі“, то атрымаецца доўгі радок
	if trans and sec_author then
		s = s .. "<br/>"
	end
	
	if sec_author then
		s = s .. "<i> by <span id=\"header_contributor_text\" class=\"vcard\">"
		s = s .. "<span class=\"fn\">"
		
		if args["перапісаць_аўтар_часткі"] then
			s = s .. args["перапісаць_аўтар_часткі"]
		elseif args["перапісаць_суаўтар"] then
			s = s .. args["перапісаць_суаўтар"]
		else
			s = s .. "[[Аўтар:" .. sec_author .. "|" .. sec_author .. "]]"
		end
		s = s .. "</span></span></i>"
	end
	
	if trans then
		if sec_author then
			s = s .. ","	
		end
		s = s .. " <i>перакладзены <span id=\"header_section_translator_text\" class=\"vcard\">"
		s = s .. "<span class=\"fn\">"
		
		if args["перапісаць_перакладчык_часткі"] then
			s = s .. args['перапісаць_перакладчык_часткі']
		else
			s = s .. "[[Аўтар:" .. trans .. "|" .. trans .. "]]"
		end
		s = s .. "</span></span></i>"		
	end
	
	return s
end

--[=[
Сканструяваць поле крыніцаў
]=]
function p.source(frame)
	local args = getArgs(frame)

	if not args["крыніца"] then
		return
	end
	local src = "<br /><span id=\"source_text\"><i>Крыніца: " .. args["крыніца"] .. "</i></span>"

	return src 
end

--[=[
Сканструяваць поле анатацыі
]=]
function p.notes(frame)
	local args = getArgs(frame)
	
	local notes_args = {
		style = "border-bottom: 1px solid #A0A0A0; background-color: #FAFAFF;",
		id = navigationNotes
	}

	local wdid = mw.wikibase.getEntityIdForCurrentPage()
	local sister_args = {"неадназначнасьць", "рэдакцыя", "партал", "зьвязаны_аўтар",
		"вікіпэдыя", "вікісховішча", "commonscat", "вікіцытатнік", "вікінавіны", 
		"вікіслоўнік", "вікікнігі",  "вікізьвесткі", "віківандроўкі", 
		"віківэрсытэт", "віківіды", "мэта"}
	local sisters = ""
	if wdid ~= nil or has_any_arg(args, sister_args) then
		notes_args['іншыя праекты'] = (get_plain_sister(frame, args, sister_args))
	end

	if args["скарот"] then
		notes_args['скарот'] = args["скарот"]
	end
		
	if args["анатацыі"] then
		notes_args['зьмест'] = args['анатацыі'] 
	end

	if not notes_args['іншыя праекты'] and
			not notes_args['зьмест'] and
			not notes_args['скарот'] then
		return nil
	end

	return frame:expandTemplate{title = "Загаловак/анатацыі", args = notes_args}
end

return p