Modulo:Periodo attività musicale

Modulo a supporto del template {{Artista musicale}} per generare la riga "Periodo di attività musicale" e la relativa categorizzazione, a partire dai parametri "anno inizio attività N", "anno fine attività N" e "note periodo attività N".

Ha una sottopagina di configurazione: Modulo:Periodo attività musicale/Configurazione.


--[[
* Modulo a supporto del template Artista musicale per generare la riga
* "Periodo di attività musicale" e la relativa categorizzazione, a partire dai  
* parametri "anno inizio attività N", "anno fine attività N" e "note periodo attività N".
]]--

require('strict')

local getArgs = require('Modulo:Arguments').getArgs
local cfg = mw.loadData('Modulo:Periodo attività musicale/Configurazione')
local errorCategory = 'Voci con template Artista musicale con periodo errato'
local trackingCategory = 'Voci con template Artista musicale con periodo attività con singolo anno'
local maxIntervals = 10

-- Verifica se il decennio è nel formato accettato "anni nnnn" e con un valore consentito.
--
-- @param {string} value
-- @return {string} la stringa non modificata o nil se non è un decennio valido
local function isDecade(value)
	return value and (value:match('^anni 19[0-9]0$') or value:match('^anni 20[0-2]0$'))
end

-- Parsifica i parametri relativi al periodo di attività musicale:
-- "anno inizio attività N", "anno fine attività N" e "note periodo attività N".
--
-- @param {table} args
-- @return {table} sequence Lua con elementi con chiavi "start", "ending"
--                ("end" è una parola riservata) e "note"
local function parseArgs(args)
	local ret = {}

	for i = 1, maxIntervals do
		local n = i == 1 and '' or (' ' .. i)
		local interval = {
			start = args['anno inizio attività' .. n],
			ending = args['anno fine attività' .. n],
			note = args['note periodo attività' .. n]
		}
		if interval.start or interval.ending then
			table.insert(ret, interval)
		else
			break
		end
	end

	return ret
end

-- Formatta il valore del parametro "anno inizio attività" del primo intervallo.
--
-- @param {string} value
-- @param {table} confCat
-- @return {string} il valore formattato
-- @return {string} l'eventuale categoria per l'anno di costituzione dell'artista
local function formatStartYear(value, confCat)
	local ret, cat
	if isDecade(value) then
		ret = string.format('[[%s]]', value)
	elseif tonumber(value) then
		cat = confCat.inizio and (confCat.inizio .. ' ' .. value) or nil
		ret = cat and string.format('[[:Categoria:%s|%s]]', cat, value) or string.format('[[%s]]', value)
	else
		cat = confCat.inizio_assente
		ret = value or '?'
	end
	return ret, cat
end

-- Formatta il valore del parametro "anno fine attività" dell'ultimo intervallo.
--
-- @param {string} value
-- @param {table} confCat
-- @return {string} il valore formattato
-- @return {string} l'eventuale categoria per l'anno di scioglimento dell'artista
local function formatEndYear(value, confCat)
	local ret, cat
	if isDecade(value) then
		ret = string.format('[[%s]]', value)
	elseif value == 'in attività' then
		cat = confCat.in_attivita
		ret = cat and string.format('[[:Categoria:%s|%s]]', cat, value) or value
	elseif tonumber(value) then
		cat = confCat.fine and (confCat.fine .. ' ' .. value) or nil
		ret = cat and string.format('[[:Categoria:%s|%s]]', cat, value) or string.format('[[%s]]', value)
	else
		cat = confCat.fine_assente
		ret = value or '?'
	end
	return ret, cat
end

-- =============================================================================
--                            Funzioni esportate
-- =============================================================================

local p = {}

-- Funzione per {{#invoke:Periodo attività musicale|main}}
function p.main(frame)
	local args = getArgs(frame, { parentOnly = false })
	local formattedIntervals, categories = {}, {}
	local ns0 = mw.title.getCurrentTitle().namespace == 0
	local sepCat = args.debug and '<br />' or ''
	local singleYear = false

	-- categorie configurate per il "tipo artista" richiesto
	local tipo_artista = args['tipo artista'] and mw.ustring.lower(args['tipo artista']) or nil
	local confCat = cfg.categorie[cfg.alias[tipo_artista] or tipo_artista] or cfg.categorie.default

	-- parsifica gli intervalli richiesti
	local intervals = parseArgs(args)

	-- formatta gli intervalli ottenuti
	for idx, interval in ipairs(intervals) do
		local start, ending, cat, formattedInterval
		if idx == 1 then
			start, cat = formatStartYear(interval.start, confCat)
			table.insert(categories, cat)
		elseif tonumber(interval.start) or isDecade(interval.start) then
			start = string.format('[[%s]]', interval.start)
		elseif interval.start then
			start = string.format('<span class="error">anno inizio attività %s non valido</span>', idx)
			table.insert(categories, errorCategory)
		else
			start = '?'
		end

		if idx == #intervals then
			ending, cat = formatEndYear(interval.ending, confCat)
			table.insert(categories, cat)
		elseif tonumber(interval.ending) or isDecade(interval.ending) then
			ending = string.format('[[%s]]', interval.ending)
		elseif interval.ending then
			ending = string.format('<span class="error">anno fine attività %s non valido</span>', idx)
			table.insert(categories, errorCategory)
		else
			ending = '?'
		end

		-- se sono più di uno e inizio=fine genera un solo link
		if #intervals > 1 and interval.start == interval.ending then
			formattedInterval = idx == 1 and start or ending
			singleYear = true
		else
			formattedInterval = string.format('%s&nbsp;–&nbsp;%s', start, ending)
		end

		if interval.note then
			local fmt = interval.note:sub(1, 1) == string.char(127) and
						'%s<small>%s</small>' or '%s <small>(%s)</small>'
			formattedInterval = string.format(fmt, formattedInterval, interval.note)
		end
		table.insert(formattedIntervals, formattedInterval)
	end

	if #intervals > 1 then
		if confCat.intermedi then
			table.insert(categories, confCat.intermedi)
		end
		if singleYear then
			table.insert(categories, trackingCategory)
		end
	end

	for i = 1, #categories do
		categories[i] = string.format('[[%sCategoria:%s]]', args.debug and ':' or '', categories[i])
	end

	return table.concat(formattedIntervals, '<br />') .. sepCat ..
		   ((ns0 or args.debug) and table.concat(categories, sepCat) or '')
end

return p