Module:Utilisateur:François Melchior/Test
La documentation pour ce module peut être créée à Module:Utilisateur:François Melchior/Test/Documentation
local M = {}
local sprint_r = require("Module:Utilisateur:François Melchior/Utile").sprint_r
function M.hello()
return "Hello!"
end
function M.helloDiv()
return "<div>Hello!</div>"
end
function M.testTemplate(frame)
return frame:expandTemplate{title = "Utilisateur:François Melchior/Bac à sable/Lua/t5/include" .. (frame.args[1] or "")}
end
function M.testTemplate2(frame)
return "^" .. frame:expandTemplate{title = "Utilisateur:François Melchior/Bac à sable/Lua/t5/include" .. (frame.args[1] or "")} .. "$"
end
function M.testTemplateTrim(frame)
return mw.text.trim(frame:expandTemplate{title = "Utilisateur:François Melchior/Bac à sable/Lua/t5/include" .. (frame.args[1] or "")})
end
function M.testTemplateTrim2(frame)
return "^" .. mw.text.trim(frame:expandTemplate{title = "Utilisateur:François Melchior/Bac à sable/Lua/t5/include" .. (frame.args[1] or "")}) .. "$"
end
function M.testTemplate_print_r(frame)
return sprint_r(frame:expandTemplate{title = "Utilisateur:François Melchior/Bac à sable/Lua/t5/include" .. (frame.args[1] or "")})
end
----------------------------------------------------------
function M.args(frame)
local ret
for k, v in pairs(frame.args) do
v = v .. " [" .. string.len(v) .. "]"
if ret then
ret = ret .. " | " .. k .. " = " .. v
else
ret = k .. " = " .. v
end
end
return ret
end
function M.parentArgs(frame)
-- local ThisFrame = mw.getCurrentFrame
local parentArgs = frame:getParent().args
local ret
local k
local v
for k, v in pairs(parentArgs) do
v = v .. " [" .. string.len(v) .. "]"
if ret then
ret = ret .. " | " .. k .. " = " .. v
else
ret = k .. " = " .. v
end
end
return ret -- ParentFrame.args --"Hello!"
end
function M.testeArgs(frame)
local taille --= table.maxn(frame.args)
for i = 1, 999 do
if not frame.args[i] then
taille = i - 1
break
end
end
local dernier = frame.args[taille]
frame.args[taille] = nil
return M.args(frame) ..
frame:expandTemplate{title = dernier, args = mw.clone(frame.args)}
end
--[[function M["paramètres"](frame)
local parentArgs = frame:getParent().args
local decoNom = frame.args["déco nom"] or ""
local decoValeur = frame.args["déco valeur"] or ""
local separateur = frame.args["sépareteur"] or ""
local ret
for k, v in pairs(parentArgs) do
v = v .. " [" .. string.len(v) .. "]"
if ret then
ret = ret .. separateur .. k .. " = " .. v
else
ret = k .. " = " .. v
end
end
return ret
end]]
----------------------------------------------------------
function M.umodule(frame)
package.preload["umodule"] = function()
local m
m = frame:expandTemplate{ title = "Utilisateur:François Melchior/main.lua", args = {} }
return m
end
-- require("umodule")
-- return "<pre>\n" .. mw.title.new("Utilisateur:François Melchior/Sommaire"):getContent() .. "\n</pre>"
return "<pre>\n" .. frame:expandTemplate{ title = "Utilisateur:François Melchior/Sommaire", args = {} } .. "\n</pre>"
end
----------------------------------------------------------
function M.patterns(s)
local pattern = "^(%+*)(%!?)%s*((%[*)([^|%]]+)|?([^|%]]*)(%]*))%s*$"
return string.match(s, pattern)
end
----------------------------------------------------------
--[[local function icombine(t1, t2)
local i = #t1
for k, v in ipairs(t2) do
i = i + 1
t1[i] = v
end
end]]
local function erreur(msg)
return mw.getCurrentFrame():expandTemplate{title = "err", args = {msg}}
end
local livre = require("Module:Livre")
-- pour la transition (temporaire)
local function contenuDeSommaire_tmp(frame, parentArgs, appelleStyle)
local ret = {}
if parentArgs["titre"] and mw.text.trim(parentArgs["titre"]) == "" then parentArgs["titre"] = nil end
parentArgs["partie"] = "début"
if not parentArgs["base"] or mw.text.trim(parentArgs["base"]) == "" then parentArgs["base"] = string.sub(livre.base(),1,-2) end
parentArgs.livre, parentArgs.accueil, parentArgs.sommaire = appelleStyle.livre, appelleStyle.accueil, appelleStyle.sommaire
table.insert(ret, appelleStyle.go(parentArgs))
local sauveNumero10 = parentArgs[10]
for i = 1, 91, 10 do
parentArgs["précédent"] = parentArgs[i - 1] or ""
parentArgs["suivant"] = parentArgs[i + 10] or ""
parentArgs["numéro"] = tostring(i)
parentArgs[1], parentArgs[2], parentArgs[3], parentArgs[4], parentArgs[5],
parentArgs[6], parentArgs[7], parentArgs[8], parentArgs[9], parentArgs[10]
= parentArgs[i], parentArgs[i + 1], parentArgs[i + 2], parentArgs[i + 3], parentArgs[i + 4],
parentArgs[i + 5], parentArgs[i + 6], parentArgs[i + 7], parentArgs[i + 8], parentArgs[i + 9]
table.insert(ret, frame:expandTemplate{title = "Contenu de sommaire/Liste", args = parentArgs})
if i == 1 then parentArgs[10] = sauveNumero10 end
end
parentArgs["partie"] = "fin"
table.insert(ret, appelleStyle.go(parentArgs))
return table.concat(ret)
end
local _
--local chapitreSuivant -- Fonction (closure) définie dans contenuDeSommaire.
local liensAutomatiques
local aPlat
-- Fonction accessoire pour contenuDeSommaire
local litChapitres
do
local args, chapitres, i, j
function litChapitres(args_init, base, niveau, parent, pagePrecedente)
local n = 1
local sousTitreEnAttente, auto
if args_init then
args = args_init
chapitres = {--[[{numero = 1}]]} --{[0] = {texte = false, page = false}}
i, j = 1, 1
pagePrecedente = ""
niveau = 1
end
while true do repeat
--[[ local entree, avancement, image = chapitreSuivant() ]]
local entree = args[j]
if not entree then
entree = next(liensAutomatiques)
if not entree then return chapitres end
--[mieux avec??] liensAutomatiques[entree] = nil
auto = "auto"
end
-- Essaye de découper en différentes parties.
local nouveauNiveau, sousTitre, complet, ouvrants, lien, fermants
= string.match(entree, "^(%+*)(%!?)%s*((%[*)(.-)(%]*))%s*$")
if sousTitre == "!" then
-- Si c'est un sous-titre, il sera associé au chapitre suivant.
sousTitreEnAttente = mw.text.trim(complet)
if chapitres[i] then i, n = i + 1, n + 1 end
-- Passage au chapitre suivant si nécessaire
j = j + 1 -- Passage à l'entrée suivante.
break
end
if nouveauNiveau == "" then
if complet == "" then
if chapitres[i] then i, n = i + 1, n + 1 end
-- Passage au chapitre suivant si nécessaire
j = j + 1 -- Passage à l'entrée suivante.
break
end
nouveauNiveau = 1
else
nouveauNiveau = #nouveauNiveau + 1 -- On compte le nombre de "+".
if chapitres[i] then i, n = i + 1, n + 1 end
-- Ne peut être ni image, ni avancement, on est donc au chapitre suivant.
end
local page
if ouvrants == "[[" and fermants == "]]" then
local x = string.find(lien, "|", 1, true)
page = mw.text.trim(x and string.sub(lien, 1, x - 1) or lien)
if chapitres[i] and not chapitres[i].image then
local image = string.match(page, "^[Ii][Mm][Aa][Gg][Ee]%s*:%s*(.*)$")
if image then
chapitres[i].image = image
j = j + 1 -- Passage à l'entrée suivante.
if chapitres[i].avancement then
i, n = i + 1, n + 1 -- Passage au chapitre suivant.
end
break
end
i, n = i + 1, n + 1 -- N'était pas une image, on est donc au chapitre suivant.
end
affiche = x and mw.text.trim(string.sub(lien, x + 1)) or page
else
if chapitres[i] and not chapitres[i].avancement then
if not string.find(complet, "%D") then
-- Champ avancement présent (ne contient que des chiffres).
chapitres[i].avancement = complet
j = j + 1 -- Passage à l'entrée suivante.
if chapitres[i].avancement then
i, n = i + 1, n + 1 -- Passage au chapitre suivant.
end
break
end
i, n = i + 1, n + 1 -- N'était pas un champ avancement, on est donc au chapitre suivant.
end
page = complet
affiche = page
lien = nil
end
-- Suppression du lien automatique s'il est déjà présent.
if liensAutomatiques[affiche] then liensAutomatiques[affiche] = nil end
--nouveauNiveau = #(nouveauNiveau or "") + 1 -- On compte le nombre de "+".
--[=[ Essaye de découper en différentes parties.
local nouveauNiveau, sousTitre, complet, ouvrants, page, affiche, fermants
= string.match(entree, "^(%+*)(%!?)%s*((%[*)([^|%]]+)|?([^|%]]*)(%]*))%s*$") ]=]
chapitres[i] = {
numero = n, texte = affiche, page = page, auto = auto,
niveau = nouveauNiveau, sousTitre = sousTitreEnAttente,
parent = parent, precedent = i - 1, suivant = i + 1}
sousTitreEnAttente = nil
j = j + 1 -- Passage à l'entrée suivante.
-- Changement de niveau: appel récursif si on monte, retour à l'appelant si on descend.
if nouveauNiveau > niveau then
local iPrecedent = i - 1
local base = aPlat and base or base .. pagePrecedente .. "/"
if not lien then chapitres[i].page = base .. page end
chapitres[i].niveauAChange = "+"
chapitres[i].numero = 1
chapitres[i].parent = i - 1
chapitres[i].precedent = 0
-- On ne peut monter que d'1 niveau à la fois.
if nouveauNiveau - niveau > 1 then
chapitres[i].texte = erreur("Niveau intermédiaire absent")
chapitres[i].page = "Modèle:Contenu de sommaire"
return chapitres
end
_, page, nouveauNiveau, lien = litChapitres(nil, base, nouveauNiveau, i - 1, lien and pagePrecedente or page)
--[[if not page then
chapitres[iPrecedent].suivant = 0
return chapitres
end]]
if nouveauNiveau ~= niveau then
chapitres[iPrecedent].suivant = 0
return chapitres--[[nil]], page, nouveauNiveau, lien
end
chapitres[i].numero = n
chapitres[i].parent = parent
chapitres[i].precedent = iPrecedent
chapitres[i - 1].suivant = 0
chapitres[iPrecedent].suivant = i
elseif nouveauNiveau < niveau then
chapitres[i].niveauAChange = nouveauNiveau - niveau
return nil, page, nouveauNiveau, lien
end
if not lien then
chapitres[i].page = base .. page
pagePrecedente = page
end
until true end
end
end
function M.contenuDeSommaire(frame)
local parentArgs = frame:getParent().args
local baseDuLivre = livre.base()
-- D'abord vérifier que le style existe
local style = parentArgs["style"] or "" --style="haut"
if style == "" then style = "par défaut" end
local styleComplet
if style == "sommaire personnalisé" then
styleComplet = baseDuLivre .. "Style du sommaire"
else
--styleComplet = "Modèle:Contenu de sommaire/Style " .. style
styleComplet = "Utilisateur:François Melchior/Modèle:Contenu de sommaire/Style " .. style
end
if mw.title.new(styleComplet).id == 0 then
-- Si le style demandé (ou le style par défaut) n'existe pas, renvoie un message d’erreur.
return erreur("Erreur: style [[" .. styleComplet .. "|" .. style .. "]] inexistant.")
end
-- Table-objet pour les appels au style.
local appelleStyle = {
go = function (args) return frame:expandTemplate{title = styleComplet, args = args} end,
livre = livre.titleParts(baseDuLivre, 1, -2), -- (-2) pour le "/".
--[[image = parentArgs.image,
titre = parentArgs.titre ~= "" and parentArgs.titre or false,]]
accueil = livre.accueil(), -- TODO: À améliorer dans Module:Livre (do some caching)
sommaire = baseDuLivre .. "Sommaire"
}
-- Traitement des options.
for nom, valeur in pairs(parentArgs) do if valeur ~="" then
local option, avecStyles, listeDeStyles
= string.match(nom, "^(option[^:]*[^:%s])%s*(%:?)(.*)$")
if avecStyles == "" or
option and string.find("," .. listeDeStyles .. ",", "%,%s*" .. style .. "%s*%,")
then appelleStyle[option] = valeur end
--[[if valeur = "avec liens automatiques" and (option = "option1" or option = "option2" or option = "option3" or option = "option4") then
appelleStyle[option] = nil end -- Temporaire (pour transition)]]
end end
if appelleStyle["option titre"] == "~" then appelleStyle["option titre"] = appelleStyle.livre end
--[[if appelleStyle.option1 then -- Temporaire (pour transition)
if appelleStyle.option2 then
if appelleStyle.option3 then
if appelleStyle.option4 then
else appelleStyle["sans liens automatiques"] = "1" ]]
--[[
-- On crée une fonction (closure) pour les appels au style.
-- Note: les arguments ajoutés au fur et à mesure ne sont effacés que si on leur donnant la valeur "false".
local appelleStyle
do
local callParams = {title = styleComplet, args = {}}
callParams.args.base = baseDuLivre
callParams.args.livre = livre.titleParts(baseDuLivre, 1, -2) -- (-2) pour le "/".
callParams.args.image = parentArgs.image
callParams.args.titre = parentArgs.titre ~= "" and parentArgs.titre
or false --callParams.args.livre
callParams.args.accueil = livre.accueil() -- TODO: À améliorer dans Module:Livre (do some caching)
callParams.args.sommaire = baseDuLivre .. "Sommaire"
-- Traitement des options
for nom, valeur in pairs(parentArgs) do
local option, avecStyles, listeDeStyles
= string.match(nom, "^(option[^:]*[^:%s])%s*(%:?)(.*)$")
if avecStyles == "" or
option and string.find("," .. listeDeStyles .. ",", "%,%s*" .. style .. "%s*%,")
then callParams.args[option] = valeur end
end
-- La fonction elle-même
function appelleStyle(argsEnPlus, pasAppeler)
for k, v in pairs(argsEnPlus) do
if v == false then
callParams.args[k] = nil
else callParams.args[k] = v end
end
return pasAppeler and "" or frame:expandTemplate(callParams)
-- "" et pas nil car pourrait poser problème dans une table.
end
end ]]
-- pour la transition (temporaire)
if parentArgs["complexe"] or parentArgs["option1"] or parentArgs["option2"] or parentArgs["option3"] or parentArgs["option4"] then
return contenuDeSommaire_tmp(frame, mw.clone(parentArgs), appelleStyle)
-- mw.clone car certains arguments ne passent pas tout seuls:
-- problème dû à la méta-table de médiawiki ?
end
local trueFalse = {oui = true, ["true"] = true, ["1"] = true,
non = false, ["false"] = false, ["0"] = false}
aPlat = trueFalse[parentArgs["à plat"] or ""]
local siLiensAuto = trueFalse[parentArgs["liens automatiques"] or ""]
if siLiensAuto == false then
liensAutomatiques = {}
else
liensAutomatiques = {Glossaire = 1, Auteurs = 1, Bibliographie = 1, Index = 1, Licence = 1}
if not siLiensAuto then for page in pairs(liensAutomatiques) do
if not mw.title.new(baseDuLivre .. page).exists then liensAutomatiques[page] = nil end
end end
end
--[[ (Fonction utilisée à l'étape suivante — closure également — module-global)
do
local i = 1
function chapitreSuivant()
local chapitre = parentArgs[i]
if chapitre then
i = i + 1
local suivant = mw.text.trim(parentArgs[i] or "")
local avancement
if not string.find(suivant, "%D") then
-- Champ avancement présent (ne contient que des chiffres ou est vide).
if suivant ~= "" then avancement = suivant end
i = i + 1
suivant = mw.text.trim(parentArgs[i] or "")
end
local image = string.match(suivant, "^%[%[%s*[Ii][Mm][Aa][Gg][Ee]%s*:%s*([^|]-)%s*%]%]$")
if image then
-- Champ image présent.
i = i + 1
suivant = mw.text.trim(parentArgs[i] or "")
-- Vérifie si on a un champ avancement après le champ image.
if not avancement and not string.find(suivant, "%D") then
if suivant ~= "" then avancement = suivant end
i = i + 1
end
end
return chapitre, avancement, image
end
end
end
--[ [ (Une seconde fonction utilisée à l'étape suivante — closure également)
local gereNiveau --TODO: à plat
do
local bases = {}
local baseActuelle = baseDuLivre
local niveauActuel = 1
local pagePrecedente
function gereNiveau(niveau, page)
local niveauAChange
if niveau > niveauActuel and pagePrecedente then
table.insert(bases, baseActuelle) -- Sauve dans la pile.
baseActuelle = baseActuelle .. pagePrecedente .. "/"
niveauActuel = niveau
niveauAChange = "+"
elseif niveau < niveauActuel then
baseActuelle = table.remove(bases) -- Restaure.
niveauActuel = niveau
niveauAChange = "-"
end
pagePrecedente = page -- Pour la prochaine montée en niveau.
return baseActuelle .. page, niveauAChange
end
end ]]
-- Construction d'une table avec les données de tous les chapitres.
local chapitres = litChapitres(parentArgs, baseDuLivre)
--do return sprint_r(chapitres) end
--liensAutomatiques={}
--[=[ Ajout des liens automatiques si nécessaire.
do
local i = #chapitres
local n = 0
--[[local niveauAChange
local dernierNiveau1 = 0
for j = i, 1, -1 do
if chapitres[j].niveau == 1 then
n = chapitres[j].numero
dernierNiveau1 = j
if j ~= i then niveauAChange = 1 - chapitres[i].niveau end
break
end
end]]
-- Trouver le dernier chapitre de niveau 1.
local dernierNiveau1 = i
while chapitres[dernierNiveau1].niveau ~= 1 do
dernierNiveau1 = chapitres[dernierNiveau1].parent
end
n = chapitres[dernierNiveau1].numero
local niveauAChange = dernierNiveau1 ~= i and 1 - chapitres[dernierNiveau1].niveau or nil
for page in pairs(liensAutomatiques) do
i = i + 1
n = n + 1
local pageComplete = baseDuLivre .. page
if siLiensAuto or mw.title.new(pageComplete).exists then
chapitres[i] = {
texte = page, page = pageComplete, numero = n, niveau = 1, auto = "auto",
precedent = dernierNiveau1 or i - 1, suivant = i + 1}
if niveauAChange then
chapitres[i].niveauAChange = niveauAChange
niveauAChange = nil
end
dernierNiveau1 = nil
end
end
end]=]
--do return "<pre>\n" .. sprint_r(chapitres) .. "\n</pre>" end
local ret = {} -- texte à retourner.
local parents = {0}
-- structure de pile pour conserver les 'parents' précédents.
local chapitreVide = {texte = false, page = false}
appelleStyle.partie = "passes"
for passe = 1, tonumber(appelleStyle:go()) or 1 do
-- Maintenant on peut faire la partie avant les chapitres.
appelleStyle.partie, appelleStyle.passe, appelleStyle.niveau = "début", passe, 1
ret[#ret + 1] = appelleStyle:go()
-- Puis faire les chapitres.
for i, chapitre in ipairs(chapitres) do
if chapitre.niveauAChange then
if chapitre.niveauAChange == "+" then
local parent = chapitres[chapitre.parent]
appelleStyle.partie, appelleStyle.niveau, appelleStyle.parent, appelleStyle["page parent"]
= "début de liste", chapitre.niveau, parent.texte, parent.page
ret[#ret + 1] = appelleStyle:go()
parents[chapitre.niveau] = chapitre.parent
else
appelleStyle.partie = "fin de liste"
for i = chapitre.niveau - chapitre.niveauAChange - 1, chapitre.niveau, -1 do
local parent = chapitres[parents[i]] or chapitreVide
ret[#ret + 1] = appelleStyle:go()
appelleStyle.niveau, appelleStyle.parent, appelleStyle["page parent"]
= i, parent.texte, parent.page
end
end
end
if chapitre.sousTitre then
appelleStyle.partie, appelleStyle["sous-titre"]
= "sous-titre", chapitre.sousTitre
ret[#ret + 1] = appelleStyle:go()
else
appelleStyle["sous-titre"] = false
end
local precedent = chapitres[chapitre.precedent] or chapitreVide
local suivant = chapitres[chapitre.suivant] or chapitreVide
appelleStyle.partie, appelleStyle.auto, appelleStyle.chapitre, appelleStyle.page,
appelleStyle["numéro"], appelleStyle.image, appelleStyle.avancement,
appelleStyle["précédent"], appelleStyle["page précédent"], appelleStyle.suivant, appelleStyle["page suivant"]
= "chapitre", chapitre.auto, chapitre.texte, chapitre.page,
chapitre.numero, chapitre.image or false, chapitre.avancement or false,
precedent.texte, precedent.page, suivant.texte, suivant.page
ret[#ret + 1] = appelleStyle:go()
end
-- Redescendre au niveau 1 si on n'y est pas.
appelleStyle.partie = "fin de liste"
for i = chapitres[#chapitres].niveau - 1, 1, -1 do
local parent = chapitres[parents[i]] or chapitreVide
appelleStyle.niveau = i
ret[#ret + 1] = appelleStyle:go()
appelleStyle.niveau, appelleStyle.parent, appelleStyle["page parent"]
= i, parent.texte, parent.page
end
-- Et terminer par la partie finale.
appelleStyle.partie, appelleStyle.auto = "fin", false
ret[#ret + 1] = appelleStyle:go()
end
return table.concat(ret)
end
----------------------------------------------------------
function M.right(frame)
local texte = frame.args[1] or ""
local n = frame.args[2] or -1
return mw.ustring.sub(texte, -n)
end
M.droite = M.right -- alias
--M.str_right = M.strRight
function M.left(frame)
local texte = frame.args[1] or ""
local n = frame.args[2] or -1
return mw.ustring.sub(texte, 1, n)
end
M.gauche = M.left -- alias
--M.str_left = M.strLeft
function M.compare(frame)
local debut = frame.args["début"] or frame.args["begin"] or 1
local fin = frame.args["fin"] or frame.args["end"] or -1
local texte1 = mw.ustring.sub(frame.args[1] or "", debut, fin)
local texte2, siOui, siNon = frame.args[2] or "", frame.args[3] or "", frame.args[4] or ""
return tostring(string.gsub(texte1 == texte2 and siOui or siNon, "{{_}}", {["{{_}}"] = texte1}))
-- Utilisation d'une table pour ne pas avoir de problèmes de "%"
-- Note: tostring car gsub renvoie 2 valeurs
end
return M