Module:Taxoboft
De Wikipedia, l'encyclopédie encyclopedia
local p = {}
--[[
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.
--]]
-- 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 '' .. texte .. '' 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 .. "
" else tres = tres .. "non
" 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 .. "
" .. (auteurs[i] or "") .. "
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 .. "
"
else
-- un taxon "normal"
" end end -- ajout de la catégorie if (categorie ~= nil) then -- tres2 = "\n" .. tres2 tres = tres .. "Catégorie insérée : Catégorie:" .. categorie .. "
" 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