Module:Interprogetto

--Modulo per implementare le funzionalità di template:Interprogetto

local p = {} -- per l'esportazione delle funzioni del modulo

local HtmlBuilder = require('Modulo:HtmlBuilder') -- richiesto per la costruzione del markup html
local progetti={} -- dati da usare per la costruzione delle righe dell'elenco di link ai progetti
local root -- radice del markup html
local log= '' -- per debug

local function add_space(s)
    --ritorna uno spazio se l'ultimo carattere non è un accento
    if mw.ustring.sub(s, -1) == "'" then
        return ''
    else
        return ' '
    end
end

local function Link(intext, pos, in_stampa)
    -- Restituisce il link nel caso normale di collegamento (progetto senza interfaccia in lingua)
    -- intext vero se è richiesto il link del testo principale, falso per la barra sinistra
    local p=progetti
    local text=''
    if intext then
        if in_stampa then
            text = table.concat({'* [[File:', p.icona[pos], '|',  p.dimensione_icona[pos], "]] ",
                            p.messaggio_stampa[pos], "'''", p.base_url[pos],
                           tostring(mw.uri.localUrl( p.collegamento[pos] )), "'''" })
        else
            text = table.concat({'* [[File:', p.icona[pos], '|link=', p.prefix[pos], '|',
                            p.dimensione_icona[pos],'|Collabora a ', p.nome_progetto[pos],
                            "]]", ' ', "'''[[", p.prefix[pos], '|', p.nome_progetto[pos],
                            "]]''' contiene ", p.oggetto[pos], ' ', p.lingua[pos],
                            p.preposizione[pos], add_space(p.preposizione[pos]), p.testo_prima[pos],
                            "'''[[",  p.prefix[pos], p.collegamento[pos], '|',
                            p.etichetta[pos], "]]'''", p.testo_dopo[pos] })
        end
    else
        text = table.concat({'* [[', p.prefix[pos], p.collegamento[pos], '|', p.nome_leftbar[pos] or p.nome_progetto[pos], ']]'})
    end
    return text
end

local function LinkRicette(intext, pos, in_stampa)
    -- Restituisce il link per le ricette su wikibook
    -- intext vero se è richiesto il link del testo principale, falso per la barra sinistra
    local p=progetti
    local text=''
    if intext then
        if in_stampa then
            text = table.concat({'* [[File:', p.icona[pos], '|',  p.dimensione_icona[pos], "]] ",
                            p.messaggio_stampa[pos], "'''", p.base_url[pos],
                           tostring(mw.uri.localUrl( p.prefix[pos] .. p.collegamento[pos] )), "'''" })
        else
            text = table.concat({'* [[File:', p.icona[pos], '|link=', p.prefix[pos], '|', p.dimensione_icona[pos],
                            '|Collabora a ', p.nome_progetto[pos],
                            "]] Il ''[[b:Libro di cucina|Libro di cucina]]'' di '''[[b:|Wikibooks]]''' contiene [[",  p.prefix[pos],
                            p.collegamento[pos], "|ricette]]", " relative a questo argomento." })
        end
    else
        text = table.concat({'* [[', p.prefix[pos], p.collegamento[pos], '|', p.nome_leftbar[pos] or p.nome_progetto[pos], ']]'})
    end
    return text
end


