Module:Taxobox2
Apparence
[voir] [modifier] [historique] [purger]
Ce module fournit une fonction permettant de générer une taxobox.
Utilisation
Fonctions exportables :
taxobox(frame)
– la fonction servant à créer une taxobox. Voir documentation détaillée pour son utilisation
Autres fonctions :
genere_sortie(texte, debug)
– formate le retour detaxobox(frame)
et insert si besoin la sortie debug
Modules externes et autres éléments dont ce module a besoin pour fonctionner :
Module:Taxobox données
− module contenant toutes les données constantes relatives à la construction d'une taxoboxModule:Taxobox fonctions
− module contenant toutes les fonctions de traitement des paramètres et de création du contenumw.title
– utilisé pour connaître le titre de la page où on est utilisé.mw.text, mw.ustring…
Déroulement de l'exécution
Les étapes pour créer une taxobox sont toujours les mêmes. Les actions de la fonction taxobox(frame)
sont :
- enregistrement frame et pframe dans la table donnees.defauts.{frame|pframe}} (pour utilisation par d'autres fonctions
- récupération du titre et du namespace de l'article (donnees.defauts.{article|titre})
- analyse des paramètres nommés. Contenu : "charte" et "nom vernaculaire" ; comportement : c_titre, c_sous_titre, c_categories, c_categories_err, c_erreurs, c_force_titre ; debug : raw, debug. Vérifications sur les paramètres (présence obligatoire de "charte", et qu'elle corresponde à une charte connue).
- analyse des paramètres non nommés pour créer la liste des commandes (suite des lignes de taxobox à créer : donnees.defauts.commandes) avec la commande tri_parametres(). Validation que cette phase c'est bien passée.
- initialisation de l'état courant de la taxobox (ouverte, fermée, nombre de tables ouvertes…)
- recherche des entrées "taxon" (commande tri_taxons). Cette fonction regroupe les lignes "taxon" dans une table, note le dernier "taxon" donné Note également si l'un des taxons indiqué peut correspondre au titre de l'article.
- détermination du titre de la taxobox (genere_titre_taxobox()).
- boucle de parcours des commandes de la taxobox. Parcours sur les lignes de donnees.defauts.commandes :
- analyse de la ligne (lecture_parametres()) en utilisant la syntaxe de la commande. Retourne resu contenant les paramètres de la ligne
- exécution de la fonction traitant la commande correspondante, sur les paramètres de la ligne
- gestion de la structuration (ouverture/fermeture de tables typiquement)
- ajout du code de la ligne à la taxobox en cours de création
- note : à chaque étape diverses vérifications de la présence d'erreurs
- détermination des modifications éventuelles du titre de l'article (mise en forme)
- détermination de l'ajout éventuel d'un sous-titre à l'article
- détermination des catégories éventuelles à ajouter (et selon le mode choisi et le namespace)
- détermination des catégories d'erreurs éventuelles à ajouter (et selon le mode choisi et le namespace)
- détermination des erreurs éventuelles à ajouter (et selon le mode choisi et le namespace)
- retour du résultat
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 créant une taxobox.
Utilise Module:Taxobox données et Module:Taxobox fonctions.
Note : le nom est temporaire. Module:Taxobox existe et contient une vieille version destinée à être remplacée.
--]]
-- la table du module
local p = {}
local donnees = require "Module:Taxobox données"
local fnc = require "Module:Taxobox fonctions"
--[[
Fonction générant la sortie finale. Permet d'inclure le debug éventuel
--]]
function p.prepare_sortie(contenu, db)
if (donnees.defauts.debug) then
return db .. donnees.defauts.frame:preprocess(contenu)
else
return donnees.defauts.frame:preprocess(contenu)
end
end
--[[
Fonction principale : traite les paramètres et génère la taxobox.
Les paramètres sont :
règne : obligatoire. Sélectionne le thème (couleur, convention typographique, lignes de classification)
nom vernaculaire : facultatif. Informe la taxobox du ou des noms vernaculaires existants
…
--]]
function p.taxobox(frame)
local dg = ""
donnees.defauts.frame = frame -- pour que les fonctions aient accès à la frame courante simplement
donnees.defauts.pframe = frame:getParent() -- pour que les fonctions aient accès à la frame courante simplement
dg = dg .. "frames préparées.<br/>"
-- on récupère les infos sur l'article où on se trouve
local curarticle = mw.title.getCurrentTitle()
if (curarticle.namespace == 0) then -- est-ce un article ou pas
donnees.defauts.article = true
else
donnees.defauts.article = false
end
-- le titre courant
donnees.defauts.titre = curarticle.text
dg = dg .. "namespaces+titre extraits.<br/>"
-- récupération des paramètres
donnees.defauts.regne = fnc.lit_parametre("charte", donnees.regnes, false, nil) -- la charte
if (donnees.defauts.regne == nil) then -- on teste charte, puis règne si marche pas
donnees.defauts.regne = fnc.lit_parametre("règne", donnees.regnes, false, true) -- le règne
end
donnees.defauts.nom_vernaculaire = fnc.lit_parametre("nom vernaculaire", nil, false, nil) -- le non vernaculaire
-- les options permettant de modifier le comportement
donnees.defauts.c_titre = fnc.lit_parametre("titre", {"oui","non","boîte","auto"}, false, "auto")
donnees.defauts.c_sous_titre = fnc.lit_parametre("sous-titre", {"oui","non","auto"}, false, "auto")
donnees.defauts.c_erreurs = fnc.lit_parametre("erreurs", {"oui","non","auto"}, false, "auto")
donnees.defauts.c_categories = fnc.lit_parametre("catégories", {"en ligne","non","boîte","auto"}, false, "auto")
donnees.defauts.c_categories_err = fnc.lit_parametre("catégorie erreurs", {"en ligne","non","boîte","auto"}, false, "auto")
donnees.defauts.c_force_titre = fnc.lit_parametre("force titre", nil, false, nil)
-- si force titre vide on utilise le titre réel
if (donnees.defauts.c_force_titre == nil) then
donnees.defauts.c_force_titre = donnees.defauts.titre
end
-- debug
donnees.defauts.c_raw = fnc.lit_parametre("raw", nil, true, nil)
donnees.defauts.c_debug = fnc.lit_parametre("debug", nil, true, nil)
-- on regarde si une erreur (ou plusieurs) s'est produite durant la récupération des paramètres
if (donnees.defauts.fatal) then
return p.prepare_sortie(fnc.erreur_globale(donnees.defauts, donnees.categorie_erreur), dg)
end
dg = dg .. "paramètres récupérés.<br/>"
-- on récupère la structure règne
donnees.defauts.regne_data = donnees.regnes[donnees.defauts.regne]
if (donnees.defauts.regne_data == nil) then
fnc.erreur_normale("Le règne indiqué ''" .. donnees.defauts.regne .. "'' n'est pas reconnu.", "syntaxe")
return p.prepare_sortie(fnc.erreur_globale(donnees.defauts, donnees.categorie_erreur), dg)
end
-- on analyse les paramètres pour générer la liste des commandes présentes
local xxx, yyy = fnc.tri_parametres(donnees)
dg = dg .. yyy
if (donnees.defauts.fatal) then -- erreur → fatal
return p.prepare_sortie(fnc.erreur_globale(donnees.defauts, donnees.categorie_erreur), dg)
end
dg = dg .. "commandes analysées.<br/>"
local w = 1
while (donnees.defauts.commandes[w] ~= nil) do
local ww = 1
while (donnees.defauts.commandes[w][ww] ~= nil) do
dg = dg .. donnees.defauts.commandes[w][ww] .. " "
ww = ww + 1
end
dg = dg .. "<br/>"
w = w + 1
end
dg = dg .. "EOC<br/>"
-- initialisation de l'état de la taxobox en construction
donnees.etat = {}
donnees.etat.ouvert = false -- la taxobox est commencée
donnees.etat.ferme = false -- la taxobox est terminée
donnees.etat.ligne = "non commencé" -- le nom de la ligne en cours
donnees.etat.tbl = 0 -- nombre de tables ouvertes
dg = dg .. "état taxobox initialisé.<br/>"
-- on parcours les commandes pour trouver les "taxon", afin de valider leur présence
-- et de trouver le titre de la taxobox
fnc.tri_taxons()
if (donnees.defauts.fatal) then -- erreur → fatal
return p.prepare_sortie(fnc.erreur_globale(donnees.defauts, donnees.categorie_erreur), dg)
end
dg = dg .. "taxons analyés (dernier taxon et titre = " .. donnees.defauts.titre_taxobox .. ").<br/>"
-- on traite le titre/sous-titre : est-ce le NS ? Est-ce le NV ? Autre ?
fnc.genere_titre_taxobox()
dg = dg .. "titre taxobox géré (titre = " .. donnees.defauts.titre_taxobox .. ").<br/>"
-- parcours des commandes et appel des fonctions de traitement de chaque ligne
local tb = ""
local i = 1
local courant = ""
local precedent = ""
while (donnees.defauts.commandes[i] ~= nil) do
-- le mot-clé
local cle = donnees.defauts.commandes[i][1]
if (cle == nil) then -- fatal
fnc.erreur_fatale("La " .. i .. "ème commande n'existe pas.", "interne")
return p.prepare_sortie(fnc.erreur_globale(donnees.defauts, donnees.categorie_erreur), dg)
end
courant = cle
dg = dg .. " - commande : " .. cle .. "<br/>"
-- on récupère le descriptif de cette commande
local cmd = fnc.syntaxe[cle]
if (cmd == nil) then
dg = dg .. " -> commande non référencée<br/>"
fnc.erreur_fatale("La " .. i .. "ème commande (''" .. cle .. "'') n'est pas référencée dans les actions.", "interne")
return p.prepare_sortie(fnc.erreur_globale(donnees.defauts, donnees.categorie_erreur), dg)
end
dg = dg .. " -> cmd : " .. type(cmd[1]) .. ", " .. type(cmd[2]) .. ", " .. type(cmd[3]) .. "<br/>"
-- si pas de fonction associée erreur non fatale et on ignore
if (cmd[3] == nil) then
dg = dg .. " -> commande non implémentée<br/>"
fnc.erreur_normale("La commande ''" .. cle .. "'' n'est pas encore implémentée.", "interne")
else
-- on analyse la ligne
local etat, resu = pcall(fnc.lecture_parametres, donnees.defauts.commandes[i], 2, cmd[2])
if (not etat) then
fnc.erreur_fatale("Échec d'appel à lecture_parametres (" .. cle .. ") (" .. resu .. ").", "interne")
return p.prepare_sortie(fnc.erreur_globale(donnees.defauts, donnees.categorie_erreur), dg) -- on quitte
end
dg = dg .. " - syntaxe analysée<br/>"
-- gestion des erreurs
if (resu == nil or resu.erreurs ~= nil) then
-- une erreur sur cette ligne est-elle fatale ?
dg = dg .. " -> commande retourne une erreur<br/>"
if (cmd[1] == 2) then
fnc.erreur_fatale((resu.erreurs or "non précisé"), "syntaxe")
return p.prepare_sortie(fnc.erreur_globale(donnees.defauts, donnees.categorie_erreur), dg) -- on quitte
else
fnc.erreur_normale((resu.erreurs or "non précisé"), "syntaxe")
end
else
dg = dg .. " - syntaxe validée<br/>"
-- on exécute la ligne
local tmpr, tmpd
tmpr, tmpd = pcall(cmd[3], resu)
if (not tmpr) then
fnc.erreur_fatale("Échec d'appel à la fonction de gestion de ''" .. cle .. "'' (" .. tmpd .. ").", "interne")
return p.prepare_sortie(fnc.erreur_globale(donnees.defauts, donnees.categorie_erreur), dg) -- on quitte
end
dg = dg .. "données : precedent=" .. precedent .. ", courant=" .. courant .. ", tbl=" .. donnees.etat.tbl .. "<br/>"
-- gestion des fermetures de tables
if (precedent == "rang" and courant ~= "rang") then
-- on quitte un rang → on ferme la table
tb = tb .. "</table>"
donnees.etat.tbl = donnees.etat.tbl - 1
end
-- traitement de "dépannage" : si "rang" sans table ouverte on ouvre la table mais c'est une erreur
if (courant == "rang" and donnees.etat.tbl <= 0) then
fnc.erreur_normale("Ligne " .. i .. " : commande ''rang'' en dehors d'une zone adéquate.", "syntaxe")
tb = tb .. '<table class="taxobox_classification taxoalternance"><caption>Erreur</caption>\n'
donnees.etat.tbl = donnees.etat.tbl + 1
end
-- on insert l'élément
tb = tb .. tmpd
dg = dg .. " - commande traitée<br/>"
end
end
-- on bascule courant/precedent
precedent = courant
-- ligne suivante
i = i + 1
end
-- traitement titre article (mise en forme si nécessaire)
local mtitre = ""
if (donnees.defauts.taxon_titre ~= nil) then -- il y a un titre NS
if (donnees.defauts.c_titre ~= "non") then
dg =dg .. "titre a modifier a priori : titre = " .. donnees.defauts.c_force_titre .. ", ciblé = " .. donnees.defauts.commandes[donnees.defauts.taxon_titre][3] .. "<br/>"
-- le titre modifié
local tmp = fnc.italiques_titre(donnees.defauts.c_force_titre, donnees.defauts.commandes[donnees.defauts.taxon_titre][3], donnees.defauts.commandes[donnees.defauts.taxon_titre][2])
dg = dg .. " -> " .. tmp .. "<br/>"
-- selon le mode
if (donnees.defauts.c_titre == "boîte" or (donnees.defauts.c_titre == "auto" and not donnees.defauts.article)) then
mtitre = mtitre .. fnc.box_ouverture("Titre")
mtitre = mtitre .. fnc.box_texte(frame:preprocess("<nowiki>" .. tmp .. "</nowiki>"))
mtitre = mtitre .. fnc.box_fermeture()
elseif (donnees.defauts.c_titre == "oui" or (donnees.defauts.c_titre == "auto" and donnees.defauts.article)) then
mtitre = mtitre .. frame:preprocess(tmp)
end
end
end
-- traitement sous-titre éventuel
local mstitre = ""
if (donnees.defauts.c_sous_titre ~= "non") then
dg = dg .. "sous-titre potentiel<br/>"
local sst = nil
-- si taxon_titre → titre en NS, on ajoute le NV si présent
if (donnees.defauts.taxon_titre ~= nil) then
dg = dg .. " -> vernaculaire : " .. (donnees.defauts.nom_vernaculaire or "non défini") .. "<br/>"
sst = donnees.defauts.nom_vernaculaire
else
-- titre NV, on ajoute le NS en sous-titre
dg = dg .. " -> scientifique : " .. donnees.defauts.titre_taxobox .. "<br/>"
sst = donnees.defauts.titre_taxobox
end
if (donnees.defauts.c_sous_titre == "boîte" or (donnees.defauts.c_sous_titre == "auto" and not donnees.defauts.article)) then
if (sst ~= nil) then
mstitre = mstitre .. fnc.box_ouverture("Sous-titre")
mstitre = mstitre .. fnc.box_texte(sst)
mstitre = mstitre .. fnc.box_fermeture()
end
elseif (donnees.defauts.c_sous_titre == "oui" or (donnees.defauts.c_sous_titre == "auto" and donnees.defauts.article)) then
-- on l'insert en tant que sous-titre
if (sst ~= nil) then
mstitre = mstitre .. '<span id="sous_titre_h1">' .. sst .. '</span>'
end
end
end
-- si besoin et selon les modalités on insert les catégories
local mcat = ""
if (donnees.defauts.r_categories[1] ~= nil and donnees.defauts.c_categories ~= "non") then
-- selon le mode
if (donnees.defauts.c_categories == "boîte" or (donnees.defauts.c_categories == "auto" and donnees.defauts.article == false)) then
mcat = mcat .. fnc.box_ouverture("Catégorie(s)")
mcat = mcat .. fnc.box_texte(donnees.defauts.r_categories, true)
mcat = mcat .. fnc.box_fermeture()
elseif (donnees.defauts.c_categories == "en ligne" or (donnees.defauts.c_categories == "auto" and donnees.defauts.article == true)) then
-- insertion "en vrai"
local i = 1
while (donnees.defauts.r_categories[i] ~= nil) do
mcat = mcat .. "[[Catégorie:" .. donnees.defauts.r_categories[i] .. "]]"
i = i + 1
end
end
end
-- si besoin et selon les modalités on insert les catégories d'erreur
local mcaterr = ""
if (donnees.defauts.r_err_categories[1] ~= nil and donnees.defauts.c_err_categories ~= "non") then
dg = dg .. "Il y a des catégories d'erreur<br/>"
-- selon le mode
if (donnees.defauts.c_err_categories == "boîte" or (donnees.defauts.c_err_categories == "auto" and donnees.defauts.article == false)) then
mcaterr = mcaterr .. fnc.box_ouverture("Catégorie d'erreur(s)")
mcaterr = mcaterr .. fnc.box_texte(donnees.defauts.r_err_categories, true)
mcaterr = mcaterr .. fnc.box_fermeture()
elseif (donnees.defauts.c_err_categories == "en ligne" or (donnees.defauts.c_err_categories == "auto" and donnees.defauts.article == true)) then
-- insertion "en vrai"
local i = 1
while (donnees.defauts.r_err_categories[i] ~= nil) do
mcat = mcat .. "[[Catégorie:" .. donnees.categorie_erreur .. "|" .. donnees.defauts.r_categories[i] .. "]]"
i = i + 1
end
end
end
-- si besoin et selon les modalités on insert les erreurs
local merr = ""
if (donnees.defauts.r_erreurs[1] ~= nil and donnees.defauts.c_erreurs ~= "non") then
-- selon le mode
if (donnees.defauts.c_erreurs == "boîte" or (donnees.defauts.c_erreurs == "auto" and donnees.defauts.article == false)) then
merr = merr .. fnc.box_ouverture("Erreur(s)")
merr = merr .. fnc.box_texte(donnees.defauts.r_erreurs)
merr = merr .. fnc.box_fermeture()
end
end
-- terminé, on retourne le tout
return p.prepare_sortie(tb .. mtitre .. mstitre .. mcat .. mcaterr .. merr, dg)
end
-- cherche le | suivant, en ignorant ceux dans des modèles ou wikiliens
-- retourne une position (utf8)
function p.pipe_suivant(ligne, posr)
local pos = posr
local cnt = 0
while (true) do
local c = mw.ustring.sub(ligne, pos, pos)
if (c == nil or c == "") then
if (pos <= posr) then
return nil
else
return pos
end
end
-- on comptabilise les entrées/sorties de modèle/lien
if (c == "[" or c == "{") then
cnt = cnt + 1
elseif (c == "]" or c == "}") then
cnt = cnt - 1
elseif (c == "|") then
-- si | on retourne la position que si cnt = 0
if (cnt == 0) then
return pos
end
end
pos = pos + 1
end
-- on ne vient pas là
return nil
end
-- découpe selon les | et range dans une table
function p.decoupe_pipe(ligne)
local tbl = {}
local pos
local courant = 1
pos = z.pipe_suivant(ligne, 1)
if (pos == nil) then
table.insert(tbl, ligne) -- un seul élément
return tbl
end
while (pos ~= nil) do
-- on recupere de "courant" à pos
local tmp = mw.ustring.sub(ligne, courant, pos-1)
table.insert(tbl, tmp)
courant = pos + 1
-- on recupere la partie suivante
pos = p.pipe_suivant(ligne, courant)
end
return tbl
end
--[[
Découpe un modèle en ses paramètres
--]]
function p.decoupe_modele(modele)
end
--[[
Prend en paramètre un modèle modulaire, et retourne sa version monolytique
--]]
function p.mono_vers_modu(modele)
return ""
end
-- on retourne le module
return p