Acest modul este folosit de un număr de mai multe module și formate, în principal de {{titlu}}.


--[=[
Acesta este un modul de implementare a logicii pentru [[Format:Titlu]] și [[Format:Titlu traduceri]]

TODO:
- centuries are defined as starting on XX01, but WS categorizes them as starting on XX00
-- check whether that's a considered policy choice
]=]

require('strict')

local p = {} --p vine de la „pachet”

local yesno = require('Modul:Yesno')
local getArgs = require('Modul:Arguments').getArgs
local TableTools = require('Modul:TableTools')
local ISO_639_language_name = require('Modul:ISO 639').language_name
local parent_links = require('Modul:Auto parents')._parent_links

local construct_header = require('Modul:Header structure').construct_header
local headerAttributions = require('Modul:Header/attribution')
local construct_defaultsort = require('Modul:Header/sort')._construct_defaultsort
local construct_year = require('Modul:Header/year').construct_year

local current_title = mw.title.getCurrentTitle()

--[=[
Wrap stylesheet in noexport div
]=]
local function get_noexport_stylesheet(template)
	return tostring(mw.html.create('div'):addClass('ws-noexport'):wikitext(mw.getCurrentFrame():extensionTag('templatestyles', '', {src = template .. '/styles.css'})))
end

--[=[
Get badge if any
]=]
local function badge()
	return require('Modul:Edition').badge({args = {category = '1', indicator = '1'}})
end

--[=[
Detect explicit formatting in fields like "section" and "title"
]=]
local function explicit_formatting(str)
	return string.match(str, "'''?")
		or string.match(str, "<%s*/?%s*[iIbB]%s*>")
		-- add more cases here or come up with a less silly way to do things
end

local function check_non_existent_author_pages(args, categories, checkArgs)
	-- check for cases that aren't supposed to produce a valid link
	
	local param = checkArgs.param
	local tracking_cat = checkArgs.tracking_cat or 'Opere cu pagini de autor inexistente'
	
	if not param or not args[param] or yesno(args[param .. '-nolink']) then
		return
	end
	
	local lower_arg = string.lower(args[param])
	local attr_data = headerAttributions.attr_data[param] or headerAttributions.attr_data[string.gsub(param, 'secțiune%-', '')]
	if attr_data and attr_data['special_cases'] and attr_data['special_cases'][lower_arg] then
		return
	end
	
	-- check if page exists
	local target = mw.title.makeTitle('Autor', args[param])
	-- expensive function!
	if not target or not target.exists then
		table.insert(categories, tracking_cat)
	end
	
	return
end

--[=[
Construct the automatic categories for the header
]=]
local function language_category_name(cat_works_start, lang)
	local cat_language_name = ISO_639_language_name(lang) or 'o limbă neidentificată'
	if lang == 'el' then
		cat_language_name = 'Greaca modernă'
	end
	return cat_works_start .. ' ' .. cat_language_name
end