local function LinkWithLanguage(intext, pos, in_stampa)
    -- Restituisce il link verso progetti con interfaccia in lingua (seleziona automaticamente quella italiana)
    -- intext vero se è richiesto il link del testo principale, falso per la barra sinistra
    local p=progetti
    local text=''
    if intext then
        if in_stampa then
            text = table.concat({'* [[File:', p.icona[pos], '|',  p.dimensione_icona[pos], "]] ",
                            p.messaggio_stampa[pos], "'''", p.base_url[pos],
                            tostring(mw.uri.localUrl( p.collegamento[pos] )), "'''" })
        else
            main_page_link=tostring(mw.uri.fullUrl(p.prefix[pos] .. 'Pagina principale', {uselang='it'}))
            text = table.concat({'* [[File:', p.icona[pos], '|link=', main_page_link, '|',
                             p.dimensione_icona[pos], '|Collabora a ', p.nome_progetto[pos],
                            "]]", ' ',  "'''<span class=\"plainlinks\">[",
                            main_page_link, ' ', p.nome_progetto[pos], "]</span>''' contiene ",
                            p.oggetto[pos], ' ', p.preposizione[pos], add_space(p.preposizione[pos]),
                            p.testo_prima[pos], "'''<span class=\"plainlinks\">[",
                            tostring(mw.uri.fullUrl(p.prefix[pos] .. p.collegamento[pos], {uselang='it'})), ' ',
                            p.etichetta[pos], "]<span class=\"plainlinks\">'''", p.testo_dopo[pos] })
        end
    else
        text = table.concat({'* [', tostring(mw.uri.fullUrl(p.prefix[pos] .. p.collegamento[pos], {uselang='it'})),
                            ' ', p.nome_leftbar[pos] or p.nome_progetto[pos], ']'})
    end
    return text
end

local function LinkIncubator(intext, pos, in_stampa)
    -- Restituisce il link verso progetti per incubator
    local p=progetti
    local text=''
    local prefix = {
        wikipedia = 'Wp',
        wiktionary = 'Wt',
        wikizionario= 'Wt',
        wikibooks= 'Wb',
        wikinews= 'Wn',
        wikinotizie= 'Wn',
        wikiquote= 'Wq',
    }

    local oggetto = p.oggetto[pos]
    if not prefix[oggetto] then oggetto='wiktionary' end
    local collegamento = tostring(mw.uri.fullUrl(table.concat({'incubator:', prefix[oggetto],
                                        '/', p.collegamento[pos]}), {uselang='it'}))
    if intext then
        if in_stampa then
            text = table.concat({'* [[File:', p.icona[pos], '|',  p.dimensione_icona[pos], "]] ",
                            p.messaggio_stampa[pos], "'''", collegamento, "'''" })
        else
            local main_page_incubator=tostring(mw.uri.fullUrl(':incubator:Main_Page/it', {uselang='it'}))
            local main_page_progetto = ''
            if oggetto == 'wiktionary' then
                main_page_progetto = '[[w:Wiktionary|Wikizionario]]'
            else
                main_page_progetto = table.concat({'[[', oggetto, ':|', oggetto:gsub("^%l", string.upper), ']]'})
            end

            text = table.concat({'* [[File:', p.icona[pos], '|link=', main_page_incubator, '|',
                                 p.dimensione_icona[pos], "|Collabora a Incubator]] '''<span class=\"plainlinks\">[",
                                main_page_incubator, " Incubator]</span>''' contiene un test su ",
                                main_page_progetto, ' ',
                                p.preposizione[pos], add_space(p.preposizione[pos]),
                                '<span class="plainlinks">[', collegamento, ' ', p.etichetta[pos], ']</span>' })
        end
    else
        text = table.concat({'* [', collegamento, ' Incubator]'})
    end
    return text
end

function Link_vuoto(intext, pos)
    -- per il parametro notizia, non dovrebbe mai essere chiamato, ma giusto in caso restituisce
    -- una stringa vuota
    return ''
end

