Actions

Module

Module:Démographie

De Wikimanche

Vous êtes bienvenu(e) pour ajouter vos remarques et suggestions sur ce modèle en page de discussion de ce modèle.

Ce modèle affiche un tableau d’évolution démographique. Les années sont affichées en ligne successives de n colonnes. Le nombre de colonnes est un paramètre optionnel (par défaut 9 colonnes).

Note : si des années ou populations sont vides, un tiret est affiché. De même si la dernière ligne n'est pas complète, des tirets sont affichés jusqu'à la fin de la ligne.

Utilisation

Ce modèle accepte des paramètres de la forme |date=population et les affiche sous forme de tableau à n colonnes. Le nombre de colonnes par défaut est 9. Ce modèle ne nécessite rien d'autre mais des options sont possibles et même fortement recommandées en ce qui concerne les notes et les source(s).

Le nombre de colonnes est paramétrable. Le nombre maximal de colonnes est 17 et le nombre maximal de lignes est 12. Les colonnes et les lignes au-delà de ces limites ne sont pas affichées.

Syntaxe complète

{{Démographie3
|titre              = <!-- exemple : Évolution démographique de xxxx depuis 1793 -->
|charte             = <!-- facultatif (exemple commune) -->
|colonnes           = <!-- cette ligne est facultative mais si elle existe le paramètre colonnes doit avoir une valeur numérique -->
|largeur-tableau    = <!-- facultatif (exemple : 50em) -->
|notes              = <!-- facultatif -->
|source             = <!-- facultatif, ne sert qu’en cas de source unique -->
|sources            = <!-- facultatif, sert s'il y a plusieurs sources -->
|année=population     <!-- pour lequel on peut ajouter les paramètres 'année notes', 'année unité' et 'année affichage' -->
|année=population     <!-- idem -->
|année=population     <!-- idem -->
|année=population     <!-- idem -->
|année=population |année unité = |année notes = |année affichage =   <!-- on peut présenter ces 4 paramètres ainsi -->
|wikidata           = <!-- oui ou identifiant Wikidata pour affichée les données de population de Wikidata
…
|flottant           = <!-- facultatif (« droite », « gauche » ou sans valeur) -->
|marge-interlignes  = <!-- facultatif (exemple : 8px) -->
|taille-police      = <!-- facultatif (exemple : 90%) -->
|hauteur-lignes     = <!-- facultatif (exemple : 120%) -->
|hyperliens-années  = <!-- facultatif (« on » ou sans valeur) -->
|années-fond        = <!-- facultatif (exemple : #ddffdd) -->
|population-fond    = <!-- facultatif (exemple : #f3fff3) -->
|notes-fond         = <!-- facultatif (exemple : #f3fff3) -->
|style-notes        = <!-- facultatif (« gauche » ou sans valeur) -->
|sansdoublescomptes = <!-- facultatif (pour compatibilité avec modèles précédents) -->
|enquêteannuelle    = <!-- facultatif (pour compatibilité avec modèles précédents) -->
}}

Paramètres principaux

Attention : les paramètres sont à écrire entièrement en minuscules.

Paramètre Description
titre Optionnel. Titre du tableau.
  • Par défaut aucun titre n'est affiché.
charte Optionnel. Charte graphique utilisée pour la ligne des dates (si années-fond inutilisée). Les valeurs possibles sont :
  • commune, intercommunalité, canton, arrondissement, département, région, aire urbaine, unité urbaine, zone insee et défaut.

Plus de détails sur les couleurs de la charte se trouvent dans la documentation de {{Charte de couleur}} (utilisé ici avec la charte communes).

colonnes Optionnel. Le nombre de colonnes du tableau.
  • Doit être un nombre entier.
  • 9 (valeur par défaut)
largeur-tableau Optionnel. La largeur du tableau. Cela peut être n'importe quel code CSS valide de type width, par exemple 100% ou 50em. Attention, si la largeur définie pour le tableau est trop faible pour son contenu, celui-ci dépassera à droite.
  • La valeur par défaut est 5,4 em multiplié par le nombre de colonnes, soit 48.6em pour 9 colonnes.
notes Optionnel. Les notes seront affichées en bas du tableau. Le texte est libre et peut comporter des références et des liens.
sources Optionnel. (Lorsqu'il y a plusieurs sources.) Chaque tableau devrait porter la mention de la ou des sources. Les sources seront affichées en bas du tableau juste sous les notes.
source Optionnel. (Lorsqu'il n'y a qu'une seule source.) La source sera affichée en bas du tableau. La seule différence avec le paramètre précédent, dont il est une variante, est que le mot « source » sera affiché au singulier.
annéen L'année pour laquelle on veut afficher la population sous la forme yyyy. Par exemple, 2013.
= populationn (ce n'est pas un paramètre mais la valeur à donner au paramètre précédent annéen)

La population associée à annéen sans aucun formatage, ni séparateur de milliers, ni unités ou notes. Par exemple, 12345.
À noter : si la population est suivie d'autres éléments ceux-ci sont également intégrés à la suite de la valeur. Il est toutefois préférable d'utiliser annéen notes et annéen unité (voir ci-dessous).

annéen notes Optionnel. Note ou référence associée à annéen. Ignorée si annéen n'existe pas. Par exemple, |2013 notes=(est.). On peut y inclure des balises <ref></ref>.
annéen unité Optionnel. Unité de la population associée à annéen. Ignorée si annéen n'existe pas. Par exemple, |2013 unité=feux.
annéen affichage Optionnel. L'affichage associé à annéen. Ignorée si annéen n'existe pas. Par exemple, |2002 affichage = [[Recensement de 2002 en Russie|2002]]*. On peut y inclure des balises <ref></ref>.
wikidata Optionnel. oui ou identifiant Wikidata pour afficher les données de population de Wikidata. Si le contenu du paramètre n'est pas un identifiant Wikidata (Qxxx), l'identifiant Wikidata de la page en cours est utilisé.

Paramètres annexes

Paramètre Description
flottant Optionnel. Définit si le tableau de population doit flotter ou non, et si oui s'il doit flotter à droite ou à gauche de la page.
  • gauche Tableau flottant à gauche.
  • droite Tableau flottant à droite.
  • non ou toute autre valeur (valeur par défaut) : Tableau non flottant.
marge-interlignes Optionnel. La marge qui précède chaque ligne de tableau. Cela peut être n'importe quel code CSS valide de type margin.
  • 6px (valeur par défaut)
hauteur-lignes Optionnel. La hauteur des lignes. Cela peut être n'importe quel code CSS valide de type line-height.
  • 100% (valeur par défaut)
taille-police Optionnel. La taille de la police. Cela peut être n'importe quel code CSS valide de type font-size.
  • 100% (valeur par défaut)
hyperliens-années Optionnel. Cette option indique s'il faut afficher les années sous forme d'hyperliens wiki ou non.
  • on : Crée des liens wiki sur les années (attention : pas de vérification si la page cible existe).
  • off (ou toute autre valeur différente de on) (par défaut) : Ne crée par de lien wiki sur les années.
années-fond Optionnel. Couleur de fond des cases d'années. Cela peut être n'importe quel code CSS valide de type background.
  • #F2F2F2 (par défaut c'est la couleur par défaut des fonds de titre de tableau sur Wikipédia qui est prise dans ce modèle)
population-fond Optionnel. Couleur de fond des cases de population. Cela peut être n'importe quel code CSS valide de type background.
  • #F9F9F9 (par défaut c'est la couleur par défaut des fonds de cases de tableau sur Wikipédia qui est prise dans ce modèle)
notes-fond Optionnel. Couleur de fond des notes (et sources). Cela peut être n'importe quel code CSS valide de type background.
  • #FFFFFF (par défaut) : le fond est blanc par défaut.
style-notes Optionnel. Cette option permet de modifier l'affichage des notes et des sources.
  • gauche : affiche les notes et sources dans un cadre, alignées à gauche.
  • non renseigné (par défaut) : affiche les notes et sources centrées et sans cadre.
sansdoublescomptes Optionnel. Si une année yyyy est renseignée dans ce paramètre, la phrase « Nombre retenu à partir de yyyy : population sans doubles comptes. » sera affichée au début des notes.
enquêteannuelle Optionnel. Année pour laquelle la population est provisoire (issue d'une enquête annuelle de l'Insee, par exemple).

Catégorie de maintenance

Les articles ayant une erreur d'utilisation de ce modèle sont insérés dans cette catégorie (note : aucune catégorie n'est insérée si le modèle est utilisé en dehors de l'espace encyclopédique. Dans ce cas les erreurs sont affichées comme des notes). Les erreurs traitées sont :

  • Charte  : charte inconnue, elle est remplacée par la valeur "défaut"
  • Nombre de colonnes : valeur de "colonnes" invalide (inférieure à 1 ou autre chose qu'un nombre), elle est remplacée par la valeur 9
  • Paramètre inconnu : un des paramètres n'est pas reconnu, il est ignoré
  • Absence d'années : aucune entrée "année=population" fournie

Remarques

Bordures

Si le paramètre marge-interlignes est nul, toutes les données sont visuellement dans un unique tableau. À noter que dans ce cas les bordures intérieures entre les lignes s'affichent légèrement différemment selon que l'on utilise Firefox ou Internet Explorer. Avec Firefox les bordures intérieures sont les mêmes que les autres bordures (fines) tandis qu'avec Internet Explorer les bordures entre les lignes sont un peu plus larges. L'effet général reste le même.

Paramètres hauteur-lignes et taille-police

Si ces paramètres n'ont pas leur valeur par défaut, l'effet obtenu est légèrement différent selon le navigateur. En effet Firefox et Internet Explorer ne traitent pas exactement de la même façon les attributs de style line-height et font-size.

Exemples

1er exemple

Évolution de la population d'Ille-et-Vilaine de 1801 à 2009
1801 1806 1821 1826 1831 1836 1841 1846 1851 1856 1861 1866
488 846508 192533 207553 453547 052547 249549 217562 958574 618580 898584 930592 609
1872 1876 1881 1886 1891 1896 1901 1906 1911 1921 1926 1931
589 532602 712615 480621 384626 875622 039613 567611 805608 021558 574561 688562 558
1936 1946 1954 1962 1968 1975 1982 1990 1999 2004 2006 2009
565 766578 246586 812614 268652 722702 199749 764798 718867 533908 449945 851979 415
{{Démographie3
 | titre             = Évolution de la population d'Ille-et-Vilaine de 1801 à 2009
 | colonnes          = 12
 | largeur-tableau   = 50.8em
 | marge-interlignes = 0px
 | taille-police     = 95%
 | années-fond       = #CCCCCC
 | population-fond   = #FFFFFF
 | 1801 = 488846
 | 1806 = 508192
 | 1821 = 533207
 | 1826 = 553453
 | 1831 = 547052
 | 1836 = 547249
 | 1841 = 549217
 | 1846 = 562958
 | 1851 = 574618
 | 1856 = 580898
 | 1861 = 584930
 | 1866 = 592609
 | 1872 = 589532
 | 1876 = 602712
 | 1881 = 615480
 | 1886 = 621384
 | 1891 = 626875
 | 1896 = 622039
 | 1901 = 613567
 | 1906 = 611805
 | 1911 = 608021
 | 1921 = 558574
 | 1926 = 561688
 | 1931 = 562558
 | 1936 = 565766
 | 1946 = 578246
 | 1954 = 586812
 | 1962 = 614268
 | 1968 = 652722
 | 1975 = 702199
 | 1982 = 749764
 | 1990 = 798718
 | 1999 = 867533
 | 2004 = 908449
 | 2006 = 945851
 | 2009 = 979415
}}

2e exemple

2e exemple
1793 1800 1806 1821 1831 1836 1841 1846 1851
1 2421 3071 3591 3091 1861 1041 0451 001991
1856 1861 1866 1872 1876 1881 1886 1891 1896
995950891874930965918910881
1901 1906 1911 1921 1926 1931 1936 1946 1954
9579589779761 0499379361 001976
1962 1968 1975 1982 1990 1999 2006 - -
1 0011 0471 1021 2651 2941 4671 667--
1962 à 1999 : population sans double compte (recensement) ; 2006 : population municipale légale.
(Sources : INSEE et cassini.ehess.fr.)
{{Démographie3
 | titre             = {{2e}} exemple
 | colonnes          = 9
 | largeur-tableau   = 60%
 | flottant          = droite
 | marge-interlignes = 6px
 | taille-police     = 90%
 | hauteur-lignes    = 120%
 | années-fond       = #F5F5F5
 | population-fond   = #F3FFF3
 | hyperliens-années = on
 | sources           = INSEE et cassini.ehess.fr.
 | 1793 = 1242
 | 1800 = 1307
 | 1806 = 1359
 | 1821 = 1309
 | 1831 = 1186
 | 1836 = 1104
 | 1841 = 1045
 | 1846 = 1001
 | 1851 = 991
 | 1856 = 995
 | 1861 = 950
 | 1866 = 891
 | 1872 = 874
 | 1876 = 930
 | 1881 = 965
 | 1886 = 918
 | 1891 = 910
 | 1896 = 881
 | 1901 = 957
 | 1906 = 958
 | 1911 = 977
 | 1921 = 976
 | 1926 = 1049
 | 1931 = 937
 | 1936 = 936
 | 1946 = 1001
 | 1954 = 976
 | 1962 = 1001
 | 1968 = 1047
 | 1975 = 1102
 | 1982 = 1265
 | 1990 = 1294
 | 1999 = 1467
 | 2006 = 1667
 | notes = 1962 à 1999 : population sans double compte (recensement) ; 2006 : population municipale légale.
}}

3e exemple

Évolution démographique depuis 1962
1962 1968 1975 1982 1990 1999
1 0011 0471 1021 2651 2941 467
Nombre retenu à partir de 1962 : population sans doubles comptes.
(Source : INSEE.)
{{Démographie3
 | titre              = Évolution démographique depuis 1962
 | années-fond        = #ddffdd
 | population-fond    = #f3fff3
 | colonnes           = 6
 | hyperliens-années  = on
 | flottant           = droite
 | 1962 = 1001
 | 1968 = 1047
 | 1975 = 1102
 | 1982 = 1265
 | 1990 = 1294
 | 1999 = 1467
 | sansdoublescomptes = 1962
 | source             = INSEE.
}}

4e exemple

Évolution démographique
1856 1861 1866 1872 1876 1881 1886 1891 1896
-------250 552263 562
1901 1906 1911 1921 1926 1931 1936 1946 1954
270 228277 753297 562321 237367 267408 282428 166431 499519 976
1962 1968 1975 1982 1990 1999 2004 - -
687 827854 3821 082 2551 196 1111 196 1111 354 3041 390 170--
Nombre retenu à partir de 1962 : population sans doubles comptes.
(Sources : SPLAF[1] et INSEE[2], [3].)

Références

{{Démographie3
|titre=Évolution démographique
|hyperliens-années=on
| années-fond        = #ddffdd
| population-fond    = #f3fff3
|1856=
|1861=
|1866=
|1872=
|1876=
|1881=
|1886=
|1891=250552
|1896=263562
|1901=270228
|1906=277753
|1911=297562
|1921=321237
|1926=367267
|1931=408282
|1936=428166
|1946=431499
|1954=519976
|1962=687827
|1968=854382
|1975=1082255
|1982=1196111
|1990=1196111
|1999=1354304
|2004=1390170
|sansdoublescomptes=1962
|sources =SPLAF<ref>[http://splaf.free.fr/ Historique du département des Yvelines]</ref> et INSEE<ref>[http://www.insee.fr/fr/ffc/docs_ffc/ElpDep_5trages90-05.xls INSEE : Estimation de population au {{1er}} janvier, par département, sexe et grande classe d'âge]</ref>{{,}}<ref>Note : avant 1968, la population se rapporte au territoire actuel des Yvelines.</ref>.
}}

Le même en supprimant les lignes vides au début de 1856 à 1886 (en l'occurrence simple mise en commentaire HTML) et en modifiant l'aspect des notes :

Évolution démographique
1891 1896 1901 1906 1911 1921 1926 1931 1936
250 552263 562270 228277 753297 562321 237367 267408 282428 166
1946 1954 1962 1968 1975 1982 1990 1999 2004
431 499519 976687 827854 3821 082 2551 196 1111 196 1111 354 3041 390 170
Nombre retenu à partir de 1962 : population sans doubles comptes.
Sources : SPLAF[1] et INSEE[2], [3].

Références

{{Démographie3
|titre=Évolution démographique
|hyperliens-années=on
|style-notes=gauche
|années-fond= #ddffdd
|population-fond= #f3fff3
<!-- |1856=
|1861=
|1866=
|1872=
|1876=
|1881=
|1886= -->
|1891=250552
|1896=263562
|1901=270228
|1906=277753
|1911=297562
|1921=321237
|1926=367267
|1931=408282
|1936=428166
|1946=431499
|1954=519976
|1962=687827
|1968=854382
|1975=1082255
|1982=1196111
|1990=1196111
|1999=1354304
|2004=1390170
|sansdoublescomptes=1962
|sources =SPLAF<ref>[http://splaf.free.fr/
 http://splaf.free.fr/ Historique du département des Yvelines]</ref> et INSEE<ref>
[http://www.insee.fr/fr/ffc/docs_ffc/ElpDep_5trages90-05.xls INSEE : Estimation de population au {{1er}} janvier, par département, sexe et grande classe d'âge]</ref>{{,}}<ref>Note : avant 1968, la population se rapporte au territoire actuel des Yvelines.</ref>.
}}

5e exemple

Évolution démographique depuis l'an 700
700 1000 1200 1400 1500 1600 1662 1715 1763 1793 1800
300 (est.)600 (est.)500 (est.)600 (est.)650 (est.)802[1]190 feux9961 0581 2421 307
1806 1821 1831 1836 1841 1846 1851 1856 1861 1866 1872
1 3591 3091 1861 1041 0451 001991995950891874
1876 1881 1886 1891 1896 1901 1906 1911 1921 1926 1931
9309659189108819579589779761 049937
1936 1946 1954 1962 1968 1975 1982 1990 1999 2004 2006
9361 0019761 0011 0471 1021 2651 2941 4671 5021 498
Feux : nombre de feux (foyers), dans un recensement d'ancien régime. / De 1962 à 2003 : population sans doubles comptes des recensements. Depuis 2004 : population municipale. 2004 : enquête annuelle. 2006 : population légale.
(Sources : INSEE, cassini.ehess.fr et livre truc sur la démographie d'ancien régime.)

Références

  1. Voir le calcul dans livre machin.
{{Démographie3
|titre=Évolution démographique depuis l'an 700
|charte=commune
|colonnes=11
|hauteur-lignes=120%
|années-fond=#9befff
|population-fond=#ffffff
| 700=300 | 700 notes=(est.)
|1000=600 |1000 notes=(est.)
|1200=500 |1200 notes=(est.)
|1400=600 |1400 notes=(est.)
|1500=650 |1500 notes=(est.)
|1600=802 |1600 notes=<ref>Voir le calcul dans '''livre machin'''.</ref>
|1662=190 |1662 unité=[[Feu fiscal|feux]]
|1715=996
|1763=1058
|1793=1242
|1800=1307
|1806=1359
|1821=1309
|1831=1186
|1836=1104
|1841=1045
|1846=1001
|1851=991
|1856=995
|1861=950
|1866=891
|1872=874
|1876=930
|1881=965
|1886=918
|1891=910
|1896=881
|1901=957
|1906=958
|1911=977
|1921=976
|1926=1049
|1931=937
|1936=936
|1946=1001
|1954=976
|1962=1001
|1968=1047
|1975=1102
|1982=1265
|1990=1294
|1999=1467
|2004=1502
|2006=1498
|notes=[[Feu fiscal|Feux]] : nombre de feux (foyers), dans un recensement d'ancien régime. / De 1962 à 2003 : [[Chiffres de population en France#Aspect statistique|population sans doubles comptes]] des recensements. Depuis 2004 : [[Chiffres de population en France#La population municipale|population municipale]]. 2004 : enquête annuelle. 2006 : [[Chiffres de population en France#Aspect législatif|population légale]].
|sources=INSEE, cassini.ehess.fr et ''livre truc sur la démographie d'ancien régime''.
}}

6e exemple - 2 tableaux côte à côte

<th scope="col" style="background-color: Problème interne au module (données);font-weight:bold;">1962 <th scope="col" style="background-color: Problème interne au module (données);font-weight:bold;">1968 <th scope="col" style="background-color: Problème interne au module (données);font-weight:bold;">1975 <th scope="col" style="background-color: Problème interne au module (données);font-weight:bold;">1982 <th scope="col" style="background-color: Problème interne au module (données);font-weight:bold;">1990 <th scope="col" style="background-color: Problème interne au module (données);font-weight:bold;">1999
Évolution démographique de la commune
1 0011 0471 1021 2651 2941 467
Nombre retenu à partir de 1962 : population sans doubles comptes.
(Source : INSEE.)
<th scope="col" style="background-color: Problème interne au module (données);font-weight:bold;">1962 <th scope="col" style="background-color: Problème interne au module (données);font-weight:bold;">1968 <th scope="col" style="background-color: Problème interne au module (données);font-weight:bold;">1975 <th scope="col" style="background-color: Problème interne au module (données);font-weight:bold;">1982 <th scope="col" style="background-color: Problème interne au module (données);font-weight:bold;">1990 <th scope="col" style="background-color: Problème interne au module (données);font-weight:bold;">1999
Évolution démographique du département
687 827854 3821 082 2551 196 1111 196 1111 354 304
Nombre retenu à partir de 1962 : population sans doubles comptes.
(Source : INSEE.)

Nous pouvons comparer les populations de la commune et du département, de même que nous pouvons comparer la population de deux communes ou bien voir le graphique du tableau à côté.

{{Démographie3
|titre=Évolution démographique de la commune
|flottant=gauche
|colonnes=6
|largeur-tableau=30em
|hyperliens-années=on
|1962=1001
|1968=1047
|1975=1102
|1982=1265
|1990=1294
|1999=1467
|sansdoublescomptes=1962
|source=INSEE.
}}
{{Démographie3
|titre=Évolution démographique du département
|flottant=droite
|colonnes=6
|hyperliens-années=on
|1962=687827
|1968=854382
|1975=1082255
|1982=1196111
|1990=1196111
|1999=1354304
|sansdoublescomptes=1962
|source=INSEE.
}}
<div style="text-align: center;">

Nous pouvons comparer les populations de la commune et du département, de même que nous pouvons comparer la population de deux communes ou bien voir le graphique du tableau à côté.
</div>

7e exemple - année affichage

(Exemple d'utilisation du paramètre annéen affichage, tiré de l'article de la ville russe d'Obninsk).

Recensements (*) ou estimations de la population[1]

Évolution démographique
1959* 1970* 1979* 1989*
16 33448 64173 402100 178
2002* 2010* 2012 -
105 706104 798105 421-

Références

  1. « Recensements et estimations de la population depuis 1897 sur », sur pop-stat.mashke.org(en) « Recensements de 1959, 1970 et 1979 », sur www.webgeo.ru — Résultats préliminaires du recensement du 14 octobre 2010 [1]
Recensements (*) ou estimations de la population<ref>{{Lien web |url=http://pop-stat.mashke.org/russia-cities.htm |titre=Recensements et estimations de la population depuis 1897 sur |site=pop-stat.mashke.org}} — {{Lien web|langue=en |url=http://www.webgeo.ru |titre=Recensements de 1959, 1970 et 1979 |site=www.webgeo.ru}} — Résultats préliminaires du recensement du 14 octobre 2010 [http://www.perepis-2010.ru/results_of_the_census/titul.pdf]</ref> :

{{Démographie3
| titre = Évolution démographique
| colonnes = 4
| 1959 affichage = 1959* | 1959 = 16334
| 1970 affichage = 1970* | 1970 = 48641
| 1979 affichage = 1979* | 1979 = 73402
| 1989 affichage = [[Recensement soviétique de 1989|1989]]* | 1989 = 100178
| 2002 affichage = [[Recensement de 2002 en Russie|2002]]* | 2002 = 105706
| 2010 affichage = 2010* | 2010 = 104798
| 2012 = 105421
| années-fond = #eeeeff
| population-fond = #f7f9ff
}}

Faire une courbe, un histogramme ou un nuage de points avec les données de population

Voir aussi

Modèle:Crédit d'auteurs

Modèles connexes

Liens externes


Modèle:Modèle utilisant les modules Lua Modèle:Projet modèle


--[[
  Module reprenant les fonctionnalités du modèle Démographie.
--]]

local p = {} -- le module

-- le module chartes (centralisation des styles)
local data = require "Module:Chartes"

-- liste des paramètres reconnus (valeur = nom de la variable)
p.parametres = {
  ["titre"] = "titre",
  ["charte"] = "charte",
  ["colonnes"] = "colonnes",
  ["notes"] = "notes",
  ["source"] = "source",
  ["sources"] = "sources",
  ["wikidata"] = "wikidata",
  ["flottant"] = "flottant",
  ["largeur-tableau"] = "largeur_tableau",
  ["sansdoublescomptes"] = "sansdoublescomptes",
  ["enquêteannuelle"] = "enqueteannuelle",
  ["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",
  -- pour permettre les paramètres "depuis Lua"
  ["largeur_tableau"] = "largeur_tableau",
  ["enqueteannuelle"] = "enqueteannuelle",
  ["marge_interlignes"] = "marge_interlignes",
  ["taille_police"] = "taille_police",
  ["hauteur_lignes"] = "hauteur_lignes",
  ["hyperliens_annees"] = "hyperliens_annees",
  ["annees_fond"] = "annees_fond",
  ["population_fond"] = "population_fond",
  ["notes_fond"] = "notes_fond",
  ["style_notes"] = "style_notes",
}


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

-- le titre par défaut, utilisé en "caption hidden" lorsqu'on ne passe pas de titre à afficher
p.titre_par_defaut = "Évolution démographique"


--[[
  Fonction exportée reprenant le fonctionnement de {{m|Charte de couleur}}

  Fonction devenue inutile (voir Module:Chartes), maintenue pour compatibilité éventuelle
  question : est-il possible de tester un appel à une fonction précise ?
--]]
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 ""))

    return data.charte_m("geographie", "secondaire", code, "non")
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
            if (temp == "") then
                return nil
            else
                return temp
            end
        else
            return temp
        end
    else
        return nil
    end
end

local function get_snack_value(t, v, ...)
	if v and type(t) == 'table' then
		return get_snack_value(t[v], ...)
	elseif v then
		return nil
	else
		return t
	end
end

--[[
  Fonction de récupération des données de Wikidata.
--]]
function p.valeur_wikidata(pm, customId)
	local id
	if customId and mw.wikibase.isValidEntityId(customId) then
		id = customId
		if not mw.wikibase.entityExists(id) then
			return
		end
	else
		id = mw.wikibase.getEntityIdForCurrentPage()
		if not id then
			return
		end
	end
	local popProp = mw.wikibase.getAllStatements( id, 'P1082' )
	if not popProp or #popProp == 0 then
		return
	end
	for _, statement in ipairs( popProp ) do
		local pop = get_snack_value(statement, 'mainsnak', 'datavalue', 'value', 'amount')
		local date_table = get_snack_value(statement, 'qualifiers', 'P585', 1, 'datavalue', 'value' )
		if pop and date_table and date_table.precision > 8 and statement.rank ~= 'deprecated' then
			local an = tonumber(date_table.time:match('^%+(%d%d%d%d)'))
			if an and pm[an] == nil then
				pm[an] = pop:match('%d+')
			end
		end
	end
end

--[[
  Supprime le premier retour à la ligne (éventuel) de forme <br/>
--]]
function p.sans_nl(texte)
    if (texte == nil or texte == "" or type(texte) ~= "string") then
        return texte
    end
    -- parenthèses car gsub() retourne plusieurs valeurs, et on veut retourner uniquement la première valeur
    return ( mw.ustring.gsub(texte, "[<][bB][rR][ ]*[/]?[>]", "", 1) )
end

--[[
  Fonction principale
  reçoit une table des paramètres (pm) issus de l'appel
--]]
function p.demographie_m(pm)
    -- 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 (pm.flottant and pm.flottant:lower() == "gauche") then
        vflottant = 'float:left; margin: 0 1em 1em 0'
    elseif (pm.flottant and pm.flottant:lower() == "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: " .. 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;font-size: small; font-style: italic;'
    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
    local colonnes_par_defaut
    if (pm.colonnes == nil) then
        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
    local largeur_tableau_par_defaut
    if (pm.largeur_tableau == nil) then
        largeur_tableau_par_defaut = true
        pm.largeur_tableau = pm.colonnes*5.4 .. "em"
    end
    if (pm.charte == nil) then
        pm.charte = "défaut"
    else
        -- on valide la charte
        pm.charte = mw.ustring.lower(pm.charte)
    end
    -- on récupère les couleurs de la charte sauf si indiquées
    local coul_annees = (pm.annees_fond or data.charte_m("geographie", "secondaire", pm.charte , "oui"))
    local coul_valeurs = (pm.population_fond or nil) -- valeur par défaut = rien

    if (coul_valeurs == nil) then
        coul_valeurs = ""
    else
        coul_valeurs = 'style="background:' .. coul_valeurs .. ';"'
    end

    -- obtient les données de wikidata, mais sans écraser les données locales
    -- * définir à une valeur "truly" pour activer (désactivé par défaut)
    -- * définir à un id wikidata pour récupérer les informations depuis une autre entité
    if pm.wikidata ~= nil then
        local testParam = require('Module:Yesno')(pm.wikidata, 'custom_id')
        if testParam == true then
            p.valeur_wikidata(pm)
        elseif testParam == 'custom_id' then
            p.valeur_wikidata(pm, pm.wikidata)
        end
    end

    -- extraction des éléments de la table, rangés dans une "vraie" table pour les trier
    local tbl = {}
    for annee, valeur in pairs(pm) do
        -- il y a aussi les paramètres nommés dans cette table, qu'on laisse
        if type(annee) == "number" then
            if annee == 1 then -- protection : un paramètre non nommé sera à l'index "1"
                p.erreur("Présence d'un paramètre non nommé", "paramètre inconnu")
            else
                -- nettoyage de la valeur
                local v = mw.text.trim(valeur or "")
                table.insert(tbl, {annee, v})
            end
        else
            -- on profite de cette boucle pour vérifier les paramètres qui n'existent pas
            if p.parametres[annee] == nil then
                -- cas particulier : les paramètres sous la forme "XXXX notes" et "XXXX unité" sont acceptés
                if not (annee:match("^[0-9]+ notes$") or annee:match("^[0-9]+ unité$") or annee:match("^[0-9]+ affichage$")) then
                    -- pas un paramètre connu ni XXXX notes → erreur
                    p.erreur("Le paramètre ''>>" .. annee .. "<<'' est inconnu", "paramètre inconnu")
                    -- on ignore simplement ce champs
                end
            end
        end
    end
    -- tri de la table
    table.sort(tbl, function (el1, el2)
        return el1[1] < el2[1]
    end)

    -- 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 = 0
    local ligne = 0
    local struct = {}
    local total = 0 -- compte du nombre total
    for pos = 1, #tbl do
        -- colonne d'insertion
        col = col + 1
        -- fin de la ligne ? on retourne à la première colonne
        if (col > pm.colonnes) then
            col = 1
        end
        -- première colonne ? on crée une nouvelle ligne
        if (col == 1) then
            ligne = ligne + 1
            table.insert(struct, {})
        end
        -- on insert dans la ligne
        table.insert(struct[ligne], tbl[pos])
        total = total + 1
    end
    -- aucune entrée ? erreur.
    if (total == 0) then
        p.erreur("Aucune année fournie au modèle", "absence d'années")
    end
    -- on traite la largeur
    if (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 (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 style="overflow:hidden; width: ' .. pm.largeur_tableau .. '; ' .. vflottant .. '; padding:0 1px; text-align:center; font-family: Arial, sans-serif;">'

    -- boucle sur les lignes
    for ligne = 1, #struct do
        local structLigne = struct[ligne]
        -- 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) then
            if (ligne == 1) then
                ret = ret .. '<caption style="margin-bottom:' .. pm.marge_interlignes .. ';">' .. pm.titre .. '</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
        ret = ret .. "<tr>\n"
        for col = 1, #structLigne do
            local structCol = structLigne[col]
            -- présence de AAAA affichage ?
            local temp = pm[structCol[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 .. ';font-weight:bold;">[[' .. structCol[1] .. ']]</th>\n'
                else
                    ret = ret .. '<th scope="col" style="background-color: ' .. coul_annees .. ';">' .. structCol[1] .. '</th>\n'
                end
            end
        end
        -- si on n'a pas terminé les colonnes on termine avec du vide
        if #structLigne < pm.colonnes then
            for col = #structLigne + 1, pm.colonnes do
                ret = ret .. '<th scope="col" style="background-color: ' .. coul_annees .. ';">-</th>\n'
            end
        end
        ret = ret .. "</tr>\n"
        -- parcours des colonnes pour insérer les valeurs
        ret = ret .. "<tr>\n"
        for col = 1, #structLigne do
            local structCol = structLigne[col]
            if (structCol[2] == "" or structCol[2] == nil) then
                ret = ret .. '<td ' .. coul_valeurs .. '>-</td>'
            else
                local tmp = ""
                -- on récupère la partie numérique au début
                local pdeb = ""
                do
                    local fStart, fEnd, match = structCol[2]:find("^([0-9]+)")
                    while fEnd do
                        pdeb = pdeb .. match
                        -- dans l'éventualité où la valeur est un nombre déjà formaté
                        fStart, fEnd, match = structCol[2]:find("^(\194\160[0-9]+)", fEnd + 1)
                    end
                end
                if (pdeb ~= "") then
                    -- si le nombre est déjà formaté on l'ajoute tel quel, sinon on lui applique un formatnum
                    -- (attention à ne pas modifier la variable pdeb, pour ne pas modifier sa longueur)
                    if (pdeb:find("\194\160")) then
                        tmp = tmp .. pdeb
                    else
                        tmp = tmp .. lang:formatNum(tonumber(pdeb))
                    end
                end
                -- on ajoute la suite (éventuelle)
                local pfin = structCol[2]:sub(#pdeb + 1)
                if (pfin ~= "") then
                    tmp = tmp .. pfin
                end
                -- si un paramètre "XXXX unité" existe on l'insert
                local unite = pm[structCol[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 = pm[structCol[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' == '' la note ne contient qu'un strip marker (ref, pre, gallery). Probablement une ref.
                    if (estref ~= '') then
                        tmp = tmp .. " "
                    end
                    tmp = tmp .. note
                end
                ret = ret .. '<td ' .. coul_valeurs .. '>' .. tmp .. '</td>'
            end
        end
        -- si on n'a pas terminé les colonnes on termine avec du vide
        if #structLigne < pm.colonnes then
            for col = #structLigne + 1, pm.colonnes do
                ret = ret .. '<td ' .. coul_valeurs .. '>-</td>'
            end
        end
        ret = ret .. "</tr>\n"
        -- fermeture table
        ret = ret .. "</table>\n"
    end

    -- si présence d'erreur on l'ajoute aux notes
    local erreurs = nil
    if (p.liste_erreurs[1] ~= nil) then
        erreurs = "<span class=\"error\" style=\"font-size: 0.9em;\">Liste des erreurs :"
        for i = 1, #p.liste_erreurs do
            erreurs = erreurs .. "<br>• " .. p.liste_erreurs[i]
        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
           ret = ret .. "Nombre retenu à partir de [[" .. pm.sansdoublescomptes .. "]] : [[Chiffres de population de la France|population sans doubles comptes]]."
           pred = true
        end
        if (pm.enqueteannuelle ~= nil) then
            if (pred) then
                ret = ret .. "<br/>"
            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 .. "<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 = "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 .. "<br/>"
            end
            ret = ret .. erreurs
        end
        -- on ferme la div des notes
        ret = ret .. '</div>'
    end

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

    -- si namespace encyclo (ttl = 0) on insert les catégories d'erreur
    if (ttl == 0) then
        for i = 1, #p.liste_cats do
            ret = ret .. "[[Catégorie:" .. p.categorie_erreur .. "|" .. p.liste_cats[i] .. "]]"
        end
    end

    -- on retourne le résultat
    return ret
end

--[[
  Fonction appelable depuis un modèle. Se contente d'appeler demographie_m() qui fait le
    traitement et est également appelable depuis un autre module
--]]
function p.demographie(frame)
    -- pour simplifier on stocke la frame et la pframe
    p.frame = frame
    p.pframe = frame:getParent()

    -- 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
        local value = p.lit_parametre(k, true)
        if value then
            pm[v] = value
        end
    end
    -- les paramètres numériques maintenant (les années)
    for k, v in pairs(p.pframe.args) do
        if type(k) == "number" then
            pm[k] = mw.text.trim(v)
        elseif p.parametres[k] == nil and k:sub(1, 1) ~= "_" then
            pm[k] = v
        end
    end
    for k, v in pairs(p.frame.args) do
        if type(k) == "number" then
            pm[k] = mw.text.trim(v)
        elseif p.parametres[k] == nil and k:sub(1, 1) ~= "_" then
            pm[k] = v
        end
    end

    -- on appelle (et on retourne) la fonction principale
    return p.demographie_m(pm)
end


return p -- on retourne le module