Aller au contenu

Module:Livre

Un livre de Wikilivres.

Ce module fournit les fonctions suivantes :

titleParts( titre[, nombre[, premier]] )
  • Utilisation dans les modèles : {{#invoke:Livre|titleParts|titre|nombre|premier}}
  • Cette fonction est similaire à la parser function {{#titleparts}} à deux choses près : elle tient compte des titres comportant une barre oblique ("/", slash) et le premier caractère du texte renvoyé ne voit pas sa casse modifiée.
  • Alias : titleparts
racine( [titre] )
  • Utilisation dans les modèles : {{#invoke:Livre|racine|titre}}
  • Cette fonction renvoie la racine (la base de toutes les sous-pages) pour le titre donné, ou celui de la page courante si aucun titre n’est donné ; elle tient compte des titres comportant une barre oblique ("/", slash).
  • Alias : root
base()
  • Utilisation dans les modèles : {{#invoke:Livre|base}}
  • Cette fonction renvoie la base du livre dont fait partie la page courante ; les différences avec la fonction racine sont qu’elle inclut une barre oblique ("/") à la fin et qu’elle tient compte des arborescences avec plusieurs livres en sous-pages[1]. Elle ne prend aucun paramètre.
  1. De plus, certains espaces de noms sont traités spécialement.
accueil()
  • Utilisation dans les modèles : {{#invoke:Livre|accueil}}
  • Cette fonction renvoie la page d’accueil du livre dont fait partie la page courante ; la différence avec la fonction base est qu’elle renvoie vers une page (et donc n’inclut pas la barre oblique à la fin). Elle ne prend aucun paramètre.
  • Alias : home
local M = {}

local slashsAutorises = {"(G[Nn][Uu])/(Linux)", "(G[Nn][Uu])/(Hurd)", "(TCP)/(IP)", "([Tt]cp)/([Ii]p)", "(I)/(O)", "(E)/(S)", "([Ee]ntrées?)/(sortie)", "(PS)/(2)", "(PL)/(SQL)", "(P)/(Invoke)", "([%s/][Ff])/(%d)"}

-- Fonction accessoire renvoyant les paramètres
-- aussi bien lors d'un appel avec {{#invoke:}} que d'un appel sous Lua.
local function getArgs(...)
    local args = {...}
    
    if type(args[1]) == "table" and args[1]["args"] then
        return args[1]["args"]
    end

    return args
end
----------------------------------------------------------
-- Trouve le n-ième slash dans texte
-- (Si n est négatif: en partant de la fin)
-- Utilisé par titleParts.
local function trouveSlashs(texte, n, i0)
    local increment = 1
    local i_fin = #texte
    i0 = i0 or 1
    
    if n < 0 then
        i0, i_fin = i_fin, i0
        n = -n
        increment = -1
    end
    
    for i = i0, i_fin, increment do
        if string.byte(texte, i) == 47 then
            n = n - 1
            if n == 0 then return i end
        end
    end
    
    return i_fin + increment
end

function M.titleParts(...)
    -- D'abord quelques préparations
    local tmp = getArgs(...)
    local titre, nombre, debut = tmp[1], tmp[2], tmp[3] -- unpack ne fonctionne pas car metatable
    
    if type(titre) ~= "string" or titre == "" then return "" end
    
    -- Ensuite on remplace les "/" qu'on veut garder par le caractère Bip (normalement pas utilisé)
    for k,motif in pairs(slashsAutorises) do
        titre = string.gsub(titre, motif, "%1\a%2")
    end
    
    -- Puis on découpe selon la demande
    local pos1
    local pos2
    
    debut = tonumber(debut) or 0
    if debut > 0 then debut = debut - 1 end
    if debut == 0 then
        pos1 = 1
    else pos1 = trouveSlashs(titre, debut) + 1 end
    
    nombre = tonumber(nombre)
    if not nombre or nombre == 0 then
        pos2 = #titre
    else pos2 = trouveSlashs(titre, nombre, pos1) - 1 end
    
    if pos2 < pos1 then return "" end
    
    titre = string.sub(titre, pos1, pos2)
    
    -- Et enfin on remet nos "/"
    return tostring(string.gsub(titre, "\a", "/")) -- gsub renvoie 2 valeurs
end

M.titleparts = M.titleParts -- alias
----------------------------------------------------------
function M.root(...)
    local titre = getArgs(...)[1]
    
    if type(titre) ~= "string" or titre == "" then
        titre = mw.title.getCurrentTitle().prefixedText
    end
    
    return M.titleParts(titre, 1)
end
M.racine = M.root -- alias
----------------------------------------------------------
local function base_or_home(pageDAccueil)
    local specialNamespaces = {[12] = true, [4] = true}
    local titre = mw.title.getCurrentTitle()
    
    -- Traitement spécial pour certains espaces de noms.
    if specialNamespaces[titre.namespace] then
        return titre.nsText .. ":" .. (pageDAccueil or "")
    end
    
    local slash = (pageDAccueil and "" or "/")
    local invSlash = (pageDAccueil and "/" or "")
    
    titre = titre.prefixedText
      -- Passe de l'objet titre au titre (chaîne)
    
    local racine = M.titleParts(titre, 1) .. slash
      -- On pourrait utiliser M.root, mais plus lourd inutilement
    
    -- Vérifie si /Multi-livres existe
    local t = mw.title.new(racine .. invSlash .. "Multi-livres")
    if t.id == 0 then return racine end -- Livre simple
    
    -- Essayer de trouver une base de livre dans /Multi-livres
    local multiLivres = "\n" .. mw.getCurrentFrame():
            expandTemplate{title = t.nsText .. ":" .. t.text}
    for page in string.gmatch(multiLivres, "[\n\r]%*([^\n\r%|%]]+)") do
        page = mw.text.trim(page, " \t\v\f[")
        if string.sub(titre, 1, #page) == page then
            if string.sub(page, -1) == "/" then
                if pageDAccueil then
                    return string.sub(page, 1, -1)
                else return page end
            else return page .. slash end
        end
    end
    return racine -- ou rien? ou erreur?
end

function M.base()
    return base_or_home()
end

function M.home()
    return base_or_home("Accueil")
end

M.accueil = M.home -- alias

return M