Utilisateur:Automatik/bac à sable/Module:Démographie - Wikiwand
For faster navigation, this Iframe is preloading the Wikiwand page for Utilisateur:Automatik/bac à sable/Module:Démographie.

Utilisateur:Automatik/bac à sable/Module:Démographie

--[[

 Module reprenant les fonctionnalités du modèle Démographie.
 Version non protégée pour tests

--]]

local p = {} -- le module

-- liste des paramètres reconnus (valeur = nom de la variable) p.parametres = {

 ["titre"] = "titre",
 ["charte"] = "charte",
 ["colonnes"] = "colonnes",
 ["largeur-tableau"] = "largeur_tableau",
 ["notes"] = "notes",
 ["source"] = "source",
 ["sources"] = "sources",
 ["flottant"] = "flottant",
 ["marge-interlignes"] = "marge_interlignes",
 ["taille-police"] = "taille_police",
 ["hauteur-lignes"] = "hauteur_lignes",
 ["hyperliens-années"] = "hyperliens_annees",
 ["années-fond"] = "annees_fond",
 ["population-fond"] = "population_fond",
 ["notes-fond"] = "notes_fond",
 ["style-notes"] = "style_notes",
 ["sansdoublescomptes"] = "sansdoublescomptes",
 ["enquêteannuelle"] = "enqueteannuelle"

}


-- table des chartes reconnues, avec leurs code couleur p.chartes = {

 ["commune"]          = { ["normal"] = "ddffdd", ["contraste"] = "b2e5b2" },
 ["intercommunalité"] = { ["normal"] = "ffe2bf", ["contraste"] = "fbbf77" },
 ["canton"]           = { ["normal"] = "ece5ca", ["contraste"] = "d4c68d" },
 ["arrondissement"]   = { ["normal"] = "e1e1e1", ["contraste"] = "b1b1b1" },
 ["département"]      = { ["normal"] = "f6f3dd", ["contraste"] = "d8d2bc" },
 ["région"]           = { ["normal"] = "bbdefd", ["contraste"] = "58abf4" },
 ["défaut"]           = { ["normal"] = "ddffdd", ["contraste"] = "b2e5b2" }

}


-- le nom de la catégorie d'erreur (pour simplifier les changements) p.categorie_erreur = "Page avec une erreur d'utilisation du modèle Démographie"

-- le titre par défaut (pour simplifier les changements) → plus utilisé : il n'y a plus de titre par défaut p.titre_par_defaut = "Évolution démographique"


--[[

 Fonction exportée reprenant le fonctionnement de ((Charte de couleur))

--]] function p.charte_de_couleur(frame)

   local pframe = frame:getParent()
   
   -- les deux 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 ou non reconnu → par défaut
   if (nom == "" or (nom ~= "communes" and nom ~= "communes contraste")) then
       return "ffffff"
   end
   -- le sélecteur de couleur
   local sel
   if (nom == "communes") then
       sel = "normal"
   else
       sel = "contraste"
   end
   
   -- absence du code → défaut
   if (code == "") then
       code = "défaut"
   end
   -- on vérifie que le code existe
   if (p.chartes[code] == nil) then
       code = "défaut" -- idem, par défaut
   end
   -- on retourne la couleur
   return p.chartes[code][sel]

end


--[[

 Insert une catégorie d'erreur

--]] p.liste_erreurs = {} p.liste_cats = {} function p.erreur(message, cle)

   table.insert(p.liste_erreurs, message)
   table.insert(p.liste_cats, cle)

end


--[[

 Fonction de récupération d'un paramètre nommé.

--]] function p.lit_parametre(nom, pasvide)

   if (type(nom) ~= "string") then
       return nil -- pas un paramètre nommé
   end
   local temp = p.frame.args[nom] or p.pframe.args[nom] -- du modèle, puis 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

--[[

 Fonction de tri de la table

--]] 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


--[[

 Traite une couleur HTML, en ajoutant le # éventuel

--]] 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

--[[

 Supprime le premier retour à la ligne (éventuel) de forme 

--]] 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

