Module:Taxoboft
Apparence
La documentation de ce module est générée par le modèle {{Documentation module}}.
Les éditeurs peuvent travailler dans le bac à sable (créer).
Voir les statistiques d'appel depuis le wikicode sur l'outil wstat et les appels depuis d'autres modules.
--[[
Ceci est un essai de taxobox dont la classification est gérée comme données
« externes », afin de tester une centralisation des informations de classification
(peut-être en attendant wikidata).
Pour le moment la classification est restreinte aux reptiles, et partielle.
Ceci n'est pas un module de prod.
--]]
local p = {}
-- données globales liées à la classification initiale
p.regne = nil -- le règne initial
p.cache_regne = nil -- faut-il masquer le règne ?
p.limite = nil -- le rang limite à traiter
p.tlimite = nil -- le type de limite
p.classification = nil -- la classification suivie
function p.erreur(texte)
if (type(texte) ~= "string") then
texte = "Erreur non précisée"
end
return '<span class="error">' .. texte .. '</span>'
end
--[[
Fonction fille de la suivante.
Cette fonction insert dans la table fournie (qui peut être vide)
la liste des éléments de classification correspondant aux paramètres
Modifie la table passée et retourne le quadruplet {rang, nom, classification, nb}
correspondant à ce qui se trouve au-dessus. Si l'une des valeurs (au moins)
vaut nil c'est qu'on est arrivé en haut de la classification.
nb est le nombre d'entrées ajoutées
Si une erreur se produit retourne un "string" contenant l'erreur.
--]]
function p.taxoboft_table(resu, rang, nom, classification, premier)
-- précaution : resu doit être une table
if (type(resu) ~= "table") then
return { false, p.erreur("Interne : l'élément fourni n'est pas une table.") }
end
-- vérification éléments obligatoires
if (rang == nil or nom == nil or classification == nil) then
return { false, p.erreur("Rang, nom et classification obligatoires.") }
end
-- on cherche si la classification existe en chargeant le module de données
local data = mw.loadData('Module:Taxoboft/data ' .. classification)
if (data == nil) then
return { false, p.erreur("La classification '" .. classification .. "' est inconnue.") }
end
-- si premier passage on enregistre les infos nécessaires
if (premier) then
p.classification = data.code_classification
p.regne = data.regne_classification
p.cache_regne = data.cache_regne
end
-- si limite indiquée dans cette classification et pas déjà précisée on la récupère
if (data.limite_classification ~= nil and p.limite == nil) then
p.limite = data.limite_classification
end
-- type de limite
if (data.limite_classification_stricte == true and p.tlimite == nil) then
p.tlimite = true
end
-- données de traitement : le rang et le nom de l'entité
local cur_rang = rang
local cur_nom = nom
local sauve_rang = rang
local sauve_nom = nom
-- boucle de parcours à partir de l'élément courant
local nb = 0
while true
do
-- si les deux sont nil on quitte la boucle (on est arrivé en haut)
if (cur_rang == nil or cur_nom == nil) then
break
end
-- on cherche la table liée à ce rang
local rtable = data.classification[cur_rang]
if (rtable == nil) then
-- problème
return { false, p.erreur("Aucune entrée pour le rang '" .. cur_rang .. "' dans la classification '"
.. classification .. "'.") }
end
-- on parcours cette table pour trouver notre élément
local i = 1
local trouve = nil
local nbm = 0
while (rtable[i] ~= nil) do
-- on cherche l'élément
trouve = rtable[i][cur_nom]
if (trouve ~= nil) then
-- on note le nombre de frères
nbm = rtable[i]["nombre"]
break
end
i = i + 1
end
if (trouve == nil) then
-- ce taxon n'existe pas dans ce rang de cette classification
return { false, p.erreur("Aucune entrée pour le taxon '" .. cur_nom .. "' dans la classification '"
.. classification .. "' au rang '" .. cur_rang .. "'.") }
end
-- on a trouvé l'élément : on le stocke dans les résultats
local tbl = { ["rang"] = cur_rang, ["nom"] = cur_nom }
-- si seul de son niveau → monotypique
if (nbm == 1) then
tbl["monotypique"] = true
end
-- informations additionnelles (si présentes)
if (trouve == 1) then
-- il est noté pour catégorisation
tbl["catégorie"] = true
elseif (type(trouve) == "table") then
if (trouve[1] == 1) then
-- il est noté pour catégorisation
tbl["catégorie"] = true
end
if (trouve[2] ~= nil) then
-- nom réel de l'article
tbl["article"] = trouve[2]
end
end
-- si limite est indiqué, et que le type de limite est "strict", on n'insert pas (et on quitte)
-- si c'est lui
if (p.limite ~= nil and p.tlimite == true and tbl["rang"] == p.limite) then
break -- on sort, on aurait atteint la limite
end
-- on insert l'élément dans les résultats (note : la table est à l'envers)
table.insert(resu, tbl)
nb = nb + 1 -- position du dernier
-- si limite est indiqué (on n'est pas en type strict), on quitte après insertion
-- si c'est lui
if (tbl["rang"] == p.limite) then
break -- on sort, on a atteint la limite
end
-- on mémorise le dernier rang
sauve_rang = cur_rang
sauve_nom = cur_nom
-- on passe au parent
cur_rang = rtable[i]["parent"][1]
cur_nom = rtable[i]["parent"][2]
end
-- on est au bout. Est-ce qu'il y a une classification au-dessus ?
if (data.classification_parente == "SOMMET") then
-- non, on indique la fin
return {nil, nil, nil, nb}
end
-- sinon on retourne le rang+nom du dernier traité, plus la classification à suivre
return {sauve_rang, sauve_nom, data.classification_parente, nb}
end
--[[
Fonction principale : génère la partie classification d'une taxobox (classification classique)
à partir du genre ou du genre et de l'espèce (ou du genre, de l'espèce et de la sous-espèce)
Paramètres :
rang= : le rang du taxon considéré
nom= : le nom du taxon considéré
nom2= : si espèce, la deuxième partie du nom
nom3= : si sous-espèce, la troisième partie du nom
image= : le fichier image (optionnel)
légende= : la légende associée (optionnel)
auteur= : l'auteur (optionnel)
classification= : la classification à suivre
--]]
function p.taxoboft_reelle(rang, nom, nom2, nom3, image, legende, classification, auteur, auteur2, auteur3, auteur4, spmono)
-- vérification éléments obligatoires
if (rang == nil or nom == nil or classification == nil) then
return p.erreur("Rang, nom et classification obligatoires.")
end
-- table des auteurs (plus pratique)
local auteurs = { auteur, auteur2, auteur3, auteur4 }
-- on crée une table vide pour recevoir les résultats
local resu = {}
local nb = 0
-- on traite la demande dans une boucle (pour passer aux classifications au-dessus)
local c_rang = rang
local c_nom = nom
local c_classif = classification
local premier = true
while true do
-- on reçoit un triplet {rang, nom, classification} ou bien une chaîne d'erreur (+ nb traité)
local from = p.taxoboft_table(resu, c_rang, c_nom, c_classif, premier)
-- erreur ?
if (type(from[1]) == "false") then
return from[2]
end
-- on ajoute le nombre d'éléments insérés
nb = nb + from[4]
-- si retour = nil on a terminé la classification
if (from[1] == nil or from[2] == nil or from[3] == nil) then
break
end
-- paramètres du rang supérieur
c_rang = from[1]
c_nom = from[2]
c_classif = from[3]
-- on supprime le dernier élément, qui serait dupliqué à la jointure
table.remove(resu)
nb = nb - 1
if (premier) then
premier = false
end
end
-- parcours terminé : on a la classification
local tres = ""
local tres2 = ""
local categorie = nil
-- on affiche les données dans l'ordre
-- d'abord l'entête taxobox
local ngb = nom
if (nom2 ~= nil) then
ngb = ngb .. " " .. nom2
end
if (nom3 ~= nil) then
ngb = ngb .. " " .. nom3
end
tres2 = tres2 .. "{{Taxobox début|" .. p.regne .. "|" .. ngb .. "|" .. (image or "") .. "|" .. (legende or "") .. "|classification=" .. p.classification
if (p.cache_regne) then
tres2 = tres2 .. "|règne=cacher}}\n"
else
tres2 = tres2 .. "}}\n"
end
tres = tres .. "taxobox début : règne='" .. p.regne .. "', classification='" ..
p.classification .. "', image='" .. (image or " ") .. "', légende='" .. (legende or " ") .. "', cacher-règne="
if (p.cache_regne) then
tres = tres .. "oui<br/>"
else
tres = tres .. "non<br/>"
end
-- s'il y a un nom d'espèce on insert une entrée pour celle-ci
-- note : impossible de savoir si une espèce est monotypique (pas présent dans la classification)
-- on utilise donc un paramètre dédié
if (nom2 ~= nil) then
local tbl = { ["rang"] = "espèce", ["nom"] = nom .. " " .. nom2 }
if (spmono) then
tbl["monotypique"] = true
end
table.insert(resu, 1, tbl)
end
-- s'il y a une sous-espèce on insert une entrée pour celle-ci
-- une sous-espèce monotypique n'existe pas, c'est pratique
if (nom3 ~= nil and nom2 ~= nil) then
local tbl = { ["rang"] = "sous-espèce", ["nom"] = nom .. " " .. nom2 .. " " .. nom3 }
table.insert(resu, 1, tbl)
end
-- on part du deuxième pour compter le nombre de monotypiques, afin d'afficher en monotypique
-- (taxobox taxon) les N premiers si besoin
local nbm = 1 -- inclure le premier
for i = 2,nb do
if (resu[i]["monotypique"]) then
nbm = nbm + 1
else
-- fini
break
end
end
for i = nb,1,-1 do
-- si présence de catégorie on le note
if (resu[i]["catégorie"] ~= nil) then
if (resu[i]["nom"] == nom) then
-- article principal de la catégorie
categorie = resu[i]["nom"] .. "|*"
else
categorie = resu[i]["nom"]
end
end
if (i <= nbm) then
-- le taxon décrit
tres2 = tres2 .. "{{Taxobox taxon|" .. p.regne .. "|" .. resu[i]["rang"] .. "|" .. resu[i]["nom"] .. "|" .. (auteurs[i] or "") .. "}}\n"
tres = tres .. "taxobox taxon : règne='" .. p.regne .. "', rang='" ..
resu[i]["rang"] .. "', nom='" .. resu[i]["nom"] .. "', auteur='" ..
(auteur or " ") .. "'"
if (resu[i]["article"] ~= nil) then
tres = tres .. ", lien article='" .. resu[i]["article"] .."'"
end
tres = tres .. "<br/>"
else
-- un taxon "normal"
tres2 = tres2 .. "{{Taxobox|" .. resu[i]["rang"] .. "|"
if (resu[i]["article"] ~= nil) then
tres2 = tres2 .. resu[i]["article"] .. "|" .. resu[i]["nom"] .. "}}\n"
else
tres2 = tres2 .. resu[i]["nom"] .. "}}\n"
end
tres = tres .. "taxobox : rang='" .. resu[i]["rang"] .. "', nom='" ..
resu[i]["nom"] .. "'"
if (resu[i]["article"] ~= nil) then
tres = tres .. ", lien article='" .. resu[i]["article"] .."'"
end
tres = tres .. "<br/>"
end
end
-- ajout de la catégorie
if (categorie ~= nil) then
-- tres2 = "[[Catégorie:" .. categorie .. "]]\n" .. tres2
tres = tres .. "Catégorie insérée : Catégorie:" .. categorie .. "<br/>"
end
-- on retourne le résultat
return tres2
end
--[[
Fonction réelle (exportée).
Juste un wrapper pour celle du dessus
Paramètres :
rang= : le rang du taxon considéré
nom= : le nom du taxon considéré
nom2= : si espèce, la deuxième partie du nom
nom3= : si sous-espèce, la troisième partie du nom
image= : le fichier image (optionnel)
légende= : la légende associée (optionnel)
auteur= : l'auteur (optionnel)
classification= : la classification à suivre
--]]
function p.taxoboft(frame)
local args = frame.args
local pargs = frame:getParent().args
-- on récupère les paramètres
local rang = pargs["rang"] or args["rang"]
local nom = pargs["nom"] or args["nom"]
local nom2 = pargs["nom2"] or args["nom2"]
local nom3 = pargs["nom3"] or args["nom3"]
local image = pargs["image"] or args["image"]
local legende = pargs["légende"] or args["légende"]
local classification = pargs["classification"] or args["classification"]
local auteur = pargs["auteur"] or args["auteur"]
local auteur2 = pargs["auteur2"] or args["auteur2"]
local auteur3 = pargs["auteur3"] or args["auteur3"]
local auteur4 = pargs["auteur4"] or args["auteur4"]
local spmono = pargs["espèce monotypique"] or args["espèce monotypique"]
if (spmono ~= nil) then
spmono = true
else
spmono = false
end
-- on ne gère pas les rangs en dessous du genre. Conversion :
if (rang == "espèce") then
rang = "genre"
elseif (rang == "sous-espèce") then
rang = "genre"
end
return frame:preprocess(p.taxoboft_reelle(rang, nom, nom2, nom3, image, legende, classification, auteur, auteur2, auteur3, auteur4, spmono))
end
-- on retourne le module
return p