La documentacion d'utilizacion d'aquel modul se pòt crear a Mòdul:Demografia/ús

--[[
  Modul que repren las foncionalitats del modèl Demografia.

  Version pas protegida per tèsts
--]]

local p = {} -- lo modul

-- lista dels paramètres reconeguts (valor = nom de la variabla)
p.parametres = {
  ["títol"] = "títol",
  ["carta"]= "carta",
  ["colomnas"]= "colomnas",
  ["largortablèu"] = "largor_tablèu",
  ["nòtas"] = "nòtas",
  ["font"] = "font",
  ["fonts"] = "fonts",
  ["flotant"] = "flotant",
  ["marge-interlinhas"] = "marge_interlinhas",
  ["talha-poliça"] = "talha_poliça",
  ["nautor-linhas"] = "nautor_linhas",
  ["iperligams-annadas"] = "iperligams_annadas",
  ["annadas-fons"] = "annadas_fon",
  ["populacion-fons"] = "populacion_fons",
  ["nòtas-fons"] = "nòtas_fons",
  ["estil-nòtas"] = "estil_nòtas",
  ["senscomptesdobles"] = "senscomptesdobles",
  ["enquèstaannadièra"] = "enquèstaannadièra"
}


-- table des chartes reconnues, avec leurs code couleur
p.chartes = {
  ["comuna"]          = { ["normal"] = "ddffdd", ["contraste"] = "b2e5b2" },
  ["intercomunalitat"] = { ["normal"] = "ffe2bf", ["contraste"] = "fbbf77" },
  ["canton"]           = { ["normal"] = "ece5ca", ["contraste"] = "d4c68d" },
  ["arrondiment"]   = { ["normal"] = "e1e1e1", ["contraste"] = "b1b1b1" },
  ["departament"]      = { ["normal"] = "f6f3dd", ["contraste"] = "d8d2bc" },
  ["region"]           = { ["normal"] = "bbdefd", ["contraste"] = "58abf4" },
  ["defaut"]           = { ["normal"] = "ddffdd", ["contraste"] = "b2e5b2" }
}


-- lo nom de la categoria d'error (per simplificar los cambiaments)
p.categorie_erreur = "Pagina amb una error d'utilizacion del modèl Demografia"

-- lo títol per defaut (per simplificar los cambiaments) → mai utilizat : i a pas mai de títol per defaut
p.titre_par_defaut = "Évolution démographique"


--[[
  Foncion exportada que repren lo foncionament de {{m|Carta de color}}
--]]
function p.carta_de_color(frame)
    local pframe = frame:getParent()
    
    -- los dos paramètres
    local nom = mw.ustring.lower(mw.text.trim(pframe.args[1] or ""))
    local code = mw.ustring.lower(mw.text.trim(pframe.args[2] or ""))
    
    -- pas de nom o pas reconegut → per defaut
    if (nom == "" or (nom ~= "comunas" and nom ~= "comunas contraste")) then
        return "ffffff"
    end

    -- lo selector de color
    local sel
    if (nom == "comunas") then
        sel = "normal"
    else
        sel = "contraste"
    end
    
    -- abséncia del còde → defaut
    if (code == "") then
        code = "defaut"
    end
    -- se verifica que lo còde existís
    if (p.chartes[code] == nil) then
        code = "defaut" -- idem, per defaut
    end
    -- se torna la color
    return p.chartes[code][sel]
end


--[[
  Inserís una categoria d'error
--]]
p.liste_erreurs = {}
p.liste_cats = {}
function p.erreur(message, cle)
    table.insert(p.liste_erreurs, message)
    table.insert(p.liste_cats, cle)
end


--[[
  Foncion de recuperacion d'un paramètre nomenat.
--]]
function p.lit_parametre(nom, pasvide)
    if (type(nom) ~= "string") then
        return nil -- pas un paramètre nomenat
    end
    local temp = p.frame.args[nom] or p.pframe.args[nom] -- del modèl, puèi de l'article
    if (temp ~= nil) then
        if (pasvide) then
            temp = mw.text.trim(temp)
            if (temp == "") then
                return nil
            else
                return temp
            end
        else
            return mw.text.trim(temp)
        end
    else
        return nil
    end
end

--[[
  Foncion de triada de la taula
--]]
function p.mysort(el1, el2)
    if (el1 == nil) then
        return true
    end
    if (el2 == nil) then
        return false
    end
    if (el1[1] < el2[1]) then
        return true
    else
        return false
    end
end


