Module:Suivi des biographies
La documentation pour ce module peut être créée à Module:Suivi des biographies/doc
--[[ Module servant au modèle:Suivi des biographies. Ce module catégorise les biographies. --]] local p = {} -- module wikidata local wd = require 'Module:Wikidata' -- les données associées local data = require "Module:Suivi des biographies/données" --[[ fonction parcourant les "parents" de l'élément indiqué et retournant le premier élément présent dans la table 'association' durant ce processus (ou référencé par un 'identique à'). Fait au maximum 'prof' itérations. Retourne 'nil' ou une table vide si rien n'est trouvé ]]-- function p.cherche_parents(el, prof, checked) if (prof <= 0) then return nil -- fin de récursion end -- évite de vérifier deux fois le même élément if type(checked) ~= 'table' then checked = {} end if checked[el] then return nil else checked[el] = true end -- si l'élément courant est dans la table on le retourne (récursion) if (data.association[el] ~= nil) then return el end -- si l'élément n'est pas une entity valide on quitte if not el:match( '^Q%d+$' ) then if el:match( '^environ Q%d+$' ) then el = el:gsub( '^environ ','' ) else return nil end end -- on récupère les P460 (réputé identique à) au cas où local args = { ["property"] = "P460", ["entity"] = el, link = "-", displayformat = "raw" } local id = wd.stringTable(args) if (id ~= nil) then -- correspond ? for k, v in pairs(id) do if (data.association[v] ~= nil) then return v -- trouvé, on quitte end end end -- si on arrive ici c'est qu'il n'a pas d'équivalence. On parcours -- les "sous-classe de" (P279) récursivement args = { ["property"] = "P279", ["entity"] = el, link = "-", displayformat = "raw" } id = wd.stringTable(args) if (id ~= nil) then -- pour chaque "sur-classe" on se ré-appelle local ret for k, v in pairs(id) do ret = p.cherche_parents(v, prof-1) if (ret ~= nil) then return ret end end end -- ici on n'a rien trouvé → nil return nil end --[[ fonction retournant une liste des éléments de la table 'p.association' trouvés à partir de la propriété 'property' pour l'entité 'entity' (ou l'article courant si 'entity' vaut 'nil') ]]-- function p.propriete_parente(property, entity) local args = { ["property"] = property, link = "-", displayformat = "raw" } local out = {} -- table des résultats if (entity ~= nil) then args["entity"] = entity end local res = wd.stringTable(args) -- si aucun résultat on retourne nil if (type(res) ~= "table") then return nil end -- on parcours tous les résultats à la recherche de ceux qui sont dans la -- liste 'association' ou ayant un élément fils de l'un d'entre eux local checked = {} for k, v in pairs(res) do -- si l'élément est présent on l'insert directement checked[k] = true if (data.association[v] ~= nil) then -- bidouille pour les professions "Environ " if v:match( '^environ Q%d+$' ) then v = v:gsub( '^environ ','' ) end table.insert(out, v) else -- on cherche "récursivement" chez les parents -- la valeur numérique est la profondeur max de recherche local d = p.cherche_parents(v, 10, checked) if (d ~= nil) then table.insert(out, d) end end end return out end --[[ fonction retournant true si la valeur 'value' est présente dans la liste des propriétés 'property' pour l'entité 'entity' (ou l'article courant si 'entity' vaut 'nil') retourne false sinon ]]-- function p.presence_propriete(property, value, entity) local args = { ["property"] = property, link = "-", displayformat = "raw" } if (entity ~= nil) then args["entity"] = entity end local res = wd.stringTable(args) -- pas de résultat, cette propriété WD est absente je présume if (res == nil) then return false end -- on parcours les résultats pour voir si celle qu'on veut est là for k, v in pairs(res) do if (v == value) then return true -- trouvé end end return false -- pas trouvé end function p.existence_propriete(property, entity) local args = { ["property"] = property, link = "-", displayformat = "raw" } if (entity ~= nil) then args["entity"] = entity end local res = wd.stringTable(args) -- pas de résultat, cette propriété WD est absente je présume if (res == nil) then return false end return true -- trouvé end -- dédoublonne le contenu function p.dedoublonne(tbl) if (type(tbl) ~= "table") then return tbl end local out = {} local tmp = {} for k, v in ipairs(tbl) do if (tmp[v] == nil) then table.insert(out, v) tmp[v] = true end end return out end -- conversion affichage d'une liste de 'association' function p.affiche_elements(tbl) local ret = "" for k, v in ipairs(tbl) do ret = ret .. data.association[v]["texte"] .. " (" .. v .. ") " end return ret end --[[ retourne true si un élément wikidata existe pour l'article courant et false sinon ]]-- function p.a_wikidata() return mw.wikibase.getEntityIdForCurrentPage() ~= nil end --[[ Fonction externe (appelable) qui catégorise l'article courant en fonction de WD Ne reçoit actuellement aucun paramètre ]]-- function p.categorise(frame) -- si on n'est pas dans l'espace encyclopédique on ne fait rien local titre = mw.title.getCurrentTitle() if ((titre == nil) or (titre.namespace ~= 0)) then return "" -- on retourne un texte vide, donc l'action est inexistante end -- on regarde si la page a une entrée wikidata local awd = p.a_wikidata() if (not awd) then -- on catégorise et on quitte return "[[Catégorie:Wikipédia:Article sans Wikidata appelant le modèle Suivi des biographies]]" end -- on regarde si c'est un humain local hwd = p.presence_propriete("P31", "Q5", nil) if (not hwd) then -- on catégorise et on quitte return "[[Catégorie:Wikipédia:Article non biographique appelant le modèle Suivi des biographies]]" end -- là il faut aller plus loin et récupérer les métiers pour catégoriser local mwd = p.propriete_parente("P106", nil) -- si aucune réponse on le place dans "autres" if (mwd == nil) then -- on catégorise et on quitte return "[[Catégorie:Portail:Biographie/Articles liés/Général]]" end -- on a (au moins) une réponse : on regarde ce que contient le 1er élément (le "principal") --[[ note : on pourrait faire du multi-catégorie (ne pas utiliser de else/elseif alors mais "cumuler" diverses catégories et retourner le tout à la fin) on pourrait aussi faire des tests plus complexes du style si militaire et pas homme politique alors faire ci sinon si cela faire ça… ]]-- if (mwd[1] == "Q483501") then return "[[Catégorie:Portail:Biographie/Articles liés/Culture et arts]]" elseif (mwd[1] == "Q47064") then return "[[Catégorie:Portail:Biographie/Articles liés/Militaire]]" elseif (mwd[1] == "Q82955") then return "[[Catégorie:Portail:Biographie/Articles liés/Politique]]" elseif (mwd[1] == "Q2066131") then return "[[Catégorie:Portail:Biographie/Articles liés/Sport]]" else -- catégorie par défaut return mwd[1] end return "" -- on ne devrait pas arriver ici end --[[ Fonction externe (appelable) qui catégorise l'article courant en fonction de WD Ne reçoit actuellement aucun paramètre version "2", avec cumul de catégories ]]-- function p.categoriseBiographie(frame) -- si on n'est pas dans l'espace encyclopédique on ne fait rien local titre = mw.title.getCurrentTitle() if ((titre == nil) or (titre.namespace ~= 0)) then return "" -- on retourne un texte vide, donc l'action est inexistante end -- on regarde si la page a une entrée wikidata local awd = p.a_wikidata() if (not awd) then return data.cat_badwd end -- on regarde si la page a une nature de l'élément définie local nature = wd.formatStatements{property = 'P31', displayformat = 'raw'} if (not nature) then -- on retourne un texte vide, donc l'action est inexistante return "" end -- pour cumuler les éléments à retourner local out = data.cat_biographie -- on regarde si c'est un humain -- traitement spécifique pour les personnages humains de la Bible local awd2 = p.presence_propriete("P31", "Q20643955", nil) -- traitement spécifique pour les humains possiblement fictifs local awd3 = p.presence_propriete("P31", "Q21070568", nil) if (awd2 or awd3) then -- catégorisation dans Croyance et religion return out .. data.cat_religion end local hwd = p.presence_propriete("P31", "Q5", nil) if (not hwd) then -- pas une biographie return nul end -- On est sur une biographie, on affine la catégorisation local genre = p.existence_propriete("P21", nil) if (not genre) then -- catégorisation des biographies sans genre out = out .. data.cat_nongenre end -- là il faut aller plus loin et récupérer les métiers pour catégoriser local mwd = p.propriete_parente("P106", nil) -- en l'absence de profession on regarde la fonction if (mwd == nil) then mwd = p.propriete_parente("P39", nil) end -- en l'absence de profession et de fonction on regarde le titre de noblesse if (mwd == nil) then mwd = p.propriete_parente("P97", nil) end -- si aucune réponse on le place dans "autres" if (mwd == nil) then -- on catégorise -- traitement spécifique pour les sahabah local hwd3 = p.presence_propriete("P361", "Q188711", nil) -- traitement spécifique pour les saints local hwd7 = p.existence_propriete("P411", nil) if (hwd3 or hwd7) then -- catégorisation dans Religion out = out .. data.cat_religion else return out .. data.cat_defaut end else -- on a (au moins) une réponse : on parcours chaque entrée et on cumule les catégories associées local nb = 0 for k, v in ipairs(mwd) do -- bidouille pour les professions "Environ " if not v:match( '^Q%d+$' ) then if v:match( '^environ Q%d+$' ) then v = v:gsub( '^environ ','' ) end end out = out .. data.association[v]["catégorie"] nb = nb + 1 end -- si 0 catégorie insérée on met celle par défaut if (nb == 0) then -- traitement spécifique pour les personnages humains de la Bible local hwd4 = p.presence_propriete("P31", "Q20643955", nil) -- traitement spécifique pour les sahabah local hwd5 = p.presence_propriete("P361", "Q188711", nil) -- traitement spécifique pour les saint local hwd6 = p.presence_propriete("P411", "Q43115", nil) if (hwd4 or hwd5 or hdw6) then -- catégorisation dans Religion return out .. data.cat_religion else out = out .. data.cat_defaut end end end -- on retourne le résultat final return out end return p