Modulo:Tracce/sandbox

Versione del 9 mag 2018 alle 17:56 di Sakretsu (discussione | contributi) (ammetto numerazione discontinua delle tracce)
local categories = {}
local discontinuous_num = '[[Categoria:Voci con template Tracce a numerazione discontinua]]'
local missing_title = '[[Categoria:Errori di compilazione del template Tracce - titolo mancante]]'
local unexpected_markup = '[[Categoria:Errori di compilazione del template Tracce - markup inaspettato]]'
local unknown_format = '[[Categoria:Errori di compilazione del template Tracce - formato durata sconosciuto]]'

-- Protects a string that will be wrapped in wiki italic markup '' ... ''
local function safeforitalics( str )
    if str ~= nil and str ~= '' then
        if str:sub(1,1) == "'" then str = "<span></span>" .. str end
        if str:sub(-1,-1) == "'" then str = str .. "<span></span>" end
    end
    return str
end

--[[
Riceve una lista di parametri e l'indice del gruppo di parametri da comporre
in una traccia
]]--

local function track(args, i, corsivo)
	local titolo = args["Titolo" .. i]
	local row_elements = {}
	table.insert(row_elements, '<li value="' .. tostring(i) .. '">')
	local interprete = args["Interprete" .. i] or ""
	if interprete ~= "" then table.insert(row_elements, interprete .. " – ") end
	corsivo = (corsivo and args["Corsivo" .. i] ~= "no") or
			(not corsivo and (args["Corsivo" .. i] == "sì" or args["Corsivo" .. i] == "si"))
	if titolo:find(corsivo and "''" or "'''") then
		categories[#categories+1] = unexpected_markup
	end
	if corsivo then
		titolo = "''" .. safeforitalics(titolo) .. "''"
	end
	table.insert(row_elements, titolo)
	local featuring = args["Featuring" .. i] or ""
	if featuring ~= "" then table.insert(row_elements, " <small>(feat. " .. featuring .. ")</small>") end
	local note = args["Note" .. i] or ""
	if note ~= "" then table.insert(row_elements, " <small>(" .. note ..  ")</small>")  end
	local string_durata = args["Durata" .. i]
	local minuti, secondi
	if string_durata then
		local string_minuti, string_secondi = mw.ustring.match(string_durata, "(%d+):(%d%d)")
		minuti = tonumber(string_minuti) or 0
		secondi = tonumber(string_secondi) or 0
	else
		minuti = tonumber(args["Minuti" .. i]) or 0
		secondi = tonumber(args["Secondi" .. i]) or 0
	end
	local durata = minuti * 60 + secondi
	if durata > 0 then
		table.insert(row_elements, " – ")
		table.insert(row_elements, string.format("%d:%02.f", minuti, secondi))
	else
		local args_durata = string_durata or args["Minuti" .. i]
				or args["Secondi" .. i] or ""
		if args_durata ~= "" then
			categories[#categories+1] = unknown_format
		end
	end
	local AutoreTesto = args["Autore testo" .. i] or ""
	local AutoreMusica = args["Autore musica" .. i] or ""
	local AutoreTestoeMusica = args["Autore testo e musica" .. i] or ""
	local edizioni = args["Edizioni" .. i] or ""
	local no_autore = false
	if AutoreTestoeMusica ~= "" then
		table.insert(row_elements, " <small>(" .. AutoreTestoeMusica )
	elseif AutoreTesto ~= "" then
		table.insert(row_elements, " <small>(testo: " .. AutoreTesto)
		if AutoreMusica ~="" then
			table.insert(row_elements, " – musica: " .. AutoreMusica)
		end
	elseif AutoreMusica ~= "" then
		table.insert(row_elements, " <small>(musica: " .. AutoreMusica)
	else
		no_autore = true
	end
	if edizioni ~= "" then
		if no_autore then
			table.insert(row_elements, " <small>(")
		else
			table.insert(row_elements, "; ")
		end
		table.insert(row_elements, "edizioni musicali " .. edizioni .. ")</small>")
	elseif not no_autore then
		table.insert(row_elements, ")</small>")
	end
	local extra = args["Extra" .. i] or ""
	if extra ~= "" then table.insert(row_elements, " – " .. extra) end
	table.insert(row_elements, "</li>\n")
	local ListaMedley = args["ListaMedley" .. i] or ""
	if ListaMedley ~= "" then table.insert(row_elements, '<div style="padding: 0.3em 0px 0.5em 2.5em;">\n' .. ListaMedley .. '</div>')  end
	return table.concat(row_elements), durata
end

--[[
Riceve una tabella di parametri e l'indice del primo gruppo di parametri del template tracce,
restituisce una stringa contenente l'output da inserire nella voce
]]--
local function componi_tracce(args)
    -- array per accumulare le righe della lista man mano che vengono elaborate
    local tracks = {}
    -- compone la testata dell'elenco tracce
    local testata = ""
    local no_autore = false
    local autoreTestoeMusica = args["Autore testi e musiche"] or ""
    if autoreTestoeMusica ~= "" then
        testata = "Testi e musiche di " .. autoreTestoeMusica
    else
        local autoreTesti = args["Autore testi"] or ""
        local autoreMusiche = args["Autore musiche"] or ""
        if autoreTesti ~= "" then
            testata = "Testi di " .. autoreTesti
            if autoreMusiche ~= "" then testata = testata .. ", musiche di " .. autoreMusiche end
        elseif autoreMusiche ~= "" then
            testata = "Musiche di " .. autoreMusiche
        else
            no_autore = true
        end
    end
    local edizioni = args["Edizioni"] or ""
    if edizioni ~= "" then
        if no_autore then
            testata = "Edizioni musicali " .. edizioni .."."
        else
            testata = testata .. "; edizioni musicali " .. edizioni .. "."
        end
    elseif not no_autore then
        testata = testata .. "."
    end
    local corsivo = true
    if args["Corsivo"] == "no" then
        corsivo = false
    end
    table.insert(tracks, testata)
    -- compone la lista dei parametri
    table.insert(tracks, "<ol>")
    local visualizza_durata = args["Visualizza durata totale"] or ""
    local durata = 0
    local somma_durata = false
    if visualizza_durata == "si" or visualizza_durata == "sì" then somma_durata = true end
    local nums = {}
    for k, v in pairs(args) do
    	local numero_titolo = k:match('%D(%d+)$')
    	if tonumber(numero_titolo) then
    		local titolo = args['Titolo' .. numero_titolo] or ''
    		if v ~= '' and titolo == '' then
    			categories[#categories+1] = missing_title
    		elseif k == 'Titolo' .. numero_titolo and titolo ~= '' then
    			table.insert(nums, tonumber(numero_titolo))
    		end
    	end
    end
    table.sort(nums)
    -- estrae le tracce dai parametri e inserisce i valori nella tabella tracks
    for k, num in ipairs(nums) do
        local new_track, durata_track = track(args, num, corsivo)
        table.insert(tracks, new_track)
        if somma_durata then durata = durata + durata_track end
        if k ~= num then categories[#categories+1] = discontinuous_num end
    end
    table.insert(tracks, "</ol>")
    if somma_durata then
        table.insert(tracks, "Durata totale: " .. string.format("%d:%02.f", math.floor(durata/60) , durata % 60) .. "</p>")
    end
    return table.concat(tracks, "\n") .. table.concat(categories)
end

local p = {}

--[[
Funzione di interfaccia con template:Tracce
Legge i parametri e li inserisce nella tabella args, che quindi passa a componi_tracce
per l'elaborazione
]]--
function p.tracce(frame)
    -- ottiene i parametri del template originale
    local pframe = frame:getParent()
    -- estrae tutti i parametri e li memorizza in una tabella
    local args = {}
    local titles = false
    for k, v in pairs( pframe.args ) do
        if v ~= nil then args[k] = v end
        if k:match("^Titolo(%d+)$") then titles = true end
    end
    -- procede solo se c'è almeno un campo titolo
    return titles and componi_tracce(args) or ""
end

-- Tavola di conversione per i parametri di en:template:Track_listing non indicizzati
local conversion_table = {
    ['all_writing'] = 'Autore testi e musiche',
    ['all_lyrics'] = 'Autore testi',
    ['all_music'] = 'Autore musiche',
    ['total_length'] = 'Visualizza durata totale'
}

-- Tavola di conversione per i parametri di en:template:Track_listing indicizzati
local conversion_table_index ={
    ['title'] = 'Titolo',
    ['note'] = 'Note',
    ['music'] = 'Autore musica',
    ['writer'] = 'Autore testo e musica',
    ['lyrics'] = 'Autore testo',
    ['length'] = 'Durata',
    ['extra'] = 'Extra'
}

--[[
Funzione di interfaccia con template:Track_listing
Legge i parametri, li converte nei parametri corrispondenti del template:Tracce
e li inserisce nella tabella args, che quindi passa a componi_tracce
per l'elaborazione
]]--
function p.en_tracks(frame)
    local pframe = frame:getParent()
    -- estrae tutti i parametri e li memorizza in una tabella (pframe ritorna una pseudotabella, vedi documentazione)
    local args = {}
    local primo_titolo
    local log ={}
    for k,v in pairs( pframe.args) do
        if conversion_table[k] then -- Controlla s è un parametro non indicizzato
            args[ conversion_table[k]] = v
        else
            -- estrae nome base e indice, se k=Title1 allora base_key=Title e pos=1
            local base_key, pos = string.match(k, "(%D+)(%d+)$")
            if pos and base_key and conversion_table_index[base_key] then --controlla se è un parametro indicizzato
                args[conversion_table_index[base_key] .. pos] = v
                pos = tonumber(pos)
                if base_key == 'title' and (not primo_titolo or pos < primo_titolo) then
                    primo_titolo = pos
                end
            else -- non è neanche un parametro indicizzato, lo copia così com'è
                args[k] = v
             end
        end
    end
    if args['Visualizza durata totale'] then args['Visualizza durata totale'] = 'si' end
    if primo_titolo then
        return componi_tracce(args, primo_titolo) -- table.concat(log, '\n*') --
    else
        return
    end
end

return p