Module:Italiques biologiques : Différence entre versions
(Page créée avec « -- gestion de la mise en italique d'un nom scientifique, en respectant les conventions de la biologie local p = {} -- fonction basique mettant le titre courant en italiq... ») |
imported>Jacques Ducloy m (1 révision importée) |
(2 révisions intermédiaires par 2 utilisateurs non affichées) | |
(Aucune différence)
|
Version actuelle datée du 21 janvier 2021 à 13:51
Utilisation
Fonctions exportables :
titre_en_italiques(frame)
– met le titre en italique, en ignorant la partie (éventuelle) homonymie. Ne met pas l'espace de nom éventuel en italique.- paramètre nommé optionnel : "lang=XX", qui insert un span décrivant la langue.
ns(frame)
− prend en paramètre non nommé un nom scientifique et retourne ce nom en italique inconditionnellement, en respectant les contraintes typographiques de la biologie. (appellé par {{Taxobox taxon}})nt(frame)
− similaire àns(frame)
mais utilisé par {{Taxobox}}. Prend en paramètres non nommés (dans l'ordre) nom, nom2 et rang, et utilise nom2 s'il est non vide sinon nom (utile pour s'adapter à la syntaxe de {{Taxobox}} qui peut être « rang | nom » ou « rang | nom wiki | nom ». Important : éviter d'utiliser cette fonction dans un autre contexte car pour des raisons techniques elle utilise du code HTML (et non wiki) pour gérer l'italiquetitre(frame)
– prend en paramètre non nommé un nom scientifique et modifie le titre de l'article pour le mettre en italique. La fonction récupère le titre de l'article et ne met en italiques qui si le titre est de la forme XXXYYY, avec XXX le nom scientifique en paramètre et YYY éventuellement vide. Seule la partie XXX est passée en italique. Ne fait rien dans les autres cas, ni si la fonction est appelée depuis au autre espace de nom que l'espace encyclopédique. (appellé par {{Taxoboxoutils titre en italique}})- paramètre nommé optionnel : "titre=XXX" : si ce paramètre est indiqué la fonction utilise XXX comme titre de la page au lieu du titre réel. De plus le résultat est retourné dans un nowiki afin de visualiser ce qui aurait été fait (option servant pour les pages de documentation et de test).
Modules externes et autres éléments dont ce module a besoin pour fonctionner :
mw.title
(récupération du titre et espace de nom de la page)
Modèle:Section déroulante début Note : ces fonctions ne testent pas s'il est pertinent d'utiliser l'italique.
Fonction ns(frame)
:
{{#invoke:Italiques biologiques|ns|Citrus ×paradisi}} → Citrus ×paradisi
{{#invoke:Italiques biologiques|ns|×Sorbopyrus auricularis}} → ×Sorbopyrus auricularis
{{#invoke:Italiques biologiques|ns|Iberodorcadion (Hispanodorcadion) aguadoi}} → Iberodorcadion (Hispanodorcadion) aguadoi
{{#invoke:Italiques biologiques|ns|Pelophylax kl. esculentus}} → Pelophylax kl. esculentus
{{#invoke:Italiques biologiques|ns|Brassica olearacea var. gemmifera}} → Brassica olearacea var. gemmifera
{{#invoke:Italiques biologiques|ns|Bla ×bli var. blo kl. blu}} → Bla ×bli var. blo kl. blu
{{#invoke:Italiques biologiques|ns|Uroplatus (genre)}} → Uroplatus (genre) − cas de mise en italique inconditonnel
Fonction titre(frame)
Note : un retour vide (après le "→") indique que la fonction a décidé de ne pas modifié le titre, elle retourne donc une chaîne vide.
{{#invoke:Italiques biologiques|titre|Citrus ×paradisi|titre=Citrus ×paradisi}} → {{DISPLAYTITLE:<span style="font-style: normal">Citrus ×paradisi</span>|noerror}}
{{#invoke:Italiques biologiques|titre|×Sorbopyrus auricularis|titre=×Sorbopyrus auricularis}} → {{DISPLAYTITLE:<span style="font-style: normal">×Sorbopyrus auricularis</span>|noerror}}
{{#invoke:Italiques biologiques|titre|Uroplatus guentheri|titre=Uroplate de Günther}} →
{{#invoke:Italiques biologiques|titre|Uroplatus guentheri|titre=Uroplatus guentheri (animal)}} → {{DISPLAYTITLE:<span style="font-style: normal">Uroplatus guentheri</span> (animal)|noerror}}
{{#invoke:Italiques biologiques|titre|Brassica olearacea var. gemmifera|titre=Brassica olearacea var. gemmifera}} → {{DISPLAYTITLE:<span style="font-style: normal">Brassica olearacea var. gemmifera</span>|noerror}}
{{#invoke:Italiques biologiques|titre|Brassica olearacea var. gemmifera|titre=Fox à poil dur}} →
{{#invoke:Italiques biologiques|titre|Uroplatus|titre=Uroplatus sikorae}} → {{DISPLAYTITLE:<span style="font-style: normal">Uroplatus</span> sikorae|noerror}} ⇒ limitation : la partie "homonymie" est considérée comme "YYY si le titre est XXXXYYY et que le nom scientifique indiqué est exactement XXXX". On voit ici que si on est titré genre sur l'article mais qu'on pense être l'espèce correspondante ça ne fait pas ce qui est prévu. Si c'est un problème il est possible d'imposer en plus la présence de parenthèses dans la partie homonymie. Me dire.
{{#invoke:Italiques biologiques|titre|Brassica olearacea ''var.'' gemmifera|titre=Fox à poil dur}} → {{Article de Biologie à corriger|clef=NS|doc=Modèle:Taxobox taxon|message=Nom de taxon 'Brassica olearacea ''var.'' gemmifera' non reconnu}} − exemple de présence d'une mise en forme dans le nom scientifique indiqué
-- gestion de la mise en italique d'un nom scientifique, en respectant les conventions de la biologie
local p = {}
-- fonction basique mettant le titre courant en italique, sauf la partie namespace et la partie homonymie si présente
-- paramètres : lang → optionnel : ajout d'un tag de langue si présent
function p.titre_en_italiques(frame)
local titre = mw.title.getCurrentTitle() -- l'objet titre pour la page courante
local resu -- le résultat qui sera retourné
local page = titre.text -- le nom de la page, sans le namespace
-- paramètre optionnel : la langue
local lang = frame.args["lang"] or frame:getParent().args["lang"]
-- variables contenant l'ouverture et la fermeture du span (ou vide)
local ospan = ""
local fspan = ""
if (lang) then
ospan = '<span lang="' .. lang .. '">'
fspan = '</span>'
end
-- préparation résultat : on commence par le namespace
if (titre.nsText ~= "") then
resu = titre.nsText .. ":"
end
-- on ajoute le span de la langue si demandé
resu = resu .. ospan
-- on ajoute l'italique
resu = resu .. "''"
if (mw.ustring.find(page, " (", 1, true)) then
-- présence d'une homonymie, on ajoute la fin des italiques
-- avant le " (" (une seule fois, au cas où il y aurait plusieurs ())
-- on ajoute aussi la fermeture éventuelle du span
resu = resu .. mw.ustring.gsub(page, " [(]", "''" .. fspan .. " (", 1)
else
-- pas d'homonymie, on ajoute la page + la fin de l'italique + fin du span
resu = resu .. page .. "''" .. fspan
end
-- résultat, dans un preprocess afin d'interpréter son action
return frame:preprocess("{{DISPLAYTITLE:" .. resu .. "|noerror}}")
end
-- retourne le texte après avoir supprimer les espaces, retour ligne... en début et fin de texte.
-- si texte == nil, la fonction retourne nil.
-- Si le texte est vide ou composé uniquement d'espces, la fonction retourne un texte vide ''.
function p.trim (texte)
return texte and string.match (texte, '^%s*(.-)%s*$')
end
-- table des éléments à ne pas mettre en italique
-- note : mettre un " " avant un terme qui existe aussi sous forme longue
-- exemple : " var.", à cause de "convar.". Sans l'espace les deux vont s'appliquer
-- au texte analysé. Notez de bien répercuter ce même espace dans la partie de droite
p.exclude = {
{ " cl[.]", " ''cl.''" },
{ "convar[.]", "''convar.''" },
{ " f[.]", " ''f.''" },
{ " gen[.]", " ''gen.''" },
{ "kl[.]", "''kl.''" },
{ "nothog[.]", "''nothog.''" },
{ "nothosp[.]", "''nothosp.''" },
{ "nothovar[.]", "''nothovar.''" },
{ " ord[.]", " ''ord.''" },
{ " fam[.]", " ''fam.''" },
{ " sect[.]", " ''sect.''" },
{ " ser[.]", " ''ser.''" },
{ " sp[.]", " ''sp.''" },
{ "subg[.]", "''subg.''" },
{ "subsp[.]", "''subsp.''" },
{ " tr[.]", " ''tr.''" },
{ " var[.]", " ''var.''" },
{ "×", "''×''" },
{ "[(]", "''(''" },
{ "[)]", "'')''" }
}
-- liste d'exclusion uniquement pour mettre droit dans la partie {{taxobox}} italique (ifgenre)
p.exclude_span = {
{ " cl[.]", " <span style=\"font-style: normal\">cl.</span>" },
{ "convar[.]", "<span style=\"font-style: normal\">convar.</span>" },
{ " f[.]", " <span style=\"font-style: normal\">f.</span>" },
{ " gen[.]", " <span style=\"font-style: normal\">gen.</span>" },
{ "kl[.]", "<span style=\"font-style: normal\">kl.</span>" },
{ "nothog[.]", "<span style=\"font-style: normal\">nothog.</span>" },
{ "nothosp[.]", "<span style=\"font-style: normal\">nothosp.</span>" },
{ "nothovar[.]", "<span style=\"font-style: normal\">nothovar.</span>" },
{ " ord[.]", " <span style=\"font-style: normal\">ord.</span>" },
{ " fam[.]", " <span style=\"font-style: normal\">fam.</span>" },
{ " sect[.]", " <span style=\"font-style: normal\">sect.</span>" },
{ " ser[.]", " <span style=\"font-style: normal\">ser.</span>" },
{ " sp[.]", " <span style=\"font-style: normal\">sp.</span>" },
{ "subg[.]", "<span style=\"font-style: normal\">subg.</span>" },
{ "subsp[.]", "<span style=\"font-style: normal\">subsp.</span>" },
{ " tr[.]", " <span style=\"font-style: normal\">tr.</span>" },
{ " var[.]", " <span style=\"font-style: normal\">var.</span>" },
{ "×", "<span style=\"font-style: normal\">×</span>" },
{ "[(]", "<span style=\"font-style: normal\">(</span>" },
{ "[)]", "<span style=\"font-style: normal\">)</span>" }
}
--[[
Liste d'exclusion de noms de clades qui sont français et donc ne doivent pas être en italique
--]]
p.exclude_clades = {
"Angiospermes"
}
--[[
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 (p.exclude_clades[i] ~= nil) do
if (p.exclude_clades[i] == nom) then
-- exception, en français, on laisse sans italiques
return true
end
i = i + 1
end
return false
end
-- si 'true' indique regne tout en italique
p.regnes = {
["test"]=false, ["algue"]=true, ["animal"]=false, ["archaea"]=true,
["bactérie"]=true, ["champignon"]=true, ["protiste"]=false, ["végétal"]=true, ["virus"]=true,
["neutre"]=true, ["eucaryote"]=false, ["procaryote"]=true
}
-- si true indique rang inférieur (ou égal) au genre
p.rangs = {
["clade"]=false, ["type"]=false, ["groupe"]=false, ["non-classé"]=false, ["sous-forme"]=true,
["forme"]=true, ["cultivar"]=true, ["variété"]=true, ["sous-espèce"]=true, ["hybride"]=true,
["espèce"]=true, ["sous-série"]=true, ["série"]=true, ["sous-section"]=false, ["section"]=false,
["sous-genre"]=true, ["genre"]=true, ["sous-tribu"]=false, ["tribu"]=false, ["super-tribu"]=false,
["infra-tribu"]=false, ["sous-famille"]=false, ["famille"]=false, ["épifamille"]=false, ["super-famille"]=false,
["micro-ordre"]=false, ["infra-ordre"]=false, ["sous-ordre"]=false, ["ordre"]=false, ["super-ordre"]=false,
["sous-cohorte"]=false, ["cohorte"]=false, ["super-cohorte"]=false, ["infra-classe"]=false, ["sous-classe"]=false,
["classe"]=false, ["super-classe"]=false, ["infra-embranchement"]=false, ["sous-embranchement"]=false, ["embranchement"]=false,
["super-embranchement"]=false, ["sous-division"]=false, ["division"]=false, ["super-division"]=false, ["infra-règne"]=false,
["rameau"]=false, ["sous-règne"]=false, ["règne"]=false, ["super-règne"]=false, ["sous-domaine"]=false,
["domaine"]=false, ["empire"]=false
}
-- retourne true si rang+regne a besoin de l'italique
function p.rang_regne_it(rang, regne)
if (rang == nil or rang == "" or regne == nil or regne == "") then
return nil
end
local reg = p.regnes[regne]
if (reg == nil) then
return nil
end
if (reg == true) then
return true -- tout en italique
end
local rag = p.rangs[rang]
if (rag == nil) then
return nil
end
if (rag == true) then
return true
else
return false
end
end
-- met un nom scientifique en italique, en respectant les conventions.
-- cette fonction met en italique sans condition.
-- cette fonction présume que le nom passé est *uniquement* un nom scientifique (pas de partie homonyme)
-- la partie rang est utilisée pour détecter les "clades" en français
function p.italique_biologique(nom, rang, regne)
if (nom == nil or nom == "") then
return ""
end
-- si pas besoin de l'italique on laisse
local it = p.rang_regne_it(rang, regne)
if (it == nil or it == false) then
return '<span style="font-style: normal">' .. nom .. '</span>'
end
-- si rang=clade et qu'on détecte que c'est du français on laisse sans modifier
if (rang == "clade") then
if (p.clade_francais(nom)) then
return '<span style="font-style: normal">' .. nom .. '</span>'
end
end
-- on remplace dans le nom toutes les occurrences à protéger
local i = 1
while(p.exclude[i] ~= nil) do
nom = mw.ustring.gsub(nom, p.exclude[i][1], p.exclude[i][2])
i = i + 1
end
-- on retourne la partie traitée
-- en insérant les italiques au début et à la fin
-- attention : si on a traité un élément au tout début (ou fin) il faut le virer et ne
-- pas remettre de '' au début (ou fin)
local deb = "''"
local fin = "''"
if (mw.ustring.find(nom, "^''")) then
nom = mw.ustring.sub(nom, 3) -- on supprime les 2 1er
deb = "" -- pas au début
end
if (mw.ustring.find(nom, "''$")) then
nom = mw.ustring.sub(nom, 1, -3) -- on supprime les 2 derniers
fin = "" -- pas à la fin
end
return '<span lang="la">' .. deb .. nom .. fin .. '</span>'
end
-- traite un nom scientifique pour la mise en italique
function p.ns(frame)
-- on récupère le rang (si cultivar, fonction dédiée)
local rang = mw.ustring.lower(mw.text.trim(frame.args["rang"] or ""))
-- on récupère le règne
local regne = mw.ustring.lower(mw.text.trim(frame.args["règne"] or ""))
-- juste un wrapper
if (rang == "cultivar") then
return ( p.italique_cultivar(p.trim(frame.args[1] or frame:getParent().args[1] or "")) )
else
return ( p.italique_biologique(p.trim(frame.args[1] or frame:getParent().args[1] or ""), rang, regne) )
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.italique_biologique(part1, "espèce", "animal")
local reste = mw.ustring.sub(nom, debut)
return itpart1 .. reste
end
-- traite un nom de cultivar pour la mise en italique
function p.nc(frame)
-- juste un wrapper
return ( p.italique_cultivar(p.trim(frame.args[1] or frame:getParent().args[1] or "")) )
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. Détecte un NV
function p.titre(frame)
local ttr
local cat = ""
-- le nom scientifique
local ns = p.trim(frame.args[1] or frame:getParent().args[1] or "")
if (ns == nil or ns == "") then
-- pas de nom scientifique, on ne peut pas travailler
return ""
end
-- on récupère règne et rang si présents
local regne = frame.args["règne"] or frame:getParent().args["règne"]
local rang = frame.args["rang"] or frame:getParent().args["rang"]
regne = mw.text.trim(regne or "")
rang = mw.text.trim(rang or "")
-- test temporaire : si le nom scientifique contient de la mise en forme
-- on range l'article dans une catégorie pour les détecter
--- selon les combinaisons règne+rang on fait des choses différentes
local a_tester = "[[{'†éèêëàâäùüûçîïôö]"
if (regne == "virus") then
a_tester = nil -- on trouve de tout dans les virus
end
if (rang == "clade") then
a_tester = "[[{'†]" -- pour les clades les noms peuvent être en français
end
if (regne == "animal" and rang == "hybride") then
a_tester = "[[{'†]" -- pour les hybrides animaux les noms peuvent être en français
end
if (rang == "cultivar") then
a_tester = "[[{†]" -- les cultivars contiennent des ' ou ‘’
end
-- seulement si on a un test à faire
if (a_tester ~= nil) then
local tst = mw.ustring.find(ns, a_tester)
if (tst) then
cat = "{{Article de Biologie à corriger|clef=NS|"
.. "doc=Modèle:Taxobox taxon|message=Nom de taxon '"
.. mw.text.nowiki(ns) .. "' non reconnu}}"
end
end
-- spécial : si paramètre "titre" → on utilise à la place
local ft = frame.args["titre"] or frame:getParent().args["titre"]
if (ft) then
-- titre forcé : on l'utilise à la place du titre réel
-- et on ne vérifie pas le namespace
ttr = ft
else
-- le titre
local titre = mw.title.getCurrentTitle()
if (titre.namespace ~= 0) then
-- seulement les articles !
return ""
end
ttr = titre.text
end
if (ttr == ns) then
-- titre exactement NS → direct
if (ft) then
if (rang == "cultivar") then
return frame:preprocess("<nowiki>" .. cat .. "{{DISPLAYTITLE:" .. p.italique_cultivar(ns) .. "|noerror}}</nowiki>")
else
return frame:preprocess("<nowiki>" .. cat .. "{{DISPLAYTITLE:" .. p.italique_biologique(ns, rang, regne) .. "|noerror}}</nowiki>")
end
else
if (rang == "cultivar") then
return frame:preprocess(cat .. "{{DISPLAYTITLE:" .. p.italique_cultivar(ns) .. "|noerror}}")
else
return frame:preprocess(cat .. "{{DISPLAYTITLE:" .. p.italique_biologique(ns, rang, regne) .. "|noerror}}")
end
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(ttr) <= lng) and (cat ~= "")) then
if (ft) then
return frame:preprocess("<nowiki>" .. cat .. "</nowiki>")
else
return frame:preprocess(cat) -- on ne fait rien
end
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(ttr, 1, lng)
if (p1 ~= ns) then
if (cat ~= "") then
return frame:preprocess(cat) -- on ne fait rien
else
return ""
end
end
-- la partie homonymie seule
local hom = mw.ustring.sub(ttr, lng+1)
-- on valide que la partie homonymie contient des ()
local tst = mw.ustring.find(ttr, "[(]")
if ((tst == nil) and (cat ~= "")) then
-- pas de parenthèse, ce n'est pas NS + homonymie
return frame:preprocess(cat) -- on ne touche rien
end
-- on retourne la mise en forme du NS italique + la partie homonymie
if (ft) then
if (rang == "cultivar") then
return frame:preprocess("<nowiki>" .. cat .. "{{DISPLAYTITLE:" .. p.italique_cultivar(ns) .. hom .. "|noerror}}</nowiki>")
else
return frame:preprocess("<nowiki>" .. cat .. "{{DISPLAYTITLE:" .. p.italique_biologique(ns, rang, regne) .. hom .. "|noerror}}</nowiki>")
end
else
if (rang == "cultivar") then
return frame:preprocess(cat .. "{{DISPLAYTITLE:" .. p.italique_cultivar(ns) .. hom .. "|noerror}}")
else
return frame:preprocess(cat .. "{{DISPLAYTITLE:" .. p.italique_biologique(ns, rang, regne) .. hom .. "|noerror}}")
end
end
end
-- met un nom scientifique en italique, en respectant les conventions. Utilisable uniquement :
-- - dans le modèle {{taxobox}} car il utilise une syntaxe HTML et non wiki pour tenir compte du style CSS associé
-- - sur des taxons qui sont à coup sur en italiques (inf. au genre) car ne sait pas quelles sont les conditions autour
-- - ne gère pas la partie homonymie (pas supposé se rencontrer dans les noms de taxon)
function p.italique_taxon(nom, rang)
if (nom == nil or nom == "") then
return ""
end
-- si c'est un clade et détecté français on enlève l'italique
if (rang == "clade") then
if (p.clade_francais(nom)) then
return '<span style="font-style: normal">' .. nom .. '</span>'
end
end
-- on remplace dans le nom toutes les occurrences à protéger
local i = 1
while(p.exclude[i] ~= nil) do
nom = mw.ustring.gsub(nom, p.exclude_span[i][1], p.exclude_span[i][2])
i = i + 1
end
return nom
end
-- wrapper
function p.nt(frame)
local nom = mw.text.trim(frame.args[1] or frame:getParent().args[1] or "")
if (nom == "") then
return ""
end
local nom2 = mw.text.trim(frame.args[2] or frame:getParent().args[2] or "")
local rang = mw.text.trim(frame.args[3] or frame:getParent().args[3] or "")
local resu
if (nom2 == "") then
resu = p.italique_taxon(nom, rang)
else
resu = p.italique_taxon(nom2, rang)
end
if (nom == resu) then
return " [[" .. resu .. "]]"
else
return frame:preprocess(" [[" .. nom .. "|" .. resu .. "]]")
end
end
-- module
return p