--[[
  Tracta una color HTML, en apondent lo # eventual
--]]
function p.couleur(nom)
    if (nom == "" or nom == nil or type(nom) ~= "string") then
        return nom
    end
    if (mw.ustring.sub(nom, 1, 1) ~= "#") then
        return "#" .. nom
    else
        return nom
    end
end

--[[
  Suprimís lo primièr retorn a la linha (eventual) de fòrma <br/>
--]]
function p.sans_nl(texte)
    if (texte == nil or texte == "" or type(texte) ~= "string") then
        return texte
    end
    return mw.ustring.gsub(texte, "[<][bB][rR][ ]*[/][>]", "", 1)
end

--[[
  Foncion principala
--]]
function p.demographie(frame)
    -- per simplificar s'emmagazina la frame e la pframe en global
    p.frame = frame
    p.pframe = frame:getParent()
    
    -- pm es la taula dels parametres → se legís totes los paramètres referenciats
    local pm = {}
    for k, v in pairs(p.parametres) do
        pm[v] = p.lit_parametre(k, true)
    end
    
    -- títol per defaut
    --[[
    if (pm.titre == "off" or pm.titre == "non") then
        pm.titre = nil
    elseif (pm.titre == nil) then
        pm.titre = p.titre_par_defaut
    end
    --]]
    -- modificacion : ara lo títol es vertadièrament opcional
    if (pm.titre == "") then
        pm.titre = nil
    end
    
    -- valor marge interlinhas
    if (pm.marge_interlignes == nil) then
        pm.marge_interlignes = "5px"
    else
        -- las valors tròp pichonas
        if (pm.marge_interlignes == "0" or pm.marge_interlignes == "0em" or pm.marge_interlignes == "0.1em" or pm.marge_interlignes == "0px" or
             pm.marge_interlignes == "1px" or pm.marge_interlignes == "2px" or pm.marge_interlignes == "3px" or pm.marge_interlignes == "4px") then
            pm.marge_interlignes = "5px"
        end
    end

    -- valor efectiva del flotant
    local vflottant = 'margin: 0 auto' -- valeur par défaut
    if (mw.ustring.lower(pm.flottant or "") == "gauche") then
        vflottant = 'float:left; margin: 0 1em 1em 0'
    elseif (mw.ustring.lower(pm.flottant or "") == "droite") then
        vflottant = 'float:right; margin: 0 0 1em 1em'
    end

    if (pm.hauteur_lignes == nil) then
        pm.hauteur_lignes = ""
    else
        pm.hauteur_lignes = "line-height:" .. pm.hauteur_lignes .. ";"
    end
    pm.taille_police = (pm.taille_police or "100%") -- valor per defaut talha poliça
    if (pm.notes_fond ~= nil) then
        pm.notes_fond = "background: " .. p.couleur(pm.notes_fond) .. ";"
    else
        pm.notes_fond = ""
    end
    local parenthese = false
    if (pm.style_notes == "gauche") then
        pm.style_notes = 'border: 1px solid #aaa; text-align:left;'
    else
        pm.style_notes = 'border: 0; border-width: 0;'
        parenthese = true
    end

    -- valeur par défaut lien
    if (pm.hyperliens_annees == nil) then
        pm.hyperliens_annees = false
    else
       -- validation valeur
        if (pm.hyperliens_annees == "on" or pm.hyperliens_annees == "oui") then
            pm.hyperliens_annees = true
        else
            pm.hyperliens_annees = false -- toute valeur autre que "on" = "off"
        end
    end
    -- valors per defaut de las colomnas
    if (pm.colonnes == nil) then
        pm.colonnes_par_defaut = true
        pm.colonnes = 9
    else
        pm.colonnes = tonumber(pm.colonnes) -- per que siá un nombre
    end
    -- se valida las colomnas
    if (type(pm.colonnes) ~= "number" or pm.colonnes < 1) then
        -- colomna erronèa : error
        p.erreur("La valor del paramètre ''colomnas'' (" .. (pm.colonnes or "<pas un nombre>") .. ") es pas valida", "nombre de colomnas")
        pm.colonnes = 9
    end
    -- largor per defaut : 5.4em * colomnas
    if (pm.largeur_tableau == nil) then
        pm.largeur_tableau = pm.colonnes*5.4 .. "em"
        pm.largeur_tableau_par_defaut = true
    end
    if (pm.charte == nil) then
        pm.charte = "defaut"
    else
        -- se valida la carta
        pm.charte = mw.ustring.lower(pm.charte)
        if (p.chartes[pm.charte] == nil) then
            -- carta desconeguda : error
            p.erreur("La valor del paramètre ''carta'' (" .. pm.charte .. ") es pas valida", "carta")
            pm.charte = "defaut" -- valor per defaut
        end
    end
    -- se recupèra las colors de la carta levat se indicadas
    local coul_annees = (pm.annees_fond or p.chartes[pm.charte]["normal"])
    local coul_valeurs = (pm.population_fond or nil) -- valor per defaut = pas res
    -- apondon del # se absent
    coul_annees = p.couleur(coul_annees)
    if (coul_valeurs == nil) then
        coul_valeurs = ""
    else
        coul_valeurs = 'style="background:' .. coul_valeurs .. ';"'
    end

    -- extraccion dels elements de la taula, recaptats dins una "vertadièra" taula per los triar
    local tbl = {}
    for annee, valeur in pairs(p.pframe.args) do
        -- ia tanben los paramètres nomenats dins aquesta taula, que se daissa
        if (type(annee) == "number") then
            if (type(valeur) == "string") then
                valeur = mw.text.trim(valeur)
            end
            table.insert(tbl, {annee,valeur})
        else
            -- se profiècha d'aquesta bocla per verificar los paramètres qu'existisson pas
            local tst = p.parametres[annee]
            if (tst == nil) then
                -- cas particular : los paramètres jos la forma "XXXX nòtas" e "XXXX unitat" son acceptats
                local tst = mw.ustring.match(annee, "^[0-9]+ notes$") or mw.ustring.match(annee, "^[0-9]+ unité$") or mw.ustring.match(annee, "^[0-9]+ afichatge$")
                -- autre : s'ignòra tanben los paramètres voids (pb de transmission d'autres modèls)
                local temp = mw.text.trim(annee)
                if (tst == nil and temp ~= "") then -- pas un paramètre conegut ni XXXX nòtas → error
                    p.erreur("Lo paramètre ''>>" .. annee .. "<<'' (" .. mw.ustring.len(annee) .. "/" .. mw.ustring.len(temp) .. " es desconegut", "paramètre desconegut")
                    -- s'ignòra simplament aqueste camp
                end
            end
        end
    end
    -- triada de la taula
    table.sort(tbl, p.mysort)

    -- aqueste còp se percor l'estructura de las infos
    local ret = ""
    local odebug = "" -- sortida de debug

    -- se percor las donadas (annadas) per generar la taula estructurada
    local col = 1
    local ligne = 1
    local struct = {}
    table.insert(struct, {}) -- se crèa la primièra linha
    local total = 0 -- compte del nombre total
    local pos = 1
    while (tbl[pos] ~= nil) do
        annee = tbl[pos][1]
        valeur = tbl[pos][2]
        pos = pos + 1
        -- il y a aussi les paramètres nommés dans cette table, qu'on laisse
        if (type(annee) == "number" and not (annee == 1 and (valeur == nil or valeur == ""))) then -- protection : un paramètre non nommé vaudra "1"
            -- nettoyage de la valeur
            local v = mw.text.trim(valeur or "")
            -- on insert dans la ligne en cours
            table.insert(struct[ligne], { annee, v })
            
            -- suivant
            total = total + 1
            col = col + 1
            -- fin de la ligne ?
            if (col > pm.colonnes) then
                col = 1
                ligne = ligne + 1
                table.insert(struct, {})
            end
        end
    end
    -- aucune entrée ? erreur.
    if (total == 0) then
        p.erreur("Cap d'annada pas provesida al modèl", "abséncia d'annadas")
        -- on insert une donnée fictive
        tbl[1] = { 1970, 0 }
    end
    -- cas particulier : si les données arrivent pile à la dernière colonne on a alors
    -- une nouvelle ligne vide, pour rien. On l'enlève si c'est le cas
    if (struct[ligne] ~= nil and struct[ligne][1] == nil) then
        struct[ligne] = nil
        ligne = ligne - 1
    end
    -- on traite la largeur
    if (pm.colonnes_par_defaut == true and ligne == 1 and total < pm.colonnes) then
        pm.colonnes = total  -- restriction du nombre de colonnes au nombre réel d'éléments
        -- il faut aussi recalculer la largeur totale : on fait le rapport entre 9 (ancien) et le nouveau nombre de colonnes
        if (pm.largeur_tableau_par_defaut == true) then
            -- uniquement si l'utilisateur n'a pas fixé la taille
            pm.largeur_tableau = pm.colonnes*5.4 .. "em"
        end
    end

    -- on récupère le "langage" courant pour utiliser formatnum
    local lang = mw.language.getContentLanguage()

    -- on récupère le namespace
    local ttl = mw.title.getCurrentTitle().namespace


    -- création du div principal
    ret = ret .. '<div class="wikitable centre overflow" align="center" style="overflow:hidden; width: ' .. pm.largeur_tableau .. '; ' .. vflottant .. ';padding-left:1px;padding-right:1px;">'

    ligne = 1
    -- boucle sur les lignes
    while (struct[ligne] ~= nil) do
        -- une ligne à faire, on crée le tableau
        if (ligne == 1) then
            ret = ret .. '<table class="wikitable" style="table-layout:fixed;width:100%;text-align:center;margin-top: 1px; ' .. pm.hauteur_lignes .. 'margin-bottom: 0;font-size:' .. pm.taille_police .. ';">\n'
        else
            ret = ret .. '<table class="wikitable" style="table-layout:fixed;width:100%;text-align:center;margin-top:' .. pm.marge_interlignes .. '; ' .. pm.hauteur_lignes .. 'margin-bottom: 0;font-size:' .. pm.taille_police .. ';">\n'
        end
        -- si titre présent on l'ajoute : visible si 1ère ligne, caché sinon
        if (pm.titre ~= nil and pm.titre ~= "") then
            if (ligne == 1) then
                ret = ret .. '<caption style="margin-bottom:' .. pm.marge_interlignes .. ';"><b>' .. pm.titre .. '</b></caption>'
            else
                ret = ret .. '<caption class="hidden">' .. pm.titre .. ", suite (" .. ligne-1 .. ')</caption>'
            end
        else
            -- titre par défaut, caché
            ret = ret .. '<caption class="hidden">' .. p.titre_par_defaut .. ' (ligne ' .. ligne .. ')</caption>'
        end
        -- parcours des colonnes pour insérer les années
        col = 1
        ret = ret .. "<tr>\n"
        while (struct[ligne][col] ~= nil) do
            -- présence de AAAA affichage ?
            local temp = p.pframe.args[struct[ligne][col][1] .. " affichage"]
            if (temp ~= nil) then
                -- on affiche l'élément indiqué à la place
                ret = ret .. '<th scope="col" style="background-color: ' .. coul_annees .. ';">' .. temp .. '</th>\n'
            else
                if (pm.hyperliens_annees) then
                    ret = ret .. '<th scope="col" style="background-color: ' .. coul_annees .. ';">[[' .. struct[ligne][col][1] .. ']]</th>\n'
                else
                    ret = ret .. '<th scope="col" style="background-color: ' .. coul_annees .. ';">' .. struct[ligne][col][1] .. '</th>\n'
                end
            end
            col = col + 1
        end
        -- si on n'a pas terminé les colonnes on termine avec du vide
        if (col <= pm.colonnes) then
            while (col <= pm.colonnes) do
                ret = ret .. '<th scope="col" style="background-color: ' .. coul_annees .. ';">-</th>\n'
                col = col + 1
            end
        end
        ret = ret .. "</tr>\n"
        -- parcours des colonnes pour insérer les valeurs
        col = 1
        ret = ret .. "<tr>\n"
        while (struct[ligne][col] ~= nil) do
            if (struct[ligne][col][2] == "" or struct[ligne][col][2] == nil) then
                ret = ret .. '<td ' .. coul_valeurs .. '>-</td>'
            else
                -- on récupère la partie numérique au début
                local pdeb = mw.ustring.match(struct[ligne][col][2], "^[0-9]*")
                local pfin = mw.ustring.match(struct[ligne][col][2], "^[0-9]*(.*)$")
                local tmp = ""
                -- si le début est présent il passe par formatnum
                if (pdeb ~= nil and pdeb ~= "") then
                    tmp = tmp .. lang:formatNum(tonumber(pdeb))
                end
                -- on ajoute la suite (éventuelle)
                if (pfin ~= nil and pfin ~= "") then
                    tmp = tmp .. pfin
                end
                -- si un paramètre "XXXX unité" existe on l'insert
                local unite = p.pframe.args[struct[ligne][col][1] .. " unitat"]
                if (unite ~= nil) then
                    tmp = tmp .. " " .. unite
                end
                -- si un paramètre "XXXX notes" existe on l'insert en tant que note
                local note = p.pframe.args[struct[ligne][col][1] .. " nòtas"]
                if (note ~= nil) then
                    -- test : on regarde si la note est déjà une ref (pour insérer une espace ou pas avant)
                    local estref = mw.text.unstrip(note)
                    -- si 'estref' = 'note' c'est un "pur" texte → ajout espace
                    if (estref == note) then
                        tmp = tmp .. " "
                    else
                        -- sinon on regarde si c'est une ref
                        local tst = mw.ustring.find(estref, '<a href="#cite', 1, true)
                        if (not tst) then
                            -- pas une ref, on ajoute l'espace
                            tmp = tmp .. " "
                        end
                    end
                    tmp = tmp .. note
                end
                ret = ret .. '<td ' .. coul_valeurs .. '>' .. tmp .. '</td>'
            end
            
            col = col + 1
        end
        -- si on n'a pas terminé les colonnes on termine avec du vide
        if (col <= pm.colonnes) then
            while (col <= pm.colonnes) do
                ret = ret .. '<td ' .. coul_valeurs .. '>-</td>'
                col = col + 1
            end
        end
        ret = ret .. "</tr>\n"
        -- fermeture table
        ret = ret .. "</table>\n"
        ligne = ligne + 1
    end
    
    -- si pas encyclo + présence d'erreur on l'ajoute aux notes
    local erreurs = nil
    if (ttl ~= 0 and p.liste_erreurs[1] ~= nil) then
        erreurs = "<span class=\"error\" style=\"font-size: 0.9em;\">Liste des erreurs :<br/>"
        local i = 1
        while (p.liste_erreurs[i] ~= nil) do
            erreurs = erreurs .. "• " .. p.liste_erreurs[i]
            if (p.liste_erreurs[i+1] ~= nil) then
                erreurs = erreurs .. "<br/>"
            end
            i = i + 1
        end
        erreurs = erreurs .. "</span>"
    end

    
    -- gestion des notes et sources
    if (pm.notes ~= nil or pm.source ~= nil or pm.sources ~= nil or pm.sansdoublescomptes ~= nil or pm.enqueteannuelle ~= nil or erreurs ~= nil) then
        local pred = false
        ret = ret .. '<div style="padding: 0.3em; margin: 6px 0; line-height: 150%; font-size: 0.9em; ' .. pm.notes_fond .. ' ' .. pm.style_notes .. '">'
        -- le double-compte si présent
        if (pm.sansdoublescomptes ~= nil) then
            -- si présent on retire le saut de ligne
            pm.sansdoublescomptes = p.sans_nl(pm.sansdoublescomptes)
           ret = ret .. "Nombre retengut a partir de [[" .. pm.sansdoublescomptes .. "]] : [[Chifras de populacion de França|populacion sens comptes dobles]]."
           pred = true
        end
        if (pm.enqueteannuelle ~= nil) then
            -- si présent on retire le saut de ligne
            pm.enqueteannuelle = p.sans_nl(pm.enqueteannuelle)
            if (pred) then
                ret = ret .. "<br/>"
            end
            ret = ret .. "[[" .. pm.enqueteannuelle .. "]] : Populacion provisòria (enquèsta annadièra)."
            pred = true
        end
        -- on ajoute les notes si présentes
        if (pm.notes ~= nil) then
            if (pred) then
                ret = ret .. "<br/>"
            end
            -- si présent on retire le saut de ligne
            pm.notes = p.sans_nl(pm.notes)
            ret = ret .. pm.notes
            pred = true
        end
        -- sources si présentes
        if (pm.source ~= nil or pm.sources ~= nil) then
            if (pred) then
                ret = ret .. "<br/>"
            end
            pred = true
            -- si on a source et sources on met tout dans sources
            if (pm.source ~= nil and pm.sources ~= nil) then
                pm.sources = pm.source .. " " .. pm.sources
                pm.source = nil
            end
            if (pm.sources ~= nil) then
                -- si présent on retire le saut de ligne
                pm.sources = p.sans_nl(pm.sources)
            end
            if (pm.source ~= nil) then
                -- si présent on retire le saut de ligne
                pm.source = p.sans_nl(pm.source)
            end
            local tmp
            if (pm.sources ~= nil) then
                tmp = "Fonts : " .. pm.sources
            else
                tmp = "Font : " .. pm.source
            end
            if (parenthese) then
                ret = ret .. "(" .. tmp .. ")"
            else
                ret = ret .. tmp
            end
        end
    
        -- on ajoute les erreurs si présentes
        if (erreurs ~= nil) then
            if (pred) then
                ret = ret .. "<br/>"
            end
            ret = ret .. erreurs
        end
        -- on ferme la div des notes
        ret = ret .. '</div>'        
    end

    -- on ferme la div principale
    ret = ret .. "</div>\n"

    -- si namespace encyclo (ttl = 0) on insert les catégories d'erreur
    if (ttl == 0) then
        local i = 1
        while (p.liste_cats[i] ~= nil) do
            ret = ret .. "[[Categoria:" .. p.categorie_erreur .. "|" .. p.liste_cats[i] .. "]]"
            i = i + 1
        end
    end

    -- se torna lo resultat
    return ret
end



return p -- se torna lo modul