local function construct_categories(args)
	local categories = {}
	
	if args['override-author'] or args['autor-înlocuit'] then
		table.insert(categories, "Pagini la care s-a înlocuit autorul")
	end
	
	if args['override-translator'] or args['traducător-înlocuit'] then
		table.insert(categories, "Pagini la care s-a înlocuit traducătorul")
	end
	
	if current_title:inNamespaces(0) or args.testing then
	--if current_title:inNamespaces(0, 114) or args.testing then
		local params_to_check = {
			{param = 'autor'},
			{param = 'editor'},
			{param = 'traducător'},
			{param = 'compozitor', tracking_cat = 'Opere cu pagini de compozitor inexistente'},
			{param = 'ilustrator', tracking_cat = 'Opere cu pagini de ilustrator inexistente'}
		}
		for k, v in pairs(params_to_check) do
			check_non_existent_author_pages(args, categories, v)
			check_non_existent_author_pages(args, categories, {param = 'secțiune-' .. v.param, tracking_cat = v.tracking_cat})
		end
	end
	
	if args['section-author'] or args['autor-secțiune'] or args['section-autor'] then
		table.insert(categories, 'Pagini cu contribuitor')
	end
	if args['override-section-author'] or args['override-section-autor'] then
		table.insert(categories, 'Pagini la care s-a înlocuit contribuitorul')
	end
	
	local author = args['autor-înlocuit'] or args['autor'] or args['override-author'] or args['author']
	if author and (string.lower(author) == 'necunoscut') and not args['nocat'] then
		if args.template_name == 'Titlu traducere' then
			table.insert(categories, 'Traduceri de lucrări anonime')
		else
			table.insert(categories, "Texte anonime")
		end
	end
	
	local editor = args['override-editor'] or args['editor'] or args['editor-înlocuit']
	if editor and not args['nocat'] then
		editor = string.lower(editor)
		if editor == 'necunoscut' or editor == '?' then
			table.insert(categories, "Opere cu editori necunoscuți")
		elseif editor == 'nemenționat' then
			table.insert(categories, "Opere cu editori nemenționați")
		end
	end
	
	local translator = args['override-translator'] or args['translator'] or args['traducător'] or args['traducător-înlocuit']
	if translator and not args['nocat'] then
		translator = string.lower(translator)
		if translator == 'necunoscut' or translator == 'nemenționat' or translator == '?' then
			table.insert(categories, 'Traduceri fără informații despre traducător')
		end
	end
	
	if args["shortcut"] or args['scurtătură'] then
		if current_title:inNamespaces(0) then
			table.insert(categories, 'Pagini în numele de spațiu principal cu scurtături')
		--elseif current_title:inNamespaces(114) then
			--table.insert(categories, 'Pagini în numele de spațiu Traduceri cu scurtături')
		end
	end
	
	if args['noyear'] then
		table.insert(categories, "Pagini cu noyear")
	end
	if yesno(args['noyearcat']) then
		table.insert(categories, "Pagini cu noyearcat")
	end
	
	if args['copertă'] then
		table.insert(categories, "Pagini cu o copertă pentru export")
	end
	
	-- sanity/maintenance checks on various parameters
	
	-- allow_explicit_formatting parameter suppresses this check
	-- used by, for example, [[Template:Versions]]
	if not yesno(args['permite-formatarea-explicită']) then
		if (args['titlu']) and explicit_formatting(args['titlu']) then
			table.insert(categories, "Pagini cu formatare explicită în câmpurile titlului")
		end
		if (args['secțiune']) and explicit_formatting(args['secțiune']) then
			table.insert(categories, "Pagini cu formatare explicită în câmpurile titlului")
		end
	end
	
	-- translation header categories
	local isMainPage = ((current_title:inNamespaces(0) and not current_title.isSubpage) or args['testing'] or args['test'])
	--local isMainPage = ((current_title:inNamespaces(0, 114) and not current_title.isSubpage) or args['testing'] or args['test'])
	
	if not args['nocat'] and isMainPage then
		local cat_works_start = 'Traduceri din limba'
		local cat_translations_start = 'Traduceri'
		if args.template_name == 'Titlu traducere' then
			cat_works_start = 'Traduceri Wikisource din limba'
			cat_translations_start = 'Traduceri Wikisource'
		end
		
		if args['limbi'] then
			for i, lang in ipairs(args['limbi']) do
				table.insert(categories, language_category_name(cat_works_start, lang))
			end
		elseif args['limbă-necesară'] then
			table.insert(categories, cat_translations_start .. ' fără limbă originală')
		end
		if args['interwiki-prefix'] then
			table.insert(categories, language_category_name(cat_works_start, args['interwiki-prefix']))
		end
		
		if args.template_name == 'Titlu traducere' and not args.original then
			table.insert(categories, 'Traduceri Wikisource fără sursă originală')
		end
	end
	
	-- detect inappropriate template use
	--[=[
	if (args['template-name'] ~= 'Translation header' and translator and string.lower(translator) == 'wikisource')
		or (current_title:inNamespaces(114) and args['template-name'] ~= 'Translation header') then
		-- tracking category for pages that should be using translation header?
	end
	if current_title:inNamespaces(0) and args['template-name'] == 'Translation header' then
		-- tracking category for translation header in mainspace?
	end
	]=]
	
	local category_links = {}
	for k, v in pairs(categories) do
		table.insert(category_links, '[[Categorie:' .. v .. ']]')
	end
	return table.concat(category_links)
