Module:Taxobox fonctions
Apparence
[voir] [modifier] [historique] [purger]
Ce module fournit diverses fonctions de traitement de l'information d'une taxobox. Ce sont des fonctions annexes qui sont déportées ici afin d'alléger le code principal.
Utilisation
[modifier le code]Fonctions exportables :
aucune (sous-module)
Fonctions utilitaires fournies pour le module principal :
- Gestion des données externes :
p.erreur_fatale(message, cat)
: insert une erreur (message) avec l'éventuelle clé de catégorie d'erreur (cat), et indique au module principal que l'erreur est fatalep.erreur_normale(message, cat)
: comme la précédente sans l'erreur fatalep.ajoute_categorie(cat)
: insert une catégorie dans la liste des catégories à insérerp.erreur_globale(def, cat)
: retourne une boîte d'erreur contenant def et insert la catégorie cat si présente
- Gestion des boîtes d'information :
p.box_ouverture(titre)
: ouvre une boîte d'information (utilisé hors espace encyclopédique pour présenter les erreurs, catégories, modifications de titre…)p.box_fermeture()
: ferme la boîte précédentep.box_sous_titre(titre)
: ajoute un sous-titre à la boîte précédentep.box_texte(texte, cat)
: ajoute le texte indiqué à la boîte précédente
- Gestion des éléments d'une taxobox :
p.tb_ligne_mixte_champs(texte)
: insert la partie "champs" d'une ligne champs+valeur (utilisée par ligne_mixte())p.tb_ligne_mixte_valeur(texte)
: insert la partie "valeur" d'une ligne champs+valeur (utilisée par ligne_mixte())p.tb_ligne_mixte(rang, nom)
: insert une ligne champs+valeurp.tb_bloc(texte)
: insert un bloc (sous-titre)p.tb_texte(texte)
: insert une zone de texte
- Gestion du formatage des noms scientifiques :
p.italiques(regne, rang)
: retourne vrai si le règne+rang doit être en italiquep.italiques_ns(nom, cible, regne, rang, lien)
: retourne nom avec la mise en forme nécessaire (si besoin) en fonction du règne et du rang. lien indique qu'il faut retourner un wikilien. cible indique la cible du wikilien (ou nil).p.italique_cultivar(nom)
: retourne nom mis en italiques selon les conventions des cultivarsp.italiques_titre(titre, ns, rang)
: retourne l'action à faire sur le titre de l'article (DISPLAYTITLE) à partir du titre de l'article (titre), du nom scientifique du taxon concerné (ns) et du rang de celui-ci (rang)
- Gestion des paramètres passés à la taxobox et autres outils :
p.genere_titre_taxobox()
: détermine le titre de la taxobox à partir des entrées taxon présentesp.lit_parametre(nom, valides, flag, fatal)
: lit un paramètre nommé passé à la taxobox. nom est le nom du paramètre nommé, valides est une liste de textes (si différent de nil la valeur doit être dans cette liste), fatal vrai indique que l'absence de valeur est une erreur fatale, flag indique si vrai que le paramètre vaudra true quelle que soit sa valeur ou false si absentp.est_dans_liste(nom, liste)
: indique si nom est présent dans listep.tri_parametres(conf)
: parcours les paramètres non nommés pour créer donnees.defauts.commandes qui contient une ligne par « ligne de commande »p.tri_taxons()
: parcours les commandes trouvées par la fonction ci-dessus pour trouver les entrées taxon présentes. Note également le dernier, et cherche en même temps si l'un d'entre eux correspond au titre de l'articlep.existe(page)
: retourne vrai si la page existe
- Outils pour la génération de la sortie :
p.insert_image(image, legende, complet)
: insert l'image indiquée. La légende sert ici uniquement pour mettre un champs de description correct. complet indique que l'image est déjà sous la forme "Fichier:XXX", sinon suppose que c'est "XXX"p.lien_en_minuscule(lien)
: retourne le lien passé en passant la première lettre en minuscule (pour insertion dans un texte)p.lecture_parametres(ligne, depart, desc)
: analyse une ligne de commande (commande + ses paramètres) à partir de depart (entier) en suivant la description desc
- Functions servant à générer les différentes lignes fonctionnelles d'une taxobox. Tous sont équivalents au taxobox "nom" correspondant
p.cmd_debut(params)
:p.cmd_fin(params)
:p.cmd_phylo_bandeau(params)
:p.cmd_rang(params)
:p.cmd_taxon(params)
:p.cmd_uicn(params)
:p.cmd_cites(params)
:p.cmd_synonymes(params)
:p.cmd_taxons(params)
:p.cmd_phylo_inexistant(params)
:p.cmd_position(params)
:
La documentation de ce module est générée par le modèle {{Documentation module}}.
Elle est incluse depuis sa sous-page de documentation. Veuillez placer les catégories sur cette page-là.
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.
--[[
Module utilisé par Module:Taxobox.
Contient diverses fonctions utiles de traitement des informations d'une taxobox.
--]]
-- table locale
local p = {}
local donnees = require "Module:Taxobox données"
--[[
Génère une erreur fatale avec le message indiqué et la catégorie indiquée.
Met à "true" le champ donnees.defauts.fatal
Ajoute le message à la liste des messages d'erreur et les catégories correspondantes
--]]
function p.erreur_fatale(message, cat)
-- noté fatal
donnees.defauts.fatal = true
-- ajout du texte
table.insert(donnees.defauts.r_erreurs, cat .. " : " .. message)
-- ajout de la catégorie d'erreur
table.insert(donnees.defauts.r_err_categories, {donnees.categorie_erreur, cat})
end
--[[
Génère une erreur non fatale (ou en tout cas quand ce n'est pas à la fonction qui détecte
l'erreur de décider que c'est fatal ou pas) avec le message indiqué et la catégorie indiquée.
Met à "true" le champ donnees.defauts.fatal
Ajoute le message à la liste des messages d'erreur et les catégories correspondantes
--]]
function p.erreur_normale(message, cat)
-- ajout du texte
table.insert(donnees.defauts.r_erreurs, cat .. " : " .. message)
-- ajout de la catégorie d'erreur
table.insert(donnees.defauts.r_err_categories, {donnees.categorie_erreur, cat})
end
--[[
Insert une catégorie "normale"
--]]
function p.ajoute_categorie(cat)
-- ajout de la catégorie
table.insert(donnees.defauts.r_categories, cat)
end
--[[
Génère une boîte d'erreur globale
Reçoit une table "defauts" contenant les données d'erreur.
--]]
function p.erreur_globale(def, cat)
local box
local frame = mw.getCurrentFrame()
local templatestyles = frame:extensionTag( 'templatestyles', '', { src = 'MediaWiki:Common.css/taxobox v3.css' } )
local classes = frame:expandTemplate{ title = 'Classes début infobox', args = { version = '3' } }
box = templatestyles .. '<div class="' .. classes .. ' large taxobox_v3 bordered error" style="width: 20em">\n'
box = box .. '<p class="entete">' .. "Erreur d'utilisation du modèle/module taxobox.<br/>Voir [[Modèle:Taxobox/Documentation|la documentation]] associée." .. '</p>\n'
if ( nil == def.r_erreurs or "" == def.r_erreurs ) then
texte = "Aucune description d'erreur fournie."
end
box = box .. '<p class="bloc">'
local i = 1
while (def.r_erreurs[i] ~= nil) do
box = box .. def.r_erreurs[i] .. '<br/>'
i = i + 1
end
box = box .. '</p>\n</div>\n'
-- insertion de la catégorie "en erreur" (sauf si NAMESPACE pas article (si indiqué))
if (def.article == true) then
if (def.r_err_categories ~= nil) then
box = box .. "[[Catégorie:" .. cat .. "|" .. def.r_err_categories[1] .. "]]\n"
else
box = box .. "[[Catégorie:" .. cat .. "]]\n"
end
end
return box
end
--[[
Ouvre une boîte d'information (pour ranger les titres, sous-titres, erreurs et catégories
selon les modes utilisés).
"titre" est le titre donné à la boîte
--]]
function p.box_ouverture(titre)
local box
local frame = mw.getCurrentFrame()
local templatestyles = frame:extensionTag( 'templatestyles', '', { src = 'MediaWiki:Common.css/taxobox v3.css' } )
local classes = frame:expandTemplate{ title = 'Classes début infobox', args = { version = '3' } }
box = templatestyles .. '<div class="' .. classes .. ' large taxobox_v3 bordered" style="width: 20em">\n'
box = box .. '<p class="entete">' .. (titre or "Titre absent") .. '</p>\n'
return box
end
--[[
Ferme la boîte ouverte ci-dessus
--]]
function p.box_fermeture()
return '</div>\n'
end
--[[
Insert un sous-titre à une boîte de message
--]]
function p.box_sous_titre(titre)
return '<span id="sous_titre_h1">' .. (titre or "Sous-titre absent") .. '</span>'
end
--[[
Insert un texte dans une boîte de message
Si 'cat' non vide c'est un texte indiquant la catégorie du texte, inséré avant lui.
--]]
function p.box_texte(texte, cat)
local txt = ""
if (type(texte) == "string") then
if (cat == true) then
txt = "[[:Catégorie:" .. texte .. "]]<br/>"
else
txt = texte
end
elseif (type(texte) == "table") then
local i = 1
while (texte[i] ~= nil) do
if (type(texte[i]) == "string") then
if (cat == true) then
txt = txt .. "[[:Catégorie:" .. texte[i] .. "]]<br/>"
else
txt = txt .. texte[i] .. "<br/>"
end
elseif (type(texte[i]) == "table") then
if (cat == true) then
txt = txt .. "[[:Catégorie:" .. texte[i][1] .. "|" .. texte[i][1] .. "/" .. texte[i][2] .. "]]<br/>"
else
txt = txt .. texte[i][2] .. "|" .. texte[i][1] .. "<br/>"
end
else
txt = txt .. "Entrée inconnue.<br/>"
end
i = i + 1
end
else
txt = nil -- erreur
end
if (type(cat) == "string") then
return '<p>' .. cat .. " : " .. (txt or "Texte vide.") .. '</p>'
else
return '<p>' .. (txt or "Texte vide.") .. '</p>'
end
end
-- génère le code de la première partie d'une ligne de classification
-- (la partie gauche : le rang)
-- non utilisée directement, voir fonction suivante.
function p.tb_ligne_mixte_champs(texte)
return '<tr>\n<th scope="row" style="width:8.5em;">' .. (texte or "") .. '</th>\n'
end
-- génère le code de la deuxième partie d'une ligne de classification
-- (la partie droite : le nom du taxon)
-- non utilisée directement, voir fonction suivante.
function p.tb_ligne_mixte_valeur(texte)
return '<td class="normal">' .. (texte or "") .. '</td>\n</tr>'
end
-- génère le code d'une ligne de classification. Utilise les deux fonctions précédentes.
-- Paramètres :
-- rang : le rang, partie gauche d'une ligne de classification
-- nom : le nom du rang associé, partie droite d'une ligne de classification
function p.tb_ligne_mixte(rang, nom)
return p.tb_ligne_mixte_champs(rang or "") .. p.tb_ligne_mixte_valeur(nom or "")
end
-- genere une entête de bloc. Ça correspond à un sous-titre de taxobox
-- Paramètres :
-- texte : texte à mettre dans la zone de sous-titre
function p.tb_bloc(texte)
return '<p class="bloc">' .. (texte or "Non indiqué") .. '</p>\n'
end
-- genere une entête de bloc. Ça correspond à un sous-titre de taxobox
-- Paramètres :
-- texte : texte à mettre dans la zone de sous-titre
function p.tb_texte(texte)
return '<p class="center">' .. (texte or "Non indiqué") .. '</p>\n'
end
-- gestion des italiques. Retourne true si le règne+rang doit être en italique, false sinon (nil si erreur)
function p.italiques(regne, rang)
-- les données du règne
local dr = donnees.regnes[regne]
if (dr == nil) then
return nil
end
if (dr.convention == "CIN") then
-- CIN, toujours en italique
return true
end
-- CINZ (puisque pas CIN) : on teste le rang
if (donnees.rangs[rang] == nil) then
return nil -- gestion d'erreur
end
if (donnees.rangs[rang].infgenre) then
return true -- inférieur au genre, italique
else
return false -- supérieur au genre, pas d'italique
end
end
--[[
Retourne vrai si le nom passé est un nom de clade en français (ça *doit* être un rang clade)
--]]
function p.clade_francais(nom)
local tst -- on regarde si présence d'accents
tst = mw.ustring.find(nom, "[éèêëàäâçùüûïîôöÉÈËÊÀÂÄÇÛÜÙÎÏÔÖ]")
if (tst ~= nil) then
return true -- visiblement en français on laisse sans mettre en italique
end
-- liste d'exclusion de noms traités comme français
local i = 1
while (donnees.exclusion_clade[i] ~= nil) do
if (donnees.exclusion_clade[i] == nom) then
-- exception, en français, on laisse sans italiques
return true
end
i = i + 1
end
return false
end
-- met en italique si besoin le nom passé en paramètre, en suivant les conventions correspondantes
-- si lien est vrai l'élément retourné est mis entre [[]].
-- si cible est une chaîne et que lien est vrai retourne [[cible|nom]] (mis en forme si besoin)
function p.italiques_ns(nom, cible, regne, rang, lien)
local disp = nom
local it = p.italiques(regne, rang)
if (it == nil) then
p.erreur_normale("L'appel à ''p.italiques(" .. (regne or "<règne absent>") .. ", " .. (rang or "<rang absent>") .. ")'' a échoué.", "interne")
return nom or ""
end
-- détection particulière : si clade et détecté en français → pas italiques
if (rang == "clade") then
if (p.clade_francais(nom)) then
it = false -- on désactive l'italique
end
end
-- besoin d'italiques, on calcule la version à afficher
if (it) then
-- on applique la remise droit des éléments qui ne doivent pas être en italique
local i = 1
while(donnees.exclusion[i] ~= nil) do
disp = mw.ustring.gsub(disp, donnees.exclusion[i][1], donnees.exclusion[i][2])
i = i + 1
end
local deb = "''"
local fin = "''"
-- éviter de débuter par 4 ' si italique + droit dès le début
if (mw.ustring.find(disp, "^''")) then
disp = mw.ustring.sub(disp, 3) -- on supprime les 2 1er
deb = "" -- pas au début
end
-- éviter de terminer par 4 ' si italique + droit à la fin
if (mw.ustring.find(disp, "''$")) then
disp = mw.ustring.sub(disp, 1, -3) -- on supprime les 2 derniers
fin = "" -- pas à la fin
end
disp = deb .. disp .. fin
end
-- on retourne en formatant (lien, cible)
if (not lien) then
return disp -- juste le nom (mis en forme)
end
if (type(cible) == "string") then
if (cible == disp) then
return "[[" .. cible .. "]]" -- éviter de retourner [[XX|XX]]
else
return "[[" .. cible .. "|" .. disp .. "]]"
end
else
if (it) then
-- italique, on doit faire [[nom|lien]]
if (nom == disp) then
return "[[" .. nom .. "]]" -- éviter de retourner [[XX|XX]]
else
return "[[" .. nom .. "|" .. disp .. "]]"
end
else
return "[[" .. disp .. "]]"
end
end
end
-- traite la mise en italiques d'un nom de cultivar. La forme est "XXXXX 'YYY'" (apostrophe simple ou typographique)
-- l'italique n'est que sur la première partie. Retourne nil si cette forme n'est pas détectée
function p.italique_cultivar(nom)
if (nom == nil or nom == "" or type(nom) ~= "string") then
return nil
end
-- on verifie que le nom se termine par ' ou ’
local der = mw.ustring.sub(nom, -1)
if (der ~= "'" and der ~= "’") then
return nil -- pas bon
end
-- on cherche la partie YYY
local pd1, pf1 = mw.ustring.find(nom, "['].*[']$")
local pd2, pf2 = mw.ustring.find(nom, "[‘].*[’]$")
if (pd1 == nil and pd2 == nil) then
return nil -- pas trouvé
end
local debut = pd1 or pd2
local fin = pf1 or pf2
-- on récupère le début (à mettre en italiques)
local part1 = mw.ustring.sub(nom, 1, debut-1)
if (part1 == nil or part1 == "") then
return nil
end
local itpart1 = p.italiques_ns(part1, nil, donnees.defauts.regne, "cultivar", false)
local reste = mw.ustring.sub(nom, debut)
return itpart1 .. reste
end
-- applique la forme italique pour le titre de l'article (DISPLAYTITLE) à partir du
-- nom scientifique reçu en paramètre. Gère la partie homonymie.
function p.italiques_titre(titre, ns, rang)
local ttr
if (titre == ns) then
-- titre exactement NS → direct
if (rang == "cultivar") then
return p.italiques_cultivar(ns)
else
return p.italiques_ns(ns, nil, donnees.defauts.regne, rang, false)
end
end
-- si le titre est plus court que le NS ça ne peut être NS+homonymie
local lng = mw.ustring.len(ns)
if (mw.ustring.len(titre) <= lng) then
return "" -- on ne fait rien
end
-- on récupère les 'lng' premiers caractères du titre : ça doit être égal au NS
-- sinon ça veut dire que ce n'est pas NS+homonymie
local p1 = mw.ustring.sub(titre, 1, lng)
if (p1 ~= ns) then
return "" -- on ne fait rien
end
-- la partie homonymie seule
local hom = mw.ustring.sub(titre, lng+1)
-- on valide que la partie homonymie contient des ()
local tst = mw.ustring.find(hom, "[(]")
if (tst == nil) then
-- pas de parenthèse, ce n'est pas NS + homonymie
return "" -- on ne touche rien
end
-- on retourne la mise en forme du NS italique + la partie homonymie
if (rang == "cultivar") then
return p.italiques_cultivar(p1) .. hom
else
return p.italiques_ns(p1, nil, donnees.defauts.regne, rang, false) .. hom
end
end
--[[
Analyse les infos pour déterminer le titre de la taxobox et sa mise en forme
--]]
function p.genere_titre_taxobox()
-- il faut le résultat de l'analyse des taxons
if (donnees.defauts.dernier_taxon == nil or donnees.defauts.dernier_taxon == 0 or donnees.defauts.commandes == nil) then
p.erreur_fatale("Données internes non initialisées (dernier_taxon / commandes).", "interne")
return nil
end
-- on vérifie que le dernier taxon a un rang valide
local tmp = donnees.rangs[donnees.defauts.commandes[donnees.defauts.dernier_taxon][2] or "ndef"]
if (tmp == nil) then
p.erreur_fatale("Le ''taxon'' donné ligne " .. donnees.defauts.dernier_taxon .. " contient un rang invalide (" .. (donnees.defauts.commandes[donnees.defauts.dernier_taxon][2] or "ndef") .. ".", "syntaxe")
return nil
end
-- on regarde si le taxon titre est noté "vernaculaire"
local i = 2
while (donnees.defauts.commandes[donnees.defauts.dernier_taxon][i] ~= nil) do
if (mw.ustring.lower(mw.text.trim(donnees.defauts.commandes[donnees.defauts.dernier_taxon][i] or "")) == "vernaculaire") then
return true -- pas de modification de titre
end
i = i + 1
end
-- on remplace le titre de la taxobox par un titre mis en forme si besoin
donnees.defauts.titre_taxobox = p.italiques_ns(donnees.defauts.commandes[donnees.defauts.dernier_taxon][3], -- le nom
nil, -- ce n'est pas un lien
donnees.defauts.regne,
donnees.defauts.commandes[donnees.defauts.dernier_taxon][2],
false) -- ce n'est pas un lien
return true
end
--[[
Fonction de récupération d'un paramètre.
"nom" est le nom du paramètre nommé.
"valides" est une liste de chaîne ou nil. Si nil toute valeur de paramètre est autorisée, sinon elles doivent être dans la liste (pas de distinction min/maj)
Note : si "valides" est une table contenant des tables, considère que c'est une table indexée par l'élément et non une liste de textes à comparer
"flag" : s'il est vrai, quelque soit la valeur du paramètre il vaudra "true", "false" sinon.
"fatal" : si vrai l'absence du paramètre (on son absence de la liste des éléments valides) génèrera une erreur
si chaîne il est utilisé comme valeur par défaut en cas d'absence du paramètre
si nil un paramètre absent retournera nil
retourne la valeur du paramètre ou nil si absent
Note : suppose que donnees.defauts.frame soit initialisé ainsi que donnees.defauts.pframe
--]]
function p.lit_parametre(nom, valides, flag, fatal)
if (donnees.defauts.pframe == nil) then
-- on génère une erreur
p.erreur_fatale("Données internes non initialisées (pframe).", "interne")
return nil
end
if (nom == nil or nom == "") then
-- on génère une erreur
p.erreur_fatale("Nom de paramètre invalide.", "interne")
return nil
end
local tmp = donnees.defauts.frame.args[nom] -- on regarde d'abord le modèle
if (tmp == nil) then -- sinon on regarde à l'appel du modèle
tmp = donnees.defauts.pframe.args[nom]
end
if (tmp == nil) then
-- pas de valeur
if (fatal == true) then -- c'est fatal
p.erreur_fatale("Le paramètre ''" .. nom .. "'' est obligatoire.", "paramètre")
return nil
end
if (fatal == nil) then -- pas d'erreur
if (flag) then
return false -- si flag absent=faux
else
return nil
end
end
return fatal -- toute autre valeur est considéré comme la valeur par défaut
end
-- valeur présente.
if (valides == nil) then
if (flag) then
return true -- si flag présent=vrai
else
return tmp -- rien à valider, on retourne
end
end
-- éléments de validation : on compare
local trouve = false
if (type(valides[1]) == "string") then
local i = 1 -- table de textes, on regarde s'il est dedans
while (valides[i] ~= nil) do
if (valides[i] == tmp) then
-- on a trouvé
trouve = true
break
end
i = i + 1 -- suivant
end
else
-- sinon on tente un accès direct
if (valides[tmp] ~= nil) then
trouve = true
end
end
-- pas trouvé : nil ou fatal
if (not trouve) then
if (fatal == true) then
p.erreur_fatale("Le paramètre ''" .. nom .. "'' a une valeur invalide.", "paramètre")
return nil
end
if (fatal == nil) then -- pas d'erreur
if (flag) then
return false -- si flag erroné=faux
else
return nil
end
end
return fatal -- toute autre valeur est considéré comme la valeur par défaut
end
-- ok
return tmp
end
--[[
Retourne la position si nom est dans liste, 0 sinon
--]]
function p.est_dans_liste(nom, liste)
if (nom == nil or nom == "" or type(liste) ~= "table") then
return 0
end
local i = 1
while (liste[i] ~= nil) do
if (liste[i] == nom) then
return i
end
i = i + 1
end
return 0
end
--[[
Cette fonction parcours les paramètres non nommés en utilisant la pframe.
Construit la liste des lignes, chaque ligne étant une liste de mots-clés.
La fin de la ligne est détectée par le retour à la ligne (et que le suivant est un motè-clé). Si le premier mot n'est pas une commande
connue génère une erreur.
--]]
function p.tri_parametres(conf)
local k, v
local ligne = {}
local descriptions = {}
local pos = 1
local pd = 1
local ok = true
local dbg = ">>>"
local i = 1
while (donnees.defauts.pframe.args[i] ~= nil) do
local v = donnees.defauts.pframe.args[i]
local v2 = donnees.defauts.pframe.args[i+1] -- pour tester le suivant
local temp = mw.ustring.sub(v, -1)
local txt = mw.text.trim(v)
if (pos == 1) then
-- le premier est passé en minuscules
if (txt ~= nil) then
ligne[pos] = mw.ustring.lower(txt)
else
ligne[pos] = txt
end
-- on vérifie si l'élément est présent dans les commandes reconnues.
if (p.syntaxe[ligne[pos]] == nil) then
ok = false
p.erreur_fatale("La commande ''" .. (ligne[pos] or "<nil>") .. "'' est inconnue.", "commande")
end
else
ligne[pos] = txt
end
pos = pos + 1
if (temp == "\n") then
-- seulement si on est à la fin ou que le suivant est un mot-clé
if (v2 == nil or p.syntaxe[mw.ustring.lower(mw.text.trim(v2 or ""))] ~= nil) then
descriptions[pd] = ligne
pd = pd + 1
ligne = {}
pos = 1
end
end
i = i + 1
end
-- si ligne n'est pas vide ça signifie qu'il n'y a pas de retour à la ligne à la fin
-- on ajoute la ligne qui n'a pas été traitée
if (ligne[1] ~= nil) then
descriptions[pd] = ligne
end
conf.defauts.commandes = descriptions
return ok, dbg
end
--[[
Parcours les commandes de la taxobox pour identifier les "taxon" trouvés.
Ceux-ci sont rangés dans une liste spécifique, et le plus bas séparément.
Cette fonction détermine également si l'un des noms scientifiques dans "taxon"
correspond au titre de l'article (→ titre taxobox)
--]]
function p.tri_taxons()
if (donnees.defauts.commandes == nil or type(donnees.defauts.commandes) ~= "table") then
p.erreur_fatale("Impossible de trouver la liste des commandes.", "interne")
return false
end
donnees.defauts.liste_taxons = {}
-- indique la correspondance nom taxon / titre article
-- 0 → rien pour le moment
-- 1 → ce taxon est de la forme XXX et le titre XXXYYY
-- 2 → identité totale entre titre et taxon
local corresp = 0
local icorresp = 0
local trouve = 0
local i = 1
while (donnees.defauts.commandes[i] ~= nil) do
if (donnees.defauts.commandes[i][1] == "taxon") then
-- on l'ajoute
table.insert(donnees.defauts.liste_taxons, i)
donnees.defauts.dernier_taxon = i
trouve = trouve + 1
-- on regarde s'il correspond au titre ou au début du titre
if (donnees.defauts.c_force_titre == donnees.defauts.commandes[i][3]) then
corresp = 2
icorresp = i
end
if (corresp ~= 2) then -- pas si on a déjà une correspondance
if (mw.ustring.match(donnees.defauts.c_force_titre, "^" .. donnees.defauts.commandes[i][3] .. ".*$") ~= nil) then
corresp = 1
icorresp = i
end
end
end
i = i + 1
end
-- si aucun trouvé c'est une erreur
if (trouve == 0) then
p.erreur_fatale("Aucune entrée ''taxon'' trouvée dans la liste des commandes.", "syntaxe")
return false
end
-- si une correspondance (corresp=1 ou 2) mais pas sur le dernier → erreur non fatale
if (corresp ~= 0 and icorresp ~= donnees.defauts.dernier_taxon) then
p.erreur_normale("L'entrée ''taxon'' qui correspond au titre n'est pas en dernière position.", "syntaxe")
end
-- si présent on enregistre l'élément qui correspond au titre (ou aucun)
if (corresp ~= 0) then
donnees.defauts.taxon_titre = icorresp
else
donnees.defauts.taxon_titre = nil -- probablement titré vernaculaire
end
-- on prend comme titre de taxobox le dernier
donnees.defauts.titre_taxobox = donnees.defauts.commandes[donnees.defauts.dernier_taxon][3]
return true
end
-- fonction pour tester l'existence d'un fichier
function p.existe(page)
local t = mw.title.new(page)
if (t.fileExists) then
return true
else
return false
end
end
-- fonction externe pour inclure une image. complet : si vrai indique que l'image est déjà formatée
function p.insert_image(image, legende, complet, absent, taille)
local buf = ""
if (absent ~= true) then
if (complet == true) then
buf = buf .. '<p class="center">' .. (image or "non précisé") .. '</p>'
else
buf = buf .. '<p class="center">[[Fichier:' .. (image or "non précisé") .. '|thumb|center|upright=1.3|alt='
if (nil ~= legende and "" ~= legende) then
buf = buf .. 'Description de cette image, également commentée ci-après'
else
buf = buf .. 'Description de l\'image ' .. (image or "non précisée")
end
buf = buf .. "]]</p>"
end
else
buf = buf .. "<p class=\"center\">''Image inexistante :<br/>'' [[:Fichier:" .. (image or "non précisé") .. "|" .. (image or "non précisé") .. "]]</p>"
end
return buf
end
--[[
Pas la première lettre de la cible du lien en minuscule (pour insertion dans texte)
--]]
function p.lien_en_minuscule(lien)
if (lien == "" or lien == nil) then
p.erreur_normale("Lien invalide passé à ''lien_en_minuscule()''.", "interne")
return "Lien invalide"
end
local resu
-- est-ce qu'il y a un "|" dans le lien
local tmp = mw.ustring.find(lien, "|", 1, true)
if (tmp ~= nil) then
-- on récupère d'un coté la première partie, de l'autre la partie dont la première lettre doit être minuscule
local p1 = mw.ustring.sub(lien, 1, tmp)
local p2 = mw.ustring.sub(lien, tmp+2, -1)
local c = mw.ustring.sub(lien, tmp+1, tmp+1)
-- on passe la 1ère lettre en minuscule
c = mw.ustring.lower(c)
-- on reconstruit le résultat
resu = p1 .. c .. p2
else
-- un lien simple, on récupère met de coté les deux [[
local p1 = mw.ustring.sub(lien, 1, 2)
local p2 = mw.ustring.sub(lien, 4, -1)
local c = mw.ustring.sub(lien, 3, 3)
-- on passe la 1ère lettre en minuscule
c = mw.ustring.lower(c)
-- on reconstruit le résultat
resu = p1 .. c .. p2
end
return resu
end
--[[
Fonctions dédiées à créer les différentes parties d'une taxobox (début, fin, rang, …)
Chaque fonction prend en paramètre :
- params : la liste nommée des paramètres associés à la commande concernée (retourné par l'analyse syntaxique de la ligne)
Chaque fonction utilise la table "donnees" (donnees.etat et donnees.defauts en pratique) pour connaître la configuration
courante ainsi que l'état actuel de la taxobox
Chaque fonction retourne le wikicode à ajouter correspondant à la ligne (texte).
Le retour est 'nil' si une erreur s'est produite. Dans ce cas la zone d'erreurs est rempli avec les informations concernées.
--]]
--[[
Lecture d'une ligne de paramètres
desc est la description symbolique de ce qu'on attend
ligne est une table (de string) contenant la ligne découpée
depart est l'offset dans la table où commencer
Retourne une table où se trouvent fixées les valeurs trouvées
Format de la description :
{
["noname"] = { "key1", "key2", ... },
["flags"] = { { { "f1", "f1b", ... }, "key" }, { { "f2", "f2b", ... }, "key2" }, ... },
|"values"] = { { { "v1", "v1b", ... }, "key" }, { { "v2", "v2b", ... }, "key2" }, ... }
}
noname : paramètres sans nom sur la ligne. La fonction associe tout paramètre qui n'est ni un
flag ni un value à la liste de mots-clés. Dans la table retournée on aura tab["key1"] = "le premier champs non nommé",
tab["key2" = "le 2ème champs non nommé"... Ceux non présents valent nil. Si trop de paramètres non nommés sont présents
les derniers sont ignorés et une erreur est retournée (voir la gestion des erreurs plus bas)
flags : paramètres ayant un nom et qui ne sont gérés que par présent/absent. La fonction compare chaque paramètre à la liste
des mots-clés possibles pour chaque flag (f1, f1b pour le premier, f2, f2b…). Si l'un est présent la fonction fixe
tab["key"] = true (nil sinon)
si un flag est donné plus d'une fois cela génère une erreur
values : identique aux flags, mais la fonction cherche une valeur associée, qui est le paramètre suivant. Cette valeur
est passée par tab["key"] = "valeur lue".
Si une value n'a pas de valeur (dernier élément de la liste) ou est donnée plusieurs fois cela génère une erreur
Erreurs : si tab["erreurs"] est non nil / non vide c'est qu'une erreur s'est produite. tab["erreurs"] contient un message
expliquant l'erreur
TODO : améliorer la transmission des erreurs.
--]]
function p.lecture_parametres(ligne, depart, desc)
local i = depart
local buf = ""
local res = {}
local j
local tmpf
-- pour éviter les tests inutiles on crée vide les parties inexistantes
if (desc["noname"] == nil) then
desc["noname"] = {}
end
if (desc["flags"] == nil) then
desc["flags"] = {}
end
if (desc["values"] == nil) then
desc["values"] = {}
end
-- on parcours les entrées
while (ligne[i] ~= nil) do
v = mw.text.trim(ligne[i])
vm = mw.ustring.lower(v) -- version minuscule (flags, values)
--- on cherche si 'v' correspond à un élément des descriptions
j = 1
if (desc["flags"] == nil) then
tmpf = 0 -- pas de flags
else
tmpf = 0
while (desc["flags"][j] ~= nil) do
tmpf = p.est_dans_liste(vm, desc["flags"][j][1])
if (tmpf > 0) then
break
end
j = j + 1
end
end
if (tmpf > 0) then
-- on a trouvé, c'est un flag
-- on vérifie qu'il n'est pas déjà donné
if (res[desc["flags"][j][2]] ~= nil) then
res["erreurs"] = "Élément ''" .. ligne[i] .. "'' en multiples exemplaires"
end
-- quoi qu'il en soit c'est le dernier qui gagne
res[desc["flags"][j][2]] = true
else
-- pas un flag, on regarde les "values"
j = 1
if (desc["values"] == nil) then
tmpf = 0
else
while (desc["values"][j] ~= nil) do
tmpf = p.est_dans_liste(vm, desc["values"][j][1])
if (tmpf > 0) then
break
end
j = j + 1
end
end
if (tmpf > 0) then
-- on a trouvé, c'est un values
-- on vérifie qu'il y a un élément en plus
if (ligne[i+1] == nil) then
-- c'est une erreur
res.erreurs = "Valeur ''" .. v .. "'' sans contenu (case suivante)."
else
-- on vérifie qu'il n'est pas déjà donné
if (res[desc["values"][j][2]] ~= nil) then
res.erreurs = "Élément ''" .. ligne[j] .. "'' en multiples exemplaires."
end
-- quoi qu'il en soit c'est le dernier qui gagne (en minuscule car c'est une valeur)
res[desc["values"][j][2]] = mw.ustring.lower(mw.text.trim(ligne[i+1]))
-- on saute l'élément
i = i + 1
end
else
-- c'est un paramètre non nommé
-- on cherche le premier non nommé qui soit nil
j = 1
while (desc["noname"][j] ~= nil) do
if (res[desc["noname"][j]] == nil) then
break
end
j = j + 1
end
if (desc["noname"][j] == nil) then
-- donc il y a trop de paramètres -> erreur
res.erreurs = "Trop de paramètres (commande ''" .. ligne[1] .. "'')"
else
-- on fixe sa valeur
res[desc["noname"][j]] = v
end
end
end
-- entrée suivante
i = i + 1
end
return res
end
--[[
Fonction débutant une taxobox. Utilise le règne pour sélectionner le style.
--]]
function p.cmd_debut(params)
local ret
-- on vérifie que la taxobox n'est pas déjà ouverte
if (donnees.etat.ouvert) then
p.erreur_normale("Commande ''début'' mais la taxobox est déjà ouverte.", "structure")
return ""
end
-- on vérifie que la taxobox n'est pas déjà fermée
if (donnees.etat.ferme) then
p.erreur_normale("Commande ''début'' mais la taxobox est déjà fermée.", "structure")
return ""
end
-- on récupère les infos liées au règne
local curregne = donnees.defauts.regne_data
if (curregne == nil) then -- ne devrait pas se produire
p.erreur_normale("Erreur de récupération des données du règne ''" .. donnees.defauts.regne .. "''.", "interne")
return ""
end
-- on vérifie que la taxobox a bien un titre (ne devrait pas se produire)
if (donnees.defauts.titre_taxobox == nil) then
p.erreur_normale("Aucun titre généré pour la taxobox.", "interne")
return ""
end
-- on ajoute la catégorie taxobox
p.ajoute_categorie("Article avec taxobox-" .. donnees.defauts.regne)
-- on note qu'elle est ouverte
donnees.etat.ouvert = true
-- ouverture du div global
local frame = mw.getCurrentFrame()
local templatestyles = frame:extensionTag( 'templatestyles', '', { src = 'MediaWiki:Common.css/taxobox v3.css' } )
local classes = frame:expandTemplate{ title = 'Classes début infobox', args = { version = '3' } }
ret = templatestyles .. '<div class="' .. classes .. ' large taxobox_v3 bordered ' .. curregne["classe"] .. '" style="width: 20em">\n' .. '<p class="entete">' .. donnees.defauts.titre_taxobox .. '</p>\n'
-- test de l'existence de l'image
local absente = false
if (params["image"] ~= nil and params["image"] ~= "") then
local t = p.existe("Fichier:" .. params["image"])
if (not t) then
p.erreur_normale("L'image indiquée n'existe pas", "image")
absente = true -- on désactive l'image
end
end
-- si présente on ajoute l'image et la légende
ret = ret .. p.insert_image(params["image"], params["legende"], false, absente)
if (params["legende"] ~= nil) then
ret = ret .. '<p class="legend">' .. params["legende"] .. '</p>\n'
end
-- si "simple" on ne met rien du tout
if (params["simple"] ~= true) then
-- l'entête de classification, ou "ndef"
local classif = donnees.classifications[mw.ustring.lower(params["classification"] or "ndef")]
if (classif == nil) then -- classification inconnue
classif = donnees.classifications["ndef"]
p.erreur_normale("La classification ''" .. params["classification"] .. "'' est inconnue.", "syntaxe")
end
if (params["phylo"]) then
-- inexistant en classification classique
-- TODO : cette partie n'est pas au point. Que faut-il vraiment mettre là ? Le passage ciblé en minuscule ne marche pas.
ret = ret .. p.tb_bloc(classif["texte"])
-- mise en minuscule du premier caractère du lien (pour la cohérence dans la phrase)
ret = ret .. p.tb_texte("[[File:danger.png|25px|left]]<small>Taxon inexistant en " .. p.lien_en_minuscule(classif["texte"]) .. ".<br />Voir le texte pour plus d'information.</small>")
p.ajoute_categorie("Taxon inexistant " .. (classif["texte2"] or donnees.classifications["ndef"]["texte2"]))
else
-- on ouvre la table
ret = ret .. '<table class="taxobox_classification" style="font-style: normal">'
ret = ret .. '<caption>' .. classif["texte"] .. '</caption>\n'
donnees.etat.tbl = donnees.etat.tbl + 1
end
-- si présent, on insert les premiers rangs de classification, sauf si "phylo" est présent ce qui indique
-- un taxon uniquement phylogénétique donc sans classification "classique" (et sauf si "cacher_regne"
-- qui permet de forcer manuellement l'absence de regne initial)
if (curregne["règne auto"] ~= nil and params["phylo"] ~= true and not params["cacher_regne"]) then
-- on parcours les entrées et on fait appel à "rang"
local i = 1
local lst = curregne["règne auto"]
while (lst[i] ~= nil) do
-- on construit les paramètres
local lparams = {}
lparams["rang"] = lst[i][1]
lparams["nom"] = lst[i][2]
if (lst[i][3] ~= nil) then
lparams["cible"] = lst[i][3]
end
ret = ret .. p.cmd_rang(lparams)
i = i + 1
end
end
end
return ret -- résultat
end
--[[
Fonction terminant une taxobox.
--]]
function p.cmd_fin(params)
local ret = ""
-- on vérifie que la taxobox est ouverte
if (not donnees.etat.ouvert) then
p.erreur_normale("Commande ''fin'' mais la taxobox n'est pas ouverte.", "structure")
return ""
end
-- on vérifie que la taxobox n'est pas déjà fermée
if (donnees.etat.ferme) then
p.erreur_normale("Commande ''fin'' mais la taxobox est déjà fermée.", "structure")
return ""
end
-- on ferme les tables qui seraient encore ouvertes (par erreur ?)
if (donnees.etat.tbl > 0) then
for i = 1, donnees.etat.tbl do
ret = ret .. "</table>"
end
-- il ne peut y avoir plus d'une table encore ouverte
if (donnees.etat.tbl > 1) then -- non fatal
p.erreur_normale("Le nombre de table ouvertes est supérieur à 1 à la fin de la taxobox.", "structure")
end
donnees.etat.tbl = 0
end
-- on ferme la taxobox
ret = ret .. "</div>"
-- on met à jour l'état
donnees.etat.ferme = true
return ret -- le résultat
end
--[[
Génère un bandeau de début de classification phylogénique
image : l'image associée, optionnelle
classification : la classification suivie
--]]
function p.cmd_phylo_bandeau(params)
local ret = ""
local tmp
-- on valide la classification
if (params.classification == nil or params.classification == "") then
params.classification = "phylo"
end
-- on récupère la classification associée
local classif = donnees.classifications[mw.ustring.lower(params.classification)]
if (classif == nil) then -- classification inconnue
classif = donnees.classifications["phylo"]
p.erreur_normale("La classification ''" .. params["classification"] .. "'' est inconnue.", "syntaxe")
end
-- on insert l'entête (pas caption de la table pour permettre l'insertion de l'image. Ce n'est pas propre)
-- uniquement si une image est fournie
if (params.image ~= nil and params.image ~= "") then
ret = ret .. p.tb_bloc(classif["texte"])
end
-- si une image est présente on l'ajoute
if (params.image ~= nil and params.image ~= "") then
local img
img = '[[Fichier:' .. params.image .. '|thumb|center|upright=1.3|alt=Image présentant la classification phylogénique également détaillée ci-après]]'
ret = ret .. p.insert_image(img, nil, true, false)
end
-- on ouvre la table
ret = ret .. '<table class="taxobox_classification" style="font-style: normal">'
-- on n'insert pas le caption si image (car on a utilisé un bloc de titre)
if (params.image == nil or params.image == "") then
ret = ret .. '<caption>' .. classif["texte"] .. '</caption>\n'
end
donnees.etat.tbl = donnees.etat.tbl + 1
return ret
end
--[[
Insert une entrée rang (ligne de classification)
paramètres :
rang : le rang de la ligne
nom : le nom du taxon associé à ce rang
lien : la cible réelle si différente de nom (optionnel, nil si absent)
--]]
function p.cmd_rang(params)
local buf = ""
if ((params.rang == nil or params.nom == nil) and (params.lien == nil or params.lien == "")) then
p.erreur_normale("Paramètre de ''rang'' ou ''nom'' absent.", "syntaxe")
return ""
end
local rg = donnees.rangs[params.rang]
if (rg == nil) then
-- ce n'est pas un rang valide
p.erreur_normale("Rang attendu, ''" .. params.rang .. "'' trouvé à la place.", "syntaxe")
return "" -- on ne retourne rien, on ignore la ligne
end
local cible -- le lien à insérer
if (params["lien"] ~= nil) then
cible = params["lien"] -- utilisé directement
else
if (params.cible == nil) then
cible = p.italiques_ns(params.nom, nil, donnees.defauts.regne, params.rang, true)
else
cible = p.italiques_ns(params.cible, params.nom, donnees.defauts.regne, params.rang, true)
end
end
local p1 = rg["wikif"]
-- si ancien, on raye le tout
if (params.ancien) then
cible = "<s>" .. cible .. "</s>"
p1 = "<s>" .. p1 .. "</s>"
end
-- on insert la ligne
buf = buf .. p.tb_ligne_mixte(p1, cible)
return buf
end
--[[
Insert une entrée "taxon" (bloc décrivant le taxon décrit)
Paramètres :
- rang : le rang du taxon
- nom : le nom du taxon
- auteur : l'auteur+date du taxon
- sans auteur : booléen, vrai si l'absence d'auteur est normal
- titre : booléen, si vrai indique qu'il faut utiliser ce taxon comme taxon titre. Non implémenté
- obsolète : si présent le contenu est considéré comme le nouveau nom du taxon
--]]
function p.cmd_taxon(params)
local ret = ""
-- vérifications
if (params["rang"] == nil or params["nom"] == nil) then
p.erreur_normale("Paramètre ''rang'' ou ''nom'' manquant pour la commande ''taxon''.", "syntaxe")
return ""
end
-- on vérifie le rang
local rang = donnees.rangs[params["rang"]]
if (rang == nil) then
p.erreur_normale("Le rang indiqué ''" .. params["rang"] .. "'' n'est pas reconnue.", "syntaxe")
return ""
end
local txtrang
-- cas particulier, géré ici
if (params["rang"] == "espèce" and donnees.defauts.regne == "virus") then
txtrang = rang["wikif alt"]
if (txtrang == nil) then
txtrang = "[[Espèce]]"
end
else
txtrang = rang["wikif long"]
end
-- préparation du bloc d'entête
ret = ret .. p.tb_bloc(txtrang)
-- on insert le nom du taxon
ret = ret .. '<p class="center"><b>'
if (params["obsolete"]) then
ret = ret .. '<s>'
end
if (params.vernaculaire == true) then
ret = ret .. params.nom -- nom vernaculaire : pas d'italique du tout
else
ret = ret .. p.italiques_ns(params.nom, nil, donnees.defauts.regne, params.rang, false)
end
-- l'auteur
if (params["auteur"] ~= nil) then
-- on insert l'auteur
ret = ret .. "<br/><small>" .. params["auteur"] .. "</small>"
else
-- insertion auteur manquant sauf si "sans auteur" auquel cas on ignore
if (params["sans auteur"] ~= nil) then
ret = ret .. "<br/>" .. donnees.defauts.regne_data["cat auteur"]
end
end
if (params["obsolete"]) then
-- on ajoute le nouveau
ret = ret .. "<br/><b>" .. p.italiques_ns(params.obsolete, nil, donnees.defauts.regne, params.rang, false) .. "</b></s>"
end
ret = ret .. '</b></p>'
-- à discuter : une catégorie par type de taxon
local liaison
if (rang["féminin"] == true) then
liaison = "une"
else
liaison = "un"
end
p.ajoute_categorie("Article avec taxobox décrivant " .. liaison .. " " .. rang["nom"])
return ret
end
--[[
Insert une ligne UICN
paramètres :
risque
critere
lien
--]]
function p.cmd_uicn(params)
local ret = ""
-- vérification
if (params["risque"] == nil) then
p.erreur_normale("Paramètre ''risque'' absent de la commande ''UICN''.", "syntaxe")
return ""
end
local risque = donnees.uicn[params["risque"]]
local trisque
if (risque == nil) then
p.erreur_normale("Paramètre ''risque'' \"" .. params["risque"] .. "\" absent de la commande ''UICN''.", "syntaxe")
trisque = "Risque invalide"
else
trisque = risque["texte"]
end
-- insertion entête
ret = ret .. p.tb_bloc("[[Statut de conservation]] [[Union internationale pour la conservation de la nature|UICN]]")
-- insertion du risque
ret = ret .. '<p class="center">'
-- on ajoute l'image sauf si DD
if (risque ~= "DD") then
ret = ret .. "[[File:Status iucn3.1_" .. params.risque .. "-fr.svg|alt=Image du statut UICN " .. params.risque .. "|link=|244px]]<br />"
end
-- on ajoute la phrase
ret = ret .. "'''" .. params.risque .. "''' "
if (params.critere ~= nil) then
ret = ret .. params.critere .. " "
end
ret = ret .. ": '''" .. trisque .. "'''\n"
if (params.lien ~= nil) then
ret = ret .. "<br/>" .. params.lien
end
ret = ret .. '</p>\n'
-- on ajoute la catégorie
p.ajoute_categorie("Statut UICN " .. trisque)
return ret
end
--[[
Insert une ligne CITES
paramètres :
annexe
date
precision
--]]
function p.cmd_cites(params)
local ret = ""
-- vérification
if (params["annexe"] == nil) then
p.erreur_normale("Paramètre ''annexe'' absent de la commande ''CITES''.", "syntaxe")
return ""
end
if (params["annexe"] ~= "I" and params["annexe"] ~= "II" and params["annexe"] ~= "I||") then
p.erreur_normale("Paramètre ''annexe'' \"" .. params["annexe"] .. "\" invalide pour la commande ''CITES''.", "syntaxe")
return ""
end
-- titre du bloc
ret = ret .. p.tb_bloc("Statut [[Convention sur le commerce international des espèces de faune et de flore sauvages menacées d'extinction|CITES]]")
-- début de la zone
ret = ret .. '<p class="center">'
-- l'image
ret = ret .. "<small>[[File:Cites " .. params.annexe
ret = ret .. ".svg|link=|alt=Image de l'annexe " .. params.annexe .. " de la CITES|30px]] "
-- lien
ret = ret .. "[[Annexe " .. params.annexe .. " de la CITES|Annexe " .. params.annexe .. "]], "
-- la deuxième partie
if (date ~= "") then
ret = ret .. "Rév. du " .. params.date .. "\n"
else
ret = ret .. "Date de rév. inconnue\n"
end
if (params.precision ~= nil) then
ret = ret .. "<br/>" .. params.precision .. "\n"
end
-- ajout de la catégorie (si article)
ret = ret .. "</small>"
p.ajoute_categorie("CITES annexe " .. params.annexe)
ret = ret .. '</p>\n'
return ret
end
--[[
Gère une ligne de synonymes.
texte : le contenu
--]]
function p.cmd_synonymes(params)
local buf = ""
if (params.synonymes == "" or params.synonymes == nil) then
p.erreur_fatale("Paramètre manquant pour la commande ''synonymes''.", "syntaxe")
return ""
end
-- bloc de "sous-titre"
local buf = p.tb_bloc("[[Synonyme (taxinomie)|Synonymes]]")
-- si ça ne commence pas par "\n" on l'ajoute (sinon les puces ne "démarrent" pas)
buf = buf .. '<p>\n' .. params.synonymes .. '</p>\n'
return buf
end
--[[
Génère une ligne de taxons.
texte : la liste des taxons.
text2 : entrée du rang (optionnel).
--]]
function p.cmd_taxons(params)
local buf = ""
-- bloc de "sous-titre"
if (params.texte2 == nil or params.texte2 == "") then
buf = p.tb_bloc("Taxons de rang inférieur")
else
-- on cherche le nom du rang
local rg = donnees.rangs[mw.ustring.lower(mw.text.trim(params.texte))]
local nom = "Taxon"
if (rg ~= nil) then
nom = rg["wikif alt"] -- on tente le nom alternatif
if (nom == nil) then
nom = rg["wikif long"]
end
else
-- on insert une erreur
p.erreur_normale("Le paramètre ''" .. params.texte .. "'' n'est pas un rang valide (commande ''taxons'').", "syntaxe")
end
buf = p.tb_bloc(nom .. "s de rang inférieur")
end
-- si ça ne commence pas par "\n" on l'ajoute (sinon les puces ne "démarrent" pas)
if (params.texte2 == nil or params.texte2 == "") then
if (params.texte == nil or params.texte == "") then
-- texte par défaut
buf = buf .. "<p>\n* Voir texte\n</p>\n"
else
buf = buf .. '<p>\n' .. params.texte .. '</p>\n'
end
else
buf = buf .. '<p>\n' .. params.texte2 .. '</p>\n'
end
return buf
end
--[[
Génère une ligne indiquant que le taxon n'existe pas en classification phylosophique
classification : la classification suivie
--]]
function p.cmd_phylo_inexistant(params)
local buf = ""
-- on valide la classification
-- on valide la classification
if (params.classification == nil or params.classification == "") then
params.classification = "phylo"
end
-- on récupère la classification associée
local classif = donnees.classifications[mw.ustring.lower(params.classification)]
if (classif == nil) then -- classification inconnue
classif = donnees.classifications["phylo"]
p.erreur_normale("La classification ''" .. params["classification"] .. "'' est inconnue.", "syntaxe")
end
-- on insert : c'est juste un affichage
buf = buf .. p.tb_bloc(classif["texte"])
-- bloc d'information
buf = buf .. "<p>[[File:Achtung.svg|25px|left|alt=Attention !|link=]]<small>Taxon inexistant en "
buf = buf .. p.lien_en_minuscule(classif["texte"]) .. ".<br/>Voir le texte pour plus d'information.</small></p>"
-- insertion catégorie
p.ajoute_categorie("Taxon inexistant " .. (classif["texte2"] or donnees.classifications["phylo"]["texte2"]))
return buf
end
--[[
Génère une ligne indiquant la position phylogénique
arbre : l'arbre (image) indiquant la position phylo du taxon
--]]
function p.cmd_position(params)
local buf = ""
if (params.arbre == nil or params.arbre == "") then
p.erreur_normale("Paramètre ''arbre'' manquant pour la commande ''position''.", "syntaxe")
return ""
end
-- bloc de "sous-titre"
local buf = p.tb_bloc("[[Classification phylogénétique|Position phylogénétique]]")
-- si ça ne commence pas par "\n" on l'ajoute (sinon les puces ne "démarrent" pas)
buf = buf .. '<p>\n' .. params.arbre .. '</p>\n'
-- groupe frère si présent
if (params.frere ~= nil and params.frere ~= "") then
-- peut-on faire la mise en forme du "frère" automatiquement ? Je ne pense pas
buf = buf .. '<p>\n[[Groupe frère]] : [[' .. params.frere .. ']]</p>\n'
end
return buf
end
--[[
Insert un séparateur. Ne pas utiliser dans une table
--]]
function p.cmd_separateur(params)
if (donnees.etat.tbl == 0) then
return '<div class="hr" style="height: 2px;"></div>\n'
else
return ""
end
end
--[[
Insert une image. Si la légende est indiquée elle est utilisée pour le champ "alt"
Paramètres :
- image : le nom de l'image
- legende : le nom de la legende
- separateur : booléen, vrai s'il faut insérer un séparateur avant
Note : peut être appelé en tant que "image", "répartition" ou "répartition image"
--]]
function p.cmd_image(params)
local buf = ""
if (params.image == nil or params.image == "") then
p.erreur_normale("Pas d'image fournie pour la commande ''" .. params.commande .. "''.", "syntaxe")
return "" -- on ignore la ligne
end
-- si demandé séparateur
if (params.separateur == true) then
buf = buf .. p.cmd_separateur(params)
end
if (params.commande == "répartition") then
buf = buf .. p.tb_bloc("[[Aire de répartition]]")
end
buf = buf .. p.insert_image(params.image, params.legende, false, false, params.taille)
if (params.legende ~= nil and params.legende ~= "") then
buf = buf .. p.tb_texte(params.legende)
end
return buf
end
--[[
Affiche une légende. Peut être appelé pour "légende" (légende simple) ou
pour "répartition légende" (légende avec couleurs)
dans le premier cas : paramètre "legende"
dans le deuxième cas : en plus "couleur" et "couleur2" (optionnel)
--]]
function p.cmd_legende(params)
local buf = ""
if (params.legende == nil or params.legende == "") then
p.erreur_normale("Pas de légende fournie pour la commande ''" .. params.commande .. "''.", "syntaxe")
return "" -- on ignore la ligne
end
if (params.commande == "répartition légende" and (params.couleur == nil or params.couleur == "")) then
p.erreur_normale("Pas de couleur fournie pour la commande ''" .. params.commande .. "''.", "syntaxe")
return "" -- on ignore la ligne
end
if (params.commande == "légende") then
buf = buf .. '<p class="legend">' .. params.legende .. '</p>\n'
else
buf = buf .. '<p class="legend" style="text-align:left">'
buf = buf .. '<small> <span style="background: #' .. params.couleur .. '">'
buf = buf .. "''' <font color=\"#"
if (params.couleur2 == nil or params.couleur2 == "") then
buf = buf .. params.couleur .. '">/</font> '
else
buf = buf .. params.couleur2 .. '">/</font> '
end
buf = buf .. "'''</span> " .. params.legende .. "</small></small><br /></p>"
end
return buf
end
--[[
Retourne le lien correspondant à la classification de référence indiquée
Si elle n'existe pas retourne le terme seul
--]]
function p.genere_reference(nom)
local res = donnees.classifications_ref[nom or ""]
if (res == nil) then
-- n'existe pas, on insert la catégorie d'erreur
p.erreur_normale("Le site (ou auteur) de référence pour la commande ''conflit'' n'est pas reconnu (''" .. (nom or "non défini") .. "'').", "site")
return nil -- on retourne nil pour indiquer "pas trouvé"
else
return res["texte"]
end
end
--[[
Découpe le texte indiqué et traite chacun pour le convertir
--]]
function p.genere_references(texte)
if (texte == nil or texte == "") then
return ""
end
local buf = ""
-- on découpe
local lst = mw.text.split(texte, "[ &,]+")
-- on converti chaque mot qu'on range dans une table
local resu = {}
local i = 1
while (lst[i] ~= nil) do
local tmp = p.genere_reference(mw.ustring.lower(lst[i]))
if (tmp == nil) then
table.insert(resu, lst[i])
else
table.insert(resu, p.genere_reference(mw.ustring.lower(lst[i])))
end
i = i + 1
end
-- on concatène le résultat pour faire la phrase finale
buf = mw.text.listToText(resu, ", ", " et ")
-- on retourne le résultat
return buf
end
--[[
Entrée "rang" mais pour lequel le nom du rang est différent selon les sources.
paramètres :
rang : le rang
nom1 : le premier nom de taxon
ref1 : selon qui
nom2 : le 2ème nom de taxon
ref2 : selon qui (pour le 2)
…
Les références peuvent être :
une liste de noms de classifications sous forme courte (ASW, ITIS, NCBI…), qui peut être
séparées par un espace ou un &
--]]
function p.cmd_conflit(params)
local buf = ""
-- test paramètres
if (params.rang == nil or params.nom1 == nil or params.site1 == nil or
params.rang == "" or params.nom1 == "" or params.site1 == "") then
p.erreur_normale("Paramètre ''rang'', ''nom1'' ou ''site1'' absent pour la commande ''conflit''.", "syntaxe")
return ""
end
local rg = donnees.rangs[params.rang]
if (rg == nil) then
-- ce n'est pas un rang valide
p.erreur_normale("Rang attendu, ''" .. params.rang .. "'' trouvé à la place (commande ''conflit'').", "syntaxe")
return "" -- on ne retourne rien, on ignore la ligne
end
-- nom du rang
local cible = ""
local i = 1
while (params["nom" .. i] ~= nil) do
if (i > 1) then
cible = cible .. "<br/>"
end
cible = cible .. p.italiques_ns(params["nom" .. i], params["cible" .. i], donnees.defauts.regne, params.rang, true) .. "<small> selon "
if (params["site" .. i] == nil) then
params["site" .. i] = "?" -- valeur par défaut
end
-- on traite la liste de références
cible = cible .. p.genere_references(params["site" .. i]) .. "</small>"
i = i + 1
end
buf = buf .. p.tb_ligne_mixte(rg["wikif"], cible)
return buf
end
--[[
Génère une ligne « parents » pour les hybrides
Paramètres ; sexe1 taxon1 sexe2 taxon2
--]]
function p.cmd_parents(params)
-- vérifications
if (params.sexe1 == nil or params.taxon1 == nil or params.taxon1 == "" or
params.sexe2 == nil or params.taxon2 == nil or params.taxon2 == "") then
p.erreur_normale("Paramètre manquant pour la commande ''parents''.", "syntaxe")
return ""
end
local buf = ""
-- valeur par défaut pour sexe1 et 2
if (params.sexe1 == "") then
params.sexe1 = "A"
end
if (params.sexe2 == "") then
params.sexe2 = "B"
end
-- la ligne
buf = buf .. "'''Parent " .. params.sexe1 .. " de l'hybridation'''<br/>"
buf = buf .. "'''''" .. params.taxon1 .. "'''''<br/>'''×'''<br/>"
buf = buf .. "'''Parent " .. params.sexe2 .. " de l'hybridation'''<br/>"
buf = buf .. "'''''" .. params.taxon2 .. "'''''"
-- le résultat, avec le séparateur
return p.cmd_separateur(params) .. p.tb_texte(buf)
end
--[[
Insert un arbre phylogénique.
Paramètres :
arbre : texte décrivant l'arbre
image : une image insérée (optionnel)
classification= : la classification suivie
--]]
function p.cmd_phylo_arbre(params)
local buf = ""
if (params.arbre == nil or params.arbre == "") then
p.erreur_normale("Paramètre ''arbre'' manquant pour la commande ''phylogénie arbre''.", "syntaxe")
return ""
end
-- l'entête de classification, ou "phylo"
local classif
if (params["classification"] == nil or params["classification"] == "") then
classif = donnees.classifications["phylo"]
else
classif = donnees.classifications[mw.ustring.lower(params["classification"])]
if (classif == nil) then
classif = donnees.classifications["phylo"]
p.erreur_normale("La classification ''" .. params["classification"] .. "'' est inconnue pour la commande ''phylogénie arbre''.", "syntaxe")
end
end
buf = buf .. p.tb_bloc(classif["texte"])
buf = buf .. "<p>'''Position :'''<br/>\n" .. params.arbre .. "</p>"
return buf
end
--[[
Liste d'association entre les commandes (mot-clés) et les fonctions associées.
Note : si une commande est ajoutée, retirée ou renommée il faut également penser à mettre à jour la liste des mot-clés
dans le module "Taxobox données" (qui sert pour la validation lors du parsing initial)
--]]
p.syntaxe = {
["début"] = { 2, donnees.df_debut, p.cmd_debut },
["fin"] = { 1, donnees.df_fin, p.cmd_fin },
["rang"] = { 1, donnees.df_rang, p.cmd_rang },
["conflit"] = { 1, donnees.df_conflit, p.cmd_conflit },
["taxon"] = { 1, donnees.df_taxon, p.cmd_taxon },
["taxons"] = { 1, donnees.df_taxons, p.cmd_taxons },
["uicn"] = { 1, donnees.df_uicn, p.cmd_uicn },
["cites"] = { 1, donnees.df_cites, p.cmd_cites },
["synonymes"] = { 1, donnees.df_synonymes, p.cmd_synonymes },
["parents"] = { 1, donnees.df_parents, p.cmd_parents },
["image"] = { 1, donnees.df_image, p.cmd_image },
["répartition"] = { 1, donnees.df_repartition, p.cmd_image },
["répartition image"] = { 1, donnees.df_repartition_image, p.cmd_image },
["répartition légende"] = { 1, donnees.df_repartition_legende, p.cmd_legende },
["légende"] = { 1, donnees.df_legende, p.cmd_legende },
["phylogénie bandeau"] = { 2, donnees.df_phylo_bandeau, p.cmd_phylo_bandeau },
["phylogénie inexistant"] = { 1, donnees.df_phylo_inexistant, p.cmd_phylo_inexistant },
["phylogénie arbre"] = { 1, donnees.df_phylo_arbre, p.cmd_phylo_arbre },
["séparateur"] = { 1, donnees.df_separateur, p.cmd_separateur },
["position"] = { 1, donnees.df_position, p.cmd_position }
} -- note : il en manque
-- le module
return p