Module:Apprentissage/bac à sable
Apparence
La documentation pour ce module peut être créée à Module:Apprentissage/bac à sable/doc
--[[----------------------------------------------------------------------------
Module:Apprentissage — proposition v2 (2026-08-17)
Rétrocompatible : tout appel existant rend le même tableau, aux trois
changements visuels du LOT 1 près (classes responsive, tri, compteur).
Toute nouveauté passe par un paramètre nommé optionnel, éteint par défaut.
LOT 0 — correctifs invisibles
· les variables ne fuient plus dans le global (v1 : infos_capacite_split,
jeu, i, infos_capacite)
· « jeux » est copié avant d'être amputé : generation_to_jeux n'est plus muté
· l'icône Capacité Plus porte enfin son propre alt (v1 : « Maîtrise »)
· classes colonne-9 / colonne-10 au lieu de colonne-8 répété
· guillemets et max-width uniformisés
· une génération inconnue rend un message clair, au lieu de planter
LOT 1 — visible, sans toucher aux pages
· les classes qu'attend MediaWiki:Gadget-tableauxFlexibles.css sont enfin
posées : tableau-apprentissage, apprentissage-usuel[-générationN],
apprentissage-capsule[-générationN], apprentissage-donneur,
apprentissage-niveau-Nniveaux. Sans elles, TOUT le CSS mobile du module
est mort — c'est le cas aujourd'hui sur les 5 410 pages.
· data-sort-value sur type, catégorie, puissance, précision, PP, coût,
numéro de CT/DT : ces colonnes n'étaient pas triables (images sans texte)
· un compteur « 57 capacités » À CÔTÉ du bouton — surtout pas dedans :
MediaWiki:Common.js échange textContent et title à chaque clic, un
compteur placé dans le bouton disparaîtrait au premier clic
· le bouton et son compteur retrouvent une taille lisible : mesuré sur le
rendu réel, le « font-size:80% » de la v1 donnait 11,2 px dans une cellule
qui en fait 14, et une cible cliquable de 69 × 14 px — sous le minimum de
24 × 24 px du critère WCAG 2.2 « Target Size (Minimum) »
LOT 2 — nouveautés, sur paramètre
· notes= notes numérotées en pied de tableau, appelées par note(n)
· colonnes-jeux= une colonne ✔/— par jeu, pour les méthodes autres que niveau
· légende= un <caption> (visible et gras : cf. MediaWiki:Common.css)
· couleur-type= colore la cellule de type (classe td.<type> du gadget couleurs)
· p.transfert la méthode « par transfert », qui n'existait pas
· colonnes-générations= sur p.transfert : une colonne par génération
d'origine, comme Bulbapedia. 63 % de ses 3 293 tableaux de transfert en
portent au moins deux, jusqu'à sept ; une colonne de texte ne peut pas
porter cela. « depuis= » force la première colonne, « pokémon= » la racine
des liens d'en-tête.
· p.obscur Colosseum / XD, sans catégoriser les capacités Ombre
NON FAIT, et pourquoi : aria-expanded sur le bouton. MediaWiki:Common.js ne
met pas l'attribut à jour au clic ; il deviendrait faux après le premier clic.
À poser en même temps qu'un correctif du gadget, pas avant.
Banc d'essai : tools/comparer_module_apprentissage.py (console Scribunto,
aucune écriture). Cas de test : wiki/Tests_Module_Apprentissage.wiki
--------------------------------------------------------------------------]]--
local p = {}
local ressources = {
["donneesCapacite"] = require("Module:Ressources/donneesCapacite")
}
local generation_actuelle = 9
local generation_to_jeux = {
{"RB", "J"}, -- gen 1
{"OA", "C"}, -- gen 2
{"RS", "E", "RFVF"}, -- gen 3
{"DP", "Pt", "HGSS"}, -- gen 4
{"NB", "N2B2"}, -- gen 5
{"XY", "ROSA"}, -- gen 6
{"SL", "USUL", "LGPE"}, -- gen 7
{{"EB", "DEPS"}, "LPA"}, -- gen 8, EB et DEPS dans la même colonne
{"EV", "LPZA"}, -- gen 9
{"VV"} -- gen 10
}
--------------------------------------------------------------------------------
-- Petits outils
--------------------------------------------------------------------------------
local function non_vide( valeur )
if valeur == nil then return false end
valeur = mw.text.trim( valeur )
return valeur ~= "" and valeur ~= "-" and valeur ~= "—"
end
--- Copie de surface. Sans elle, amputer « jeux » ampute generation_to_jeux.
local function copier( tableau )
local copie = {}
for i, valeur in ipairs( tableau ) do copie[i] = valeur end
return copie
end
--- Le nombre de colonnes communes à toutes les méthodes, concours compris.
local function nb_communes( generation )
if generation == 3 or generation == 6 then return 9
elseif generation == 4 then return 8
else return 6
end
end
local function lire_generation( frame )
local generation = frame.args['génération']
if generation == nil then return generation_actuelle end
return tonumber( generation )
end
local function lire_type( frame )
local poke_type = frame.args['type']
if poke_type == nil then return "inconnu" end
return mw.text.trim( string.lower( string.gsub( poke_type, "É", "é" ) ) )
end
--- Les jeux de la génération, ou ceux demandés. « sans » retire un jeu absent
--- de la méthode (LPA n'a ni capsule ni reproduction).
local function lire_jeux( frame, generation, sans )
local jeux = frame.args['jeux']
if jeux == nil then
jeux = copier( generation_to_jeux[generation] )
if sans ~= nil then
for i = #jeux, 1, -1 do
if jeux[i] == sans then table.remove( jeux, i ) end
end
end
else
jeux = mw.text.split( jeux, "/" )
for i, jeu in ipairs( jeux ) do jeux[i] = mw.text.trim( jeu ) end
end
return jeux
end
local function oui( valeur )
return valeur == "oui" or valeur == "1"
end
--------------------------------------------------------------------------------
-- LOT 1 — le tri
--------------------------------------------------------------------------------
--- Les valeurs BRUTES de la capacité, pour trier ce que donneesCapacite ne rend
--- qu'en images. Renvoie nil si la capacité est inconnue (ou génération future).
local function donnees_brutes( generation, capacite )
local ok, data = pcall( mw.loadData,
'Module:Data/Données Capacités Génération ' .. generation )
if not ok or type( data ) ~= "table" then return nil end
return data[capacite]
end
--- « ?? » (inconnu) et « — » (sans objet) doivent tomber au bas du tri, pas
--- se mêler aux nombres.
local function tri_nombre( valeur )
if valeur == nil then return -2 end
if valeur == 0 then return -1 end
return valeur
end
local function attribut_tri( valeur )
if valeur == nil then return "" end
-- Pas de mw.text.nowiki ici : il échapperait des caractères qui n'ont aucun
-- sens wiki dans un attribut. Seul le guillemet doit être neutralisé.
return ' data-sort-value="'
.. string.gsub( tostring( valeur ), '"', '"' ) .. '"'
end
--------------------------------------------------------------------------------
-- LOT 2 — les notes de pied de tableau
--------------------------------------------------------------------------------
--- Découpe le paramètre « notes » : une note par ligne, numérotées dans l'ordre.
local function lire_notes( frame )
local notes = frame.args['notes']
if notes == nil or mw.text.trim( notes ) == "" then return {} end
local lignes = mw.text.split( mw.text.trim( notes ), "\n" )
local propres = {}
for _, ligne in ipairs( lignes ) do
if mw.text.trim( ligne ) ~= "" then
table.insert( propres, mw.text.trim( ligne ) )
end
end
return propres
end
--- Le nom de la capacité, débarrassé de son éventuel appel de note.
--- Les parenthèses autour de string.gsub sont indispensables : gsub renvoie
--- DEUX valeurs, et la seconde serait prise par mw.text.trim pour son charset —
--- le nom garderait alors ses espaces et la page tomberait en catégorie de
--- maintenance. C'est ce que le banc d'essai a attrapé.
local function nettoyer_nom( champ )
return mw.text.trim( ( string.gsub( champ, "note%(%d+%)", "" ) ) )
end
--- Remplace les appels « note(2) » d'un champ par un renvoi cliquable.
local function appliquer_notes( texte, ancre )
if texte == nil then return texte end
return ( string.gsub( texte, "note%((%d+)%)", function( numero )
return '<sup>[[#' .. ancre .. '-' .. numero .. '|' .. numero .. ']]</sup>'
end ) )
end
local function pied_de_notes( notes, ancre, colspan )
if #notes == 0 then return "" end
local morceaux = { '<tfoot><tr><td class="colonne-toutes" colspan="' .. colspan
.. '" style="text-align:left; font-size:90%">' }
for numero, texte in ipairs( notes ) do
table.insert( morceaux, '<span id="' .. ancre .. '-' .. numero .. '">'
.. numero .. '.</span> ' .. texte .. '<br />' )
end
table.insert( morceaux, '</td></tr></tfoot>' )
return table.concat( morceaux, "" )
end
--------------------------------------------------------------------------------
-- Le squelette commun : classes, en-têtes, cellules, bouton
--------------------------------------------------------------------------------
--- LOT 1 — les classes que MediaWiki:Gadget-tableauxFlexibles.css attend.
--- « famille » vaut "usuel" ou "capsule" ; « suffixes » ajoute par exemple
--- "apprentissage-donneur" ou "apprentissage-niveau-2niveaux".
local function classes_table( famille, generation, poke_type, suffixes )
local classes = { "tableaustandard", poke_type, "centre", "sortable",
"tableau-overflow", "tableau-apprentissage",
"apprentissage-" .. famille,
"apprentissage-" .. famille .. "-génération" .. generation }
for _, suffixe in ipairs( suffixes or {} ) do
table.insert( classes, suffixe )
end
return table.concat( classes, " " )
end
local function ouvrir_table( famille, generation, poke_type, suffixes, legende )
local html = '<div class="center"><table class="'
.. classes_table( famille, generation, poke_type, suffixes )
.. '" style="max-width: 100%;">'
if legende ~= nil and mw.text.trim( legende ) ~= "" then
html = html .. '<caption>' .. mw.text.trim( legende ) .. '</caption>'
end
return html .. '<thead>'
end
--- Les six (ou huit, ou neuf) en-têtes communs. « depart » vaut 1, sauf pour
--- capsule et disque où la colonne 1 est le numéro.
--- Les libellés d'en-tête, repris À LA LETTRE de la v1 : ils diffèrent d'une
--- méthode à l'autre (capsule ne lie rien, reproduction abrège, donneur écrit
--- « [[Précision|Précision]] »). Les reproduire exactement est ce qui rend la
--- comparaison v1/v2 concluante.
local TITRES = {
niveau = { '[[Capacité|Nom]]', '[[Type]]', '[[Catégorie de capacité|Catégorie]]',
'[[Puissance (statistique)|Puissance]]', '[[Précision]]', '[[PP]]' },
capsule = { 'Capacité', 'Type', 'Catégorie', 'Puissance', 'Précision', 'PP' },
reproduction = { '[[Capacité]]', '[[Type]]', '[[Catégorie de capacité|Cat.]]',
'[[Puissance (statistique)|Puis.]]', '[[Précision|Préc.]]', '[[PP]]' },
usuel = { '[[Capacité]]', '[[Type]]', '[[Catégorie de capacité|Catégorie]]',
'[[Puissance (statistique)|Puissance]]', '[[Précision|Précision]]', '[[PP]]' },
}
local function entetes_communes( generation, depart, titres )
local html = {}
for i, titre in ipairs( titres ) do
table.insert( html, '<th class="colonne-' .. ( depart + i - 1 )
.. '" scope="col">' .. titre .. '</th>' )
end
if generation == 3 or generation == 4 or generation == 6 then
table.insert( html, '<th class="colonne-' .. ( depart + 6 )
.. '" scope="col">[[Concours Pokémon|Type Concours]]</th>' )
table.insert( html, '<th class="colonne-' .. ( depart + 7 )
.. '" scope="col">[[Charme (concours)|Charme]]</th>' )
if generation == 3 or generation == 6 then
table.insert( html, '<th class="colonne-' .. ( depart + 8 )
.. '" scope="col">[[Blocage (concours)|Blocage]]</th>' )
end
end
return table.concat( html, "" )
end
--- Les cellules communes d'une ligne, avec leur valeur de tri.
--- « suffixe_nom » colle un <sup> après le nom (capsule : le jeu du numéro).
local function cellules_communes( donnees, brutes, generation, depart, options )
options = options or {}
local html = {}
local nom = donnees[1] .. ( options.suffixe_nom or "" )
table.insert( html, '<td class="colonne-' .. depart .. '">' .. nom .. '</td>' )
local classe_type = 'colonne-' .. ( depart + 1 )
if options.couleur_type and brutes ~= nil and brutes[1] ~= nil then
classe_type = classe_type .. ' '
.. string.lower( ( string.gsub( brutes[1], "É", "é" ) ) )
end
local tris = {
brutes and brutes[1] or nil,
brutes and brutes[2] or nil,
brutes and tri_nombre( brutes[3] ) or nil,
brutes and tri_nombre( brutes[4] ) or nil,
brutes and tri_nombre( brutes[5] ) or nil,
}
table.insert( html, '<td class="' .. classe_type .. '"' .. attribut_tri( tris[1] )
.. '>' .. donnees[2] .. '</td>' )
for i = 3, 6 do
table.insert( html, '<td class="colonne-' .. ( depart + i - 1 ) .. '"'
.. attribut_tri( tris[i - 1] ) .. '>' .. donnees[i] .. '</td>' )
end
if generation == 3 or generation == 4 or generation == 6 then
table.insert( html, '<td class="colonne-' .. ( depart + 6 ) .. '"'
.. attribut_tri( brutes and brutes[6] or nil ) .. '>' .. donnees[7] .. '</td>' )
table.insert( html, '<td class="colonne-' .. ( depart + 7 ) .. '"'
.. attribut_tri( brutes and tri_nombre( brutes[7] ) or nil ) .. '>'
.. donnees[8] .. '</td>' )
if generation == 3 or generation == 6 then
table.insert( html, '<td class="colonne-' .. ( depart + 8 ) .. '"'
.. attribut_tri( brutes and tri_nombre( brutes[8] ) or nil ) .. '>'
.. donnees[9] .. '</td>' )
end
end
return table.concat( html, "" )
end
--- Le nom que partagent le bouton et le tbody qu'il replie. MediaWiki:Common.js
--- pilote TOUS les tbody de ce nom : deux tableaux de même méthode et de même
--- génération sur une page se replient donc ensemble. Cela arrive sur 21 % des
--- pages (formes régionales : sur Raichu, ListeCapsules8 existe deux fois).
--- « identifiant= » permet de les distinguer ; sans lui, rien ne change.
local function nom_du_groupe( frame, nom_classe, generation )
local nom = nom_classe .. generation
local identifiant = frame.args['identifiant']
if identifiant ~= nil and mw.text.trim( identifiant ) ~= "" then
-- Un nom de classe CSS ne tolère ni espace ni accent.
identifiant = mw.ustring.gsub( mw.text.trim( identifiant ), "[^%w]", "" )
if identifiant ~= "" then nom = nom .. "-" .. identifiant end
end
return nom
end
--- La ligne du bouton. Le compteur est un <span> HORS du bouton : Common.js
--- échange textContent et title au clic et l'effacerait.
---
--- LOT 1 — la taille. Mesuré sur le rendu réel : le « font-size:80% » de la v1
--- donnait **11,2 px** dans une cellule qui en fait 14, et la cible cliquable
--- mesurait 69 × 14 px — sous le minimum de 24 × 24 px du critère WCAG 2.2
--- « Target Size (Minimum) ». Un <button> n'hérite pas non plus de la police du
--- tableau : le navigateur lui impose Arial, alors que la page est en sans-serif.
--- D'où : taille pleine, police héritée, et un peu de rembourrage pour la cible.
--- Le compteur reste secondaire, mais lisible (90 %, soit 12,6 px).
local STYLE_BOUTON = "font-size:100%; font-family:inherit; padding:3px 6px; line-height:1.4"
local STYLE_COMPTEUR = "font-size:90%; color:#54595d"
local function ligne_bouton( frame, nom_classe, generation, colspan, total )
local groupe = nom_du_groupe( frame, nom_classe, generation )
local bouton
if oui( frame.args['masquer'] ) then bouton = { "afficher", "[-] Masquer", "[+] Afficher" }
else bouton = { "masquer", "[+] Afficher", "[-] Masquer" }
end
local compteur = ""
if total ~= nil and total > 0 then
local mot = " capacités"
if total == 1 then mot = " capacité" end
compteur = ' <span class="apprentissage-compteur" style="' .. STYLE_COMPTEUR
.. '">' .. total .. mot .. '</span>'
end
return '<tr><td class="colonne-toutes" colspan="' .. colspan
.. '"><button type="button" name="' .. groupe
.. '" value="' .. bouton[1] .. '" style="' .. STYLE_BOUTON .. '" title="'
.. bouton[2] .. '">' .. bouton[3] .. '</button>' .. compteur
.. '</td></tr></thead><tbody class="' .. groupe .. '">'
end
local function ligne_vide( colspan, phrase )
return '</thead><tbody><tr><td class="colonne-toutes" colspan="' .. colspan
.. '">' .. phrase .. '</td></tr>'
end
--- Le wiki nomme ses catégories de maintenance « Page avec un X incorrect »
--- (nom de capacité, nom de Pokémon, paramètre de distribution). On suit le
--- même schéma. La catégorie reste à créer — une ligne, et elle listera d'elle
--- même les pages fautives.
local function generation_invalide( generation )
return '<span class="error">Module:Apprentissage : génération « '
.. tostring( generation ) .. ' » inconnue.</span>'
.. '[[Catégorie:Page avec un paramètre d\'apprentissage incorrect]]'
end
--------------------------------------------------------------------------------
-- LOT 2 — les colonnes par jeu, pour les méthodes autres que « niveau »
--------------------------------------------------------------------------------
--- Découpe une ligne et sépare les champs de la méthode des colonnes de jeu.
--- Actif seulement si colonnes-jeux=oui ; sinon la ligne garde sa forme d'origine.
local function colonnes_de_jeux( frame, generation )
if not oui( frame.args['colonnes-jeux'] ) then return nil end
local jeux = frame.args['jeux']
if jeux == nil then jeux = copier( generation_to_jeux[generation] )
else
jeux = mw.text.split( jeux, "/" )
for i, jeu in ipairs( jeux ) do jeux[i] = mw.text.trim( jeu ) end
end
return jeux
end
--- Les colonnes de jeu réutilisent la classe « colonne-niveau » : pour que le
--- CSS du gadget les prenne en charge, la table doit porter le compte, comme
--- le fait déjà p.niveau.
local function suffixes_jeux( colonnes_jeux )
if colonnes_jeux == nil or #colonnes_jeux == 0 then return {} end
return { "apprentissage-niveau-" .. #colonnes_jeux .. "niveaux" }
end
local function entetes_jeux( frame, jeux )
if jeux == nil then return "" end
local html = {}
for _, jeu in ipairs( jeux ) do
local libelle
if type( jeu ) == "table" then
local abreviations = {}
for _, un in ipairs( jeu ) do
table.insert( abreviations,
frame:expandTemplate{ title = "Abréviation", args = { un, "" } } )
end
libelle = table.concat( abreviations, ", " )
else
libelle = frame:expandTemplate{ title = "Abréviation", args = { jeu, "" } }
end
-- Volontairement « colonne-niveau », et non une classe neuve : le gadget
-- CSS style déjà cette classe (.apprentissage-niveau-Nniveaux .colonne-niveau).
-- Réutiliser ce qui existe évite de demander la moindre ligne de CSS.
table.insert( html, '<th class="colonne-niveau" scope="col">' .. libelle .. '</th>' )
end
return table.concat( html, "" )
end
--- Une cellule par jeu : ✔ quand le champ est rempli, — sinon. Un texte libre
--- (« N.15 », « CT12 ») est affiché tel quel.
local function cellules_jeux( champs, premier, jeux, ancre )
if jeux == nil then return "" end
local html = {}
for i = 1, #jeux do
local valeur = champs[premier + i - 1]
if non_vide( valeur ) then
valeur = mw.text.trim( valeur )
if valeur == "oui" or valeur == "x" or valeur == "X" then valeur = "✔" end
table.insert( html, '<td class="colonne-niveau" data-sort-value="1">'
.. appliquer_notes( valeur, ancre ) .. '</td>' )
else
table.insert( html, '<td class="colonne-niveau" data-sort-value="0">—</td>' )
end
end
return table.concat( html, "" )
end
--------------------------------------------------------------------------------
-- LOT 2 — les colonnes par GÉNÉRATION D'ORIGINE, pour le transfert
--------------------------------------------------------------------------------
--
-- Bulbapedia ne met pas « d'où vient l'attaque » dans une colonne de texte : il
-- met **une colonne par génération antérieure**, et coche celles où l'attaque
-- s'apprenait. Mesuré sur notre cache (6 769 pages, le 2026-08-17) :
--
-- 3 293 tableaux « by transfer », 43 073 lignes
-- 1 colonne : 1 203 · 2 : 848 · 3 : 471 · 4 : 213
-- 5 : 212 · 6 : 209 · 7 : 137
--
-- Soit **2 090 tableaux (63 %) à deux colonnes ou plus**, jusqu'à sept. Une
-- seule colonne « Provenance » ne peut pas porter cela sans devenir du texte
-- non triable. D'où ces colonnes-ci.
--
-- Sur Poképédia, les 323 tableaux de transfert existants n'écrivent AUCUNE
-- provenance : ils passent une simple liste de noms à p.niveau, qui affiche
-- alors des colonnes de niveau vides. L'information existe chez Bulbapedia et
-- se perd chez nous ; ces colonnes sont l'endroit où la remettre.
local ROMAINS = { "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X" }
--- « 2,3,4 » ou « II, III » -> { [2]=true, [3]=true, [4]=true }.
--- Un « * » collé au chiffre note une génération où l'attaque ne s'obtenait que
--- par événement ou capacité spéciale : c'est le fond rayé de Bulbapedia.
local function ensemble_generations( champ )
local ensemble = {}
if champ == nil then return ensemble end
for _, morceau in ipairs( mw.text.split( champ, "," ) ) do
morceau = mw.text.trim( morceau )
local special = false
if string.sub( morceau, -1 ) == "*" then
special = true
morceau = mw.text.trim( string.sub( morceau, 1, -2 ) )
end
local numero = tonumber( morceau )
if numero == nil then
for i, romain in ipairs( ROMAINS ) do
if string.upper( morceau ) == romain then numero = i end
end
end
if numero ~= nil then
ensemble[numero] = special and "special" or true
end
end
return ensemble
end
--- Les générations à afficher : celles qui précèdent la génération du tableau,
--- bornées par « depuis= », et **amputées de celles que personne ne remplit** —
--- même règle que les colonnes de jeu vides de p.niveau. Sans elle, un Pokémon
--- de neuvième génération recevrait huit colonnes toutes vides.
local function colonnes_de_generations( frame, generation, lignes )
if not oui( frame.args['colonnes-générations'] ) then return nil end
local depuis = tonumber( frame.args['depuis'] or "" ) or 1
if depuis < 1 then depuis = 1 end
local remplies = {}
for _, ligne in ipairs( lignes ) do
local champs = mw.text.split( ligne, "/" )
for numero in pairs( ensemble_generations( champs[2] ) ) do
remplies[numero] = true
end
end
local liste = {}
for g = depuis, generation - 1 do
if remplies[g] or frame.args['depuis'] ~= nil then
table.insert( liste, g )
end
end
return liste
end
--- Le titre de la sous-page de génération du Pokémon de la page courante, quand
--- elle existe. « rootText » vaut « Bulbizarre » aussi bien depuis la page
--- principale que depuis « Bulbizarre/Génération 2 ». Le test d'existence est
--- une fonction coûteuse : une seule par colonne, jamais par cellule, et sous
--- pcall pour qu'un dépassement de quota n'efface pas le tableau.
local function lien_de_generation( frame, numero )
local racine = frame.args['pokémon']
if racine == nil or mw.text.trim( racine ) == "" then
racine = mw.title.getCurrentTitle().rootText
end
local cible = mw.text.trim( racine ) .. "/Génération " .. numero
local ok, page = pcall( mw.title.new, cible )
if ok and page ~= nil then
local vu, existe = pcall( function() return page.exists end )
if vu and existe then
return '[[' .. cible .. '|' .. ROMAINS[numero] .. ']]'
end
end
return ROMAINS[numero]
end
--- Les largeurs mobiles du gadget s'arrêtent à trois colonnes étroites
--- (.apprentissage-niveau-1/2/3niveaux). Au-delà, la classe est posée quand
--- même : cinq lignes de CSS suffiraient à l'honorer, et sans elles les
--- cellules se rangent d'elles-mêmes — aucune n'est cassée.
local function suffixes_generations( generations )
if generations == nil or #generations == 0 then return {} end
return { "apprentissage-niveau-" .. #generations .. "niveaux" }
end
local function entetes_generations( frame, generations )
if generations == nil then return "" end
local html = {}
for _, numero in ipairs( generations ) do
table.insert( html, '<th class="colonne-niveau" scope="col" title="Génération '
.. ROMAINS[numero] .. '">' .. lien_de_generation( frame, numero ) .. '</th>' )
end
return table.concat( html, "" )
end
local function cellules_generations( champ, generations )
if generations == nil then return "" end
local ensemble = ensemble_generations( champ )
local html = {}
for _, numero in ipairs( generations ) do
local etat = ensemble[numero]
if etat == "special" then
table.insert( html, '<td class="colonne-niveau" data-sort-value="2"'
.. ' title="Uniquement par événement ou capacité spéciale">✦</td>' )
elseif etat then
table.insert( html, '<td class="colonne-niveau" data-sort-value="1">✔</td>' )
else
table.insert( html, '<td class="colonne-niveau" data-sort-value="0">—</td>' )
end
end
return table.concat( html, "" )
end
--------------------------------------------------------------------------------
-- p.niveau
--------------------------------------------------------------------------------
function p.niveau( frame )
local infos = frame.args[1]
if infos == nil then return "Aucune information donnée" else infos = mw.text.trim( infos ) end
infos = mw.text.split( infos, "\n" )
local generation = lire_generation( frame )
if generation == nil or generation_to_jeux[generation] == nil then
return generation_invalide( frame.args['génération'] )
end
local poke_type = lire_type( frame )
local notes = lire_notes( frame )
local ancre = "note-niveau-" .. generation
local generation_to_colspans = {
{6, 2}, {6, 2}, {9, 3}, {8, 3}, {6, 2}, {9, 2}, {6, 3}, {6, 2}, {6, 2}, {6, 1}
}
local colspans = { generation_to_colspans[generation][1],
generation_to_colspans[generation][2] }
local nb_jeux_possibles = generation_to_colspans[generation][2]
-- Les colonnes de jeu sans aucune donnée n'apparaissent pas.
local presence = {}
for j = 1, nb_jeux_possibles do presence[j] = false end
local total = 0
for _, ligne in ipairs( infos ) do
local champs = mw.text.split( ligne, "/" )
if champs[1] ~= nil and mw.text.trim( champs[1] ) ~= "" then total = total + 1 end
for j = 1, nb_jeux_possibles do
if non_vide( champs[j + 1] ) then presence[j] = true end
end
end
for j = 1, nb_jeux_possibles do
if presence[j] == false then colspans[2] = colspans[2] - 1 end
end
colspans[3] = colspans[1] + colspans[2]
local jeux = {}
for j = 1, nb_jeux_possibles do
if presence[j] then table.insert( jeux, generation_to_jeux[generation][j] ) end
end
-- Le gadget ne définit que 1niveaux, 2niveaux et 3niveaux : quand aucune
-- colonne de niveau n'est renseignée, il n'y a pas de classe à poser.
local suffixes = {}
if colspans[2] > 0 then
table.insert( suffixes, "apprentissage-niveau-" .. colspans[2] .. "niveaux" )
end
local resultat = {}
table.insert( resultat, ouvrir_table( "usuel", generation, poke_type, suffixes,
frame.args['légende'] ) )
table.insert( resultat, '<tr><th class="cellule-entête" colspan="' .. colspans[1]
.. '" scope="colgroup">[[Capacité]]</th>' )
if colspans[2] > 0 then
table.insert( resultat, '<th class="cellule-entête" colspan="' .. colspans[2]
.. '" scope="colgroup">[[Niveau]]</th>' )
end
table.insert( resultat, '</tr><tr>'
.. entetes_communes( generation, 1, TITRES.niveau ) )
for _, jeux_colonne in ipairs( jeux ) do
if type( jeux_colonne ) == "string" then
table.insert( resultat, '<th class="colonne-niveau" scope="col">'
.. frame:expandTemplate{ title = "Abréviation", args = { jeux_colonne, "" } }
.. '</th>' )
else
local abreviations = {}
for _, jeu_colonne in ipairs( jeux_colonne ) do
table.insert( abreviations,
frame:expandTemplate{ title = "Abréviation", args = { jeu_colonne, "" } } )
end
table.insert( resultat, '<th class="colonne-niveau" scope="col">'
.. table.concat( abreviations, ", " ) .. '</th>' )
end
end
table.insert( resultat, '</tr>' )
if #infos == 1 and infos[1] == "Aucune" then
table.insert( resultat, ligne_vide( colspans[3],
'Ce Pokémon n\'apprend aucune capacité par montée en niveau lors de cette génération.' ) )
else
table.insert( resultat, ligne_bouton( frame, "ListeCapacites", generation,
colspans[3], total ) )
for _, ligne in ipairs( infos ) do
local champs = mw.text.split( ligne, "/" )
if champs[1] ~= nil and champs[1] ~= "" then
local nom_capacite = nettoyer_nom( champs[1] )
local jeux_capacite = {}
for j = 1, nb_jeux_possibles do
if non_vide( champs[j + 1] ) then
table.insert( jeux_capacite, generation_to_jeux[generation][j] )
end
end
local donnees = ressources.donneesCapacite( generation, nom_capacite, jeux_capacite )
local brutes = donnees_brutes( generation, nom_capacite )
local renvoi = appliquer_notes(
string.match( champs[1], "note%(%d+%)" ) or "", ancre )
table.insert( resultat, '<tr>' .. cellules_communes( donnees, brutes,
generation, 1, { suffixe_nom = renvoi,
couleur_type = oui( frame.args['couleur-type'] ) } ) )
for j = 2, nb_jeux_possibles + 1 do
if presence[j - 1] then
local contenu, valeur_tri = "—", 101
if champs[j] ~= nil then
contenu, valeur_tri = "", nil
local morceaux = mw.text.split( mw.text.trim( champs[j] ), ", " )
local est_sup = true
for k, morceau in ipairs( morceaux ) do
local maitrise, capacite_plus = false, false
if mw.ustring.find( morceau, "M" ) == 1 then
maitrise = true
morceau = mw.ustring.sub( morceau, 2 )
elseif mw.ustring.find( morceau, "P" ) == 1 then
capacite_plus = true
morceau = mw.ustring.sub( morceau, 2 )
end
if morceau == "—" or morceau == "-" or morceau == "" then
morceau = "—"
if valeur_tri == nil then valeur_tri = 101 end
est_sup = false
elseif string.find( morceau, "Départ" ) or string.find( morceau, "Évolution" ) then
if valeur_tri == nil then valeur_tri = 0 end
est_sup = false
elseif tonumber( morceau ) ~= nil then
if valeur_tri == nil then valeur_tri = tonumber( morceau ) end
morceau = "N." .. morceau
est_sup = false
else
if valeur_tri == nil then valeur_tri = 0 end
est_sup = not est_sup
end
if k ~= 1 and not est_sup then contenu = contenu .. "<br/>" end
if maitrise then
contenu = contenu ..
"[[Fichier:Icône Maîtrise LPA.png|x20px|Maîtrise|link=Maîtrise]]"
end
if capacite_plus then
contenu = contenu ..
"[[Fichier:Icône Capacité Plus LPZA.png|x20px|Capacité Plus|link=Capacité Plus]]"
end
if est_sup then
contenu = contenu .. frame:expandTemplate{ title = 'Sup', args = { morceau } }
else
contenu = contenu .. morceau
end
end
end
table.insert( resultat, '<td class="colonne-niveau" style="white-space:nowrap"'
.. ' data-sort-value="' .. tostring( valeur_tri or 101 ) .. '">'
.. appliquer_notes( contenu, ancre ) .. '</td>' )
end
end
table.insert( resultat, '</tr>' )
end
end
end
table.insert( resultat, '</tbody>' .. pied_de_notes( notes, ancre, colspans[3] )
.. '</table></div>' )
return table.concat( resultat, "" )
end
--------------------------------------------------------------------------------
-- p.capsule / p.disque
--------------------------------------------------------------------------------
--- Les capacités qui sont des CS selon la génération. « depend » : cela dépend
--- du jeu, précisé en 3e champ.
local CAPACITES_SECRETES = {
["Coupe"] = {true, true, true, true, true, true},
["Vol"] = {true, true, true, true, true, true},
["Surf"] = {true, true, true, true, true, true},
["Force"] = {true, true, true, true, true, true},
["Flash"] = {true, true, true, false, false, false},
["Siphon"] = {false, true, false, "depend", false, false},
["Cascade"] = {false, true, true, true, true, true},
["Éclate-Roc"] = {false, false, true, true, false, "depend"},
["Plongée"] = {false, false, "depend", false, true, "depend"},
["Anti-Brume"] = {false, false, false, "depend", false, false},
["Escalade"] = {false, false, false, true, false, false}
}
CAPACITES_SECRETES["Plongée"]["rse"] = true
CAPACITES_SECRETES["Plongée"]["rfvf"] = false
CAPACITES_SECRETES["Siphon"]["dpp"] = false
CAPACITES_SECRETES["Siphon"]["hgss"] = true
CAPACITES_SECRETES["Anti-Brume"]["dpp"] = true
CAPACITES_SECRETES["Anti-Brume"]["hgss"] = false
CAPACITES_SECRETES["Éclate-Roc"]["xy"] = false
CAPACITES_SECRETES["Éclate-Roc"]["rosa"] = true
CAPACITES_SECRETES["Plongée"]["xy"] = false
CAPACITES_SECRETES["Plongée"]["rosa"] = true
local function sigle_capsule( disque, capacite, generation, jeu )
if disque then return 'DT' end
local regle = CAPACITES_SECRETES[capacite]
if regle == nil then return 'CT' end
if regle[generation] == true then return 'CS' end
if regle[generation] == "depend" and jeu ~= nil
and regle[mw.text.trim( string.lower( jeu ) )] == true then
return 'CS'
end
return 'CT'
end
local function capsule_et_disque( disque, frame )
local infos = frame.args[1]
if infos == nil then return "Aucune information donnée" else infos = mw.text.trim( infos ) end
local generation = lire_generation( frame )
if generation == nil or generation_to_jeux[generation] == nil then
return generation_invalide( frame.args['génération'] )
end
local poke_type = lire_type( frame )
local jeux = lire_jeux( frame, generation, generation == 8 and "LPA" or nil )
local notes = lire_notes( frame )
local colonnes_jeux = colonnes_de_jeux( frame, generation )
local mot = disque and 'disque' or 'capsule'
local nom_classe = disque and 'ListeDisques' or 'ListeCapsules'
local ancre = "note-" .. mot .. "-" .. generation
local colspan = 1 + nb_communes( generation )
+ ( colonnes_jeux and #colonnes_jeux or 0 )
local resultat = {}
table.insert( resultat, ouvrir_table( "capsule", generation, poke_type,
suffixes_jeux( colonnes_jeux ), frame.args['légende'] ) )
table.insert( resultat, '<tr><th class="colonne-1" scope="col">Numéro</th>' )
table.insert( resultat, entetes_communes( generation, 2, TITRES.capsule ) )
table.insert( resultat, entetes_jeux( frame, colonnes_jeux ) )
table.insert( resultat, '</tr>' )
if infos == "Aucune" then
table.insert( resultat, ligne_vide( colspan,
'Ce Pokémon n\'apprend aucune capacité par ' .. mot .. ' lors de cette génération.' ) )
else
local lignes = mw.text.split( infos, "\n" )
local total = 0
for _, ligne in ipairs( lignes ) do
local champs = mw.text.split( ligne, "/" )
if non_vide( champs[1] ) and non_vide( champs[2] ) then total = total + 1 end
end
table.insert( resultat, ligne_bouton( frame, nom_classe, generation, colspan, total ) )
for _, ligne in ipairs( lignes ) do
local champs = mw.text.split( ligne, "/" )
if champs[1] ~= nil and champs[1] ~= "" and champs[2] ~= nil and champs[2] ~= "" then
local numero = mw.text.trim( champs[1] )
local nom_capacite = nettoyer_nom( champs[2] )
local sigle = sigle_capsule( disque, nom_capacite, generation, champs[3] )
local donnees = ressources.donneesCapacite( generation, nom_capacite, jeux )
local brutes = donnees_brutes( generation, nom_capacite )
local suffixe = appliquer_notes(
string.match( champs[2], "note%(%d+%)" ) or "", ancre )
if champs[3] and not colonnes_jeux then
suffixe = suffixe .. '<sup>'
.. frame:expandTemplate{ title = 'Abréviation', args = { champs[3] } }
.. '</sup>'
end
table.insert( resultat, '<tr><td class="colonne-1" data-sort-value="'
.. ( tonumber( ( string.gsub( numero, "%D", "" ) ) ) or 0 ) .. '">[['
.. sigle .. numero .. ']]</td>' )
table.insert( resultat, cellules_communes( donnees, brutes, generation, 2,
{ suffixe_nom = suffixe,
couleur_type = oui( frame.args['couleur-type'] ) } ) )
table.insert( resultat, cellules_jeux( champs, 3, colonnes_jeux, ancre ) )
table.insert( resultat, '</tr>' )
end
end
end
table.insert( resultat, '</tbody>' .. pied_de_notes( notes, ancre, colspan )
.. '</table></div>' )
return table.concat( resultat, "" )
end
function p.capsule( frame )
return capsule_et_disque( false, frame )
end
function p.disque( frame )
return capsule_et_disque( true, frame )
end
--------------------------------------------------------------------------------
-- p.reproduction
--------------------------------------------------------------------------------
function p.reproduction( frame )
ressources["infosPokemon"] = require("Module:Ressources/infosPokemon")
local infos = frame.args[1]
if infos == nil then return "Aucune information donnée" else infos = mw.text.trim( infos ) end
local generation = lire_generation( frame )
if generation == nil or generation_to_jeux[generation] == nil then
return generation_invalide( frame.args['génération'] )
end
local poke_type = lire_type( frame )
local jeux = lire_jeux( frame, generation, generation == 8 and "LPA" or nil )
local notes = lire_notes( frame )
local colonnes_jeux = colonnes_de_jeux( frame, generation )
local ancre = "note-reproduction-" .. generation
local methodes = frame.args['méthodes']
if methodes == nil then methodes = { "[[niveau]]", "[[reproduction]]" }
else methodes = mw.text.split( methodes, "/" )
end
local communes = nb_communes( generation )
local colspan = communes + #methodes + ( colonnes_jeux and #colonnes_jeux or 0 )
local resultat = {}
table.insert( resultat, ouvrir_table( "usuel", generation, poke_type,
suffixes_jeux( colonnes_jeux ), frame.args['légende'] ) )
table.insert( resultat, '<tr>' .. entetes_communes( generation, 1, TITRES.reproduction ) )
for _, methode in ipairs( methodes ) do
table.insert( resultat, '<th class="colonne-toutes" scope="col">Parents l\'apprenant par '
.. methode .. '</th>' )
end
table.insert( resultat, entetes_jeux( frame, colonnes_jeux ) )
table.insert( resultat, '</tr>' )
if infos == "Aucune" then
table.insert( resultat, ligne_vide( colspan,
'Ce Pokémon n\'apprend aucune capacité par reproduction lors de cette génération.' ) )
else
local lignes = mw.text.split( infos, "\n" )
local total = 0
for _, ligne in ipairs( lignes ) do
local champs = mw.text.split( ligne, "/" )
if champs[1] ~= nil and mw.text.trim( champs[1] ) ~= "" then total = total + 1 end
end
table.insert( resultat, ligne_bouton( frame, "ListeReproduction", generation,
colspan, total ) )
for _, ligne in ipairs( lignes ) do
local champs = mw.text.split( ligne, "/" )
if champs[1] ~= nil and mw.text.trim( champs[1] ) ~= "" then
local brut = champs[1]
local jeu = ""
if string.match( brut, "jeu%([^)]*%)" ) then
jeu = frame:expandTemplate{ title = 'Sup',
args = { string.sub( string.match( brut, "jeu%([^)]*%)" ), 5, -2 ) } }
brut = string.gsub( brut, "jeu%([^)]*%)", "" )
end
if string.match( brut, "sup%([^)]*%)" ) then
jeu = frame:expandTemplate{ title = 'Sup',
args = { string.sub( string.match( brut, "sup%([^)]*%)" ), 5, -2 ) } }
brut = string.gsub( brut, "sup%([^)]*%)", "" )
end
local renvoi = appliquer_notes( string.match( brut, "note%(%d+%)" ) or "", ancre )
brut = nettoyer_nom( brut )
local donnees = ressources.donneesCapacite( generation, brut, jeux )
local brutes = donnees_brutes( generation, brut )
table.insert( resultat, '<tr>' .. cellules_communes( donnees, brutes,
generation, 1, { suffixe_nom = jeu .. renvoi,
couleur_type = oui( frame.args['couleur-type'] ) } ) )
for m = 1, #methodes do
local parents = champs[m + 1]
local contenu = "—"
if parents ~= nil and mw.text.trim( parents ) ~= "" then
local liste = {}
for _, parent in ipairs( mw.text.split( parents, "," ) ) do
table.insert( liste, ressources.infosPokemon( parent, "miniature" ) )
end
contenu = table.concat( liste, "" )
end
table.insert( resultat, '<td class="colonne-toutes">' .. contenu .. '</td>' )
end
table.insert( resultat, cellules_jeux( champs, #methodes + 2, colonnes_jeux, ancre ) )
table.insert( resultat, '</tr>' )
end
end
end
if oui( frame.args['queulorior'] ) then
table.insert( resultat, '<tr><td class="colonne-toutes" colspan="' .. colspan
.. '">Grâce à sa capacité [[Gribouille]], [[Queulorior]] est capable d\'apprendre '
.. 'toutes ces capacités, qu\'il peut également transmettre par reproduction.</td></tr>' )
end
table.insert( resultat, '</tbody>' .. pied_de_notes( notes, ancre, colspan )
.. '</table></div>' )
return table.concat( resultat, "" )
end
--------------------------------------------------------------------------------
-- p.donneur
--------------------------------------------------------------------------------
function p.donneur( frame )
local infos = frame.args[1]
if infos == nil then return "Aucune information donnée" else infos = mw.text.trim( infos ) end
local generation = lire_generation( frame )
if generation == nil or generation_to_jeux[generation] == nil then
return generation_invalide( frame.args['génération'] )
end
local poke_type = lire_type( frame )
local jeux = lire_jeux( frame, generation )
local notes = lire_notes( frame )
local colonnes_jeux = colonnes_de_jeux( frame, generation )
local ancre = "note-donneur-" .. generation
local prix_unite = frame.args['prix-unité']
if prix_unite == nil then prix_unite = "[[Point de Combat|PCo]]" end
local communes = nb_communes( generation )
local colspan = communes + 2 + ( colonnes_jeux and #colonnes_jeux or 0 )
local suffixes = suffixes_jeux( colonnes_jeux )
table.insert( suffixes, "apprentissage-donneur" )
local resultat = {}
table.insert( resultat, ouvrir_table( "usuel", generation, poke_type, suffixes,
frame.args['légende'] ) )
table.insert( resultat, '<tr>' .. entetes_communes( generation, 1, TITRES.usuel ) )
table.insert( resultat, '<th class="colonne-lieu" scope="col">Lieu</th>'
.. '<th class="colonne-coût" scope="col">Coût</th>' )
table.insert( resultat, entetes_jeux( frame, colonnes_jeux ) )
table.insert( resultat, '</tr>' )
if infos == "Aucune" then
table.insert( resultat, ligne_vide( colspan,
'Ce Pokémon n\'apprend aucune capacité par donneur lors de cette génération.' ) )
else
local lignes = mw.text.split( infos, "\n" )
local total = 0
for _, ligne in ipairs( lignes ) do
local champs = mw.text.split( ligne, "/" )
if non_vide( champs[1] ) then total = total + 1 end
end
table.insert( resultat, ligne_bouton( frame, "ListeDonneur", generation, colspan, total ) )
for _, ligne in ipairs( lignes ) do
local champs = mw.text.split( ligne, "/" )
if champs[1] ~= nil and champs[1] ~= "" then
local renvoi = appliquer_notes( string.match( champs[1], "note%(%d+%)" ) or "", ancre )
local nom_capacite = nettoyer_nom( champs[1] )
local donnees = ressources.donneesCapacite( generation, nom_capacite, jeux )
local brutes = donnees_brutes( generation, nom_capacite )
local lieu = champs[2] or ""
local cout, unite = champs[3], champs[4]
if cout == nil then cout, unite = "—", ""
elseif unite == nil then unite = prix_unite
end
-- Un « / » dans le coût (balise, lien) a découpé la ligne : on recolle.
local k = 5
while champs[k] do
unite = unite .. "/" .. champs[k]
k = k + 1
end
local tri_cout = tonumber( ( string.gsub( cout, "[^%d]", "" ) ) )
table.insert( resultat, '<tr>' .. cellules_communes( donnees, brutes, generation, 1,
{ couleur_type = oui( frame.args['couleur-type'] ) } ) )
table.insert( resultat, '<td class="colonne-lieu">'
.. appliquer_notes( lieu, ancre ) .. '</td>' )
table.insert( resultat, '<td class="colonne-coût"'
.. attribut_tri( tri_cout or -1 ) .. '>'
.. appliquer_notes( cout .. " " .. unite, ancre ) .. '</td>' )
table.insert( resultat, cellules_jeux( champs, 5, colonnes_jeux, ancre ) )
table.insert( resultat, '</tr>' )
end
end
end
table.insert( resultat, '</tbody>' .. pied_de_notes( notes, ancre, colspan )
.. '</table></div>' )
return table.concat( resultat, "" )
end
--------------------------------------------------------------------------------
-- p.preevolution / p.evenement / p.transfert : même forme, une colonne finale
--------------------------------------------------------------------------------
--- Fabrique une fonction « colonnes communes + une colonne libre ».
--- « miniature » rend le champ final comme un Pokémon plutôt que du texte.
local function methode_a_colonne_finale( reglages )
return function( frame )
if reglages.miniature then
ressources["infosPokemon"] = require("Module:Ressources/infosPokemon")
end
local infos = frame.args[1]
if infos == nil then return "Aucune information donnée" else infos = mw.text.trim( infos ) end
local generation = lire_generation( frame )
if generation == nil or generation_to_jeux[generation] == nil then
return generation_invalide( frame.args['génération'] )
end
local poke_type = lire_type( frame )
local jeux = lire_jeux( frame, generation )
local notes = lire_notes( frame )
local colonnes_jeux = colonnes_de_jeux( frame, generation )
local ancre = "note-" .. reglages.ancre .. "-" .. generation
-- Les colonnes par génération d'origine remplacent la colonne de texte.
-- Elles demandent de connaître toutes les lignes avant d'écrire l'en-tête :
-- une génération que personne ne remplit ne mérite pas sa colonne.
local lignes = {}
if infos ~= "Aucune" then lignes = mw.text.split( infos, "\n" ) end
local generations = nil
if reglages.generations then
generations = colonnes_de_generations( frame, generation, lignes )
if generations ~= nil and #generations == 0 then generations = nil end
end
local colspan = nb_communes( generation )
+ ( generations and #generations or 1 )
+ ( colonnes_jeux and #colonnes_jeux or 0 )
local suffixes = suffixes_jeux( colonnes_jeux )
for _, suffixe in ipairs( suffixes_generations( generations ) ) do
table.insert( suffixes, suffixe )
end
local resultat = {}
table.insert( resultat, ouvrir_table( "usuel", generation, poke_type,
suffixes, frame.args['légende'] ) )
table.insert( resultat, '<tr>' .. entetes_communes( generation, 1, TITRES.usuel ) )
if generations ~= nil then
table.insert( resultat, entetes_generations( frame, generations ) )
else
local titre_final = frame.args['colonne'] or reglages.titre
table.insert( resultat, '<th class="colonne-toutes" scope="col">'
.. titre_final .. '</th>' )
end
table.insert( resultat, entetes_jeux( frame, colonnes_jeux ) )
table.insert( resultat, '</tr>' )
if infos == "Aucune" then
table.insert( resultat, ligne_vide( colspan, reglages.phrase_vide ) )
else
local total = 0
for _, ligne in ipairs( lignes ) do
local champs = mw.text.split( ligne, "/" )
if non_vide( champs[1] ) then total = total + 1 end
end
table.insert( resultat, ligne_bouton( frame, reglages.classe, generation,
colspan, total ) )
for _, ligne in ipairs( lignes ) do
local champs = mw.text.split( ligne, "/" )
if champs[1] ~= nil and champs[1] ~= "" then
local renvoi = appliquer_notes(
string.match( champs[1], "note%(%d+%)" ) or "", ancre )
local nom_capacite = nettoyer_nom( champs[1] )
local donnees = ressources.donneesCapacite( generation, nom_capacite, jeux )
local brutes = donnees_brutes( generation, nom_capacite )
local final = champs[2]
if final == nil or mw.text.trim( final ) == "" then
final = reglages.defaut
end
local style = ""
if reglages.miniature then
final = ressources.infosPokemon( final )
style = ' style="text-align:left"'
else
final = appliquer_notes( final, ancre )
end
table.insert( resultat, '<tr>' .. cellules_communes( donnees, brutes,
generation, 1, { suffixe_nom = renvoi,
couleur_type = oui( frame.args['couleur-type'] ) } ) )
if generations ~= nil then
table.insert( resultat, cellules_generations( champs[2], generations ) )
else
table.insert( resultat, '<td class="colonne-toutes"' .. style .. '>'
.. final .. '</td>' )
end
table.insert( resultat, cellules_jeux( champs, 3, colonnes_jeux, ancre ) )
table.insert( resultat, '</tr>' )
end
end
end
table.insert( resultat, '</tbody>' .. pied_de_notes( notes, ancre, colspan )
.. '</table></div>' )
return table.concat( resultat, "" )
end
end
p.preevolution = methode_a_colonne_finale{
titre = "Pré-évolution", defaut = "Inconnue", miniature = true,
classe = "ListePreevolution", ancre = "preevolution",
phrase_vide = "Ce Pokémon n'apprend aucune capacité par pré-évolution lors de cette génération."
}
p.evenement = methode_a_colonne_finale{
titre = "Événement", defaut = "Inconnu", miniature = false,
classe = "ListeEvenement", ancre = "evenement",
phrase_vide = "Ce Pokémon n'apprend aucune capacité par événement lors de cette génération."
}
--- LOT 2 — la méthode « par transfert », qui n'avait pas de fonction : les pages
--- détournaient p.niveau, dont le tableau vide annonce « par montée en niveau ».
--- « colonnes-générations=oui » remplace la colonne « Provenance » par une
--- colonne par génération d'origine, comme le fait Bulbapedia. Sans le
--- paramètre, le tableau garde sa colonne de texte : rien ne change.
p.transfert = methode_a_colonne_finale{
titre = "Provenance", defaut = "—", miniature = false, generations = true,
classe = "ListeTransfert", ancre = "transfert",
phrase_vide = "Ce Pokémon n'apprend aucune capacité par transfert lors de cette génération."
}
--------------------------------------------------------------------------------
-- p.obscur — LOT 2 : Colosseum et XD
--------------------------------------------------------------------------------
--- Les capacités Ombre n'ont pas de fiche dans Module:Data/Données Capacités :
--- les passer à donneesCapacite verse la page en catégorie de maintenance et
--- affiche « ?? ». Ici, une capacité absente des données est rendue en clair,
--- sans catégoriser — c'est un manque connu, pas une faute de saisie.
function p.obscur( frame )
local infos = frame.args[1]
if infos == nil then return "Aucune information donnée" else infos = mw.text.trim( infos ) end
local generation = lire_generation( frame )
if generation == nil or generation_to_jeux[generation] == nil then
return generation_invalide( frame.args['génération'] )
end
local poke_type = lire_type( frame )
local jeux = lire_jeux( frame, generation )
local notes = lire_notes( frame )
local ancre = "note-obscur-" .. generation
local colspan = nb_communes( generation ) + 2
local resultat = {}
table.insert( resultat, ouvrir_table( "usuel", generation, poke_type, {},
frame.args['légende'] ) )
table.insert( resultat, '<tr>' .. entetes_communes( generation, 1, TITRES.usuel ) )
table.insert( resultat, '<th class="colonne-toutes" scope="col">Jeu</th>'
.. '<th class="colonne-toutes" scope="col">Obtention</th></tr>' )
if infos == "Aucune" then
table.insert( resultat, ligne_vide( colspan,
'Ce Pokémon n\'apprend aucune capacité dans Pokémon Colosseum ni Pokémon XD.' ) )
else
local lignes = mw.text.split( infos, "\n" )
local total = 0
for _, ligne in ipairs( lignes ) do
local champs = mw.text.split( ligne, "/" )
if non_vide( champs[1] ) then total = total + 1 end
end
table.insert( resultat, ligne_bouton( frame, "ListeObscur", generation, colspan, total ) )
for _, ligne in ipairs( lignes ) do
local champs = mw.text.split( ligne, "/" )
if champs[1] ~= nil and champs[1] ~= "" then
local renvoi = appliquer_notes(
string.match( champs[1], "note%(%d+%)" ) or "", ancre )
local nom_capacite = nettoyer_nom( champs[1] )
local brutes = donnees_brutes( generation, nom_capacite )
local donnees
if brutes == nil then
-- Hors données : on affiche sans catégoriser la page.
donnees = { '[[' .. nom_capacite .. ']]',
"[[Fichier:Miniature Type Inconnu.png|class=type|link=Type inconnu|alt=Type inconnu]]",
"[[Fichier:Miniature Type Inconnu.png|class=type|link=Catégorie de capacité|alt=Catégorie inconnue]]",
"??", "??", "??", "??", "??", "??" }
else
donnees = ressources.donneesCapacite( generation, nom_capacite, jeux )
end
table.insert( resultat, '<tr>' .. cellules_communes( donnees, brutes, generation, 1,
{ suffixe_nom = renvoi,
couleur_type = oui( frame.args['couleur-type'] ) } ) )
table.insert( resultat, '<td class="colonne-toutes">'
.. appliquer_notes( champs[2] or "—", ancre ) .. '</td>' )
table.insert( resultat, '<td class="colonne-toutes">'
.. appliquer_notes( champs[3] or "—", ancre ) .. '</td></tr>' )
end
end
end
table.insert( resultat, '</tbody>' .. pied_de_notes( notes, ancre, colspan )
.. '</table></div>' )
return table.concat( resultat, "" )
end
return p