Module:Italiques biologiques

De Les Mots de l'agronomie
Version datée du 21 janvier 2021 à 13:51 par Motsagro (discussion | contributions) (1 révision importée)
(diff) ← Version précédente | Voir la version actuelle (diff) | Version suivante → (diff)
Aller à la navigationAller à la recherche

-- 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 = ''
       fspan = ''
   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("")

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 Modèle:Article de Biologie à corriger italique (ifgenre) p.exclude_span = { { " 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 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 '' .. nom .. '' 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 '' .. nom .. '' 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 '' .. deb .. nom .. fin .. '' 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 = "Modèle:Article de Biologie à corriger" 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("" .. cat .. "{{DISPLAYTITLE:" .. p.italique_cultivar(ns) .. "|noerror}}") else return frame:preprocess("" .. cat .. "{{DISPLAYTITLE:" .. p.italique_biologique(ns, rang, regne) .. "|noerror}}") end else if (rang == "cultivar") then return frame:preprocess(cat .. "") else return frame:preprocess(cat .. "") 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("" .. cat .. "") 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("" .. cat .. "{{DISPLAYTITLE:" .. p.italique_cultivar(ns) .. hom .. "|noerror}}") else return frame:preprocess("" .. cat .. "{{DISPLAYTITLE:" .. p.italique_biologique(ns, rang, regne) .. hom .. "|noerror}}") end else if (rang == "cultivar") then return frame:preprocess(cat .. "") else return frame:preprocess(cat .. "") end end end -- met un nom scientifique en italique, en respectant les conventions. Utilisable uniquement : -- - dans le modèle Modèle:Article de Biologie à corriger 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 '' .. nom .. '' 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(" " .. resu .. "") end end -- module return p