--[[

 Fonction principale

--]] function p.demographie(frame)

   -- pour simplifier on stocke la frame et la pframe en global
   p.frame = frame
   p.pframe = frame:getParent() or p.frame
   
   -- pm est la table des parametres → on lit tous les paramètres référencés
   local pm = {}
   for k, v in pairs(p.parametres) do
       pm[v] = p.lit_parametre(k, true)
   end
   
   -- titre par défaut
   --[[
   if (pm.titre == "off" or pm.titre == "non") then
       pm.titre = nil
   elseif (pm.titre == nil) then
       pm.titre = p.titre_par_defaut
   end
   --]]
   -- modification : maintenant le titre est réellement optionnel
   if (pm.titre == "") then
       pm.titre = nil
   end
   
   -- valeur marge interlignes
   if (pm.marge_interlignes == nil) then
       pm.marge_interlignes = "5px"
   else
       -- les valeurs trop petites
       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
   -- valeur effective du flottant
   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%") -- valeur par défaut taille police
   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
   -- valeurs par défaut des colonnes
   if (pm.colonnes == nil) then
       pm.colonnes_par_defaut = true
       pm.colonnes = 9
   else
       pm.colonnes = tonumber(pm.colonnes) -- pour que ce soit un nombre
   end
   -- on valide les colonnes
   if (type(pm.colonnes) ~= "number" or pm.colonnes < 1) then
       -- colonne erronée : erreur
       p.erreur("La valeur du paramètre colonnes (" .. (pm.colonnes or "<pas un nombre>") .. ") n'est pas valide", "nombre de colonnes")
       pm.colonnes = 9
   end
   -- largeur par défaut : 5.4em * colonnes
   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 = "défaut"
   else
       -- on valide la charte
       pm.charte = mw.ustring.lower(pm.charte)
       if (p.chartes[pm.charte] == nil) then
           -- charte inconnue : erreur
           p.erreur("La valeur du paramètre charte (" .. pm.charte .. ") n'est pas valide", "charte")
           pm.charte = "défaut" -- valeur par défaut
       end
   end
   -- on récupère les couleurs de la charte sauf si indiquées
   local coul_annees = (pm.annees_fond or p.chartes[pm.charte]["normal"])
   local coul_valeurs = (pm.population_fond or nil) -- valeur par défaut = rien
   -- ajout du # si absent
   coul_annees = p.couleur(coul_annees)
   if (coul_valeurs == nil) then
       coul_valeurs = ""
   else
       coul_valeurs = 'style="background:' .. coul_valeurs .. ';"'
   end
   -- extraction des éléments de la table, rangés dans une "vraie" table pour les trier
   local tbl = {}
   for annee, valeur in pairs(p.pframe.args) do
       -- il y a aussi les paramètres nommés dans cette table, qu'on laisse
       if (type(annee) == "number") then
           if (type(valeur) == "string") then
               valeur = mw.text.trim(valeur)
           end
           table.insert(tbl, {annee,valeur})
       else
           -- on profite de cette boucle pour vérifier les paramètres qui n'existent pas
           local tst = p.parametres[annee]
           if (tst == nil) then
               -- cas particulier : les paramètres sous la forme "XXXX notes" et "XXXX unité" sont acceptés
               local tst = mw.ustring.match(annee, "^[0-9]+ notes$") or mw.ustring.match(annee, "^[0-9]+ unité$") or mw.ustring.match(annee, "^[0-9]+ affichage$")
               -- autre : on ignore également les paramètres vides (pb de transmission d'autres modèles)
               local temp = mw.text.trim(annee)
               if (tst == nil and temp ~= "") then -- pas un paramètre connu ni XXXX notes → erreur
                   p.erreur("Le paramètre >>" .. annee .. "<< (" .. mw.ustring.len(annee) .. "/" .. mw.ustring.len(temp) .. " est inconnu", "paramètre inconnu")
                   -- on ignore simplement ce champs
               end
           end
       end
   end
   -- tri de la table
   table.sort(tbl, p.mysort)
   -- cette fois on parcours la structure des infos
   local ret = ""
   local odebug = "" -- sortie de debug
   -- on parcours les données (années) pour générer la table structurée
   local col = 1
   local ligne = 1
   local struct = {}
   table.insert(struct, {}) -- on crée la première ligne
   local total = 0 -- compte du 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("Aucune année fournie au modèle", "absence d'années")
       -- 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
   -- on force le namespace à "non encyclopédique" pour avoir systématiquement les messages d'erreur
   local ttl = 1  -- 1 ou autre chose, mais pas pas 0. Il faudrait si on conserve ça virer le code qui teste cette valeur (plus propre)


   -- création du div principal

ret = ret .. '

'
   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 .. '\n' else ret = ret .. '
\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 .. '' else ret = ret .. '' end else -- titre par défaut, caché ret = ret .. '' end -- parcours des colonnes pour insérer les années col = 1 ret = ret .. "\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 .. '\n'
           else
               if (pm.hyperliens_annees) then
ret = ret .. '\n'
               else
ret = ret .. '\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 .. '\n'
               col = col + 1
           end
       end
ret = ret .. "\n" -- parcours des colonnes pour insérer les valeurs col = 1 ret = ret .. "\n" while (struct[ligne][col] ~= nil) do if (struct[ligne][col][2] == "" or struct[ligne][col][2] == nil) then ret = ret .. ''
           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] .. " unité"]
               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] .. " notes"]
               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 .. ''
           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 .. ''
               col = col + 1
           end
       end
ret = ret .. "\n" -- fermeture table ret = ret .. "
' .. pm.titre .. '
' .. temp .. '[[' .. struct[ligne][col][1] .. ']]' .. struct[ligne][col][1] .. '-
-' .. tmp .. '-
\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 = "Liste des erreurs :
" 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 .. "
" end i = i + 1 end erreurs = erreurs .. "
" 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 .. '
'
       -- 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 retenu à partir de " .. pm.sansdoublescomptes .. " : population sans doubles comptes."
          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 .. "
" end ret = ret .. "" .. pm.enqueteannuelle .. " : Population provisoire (enquête annuelle)." pred = true end -- on ajoute les notes si présentes if (pm.notes ~= nil) then if (pred) then ret = ret .. "
" 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 .. "
" 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 = "Sources : " .. pm.sources else tmp = "Source : " .. 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 .. "
" end ret = ret .. erreurs end -- on ferme la div des notes
ret = ret .. '
'
   end
   -- on ferme la div principale
ret = ret .. "

\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 .. "" .. p.liste_cats[i] .. ""
           i = i + 1
       end
   end
   -- on retourne le résultat
   return ret

end


return p -- on retourne le module

{{bottomLinkPreText}} {{bottomLinkText}}
Utilisateur:Automatik/bac à sable/Module:Démographie
Listen to this article