Utilisateur:Automatik/bac à sable/Module:Démographie
De Wikipedia, l'encyclopédie encyclopedia
local p = {} -- le module
--[[
Module reprenant les fonctionnalités du modèle Démographie.
Version non protégée pour tests
--]]
-- 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 .. '
' .. temp .. ' | [[' .. struct[ligne][col][1] .. ']] | ' .. struct[ligne][col][1] .. ' | - |
---|---|---|---|
- | ' .. tmp .. ' | - |
ligne = 1 -- boucle sur les lignes while (struct[ligne] ~= nil) do -- une ligne à faire, on crée le tableau if (ligne == 1) thenret = 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 .. "
\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 = falseret = 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 .. "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
end
-- on ferme la div principaleret = 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