Aller au contenu

Module:Utilisateur:François Melchior/Livre

Un livre de Wikilivres.

La documentation pour ce module peut être créée à Module:Utilisateur:François Melchior/Livre/Documentation

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)"}
--[[
local function each(t)
    return function (a, b)
        local k, v = next(t, b)
        b = true
        return v
    end
end ]]

local sprint_r = require("Module:Utilisateur:François Melchior/Utile").sprint_r

-- 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
--[[
local function getFrame(...)
    local args = {...}
    
    if type(args[1]) == "table" and args[1]["args"] then
        return args[1]
    end

    return mw.getCurrentFrame()
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
    
    --[[
    if string.upper(string.sub(titre,1,5)) == "AIDE:" then
        return "Aide:" ..
    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