Module:Navigation
Apparence
- Cette documentation est incluse depuis Module:Navigation/Documentation. [rafraîchir] · [modifier] · [historique]
Ce module contient la fonction suivante :
- contenuDeSommaire
- cœur fonctionnel du modèle {{contenu de sommaire}} ; il lit directement les paramètres de celui-ci.
local M = {}
local function erreur(msg)
return mw.getCurrentFrame():expandTemplate{title = "err", args = {msg}}
end
local _
local livre = require("Module:Livre")
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 = {}
i, j = 1, 1
pagePrecedente = ""
niveau = 1
end
while true do repeat
local entree = args[j]
if not entree then
entree = next(liensAutomatiques)
if not entree then return chapitres end
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
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 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 ""
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 end
local t = mw.title.new(styleComplet)
if t.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
if t.namespace == 0 then styleComplet = ":" .. styleComplet end
-- Table-objet pour les appels au style.
-- (Note: s'utilise elle-même comme métatable à cause de "expandTemplate" qui émet une erreur si il reçoit une fonction parmi ses arguments)
local appelleStyle = {
go = function (t) return frame:expandTemplate{title = styleComplet, args = t.__index} end,
__index = {
livre = livre.titleParts(baseDuLivre, 1, -2), -- (-2) pour le "/".
accueil = livre.accueil(), -- TODO: À améliorer dans Module:Livre (do some caching)
sommaire = baseDuLivre .. "Sommaire"
}
}
setmetatable(appelleStyle, appelleStyle)
appelleStyle.__newindex = appelleStyle.__index
-- 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 appelleStyle[option] = valeur end
end
if appelleStyle["option titre"] == "~" then appelleStyle["option titre"] = appelleStyle.livre 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
-- Construction d'une table avec les données de tous les chapitres.
local chapitres = litChapitres(parentArgs, baseDuLivre)
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
return M