-- default_parameter: contiene i valori di default dei parametri
--   priorità: ordine di priorità in cui visualizzare il link (un numero intero)
--   funzione da richiamare per inserire i link
--   prefisso_progetto: prefisso da usare per i link del progetto
--   nome_progetto: nome del progetto
--   nome_leftbar: nome da usare per il collegamento nella barra di sinistra (falso se coincide con
--                   il nome del progetto, altrimenti una stringa, da usare per esempio per wikiricette)
--   logo del progetto: nome del file che contiene il logo del progetto
--   dimensioni del logo: dimensioni da usare per il logo
--   oggetto standard: per il contenuto ('opere originali', 'testi o manuali', ecc..).
--   preposizione standard: da mettere prima dell'etichetta ('di o su', 'relative a questo argomento', ecc..),
--                          se è false non viene sostituita
--   testo di apertura intorno all'etichetta: stringa vuota o testo da usare immediatamente prima del
--                                            collegamento (usate dal wikizionario per la virgoletta di
--                                              apertura e da wikiricette per non inserire niente)
--   testo di chiusura intorno all'etichetta: stringa vuota o testo di chiusura da usare immediatamente
--                                            dopo il collegamento (usate dal wikizionario per la virgoletta
--                                            di chiusura e da wikiricette per scrivere " relative a questo argomento")
--   lingua originale: lingua di un testo linkato (false se non è possibile impostarla,  true per
--                       i progetti per cui si può impostare.
--                     da usare per i progetti che prevedono l'inserimento di "in xxxxx" tra il nome
--                     del progetto e l'etichetta standard per il tipo di contenuto)

local default_parameter ={
    w =              {1, Link, 'w:', 'Wikipedia', false, 'Wikipedia-logo-v2.svg', '18px', 'una voce', 'riguardante', '', '', false, "'''Wikipedia''' contiene una voce riguardante", "http://it.wikipedia.org"},
    wikisource =     {2, Link, 'wikisource:', 'Wikisource', false, 'Wikisource-logo.svg', '18px', 'opere originali', 'di o su', '', '', false, "'''Wikisource''' contiene opere originali in inglese: ", 'http://en.wikisource.org'},
    s =              {3, Link, 's:', 'Wikisource', false, 'Wikisource-logo.svg', '18px', 'opere originali', 'di o su', '', '', true, "'''Wikisource''' contiene opere originali: ", "http://it.wikisource.org"},
    testo =          {4, Link, 's:', 'Wikisource', 'Testo completo', 'Wikisource-logo.svg', '18px', 'il testo completo', 'di o su', '', '', true, "'''Wikisource''' contiene opere originali: ", "http://it.wikisource.org"},
    wikiquote =      {5, Link, 'wikiquote:', 'Wikiquote', false, 'Wikiquote-logo.svg', '18px', 'citazioni', 'di o su', '', '' , false, "'''Wikiquote''' contiene citazioni in inglese: ", "http://en.wikiquote.org"},
    q =              {6, Link, 'q:', 'Wikiquote', false, 'Wikiquote-logo.svg', '18px',  'citazioni', 'di o su', '', '' , true, "'''Wikiquote''' contiene citazioni: ", "http://it.wikiquote.org"},
    wikibooks =      {8, Link, 'wikibooks:', 'Wikibooks', false, 'Wikibooks-logo.svg', '22px', 'testi o manuali', 'su', '', '' , false, "'''Wikibooks''' contiene testi o manuali: ", "http://en.wikibooks.org"},
    b =              {29, Link, 'b:', 'Wikibooks', false, 'Wikibooks-logo.svg', '22px', 'testi o manuali', 'su', '', '' , false, "'''Wikibooks''' contiene testi o manuali in inglese:", "http://it.wikibooks.org"},
    ricetta =        {10, LinkRicette, 'b:Libro di cucina/Ricette/', 'Wikibooks', 'Ricette', 'Wikibooks-logo.svg', '22px', '', '', '', '' , false, "'''Wikibooks''' contiene la ricetta: ", "http://it.wikibooks.org"},
    wiktionary =     {11, Link, 'wiktionary:', 'Wikizionario', false, 'Wiktionary small.svg', '18px', 'il lemma di dizionario', false, '«', '»', false, "'''Wikizionario''' contiene la voce di dizionario:", "http://it.wiktionary.org"},
    wikt =           {12, Link, 'wikt:', 'Wikizionario', false, 'Wiktionary small.svg', '18px', 'il lemma di dizionario', false, '«', '»', false, "'''Wikizionario''' contiene la voce di dizionario in inglese: ", "http://en.wiktionary.org"},
    v =              {17, Link, 'v:', 'Wikiversità', false, 'Wikiversity-logo-It.svg', '18px', 'informazioni', 'su', '', '', false, "'''Wikiversità''' contiene informazioni: ", "http://it.wikiversity.org"},
    wikinews =       {18, Link, 'wikinews:', 'Wikinotizie', false, 'Wikinews-logo.svg', '25px', 'notizie di attualità', 'su', '', '', false, "'''Wikinotizie''' contiene notizie di attualità in inglese: ", "http://en.wikinews.org"},
    n =              {19, Link, 'n:', 'Wikinotizie', false, 'Wikinews-logo.svg', '25px', 'notizie di attualità', 'su', '', '', false, "'''Wikinotizie''' contiene notizie di attualità: ", "http://it.wikinews.org"},
    commons =        {20, LinkWithLanguage, 'commons:', 'Commons', false, 'Commons-logo.svg', '18px', 'immagini o altri file', 'su', '', '', false, "'''Wikimedia Commons''' contiene file multimediali: ", "http://commons.wikimedia.org"},
    meta =           {22, LinkWithLanguage, 'meta:', 'Meta-Wiki', false, 'Wikimedia Community Logo.svg', '18px', 'informazioni', 'su', '', '', false, "'''Meta-Wiki''' contiene informazioni: ", "http://meta.wikimedia.org"},
    m =              {23, LinkWithLanguage, 'm:', 'Meta-Wiki', false, 'Wikimedia Community Logo.svg', '18px', 'informazioni', 'su', '', '', false, "'''Meta-Wiki''' contiene informazioni: ", "http://meta.wikimedia.org"},
    wikispecies =    {24, LinkWithLanguage, 'wikispecies:', 'Wikispecies', false, 'WikiSpecies notext.svg', '21px', 'informazioni', 'su', '', '', false, "'''Wikispecies''' contiene informazioni: ", "http://species.wikimedia.org"},
    incubator =      {30, LinkIncubator, 'incubator:', 'Incubator', false, 'Incubator-notext.svg', '18px', '[[wikipedia]]', 'in', '', '', false, " '''Wikimedia''' Incubator contiene un test: ", "http://incubator.wikimedia.org"},
    notizia =        {0,  Link_vuoto, 'n:', 'Wikinotizie', false, 'Wikinews-logo.svg', '25px', '', '', ': ', '', false, "'''Wikinotizie''' contiene notizie di attualità: ", 'http://it.wikinews.org'},
}

local serial_parameter = {
    w = 'w',
    wiktionary = 'wiktionary',
    commons = 'commons',
    s = 's',
    q = 'wikiquote',
}
-- nota oldwikisource rimosso, stando a http://toolserver.org/~kolossos/templatetiger/template-parameter.php?template=interprogetto&lang=itwiki non usato

local function sort_by_first(t1, t2)
    -- per ordinare una tabella in base al valore del primo elemento della tabella
    if t1[1] < t2[1] then
        return true
    end
end

local function RenderLeftBar(naked)
    -- Crea la barra di sinistra con i link interprogetto
    -- costruisce le righe per la barra di sinistra
    -- Se 'naked' è falso o non viene specificato i link vengono inseriti
    -- all'interno di un tag "div" id="interProject" (vedi [[Mediawiki:Monobook.js]] o [[Mediawiki:Vector.js]])
    -- Se 'naked' è vero allora vengono inseriti i soli link


    naked = naked or false
    local leftbar
    if naked then
        leftbar = HtmlBuilder.create()
    else
        leftbar = HtmlBuilder.create('div').attr('title', 'Collegamenti verso gli altri progetti Wikimedia')
    end
    for i = 1, #progetti.ordine do
        local pos = progetti.ordine[i][2]
        local link =progetti.link[pos]
        leftbar.newline().wikitext(link(false, pos))
        if progetti.nome_leftbar[pos] then
            leftbar.wikitext(table.concat({'<br />(', progetti.nome_progetto[pos], ')'}))
        end

    end
    if naked then
        root
            .node(leftbar)
    else
        root
        .tag('div')
            .attr('id', 'interProject')
            .cssText('display:none; clear: both; border-top: 2px dotted #AAAAAA; margin-top: 2em')
            .node(leftbar)
    end
end

local function RenderLinksInText(in_stampa)
    -- Scandisce la tabella progetti e produce il codice html per l'elenco puntato
    for i = 1, #progetti.ordine  do
        local pos = progetti.ordine[i][2]
        root.newline()
        local link=progetti.link[pos]
        root.wikitext(link(true, pos, in_stampa))
    end
end

function p.interprogetto(frame)
    local origArgs
    -- Se chiamata mediante  #invoke, usa gli argomenti passati al template invocante.
    -- Altrimenti a scopo di test assume che gli argomenti siano passati direttamente
    if frame == mw.getCurrentFrame() then
        origArgs = frame:getParent().args
    else
        origArgs = frame
    end

    local in_stampa = false
    if frame.args['stampa'] then
        in_stampa = true
    end

    -- Carico i parametri
    local current_page = mw.title.getCurrentTitle()
    local current_title = current_page.fullText
    local etichetta = origArgs.etichetta or current_page.text
    local preposizione = origArgs.preposizione
    local oggetto = origArgs.oggetto

    progetti ={
        ordine = {},
        link     = {},
        prefix   = {},
        nome_progetto = {},
        nome_leftbar = {},
        collegamento = {},
        etichetta = {},
        icona = {},
        dimensione_icona = {},
        oggetto = {},
        preposizione = {},
        testo_prima = {},
        testo_dopo = {},
        lingua = {},
        messaggio_stampa = {},
        base_url = {}

    }
    local pos = 0
    local notizia_presente = false
    local incubator_without_value = false
    -- Scandisco tutti gli argomenti per costruire una tabella in cui ad ogni riga corrisponde un link
    -- a un altro progetto con le opzioni che sono state settate per quel progetto
    for k, collegamento in pairs(origArgs) do
        -- controlla se è un parametro posizionale e in questo caso usa il suo valore come nome del
        -- progetto a cui puntare, con pagina corrispondente a quella  della pagina corrente
        -- in cui è inserito il template
        if collegamento == nil then collegamento = "" end
        if tonumber(k) then
            k = mw.text.trim(collegamento) -- elimino eventuali spazi iniziali e finali
            collegamento = ''
            if k == 'incubator' then
                k = ''
                incubator_without_value = true -- se incubator non è valorizzato loggo l'errore
            end
        end
        -- testo se è un parametro seriale e in questo caso loggo il numero di indice
        local parameter_index = string.match(k, '%d')
        local offset_ordine = 0
        if parameter_index then
            local base_k = string.gsub(k, '%d', '')
            if serial_parameter[base_k] then
                k = serial_parameter[base_k]
                offset_ordine = tonumber(parameter_index) * 100
                if collegamento == "" then
                    collegamento = origArgs['collegamento' .. parameter_index] or current_title
                end
            else
                parameter_index = ""
            end
        else
            parameter_index = ""
        end
        if collegamento == '' then collegamento = current_title end
        -- se k corrisponde a un progetto inserito in default_parameter aggiungo una riga alla tabella
        -- progetti con i parametri da usare per visualizzare i collegamenti
        if default_parameter[k] then
            pos = pos+1
            progetti.ordine[pos] = {default_parameter[k][1]+offset_ordine, pos}
            progetti.link[pos] = default_parameter[k][2]
            progetti.prefix[pos] =  default_parameter[k][3]
            progetti.nome_progetto[pos] = default_parameter[k][4]
            progetti.nome_leftbar[pos] = origArgs[k .. parameter_index .. '_etichetta_lb'] or
                                         origArgs['etichetta_lb' .. parameter_index] or default_parameter[k][5]
            progetti.collegamento[pos] = collegamento
            progetti.etichetta[pos] =  origArgs[k .. parameter_index .. '_etichetta'] or
                                       origArgs['etichetta' .. parameter_index] or etichetta
            progetti.icona[pos] = default_parameter[k][6]
            progetti.dimensione_icona[pos] = default_parameter[k][7]
            progetti.oggetto[pos]  = origArgs[k .. parameter_index .. '_oggetto'] or
                                     origArgs['oggetto' .. parameter_index] or oggetto or
                                     default_parameter[k][8]
            if default_parameter[k][9] then
                progetti.preposizione[pos] = origArgs[k .. parameter_index .. '_preposizione'] or
                                             origArgs['preposizione' .. parameter_index] or
                                             preposizione or default_parameter[k][9]
            else
                progetti.preposizione[pos] = ''
            end
            progetti.testo_prima[pos] = default_parameter[k][10]
            progetti.testo_dopo[pos] = default_parameter[k][11]
            if k=='notizia' then
                notizia_presente = true
                if origArgs.data then
                    progetti.testo_dopo[pos] = table.concat({' <small>', origArgs.data, '</small>'})
                end
            end
            if default_parameter[k][12] and origArgs[k .. parameter_index .. '_lingua'] then
                progetti.lingua[pos] = table.concat({' in lingua ', origArgs[k ..'_lingua'], ' '})
            else
                progetti.lingua[pos] = ' '
            end
            progetti.messaggio_stampa[pos] = default_parameter[k][13]
            progetti.base_url[pos] = default_parameter[k][14]
        end
    end
    root = HtmlBuilder.create()
    local noleftbar = origArgs['noleftbar'] or false
    local naked = origArgs['naked'] or false
    if notizia_presente then -- gestisco il parametro "notizia" a parte
        if #progetti.ordine>1 then
            root.wikitext('<strong class="error">Errore: il parametro "notizia" se presente deve essere unico</strong>[[categoria:Errori del template Interprogetto]]')
        else
            if in_stampa then
                root.wikitext(table.concat({'* [[File:', progetti.icona[1], '|', progetti.dimensione_icona[1],
                           "]] ", progetti.messaggio_stampa[1], "'''", progetti.base_url[1],
                           tostring(mw.uri.localUrl(progetti.collegamento[1] )), "'''"  }))
            else
                root.wikitext(table.concat({'* [[File:', progetti.icona[1], '|link=', progetti.prefix[1], '|',
                             progetti.dimensione_icona[1],'|Collabora a ', progetti.nome_progetto[1],
                            "]]", " Articolo su '''[[", progetti.prefix[1], progetti.nome_progetto[1], '|',
                            progetti.nome_progetto[1], "]]''': ", "'''[[",  progetti.prefix[1],
                            progetti.collegamento[1], '|', progetti.collegamento[1], "]]'''", progetti.testo_dopo[1] }))
            end
        end
    else
        if #progetti.ordine > 0 then
            table.sort(progetti.ordine, sort_by_first)
            if not(in_stampa or noleftbar) then RenderLeftBar(naked) end
            if not(origArgs[1]) or mw.text.trim(origArgs[1])~= 'nolink'  then
                RenderLinksInText(in_stampa)
            end
        end
    end
    if incubator_without_value  then
        root.wikitext('<strong class="error">Errore: il parametro "incubator" deve essere valorizzato</strong>[[categoria:Errori del template Interprogetto]]')
    end
    return tostring(root)
end

function p.openleftbar()
    -- ritorna il codice css di apertura all'interno del quale vengono inseriti i link che vanno nella
    -- barra di sinistra
    return '<div id="interProject" style="display:none; clear: both; border-top: 2px dotted #AAAAAA; margin-top: 2em"><div title="Collegamenti verso gli altri progetti Wikimedia">'
end

function p.closeleftbar()
    -- ritorna il codice css di chiusura dei link della barra sinistra
    return '</div></div>'
end

return p