end

--[=[
Check for numerical parameters (which shouldn't be used)
]=]
local function check_for_numerical_arguments(args)
	for k, v in pairs(args) do
		if type(k) == 'number' then
			return '[[Categorie:' .. 'Titluri cu argumente numerice' .. ']]'
		end
	end
	return ''
end

--[=[
Add categories from the categories parameter
]=]

local function manual_categories(args)
	if not args.categories then
		return ''
	end
	
	-- Replace each string that ends in a slash with a category definition.
	-- This does include the final one because we're adding a slash to the input string.
	local categories = mw.ustring.gsub(args.categories .. '/', '([^/]+)/*', '[[Categorie:%1]]')
	
	return '[[Categorie:' .. 'Lucrări care folosesc parametrul categorii' .. ']]' .. categories
end

--[=[
Categorize subpages
]=]
local function check_subpages()
	local title = current_title
	local parent_exists = false
	while title.isSubpage and not parent_exists do
		title = mw.title.new(title.baseText, title.nsText)
		parent_exists = title.exists
	end
	if parent_exists and title:inNamespaces(0) then
		return '[[Categorie:' .. 'Subpagini' .. ']]'
	elseif parent_exists then
		return '[[Categorie:' .. title.nsText .. ' subpagini' .. ']]'
	else
		return ''
	end
end

--[=[
Assemble the title
]=]
local function header_title(args)
	local title = args.titlu or ''
	local titleSpan = tostring(mw.html.create('span'):attr('id', 'header-title-text'):wikitext(title))
	
	local year = construct_year(args)
	local attr = headerAttributions.construct_attributions(args)
	local section = headerAttributions.construct_section(args)
	
	if attr ~= '' and title ~= '' then
		attr = '<br id=\"header-title=break\" />' .. attr
	end
	
	return table.concat({titleSpan, year, attr, section})
end

--[=[
[[Format:Titlu]]
]=]
function p._header(args, argsWithBlanks)
	argsWithBlanks = argsWithBlanks or args
	
	-- aliases
	local dup_cat = ''
	local newArgs = {}
	
	local aliases = {
		['section-autor'] = 'contribuitor',
		['section-traducător'] = 'traducător%-contribuitor'
	}
	for k, v in pairs(args) do
		local newkey = string.lower(string.gsub(string.gsub(tostring(k), '_', '-'), ' ', '-'))
		for arg, alias in pairs(aliases) do
			newkey = string.gsub(newkey, alias, arg)
		end
		if newkey ~= tostring(k) then
			if argsWithBlanks[newkey] then
				dup_cat = '[[Categorie:' .. 'Pagini care folosesc argumente duplicate în declarațiile formatelor' .. ']]'
			end
			if not args[newkey] then
				newArgs[newkey] = newArgs[newkey] or v
			end
		end
	end
	for k, v in pairs(newArgs) do
		args[k] = v
		argsWithBlanks[k] = v
	end
	
	args.sortkey = args.defaultsort or args.sortkey
	
	-- default values
	args.template_name = args.template_name or 'Titlu'
	
	args.testing = yesno(args.testing or current_title.fullText == 'Format:Titlu/teste' or current_title.fullText == 'Format:Titlu traducere/teste')
	
	args.nocat = yesno(args.nocat) or false
	-- noyearcat has different behavior for nil and false
	if args.nocat == true then
		args.noyearcat = true
	end
	
	-- language handling
	local languages = {}
	for k, v in pairs(args) do
		local n
		local nText = string.match(k, '^limbă%d*$')
		if nText then
			n = string.gsub(nText, 'limbă(%d*)$', '%1')
			n = tonumber(n) or 1
			languages[n] = v
		end
	end
	languages = TableTools.compressSparseArray(languages)
	
	if #languages > 0 then
		args.limbi = languages
	end
	if args.limbi then
		local language_names = {}
		for i, lang in ipairs(args.limbi) do
			local language_name = ISO_639_language_name(lang)
			if language_name then
				table.insert(language_names, language_name)
			end
		end
		
		if #language_names == 1 then
			args.language_name = language_names[1]
		elseif #language_names > 1 then
			args.language_name = table.concat(language_names, ', ', 1, #language_names - 1) .. ' și ' .. language_names[#language_names]
		end
	end
	
	args['limbă-necesară'] = yesno(args['limbă-necesară']) or false
	
	if not args['interwiki-prefix'] and args['limbi'] then
		if #(args['limbi']) > 1 then
			args['interwiki-prefix'] = 'mul'
		else
			args['interwiki-prefix'] = args['limbi'][1]
		end
	end
	
	-- add values to argsWithBlanks
	for k, v in pairs(args) do
		if not argsWithBlanks[k] then
			argsWithBlanks[k] = v
		end
	end
	
	-- default values for title and section (allow override by setting to blank)
	if not argsWithBlanks['titlu'] then
		args['titlu'] = parent_links({})
		argsWithBlanks['titlu'] = args['titlu']
	end
	if not argsWithBlanks['secțiune'] and current_title.isSubpage then
		args['secțiune'] = current_title.subpageText
		argsWithBlanks['secțiune'] = args['secțiune']
	end
	
	-- header args
	
	args.pre_container = badge()
	args.header_class = 'wst-header ws-header ws-noexport noprint dynlayout-exempt ' .. (args.header_class or '')
	args.main_class = 'headertemplate'

	-- title
	args.main_title = header_title(args)
	
	-- FIXME: just use Wikidata instead of interwiki links?
	local interwiki = ''
	if args.template_name == 'Titlu traducere' and args['interwiki-prefix'] then
		interwiki = tostring(mw.html.create('span'):addClass('interwiki-info'):attr('id', args['interwiki-prefix']):attr('titlu', '(original)'))
		if args.original and (args['interwiki-prefix'] == 'ang' or args['interwiki-prefix'] == 'enm' or args['interwiki-prefix'] == 'sco') then
			-- cycle to mul.ws and back around to en.ws
			interwiki = interwiki .. '[[' .. args['interwiki-prefix'] .. ':en:' .. args.original .. ']]'
		elseif args.original and args['interwiki-prefix'] then
			-- general interwiki link
			interwiki = interwiki .. '[[' .. args['interwiki-prefix'] .. ':' .. args.original .. ']]'
		end
	end
	
	-- defaultsort tracking categories
	args.equalsortcat = '[[Categorie:' .. 'Titluri cu DefaultSort egal cu numele paginii' .. ']]'
	args.diffsortcat = '[[Categorie:' .. 'Titluri care aplică o cheie DefaultSort' .. ']]'
	
	args.post_notes = table.concat({
		headerAttributions.construct_microformat(args),
		check_subpages(),
		manual_categories(args),
		construct_categories(args),
		check_for_numerical_arguments(argsWithBlanks),
		construct_defaultsort(args),
		dup_cat,
		interwiki
	})
	
	return get_noexport_stylesheet('Titlu') .. construct_header(args)
end

function p.header(frame)
	return p._header(
		getArgs(frame),
		getArgs(frame, {removeBlanks = false})
	)
end

--[=[
[[Template:Translation header]]
]=]
function p._translation_header(args, argsWithBlanks)
	argsWithBlanks = argsWithBlanks or args
	
	args.header_class = 'wst-translation-header'
	args.template_name = 'Titlu traducere'
	args.notes_class = 'header-notes'
	args['language-required'] = true
	args['limbă-necesară'] = true
	
	return get_noexport_stylesheet('Titlu traducere') .. p._header(args, argsWithBlanks)
end

function p.translation_header(frame)
	return p._translation_header(
		getArgs(frame),
		getArgs(frame, {removeBlanks = false})
	)
end

return p