Aller au contenu

Module:MiniBio

Une page de Wikipédia, l'encyclopédie libre.
Ceci est une version archivée de cette page, en date du 1 août 2019 à 10:02 et modifiée en dernier par Od1n (discuter | contributions) (utilisation de Module:Date::determinationMois pour centralisation code, et qui par rapport à valideMois supporte les numéros au format numérique, ce qui justement nous intéresse ici). Elle peut contenir des erreurs, des inexactitudes ou des contenus vandalisés non présents dans la version actuelle.

 Documentation[voir] [modifier] [historique] [purger]

Utilisation

Fonction exportable :

Autres fonctions :

  • trim() – Supprime les espaces en début et fin d'une chaîne

Modules externes et autres éléments dont ce module a besoin pour fonctionner :

  • Module:Outils – gestion paramètres du module.
  • Module:Date – gestion des dates.
  • Module:Date_complexe – gestion avancée des dates.
  • Module:Yesno – transforme un paramètre"oui/non/yes/no/..." en booléen
  • mw.ustring - gestion des chaînes de caractères UTF8
  • mw.text - gestion des chaînes de caractères
  • mw.wikibase - accès à la Wikidata

Exemples

local Exports = {} -- Objet à exporter.

-- Cette fonction supprime les espaces au début et à la fin de la chaîne de caractères passée en argument.
-- Ce traitement est fait avec les fonctions UTF8 (pas sûr que ce soit nécessaire pour supprimer des espaces).
function trim(s)
	if s == nil then
		return nil
	else
		return mw.ustring.gsub(mw.ustring.gsub(s,"^%s+", ""),"%s+$", "")
	end
end

-- Retourne une MiniBio de la personne demandée dans les arguments.
-- Le modèle MiniBio détaille les paramètres qu'il faut transmettre à cette fonction.
function Exports.MiniBio(frame)
	local outils=require('Module:Outils')
	local date_complexe=require('Module:Date_complexe')
	local Date=require('Module:Date') -- Majuscule initiale car le mot date est un mot clef du langage
	local yesno = require('Module:Yesno') -- Convertit les valeurs wikidata en true ou false.
	local args=outils.extractArgs(frame) -- Retourne les paramètres d'appel du modèle et du module
	local res='' -- Chaîne résultat de la fonction
	local type_par_defaut='en ligne' -- Type de formatage des informations
	local type_carte='carte'         -- idem
	local id -- Identifiant wikidata de la personne concernée
	local entity -- Frame contennant les informations de la personne concernée
	local dateNaiss,dateDeces -- Dates de naissance et de décès de la personne concernée
	
    -- Nettoyage des paramètres
    args[1]=trim(args[1])
    args[2]=trim(args[2])
	args['wikidata']=trim(args['wikidata'])
	
	-- Arrêt si l'on n'a pas assez d'informations
	if (not args[1] or args[1]=='') and (not args['wikidata'] or args['wikidata']=='') then
		return ''
	end
	
	-- Nettoyage des paramètres (suite)
	args['lang']=trim(args['lang'])
	-- Contrôle le paramètre 'type'.
	-- Il est convertit en minuscules.
	-- S'il est absent ou d'une valeur non prévue, on lui assigne la valeur par défaut
	if args['type'] then
		args['type']=mw.ustring.lower(trim(args['type']))
		if args['type']~=type_par_defaut and args['type']~=type_carte then
	    	args['type']=type_par_defaut
	    end
    else
    	args['type']=type_par_defaut
    end
    -- Contrôle le paramètre lien
	args['lien']=yesno(trim(args['lien']),true,true) -- true par défaut ou absent
	if args['lien']==nil then
		args['lien']=true
	end
	-- Mise en tableau des dates pour une manipulation plus aisée
	-- Les dates de naissance auront des indices impairs, les décès seront pairs
	local tabDateAlt = {
		[1]=args['DNaissAlt1'], [2]=args['DDecesAlt1'],
		[3]=args['DNaissAlt2'], [4]=args['DDecesAlt2'],
		[5]=args['DNaissAlt3'], [6]=args['DDecesAlt3']
	}

	-- Contrôle les paramètres autres dates.
	-- On va transformer les dates données sous forme naturelle à une table contenant trois éléments :
	-- [1] : le jour, [2] : le mois et {3] l'année.
	-- On considère que s'il y a moins de trois éléments alors le jour ou/et le mois ont été omis
	-- donc la table peut ne pas avoir d'élément [1] voire [2] ; mais elle aura toujours un élément [3].
	for i=1,#tabDateAlt do
		tabDateAlt[i]=trim(tabDateAlt[i])
		if type(tabDateAlt[i])~='string' or tabDateAlt[i]=='' then
			tabDateAlt[i]=nil
		else
			-- On transforme les / en espaces
			-- On supprime les espaces superfétatoires
			-- On éclate la chaîne (délimitée par des espaces) en un tableau 
			tabDateAlt[i]=mw.text.split(mw.ustring.gsub(mw.ustring.gsub(tabDateAlt[i],"/", " "),"%s+"," "),' ')
			-- Si la mention "av. J.-C." est présente, elle est réaccrochée à l'année
			-- Pour cela, on teste que le dernier élément du tableau (s'il contient plus de deux éléments)
			-- ne peut pas se convertir en nombre (on ne teste pas type()=='string' car ce sont tous des chaînes de caractères)
			-- Dans un premier temps si la chaîne est en plusieurs morceaux. On traite les parties non numériques
			while #tabDateAlt[i]>=2 and not tonumber(tabDateAlt[i][#tabDateAlt[i]]) and not tonumber(tabDateAlt[i][#tabDateAlt[i]-1]) do
				tabDateAlt[i][#tabDateAlt[i]-1]=tabDateAlt[i][#tabDateAlt[i]-1] .. ' ' .. tabDateAlt[i][#tabDateAlt[i]]
				tabDateAlt[i][#tabDateAlt[i]]=nil
			end
			-- Dernier réaccrochage (à la partie numérique)
			if #tabDateAlt[i]>=2 and not tonumber(tabDateAlt[i][#tabDateAlt[i]]) then
				tabDateAlt[i][#tabDateAlt[i]-1]=tabDateAlt[i][#tabDateAlt[i]-1] .. ' ' .. tabDateAlt[i][#tabDateAlt[i]]
				tabDateAlt[i][#tabDateAlt[i]]=nil
			end
			-- Si le jour ou/et le mois ne sont pas indiqués, on décale les infos vers les indices supérieurs
			if #tabDateAlt[i]>=1 then 
				while not tabDateAlt[i][3] do
					tabDateAlt[i][3]=tabDateAlt[i][2]
					tabDateAlt[i][2]=tabDateAlt[i][1]
					tabDateAlt[i][1]=nil
				end
			end
		end
	end

	--Si le paramètre wikidata n'est pas indiqué alors on fera une recherche sur nom de page.
	if args['wikidata'] and args['wikidata']~='' then
		id=args['wikidata']
    else
	    -- Si l'on a bien un premier paramètre
		if args[1] and args[1]~='' then
	    	id=mw.wikibase.getEntityIdForTitle(args[1])
	    end
    end
	-- Recherche des informations nécessaires
	if id then
   		entity=mw.wikibase.getEntity(id) -- Opération coûteuse
   	end
    
	-- Si l'entité nous a été retournée
	if entity and entity.claims then
		-- On vérifie qu'on a affaire à un être humain
		if entity.claims['P31'] and entity.claims['P31'][1].mainsnak.datavalue.value.id=='Q5' then
			-- On accède à la date de naissance et on la reformate
			if entity.claims['P569'] and entity.claims['P569'][1].mainsnak.datavalue then
				dateNaiss=date_complexe.splitDate(entity.claims['P569'][1].mainsnak.datavalue.value.time)
			end
			-- On accède à la date de décès et on la reformate
			if entity.claims['P570'] and entity.claims['P570'][1].mainsnak.datavalue then
				dateDeces=date_complexe.splitDate(entity.claims['P570'][1].mainsnak.datavalue.value.time)
			end
		end
	end

	-- Mise en place du lien wikidata du type : [[Prénom Nom]]
	-- Si l'id wikidata n'a pas été fourni on se rabat sur les noms indiqués dans l'appel
	if not args['wikidata'] or not entity then
		if args['lien'] then
			if args[2] and args[2] ~= '' then
				res = '|' .. args[2]
			end
			res = args[1] .. res
		else
			if args[2] and args[2] ~= '' then
				res = args[2]
			else
				res = args[1]
			end
		end
	else
	-- Si l'id wikidata a été indiqué, on va chercher le titre de la page
		local tmp=entity:getLabel()
		if args['lien'] then
			if args[2] and args[2] ~= '' then
				res = '|' .. args[2]
			else
				if args[1] and tmp ~= args[1]  and args[1] ~= '' then
					res = '|' .. args[1]
				end
			end
			res = tmp .. res
		else
			if args[2] and args[2] ~= '' then
				res = args[2]
			else
				if args[1] and args[1] ~= '' then
					res = args[1]
				else
					res = tmp
				end
			end
		end
	end
	if res ~= '' and args['lien'] then
		res = '[[' .. res .. ']]'
	end

	-- Gestion du lien interwiki	
	if args['lang'] and entity then
		local tmp = entity:getSitelink()
		-- Teste si la page existe dans le wiki
		if not tmp or tmp == '' then
			tmp = entity:getSitelink(args['lang'] .. 'wiki')
			-- Teste si la page existe dans le wiki de la langue voulue
			if tmp and tmp ~= '' then
				res = res .. ' [[w:' .. args['lang'] .. ':' .. tmp
					.. '|<span class="indicateur-langue" title="Équivalent de l’article dans une autre langue">(' .. args['lang'] .. ')</span>]]'
			end
		end
	end
	
	if entity then
    	-- Formatage des résultats par défaut "en ligne"
    	if args['type']==type_par_defaut then
    		-- Affichage des dates de vie
    		if dateNaiss or dateDeces then
				res = res .. ' ('
				if dateNaiss then
					res = res .. Date.modeleDate({[3]=tonumber(dateNaiss.era .. dateNaiss.year),['avJC']=((dateDeces and dateDeces.era=='-') and 'non' or 'oui')})
				else
					res = res .. '???'
				end
				if dateDeces then
					res = res .. '-' .. Date.modeleDate({[3]=tonumber(dateDeces.era .. dateDeces.year)})
				end
				res = res .. ')'
			end
			-- Formatage des dates alternatives
			local dateAlt=false
			for i=1,#tabDateAlt,2 do
				if tabDateAlt[i] and tabDateAlt[i+1] then
					-- On ne garde que les années
					tabDateAlt[i][1] = nil
					tabDateAlt[i][2] = nil
					tabDateAlt[i+1][1] = nil
					tabDateAlt[i+1][2] = nil
					tabDateAlt[i].avJC='non'
					res = res .. ' ou (' .. Date.modeleDate(tabDateAlt[i]) .. '-' .. Date.modeleDate(tabDateAlt[i+1]) .. ')'
					dateAlt=true
				end
			end
			if dateAlt then
				res = res .. ' selon les sources'
			end
			-- Affichage du lien vers la Wikidata
			res = res .. ' [[Fichier:Blue pencil.svg|Modifier Wikidata|link=d:' .. id .. '|10px]]'
    	end
    	
    	-- Formatage des résultats "carte"
    	if args['type']==type_carte then
			-- Affichage de l'image
			if entity.claims['P18'] and entity.claims['P18'][1].mainsnak.datavalue then
				res = res .. '[[Fichier:' .. entity.claims['P18'][1].mainsnak.datavalue.value
					.. '|frameless|gauche|alt=' .. args[1] .. '|' .. args[1] .. ']]'
			end
			-- Affichage de la date de naissance
			if dateNaiss then
				local tmp={}
				if dateNaiss.day~=0 then
					tmp[1]=dateNaiss.day
				end
				if dateNaiss.month~=0 then
					tmp[2]=dateNaiss.month
				end
				tmp[3]=tonumber(dateNaiss.era .. dateNaiss.year)
				res = res .. '<br/>Naissance : ' .. Date.modeleDate(tmp)
				-- Formatage des dates alternatives
				-- Les dates de naissance sont sur les numéros impairs
				local dateAlt=false
				for i=1,#tabDateAlt,2 do
					if tabDateAlt[i] then
						res = res .. '<br/>ou ' .. Date.modeleDate(tabDateAlt[i])
						dateAlt=true
					end
				end
				if dateAlt then
					res = res .. ' selon les sources'
				end
			end
			-- Affichage de la date de décès
			if dateDeces then
				local tmp={}
				if dateDeces.day~=0 then
					tmp[1]=dateDeces.day
				end
				if dateDeces.month~=0 then
					tmp[2]=dateDeces.month
				end
				tmp[3]=tonumber(dateDeces.era .. dateDeces.year)
				res = res .. '<br/>Décès : ' .. Date.modeleDate(tmp)
				-- Formatage des dates alternatives
				-- Les dates de décès sont sur les numéros pairs
				local dateAlt=false
				for i=2,#tabDateAlt,2 do
					if tabDateAlt[i] then
						res = res .. '<br/>ou ' .. Date.modeleDate(tabDateAlt[i])
						dateAlt=true
					end
				end
				if dateAlt then
					res = res .. ' selon les sources'
				end
			end
			-- Formatage de la carte
			-- Plus Clearfix CSS
			-- Et lien vers la Wikidata
			res = '<div style="background:#eaecf0;width:450px;border-radius:5%;padding:15px">' .. res 
				.. '<div style="clear:both;"></div><small><small>[[d:' .. id .. '|Modifier Wikidata]]</small></small></div>'
    	end
    end
	
	return res
end

-- Retourne les catégories dates de vie d'une personne
--         Naissance en ...
--         Décès en ...
--         Décès à ... ans
--         Mort récente
function Exports.categorise() -- 
	local date_complexe=require('Module:Date_complexe')
	local Date=require('Module:Date') -- Majuscule initiale car le mot date est un mot clef du langage
	local res='' -- Chaîne résultat de la fonction
	local entity=mw.wikibase.getEntity() -- Frame contennant les informations de la personne concernée
	local dateNaiss,dateDeces -- Dates de naissance et de décès de la personne concernée
	local age -- age de la personne concernée
	
	-- Si l'entité nous a été retournée
	if entity and entity.claims then
		-- On vérifie qu'on a affaire à un être humain
		if entity.claims['P31'] and entity.claims['P31'][1].mainsnak.datavalue.value.id=='Q5' then
			-- On accède à la date de naissance et on crée la catégorie "Naissance en..."
			if entity.claims['P569'] and entity.claims['P569'][1].mainsnak.datavalue then
				dateNaiss=date_complexe.splitDate(entity.claims['P569'][1].mainsnak.datavalue.value.time)
				if dateNaiss then
					res = res .. '[[Catégorie:Naissance en '
					if dateNaiss.month~=0 then
						res = res .. Date.determinationMois(dateNaiss.month) .. ' '
					end
					res = res .. dateNaiss.year
					if dateNaiss.era=='-' then
						res = res .. ' av. J.-C.'
					end
					res = res  .. ']]'
				end
			end
			-- On accède à la date de décès et on crée la catégorie "Décès en..."
			if entity.claims['P570'] and entity.claims['P570'][1].mainsnak.datavalue then
				dateDeces=date_complexe.splitDate(entity.claims['P570'][1].mainsnak.datavalue.value.time)
				if dateDeces then
					res = res .. '[[Catégorie:Décès en '
					if dateDeces.month~=0 then
						res = res .. Date.determinationMois(dateDeces.month) .. ' '
					end
					res = res .. dateDeces.year
					if dateDeces.era=='-' then
						res = res .. ' av. J.-C.'
					end
					res = res  .. ']]'					
				end
			end
			-- Si on a la date de décès complète
			if dateDeces and dateDeces.day~=0 and dateDeces.month~=0 and dateDeces.year~=0 then
				-- Si on a la date de naissance complète
				if dateNaiss and dateNaiss.day~=0 and dateNaiss.month~=0 and dateNaiss.year~=0 then
					-- Crée la catégorie "Décès à ... ans"
					age=Date.age(dateNaiss.era..dateNaiss.year,dateNaiss.month,dateNaiss.day,dateDeces.era..dateDeces.year,dateDeces.month,dateDeces.day)
					if age == 0 then
						res = res .. '[[Catégorie:Décès avant 1 an]]'
					elseif age == 1 then
						res = res .. '[[Catégorie:Décès à 1 an]]'
					elseif age > 122 then
						res = res .. '[[Catégorie:Décès supposé après 122 ans]]'
					else
						res = res .. '[[Catégorie:Décès à ' .. age .. ' ans]]'
					end
				end
				-- Calcule si l'on affiche [[Catégorie:Mort récente]]
				-- On compare si la différence entre la date du jour et la date de décès est de moins de 5 jours
				if 	os.difftime(os.time(),os.time(dateDeces))<=5*86400 then
						res = res .. '[[Catégorie:Mort récente]]'
				end
			end
		end
	end
	return res
end

return Exports