Basculer le menu
Changer de menu des préférences
Basculer le menu personnel
Non connecté(e)
Votre adresse IP sera visible au public si vous faites des modifications.

« Module:PageInfo » : différence entre les versions

De Nefald
Hiob (discussion | contributions)
Aucun résumé des modifications
Hiob (discussion | contributions)
Annulation des modifications 735 de Hiob (discussion)
Balise : Annulation
 
(2 versions intermédiaires par le même utilisateur non affichées)
Ligne 1 : Ligne 1 :
local p = {}
local p = {}


-- Fonction pour extraire la description d'une page
-- Fonction principale qui retourne toutes les infos d'une page
function p.getDescription(frame)
function p.getInfo(frame)
     local pageName = frame.args[1]
     local pageName = frame.args[1]
     if not pageName or pageName == '' then
     if not pageName or pageName == '' then
         return ''
         return "'''Erreur :''' Aucun nom de page fourni"
     end
     end
      
      
     local pageObj = mw.title.new(pageName)
     local pageObj = mw.title.new(pageName)
     if not pageObj or not pageObj.exists then
     if not pageObj then
         return "''Page inexistante''"
        return "'''Erreur :''' Titre invalide : " .. pageName
    end
   
    if not pageObj.exists then
         return "'''Erreur :''' La page '" .. pageName .. "' n'existe pas"
     end
     end
      
      
    local result = {}
   
    -- Informations de base
    table.insert(result, "=== Informations de la page ===")
    table.insert(result, "* '''Titre complet :''' " .. pageObj.prefixedText)
    table.insert(result, "* '''Namespace :''' " .. pageObj.nsText)
    table.insert(result, "* '''Titre (sans namespace) :''' " .. pageObj.text)
    table.insert(result, "* '''URL :''' " .. pageObj:fullUrl())
    table.insert(result, "* '''ID de la page :''' " .. pageObj.id)
   
    -- Contenu
     local content = pageObj:getContent()
     local content = pageObj:getContent()
     if not content then
     if content then
         return ''
         local contentLength = mw.ustring.len(content)
        table.insert(result, "* '''Taille du contenu :''' " .. contentLength .. " caractères")
       
        -- Compter les sections
        local _, sectionCount = content:gsub('\n==', '\n==')
        table.insert(result, "* '''Nombre de sections :''' " .. sectionCount)
     end
     end
      
      
     -- 1. Chercher un modèle {{Description|...}} ou {{Short description|...}}
     -- Catégories
    local desc = content:match('{{[Ss]hort description%s*|%s*([^}]+)}}')
    local categories = pageObj.categories
     if desc then
    if categories and #categories > 0 then
         return mw.text.trim(desc)
        table.insert(result, "* '''Catégories :''' " .. #categories)
        local catList = {}
        for _, cat in ipairs(categories) do
            table.insert(catList, cat.text)
        end
        table.insert(result, "** " .. table.concat(catList, ", "))
     else
         table.insert(result, "* '''Catégories :''' Aucune")
     end
     end
      
      
     desc = content:match('{{[Dd]escription%s*|%s*([^}]+)}}')
     -- Protection
     if desc then
    if pageObj.protectionLevels and next(pageObj.protectionLevels) then
         return mw.text.trim(desc)
        table.insert(result, "* '''Protection :''' Oui")
        for action, level in pairs(pageObj.protectionLevels) do
            table.insert(result, "** " .. action .. " : " .. table.concat(level, ", "))
        end
     else
         table.insert(result, "* '''Protection :''' Non")
     end
     end
      
      
     -- 2. Chercher dans un champ description d'infobox
     -- Redirection
    desc = content:match('|%s*description%s*=%s*([^\n|]+)')
    if pageObj.isRedirect then
     if desc then
        table.insert(result, "* '''Type :''' Page de redirection")
         return mw.text.trim(desc)
     else
         table.insert(result, "* '''Type :''' Page normale")
     end
     end
      
      
     -- 3. Extraire le premier paragraphe significatif
     return table.concat(result, "\n")
    -- Nettoyer le contenu
end
     local cleaned = content
 
-- Fonction pour obtenir uniquement le titre
function p.getTitle(frame)
     local pageName = frame.args[1]
    if not pageName or pageName == '' then
        return ''
    end
      
      
     -- Supprimer les infobox complètes
     local pageObj = mw.title.new(pageName)
     cleaned = cleaned:gsub('{{[Ii]nfobox.-}}', '', 1)
     if not pageObj or not pageObj.exists then
        return "''Page inexistante''"
    end
      
      
     -- Supprimer tous les autres modèles
     return pageObj.text
     cleaned = cleaned:gsub('{{[^}]+}}', '')
end
 
-- Fonction pour obtenir le namespace
function p.getNamespace(frame)
     local pageName = frame.args[1]
    if not pageName or pageName == '' then
        return ''
    end
      
      
     -- Supprimer les catégories
     local pageObj = mw.title.new(pageName)
    cleaned = cleaned:gsub('%[%[[Cc]ategory:[^%]]+%]%]', '')
     if not pageObj or not pageObj.exists then
    cleaned = cleaned:gsub('%[%[[Cc]atégorie:[^%]]+%]%]', '')
        return "''Page inexistante''"
   
    -- Supprimer les balises HTML
    cleaned = cleaned:gsub('<[^>]+>', '')
   
    -- Supprimer les titres de section (=== ... ===)
    cleaned = cleaned:gsub('\n%s*==[^=].-==%s*\n', '\n')
   
    -- Supprimer les lignes vides multiples
    cleaned = cleaned:gsub('\n\n+', '\n')
   
    -- Extraire le premier paragraphe significatif (au moins 20 caractères)
     for line in cleaned:gmatch('[^\n]+') do
        line = mw.text.trim(line)
       
        -- Ignorer les lignes vides, listes, tableaux
        if line ~= ''
          and not line:match('^[*#:;]')
          and not line:match('^%s*{|')
          and not line:match('^%s*|}')
          and not line:match('^%s*|')
          and #line > 20 then
           
            -- Limiter la longueur à 200 caractères
            if #line > 200 then
                line = line:sub(1, 197) .. '...'
            end
           
            return line
        end
     end
     end
      
      
     return "''Aucune description disponible''"
     return pageObj.nsText ~= '' and pageObj.nsText or 'Principal'
end
end


-- Fonction pour extraire le lien de documentation
-- Fonction pour obtenir l'URL complète
function p.getDocumentation(frame)
function p.getUrl(frame)
     local pageName = frame.args[1]
     local pageName = frame.args[1]
     if not pageName or pageName == '' then
     if not pageName or pageName == '' then
Ligne 91 : Ligne 110 :
     local pageObj = mw.title.new(pageName)
     local pageObj = mw.title.new(pageName)
     if not pageObj or not pageObj.exists then
     if not pageObj or not pageObj.exists then
         return ''
         return "''Page inexistante''"
     end
     end
      
      
     local content = pageObj:getContent()
     return pageObj:fullUrl()
     if not content then
end
 
-- Fonction pour obtenir les catégories
function p.getCategories(frame)
    local pageName = frame.args[1]
     if not pageName or pageName == '' then
         return ''
         return ''
     end
     end
      
      
    -- Chercher un lien de documentation dans l'infobox
     local pageObj = mw.title.new(pageName)
     local doc = content:match('|%s*documentation%s*=%s*(%[?https?://[^%s%]|]+)')
     if not pageObj or not pageObj.exists then
     if doc then
         return "''Page inexistante''"
        doc = doc:gsub('%[', ''):gsub('%]', '')
         return '[' .. doc .. ' Documentation]'
     end
     end
      
      
     -- Chercher un lien dans un champ "lien" ou "site"
     local categories = pageObj.categories
    doc = content:match('|%s*[Ll]ien%s*=%s*(%[?https?://[^%s%]|]+)')
     if not categories or #categories == 0 then
     if not doc then
         return "''Aucune catégorie''"
         doc = content:match('|%s*[Ss]ite%s*=%s*(%[?https?://[^%s%]|]+)')
     end
     end
      
      
     if doc then
     local catList = {}
        doc = doc:gsub('%[', ''):gsub('%]', '')
    for _, cat in ipairs(categories) do
         return '[' .. doc .. ' Site officiel]'
         table.insert(catList, cat.text)
     end
     end
      
      
     return "''Aucune documentation''"
     return table.concat(catList, ', ')
end
end


-- Fonction de debug complète
-- Fonction pour extraire la description d'une page
function p.getInfo(frame)
function p.getDescription(frame)
     local pageName = frame.args[1]
     local pageName = frame.args[1]
     if not pageName or pageName == '' then
     if not pageName or pageName == '' then
         return "'''Erreur :''' Aucun nom de page fourni"
         return ''
     end
     end
      
      
     local pageObj = mw.title.new(pageName)
     local pageObj = mw.title.new(pageName)
     if not pageObj then
     if not pageObj or not pageObj.exists then
         return "'''Erreur :''' Titre invalide"
         return "''Page inexistante''"
    end
   
    local content = pageObj:getContent()
    if not content then
        return ''
     end
     end
      
      
     local output = "'''Informations sur la page : " .. pageName .. "'''\n\n"
    -- PRIORITÉ 1 : Chercher {{SHORTDESC:...}} (magic word de l'extension)
     local desc = content:match('{{SHORTDESC:([^}]+)}}')
    if desc then
        desc = mw.text.trim(desc)
        if desc ~= '' then
            return desc
        end
    end
      
      
     output = output .. "* '''Existe :''' " .. (pageObj.exists and "Oui" or "Non") .. "\n"
     -- PRIORITÉ 1bis : Chercher aussi {{Short description|...}} (template standard)
    desc = content:match('{{[Ss]hort%s+description%s*|%s*([^}]+)}}')
    if desc then
        desc = mw.text.trim(desc)
        desc = desc:gsub('|.*$', '') -- Nettoyer paramètres supplémentaires
        if desc ~= '' then
            return desc
        end
    end
      
      
     if not pageObj.exists then
    -- PRIORITÉ 2 : Chercher dans un champ description d'infobox
         return output
    desc = content:match('|%s*description%s*=%s*([^\n|]+)')
     if desc then
        desc = mw.text.trim(desc)
        if desc ~= '' and #desc > 10 then
            return desc
         end
     end
     end
      
      
     output = output .. "* '''Namespace :''' " .. pageObj.namespace .. "\n"
     -- PRIORITÉ 3 : Extraire le premier paragraphe après l'infobox
     output = output .. "* '''Titre complet :''' " .. pageObj.fullText .. "\n"
     local afterInfobox = content:match('}}%s*\n(.+)')
      
      
     local content = pageObj:getContent()
     if afterInfobox then
    if content then
        local beforeSection = afterInfobox:match('^(.-)%s*\n%s*==')
         output = output .. "* '''Longueur du contenu :''' " .. #content .. " caractères\n"
       
         output = output .. "* '''Premiers 200 caractères :'''\n<pre>" .. content:sub(1, 200) .. "...</pre>\n"
        if not beforeSection then
            beforeSection = afterInfobox
        end
          
         local cleaned = beforeSection
          
          
         local desc = p.getDescription(frame)
         -- Supprimer les magic words et templates
         output = output .. "* '''Description extraite :''' " .. desc .. "\n"
        cleaned = cleaned:gsub('{{SHORTDESC:[^}]+}}', '')
        cleaned = cleaned:gsub('{{[^}]+}}', '')
        cleaned = cleaned:gsub('%[%[[Cc]ategor[yi]e?:[^%]]+%]%]', '')
        cleaned = cleaned:gsub('<[^>]+>', '')
         cleaned = cleaned:gsub('\n\n+', '\n')
        cleaned = cleaned:gsub("'''", '')
        cleaned = cleaned:gsub("''", '')
          
          
         local doc = p.getDocumentation(frame)
         for line in cleaned:gmatch('[^\n]+') do
        output = output .. "* '''Documentation extraite :''' " .. doc .. "\n"
            line = mw.text.trim(line)
           
            if line ~= ''
              and not line:match('^[*#:;]')
              and not line:match('^%s*{|')
              and not line:match('^%s*|}')
              and not line:match('^%s*|[^%[]')
              and #line > 30 then
               
                if #line > 300 then
                    local cut = line:sub(1, 297)
                    local lastPeriod = cut:match('.*()%.%s')
                    if lastPeriod and lastPeriod > 200 then
                        line = cut:sub(1, lastPeriod)
                    else
                        line = cut .. '...'
                    end
                end
               
                return line
            end
        end
     end
     end
      
      
     return output
     return "''Aucune description disponible''"
end
end


-- Fonction pour obtenir des statistiques
-- Fonction pour obtenir la taille de la page
function p.getStats(frame)
function p.getSize(frame)
     local pageName = frame.args[1]
     local pageName = frame.args[1]
     if not pageName or pageName == '' then
     if not pageName or pageName == '' then
Ligne 167 : Ligne 244 :
     local pageObj = mw.title.new(pageName)
     local pageObj = mw.title.new(pageName)
     if not pageObj or not pageObj.exists then
     if not pageObj or not pageObj.exists then
         return ''
         return "''Page inexistante''"
     end
     end
      
      
     local content = pageObj:getContent()
     local content = pageObj:getContent()
     if not content then
     if not content then
         return ''
         return '0'
     end
     end
      
      
     local chars = #content
     return tostring(mw.ustring.len(content))
    local lines = select(2, content:gsub('\n', '\n')) + 1
    local words = select(2, content:gsub('%S+', ''))
   
    return string.format("%d caractères, %d lignes, ~%d mots", chars, lines, words)
end
end


-- Fonction pour extraire l'auteur
-- Fonction pour compter les sections
function p.getAuthor(frame)
function p.countSections(frame)
     local pageName = frame.args[1]
     local pageName = frame.args[1]
     if not pageName or pageName == '' then
     if not pageName or pageName == '' then
         return ''
         return '0'
     end
     end
      
      
     local pageObj = mw.title.new(pageName)
     local pageObj = mw.title.new(pageName)
     if not pageObj or not pageObj.exists then
     if not pageObj or not pageObj.exists then
         return ''
         return "''Page inexistante''"
     end
     end
      
      
     local content = pageObj:getContent()
     local content = pageObj:getContent()
     if not content then
     if not content then
         return ''
         return '0'
     end
     end
      
      
     local author = content:match('|%s*[Aa]uteur%s*=%s*([^\n|]+)')
     local _, count = content:gsub('\n==', '\n==')
     if author then
    return tostring(count)
         return mw.text.trim(author)
end
 
-- Fonction pour vérifier si une page est protégée
function p.isProtected(frame)
    local pageName = frame.args[1]
     if not pageName or pageName == '' then
         return 'Non'
     end
     end
      
      
     author = content:match('|%s*[Aa]uthor%s*=%s*([^\n|]+)')
     local pageObj = mw.title.new(pageName)
     if author then
     if not pageObj or not pageObj.exists then
         return mw.text.trim(author)
         return "''Page inexistante''"
     end
     end
      
      
     return ''
     if pageObj.protectionLevels and next(pageObj.protectionLevels) then
        return 'Oui'
    else
        return 'Non'
    end
end
end


-- Fonction pour extraire la version
-- Fonction pour vérifier si une page est une redirection
function p.getVersion(frame)
function p.isRedirect(frame)
     local pageName = frame.args[1]
     local pageName = frame.args[1]
     if not pageName or pageName == '' then
     if not pageName or pageName == '' then
         return ''
         return 'Non'
     end
     end
      
      
     local pageObj = mw.title.new(pageName)
     local pageObj = mw.title.new(pageName)
     if not pageObj or not pageObj.exists then
     if not pageObj or not pageObj.exists then
         return ''
         return "''Page inexistante''"
     end
     end
      
      
     local content = pageObj:getContent()
     return pageObj.isRedirect and 'Oui' or 'Non'
     if not content then
end
 
-- Fonction pour obtenir l'ID de la page
function p.getId(frame)
    local pageName = frame.args[1]
     if not pageName or pageName == '' then
         return ''
         return ''
     end
     end
      
      
     local version = content:match('|%s*[Vv]ersion%s*=%s*([^\n|]+)')
     local pageObj = mw.title.new(pageName)
     if version then
     if not pageObj or not pageObj.exists then
         return mw.text.trim(version)
         return "''Page inexistante''"
     end
     end
      
      
     version = content:match('[Vv]ersion%s*:?%s*(%d+%.%d+[%.%d]*)')
     return tostring(pageObj.id)
     if version then
end
         return version
 
-- Fonction pour obtenir le titre complet (avec namespace)
function p.getFullTitle(frame)
    local pageName = frame.args[1]
     if not pageName or pageName == '' then
         return ''
     end
     end
      
      
     version = content:match('v(%d+%.%d+[%.%d]*)')
     local pageObj = mw.title.new(pageName)
     if version then
     if not pageObj or not pageObj.exists then
         return version
         return "''Page inexistante''"
     end
     end
      
      
     return ''
     return pageObj.prefixedText
end
end


-- Fonction pour extraire la date de mise à jour
-- Fonction pour extraire l'image principale de la page
function p.getUpdateDate(frame)
function p.getMainImage(frame)
     local pageName = frame.args[1]
     local pageName = frame.args[1]
     if not pageName or pageName == '' then
     if not pageName or pageName == '' then
Ligne 256 : Ligne 349 :
     local pageObj = mw.title.new(pageName)
     local pageObj = mw.title.new(pageName)
     if not pageObj or not pageObj.exists then
     if not pageObj or not pageObj.exists then
         return ''
         return "''Page inexistante''"
     end
     end
      
      
Ligne 264 : Ligne 357 :
     end
     end
      
      
     local date = content:match('|%s*[Mm]ise%s*à%s*jour%s*=%s*([^\n|]+)')
    -- Chercher dans l'infobox d'abord
     if date then
     local image = content:match('|%s*image%s*=%s*([^\n|]+)')
         return mw.text.trim(date)
    if image then
        image = mw.text.trim(image)
        -- Nettoyer les éventuels paramètres de taille
        image = image:gsub('%s*|.*$', '')
        if image ~= '' then
            return image
        end
    end
   
    -- Chercher la première image dans le contenu
    image = content:match('%[%[Fichier:([^%]|]+)')
    if not image then
        image = content:match('%[%[File:([^%]|]+)')
    end
    if not image then
        image = content:match('%[%[Image:([^%]|]+)')
    end
   
     if image then
         return mw.text.trim(image)
    end
   
    return "''Aucune image''"
end
 
-- Fonction pour obtenir la date de dernière modification
function p.getLastModified(frame)
    local pageName = frame.args[1]
    if not pageName or pageName == '' then
        return ''
     end
     end
      
      
     date = content:match('|%s*[Uu]pdate[Dd]?%s*=%s*([^\n|]+)')
     local pageObj = mw.title.new(pageName)
     if date then
     if not pageObj or not pageObj.exists then
         return mw.text.trim(date)
         return "''Page inexistante''"
     end
     end
      
      
     date = content:match('|%s*[Dd]ate%s*=%s*([^\n|]+)')
     -- Utiliser l'API pour obtenir la date de dernière modification
     if date then
    local revId = pageObj.latest
         return mw.text.trim(date)
     if not revId then
         return "''Indisponible''"
     end
     end
      
      
     return ''
     return "Révision #" .. revId
end
end


return p
return p

Dernière version du 7 octobre 2025 à 11:52

La documentation pour ce module peut être créée à Module:PageInfo/doc

local p = {}

-- Fonction principale qui retourne toutes les infos d'une page
function p.getInfo(frame)
    local pageName = frame.args[1]
    if not pageName or pageName == '' then
        return "'''Erreur :''' Aucun nom de page fourni"
    end
    
    local pageObj = mw.title.new(pageName)
    if not pageObj then
        return "'''Erreur :''' Titre invalide : " .. pageName
    end
    
    if not pageObj.exists then
        return "'''Erreur :''' La page '" .. pageName .. "' n'existe pas"
    end
    
    local result = {}
    
    -- Informations de base
    table.insert(result, "=== Informations de la page ===")
    table.insert(result, "* '''Titre complet :''' " .. pageObj.prefixedText)
    table.insert(result, "* '''Namespace :''' " .. pageObj.nsText)
    table.insert(result, "* '''Titre (sans namespace) :''' " .. pageObj.text)
    table.insert(result, "* '''URL :''' " .. pageObj:fullUrl())
    table.insert(result, "* '''ID de la page :''' " .. pageObj.id)
    
    -- Contenu
    local content = pageObj:getContent()
    if content then
        local contentLength = mw.ustring.len(content)
        table.insert(result, "* '''Taille du contenu :''' " .. contentLength .. " caractères")
        
        -- Compter les sections
        local _, sectionCount = content:gsub('\n==', '\n==')
        table.insert(result, "* '''Nombre de sections :''' " .. sectionCount)
    end
    
    -- Catégories
    local categories = pageObj.categories
    if categories and #categories > 0 then
        table.insert(result, "* '''Catégories :''' " .. #categories)
        local catList = {}
        for _, cat in ipairs(categories) do
            table.insert(catList, cat.text)
        end
        table.insert(result, "** " .. table.concat(catList, ", "))
    else
        table.insert(result, "* '''Catégories :''' Aucune")
    end
    
    -- Protection
    if pageObj.protectionLevels and next(pageObj.protectionLevels) then
        table.insert(result, "* '''Protection :''' Oui")
        for action, level in pairs(pageObj.protectionLevels) do
            table.insert(result, "** " .. action .. " : " .. table.concat(level, ", "))
        end
    else
        table.insert(result, "* '''Protection :''' Non")
    end
    
    -- Redirection
    if pageObj.isRedirect then
        table.insert(result, "* '''Type :''' Page de redirection")
    else
        table.insert(result, "* '''Type :''' Page normale")
    end
    
    return table.concat(result, "\n")
end

-- Fonction pour obtenir uniquement le titre
function p.getTitle(frame)
    local pageName = frame.args[1]
    if not pageName or pageName == '' then
        return ''
    end
    
    local pageObj = mw.title.new(pageName)
    if not pageObj or not pageObj.exists then
        return "''Page inexistante''"
    end
    
    return pageObj.text
end

-- Fonction pour obtenir le namespace
function p.getNamespace(frame)
    local pageName = frame.args[1]
    if not pageName or pageName == '' then
        return ''
    end
    
    local pageObj = mw.title.new(pageName)
    if not pageObj or not pageObj.exists then
        return "''Page inexistante''"
    end
    
    return pageObj.nsText ~= '' and pageObj.nsText or 'Principal'
end

-- Fonction pour obtenir l'URL complète
function p.getUrl(frame)
    local pageName = frame.args[1]
    if not pageName or pageName == '' then
        return ''
    end
    
    local pageObj = mw.title.new(pageName)
    if not pageObj or not pageObj.exists then
        return "''Page inexistante''"
    end
    
    return pageObj:fullUrl()
end

-- Fonction pour obtenir les catégories
function p.getCategories(frame)
    local pageName = frame.args[1]
    if not pageName or pageName == '' then
        return ''
    end
    
    local pageObj = mw.title.new(pageName)
    if not pageObj or not pageObj.exists then
        return "''Page inexistante''"
    end
    
    local categories = pageObj.categories
    if not categories or #categories == 0 then
        return "''Aucune catégorie''"
    end
    
    local catList = {}
    for _, cat in ipairs(categories) do
        table.insert(catList, cat.text)
    end
    
    return table.concat(catList, ', ')
end

-- Fonction pour extraire la description d'une page
function p.getDescription(frame)
    local pageName = frame.args[1]
    if not pageName or pageName == '' then
        return ''
    end
    
    local pageObj = mw.title.new(pageName)
    if not pageObj or not pageObj.exists then
        return "''Page inexistante''"
    end
    
    local content = pageObj:getContent()
    if not content then
        return ''
    end
    
    -- PRIORITÉ 1 : Chercher {{SHORTDESC:...}} (magic word de l'extension)
    local desc = content:match('{{SHORTDESC:([^}]+)}}')
    if desc then
        desc = mw.text.trim(desc)
        if desc ~= '' then
            return desc
        end
    end
    
    -- PRIORITÉ 1bis : Chercher aussi {{Short description|...}} (template standard)
    desc = content:match('{{[Ss]hort%s+description%s*|%s*([^}]+)}}')
    if desc then
        desc = mw.text.trim(desc)
        desc = desc:gsub('|.*$', '') -- Nettoyer paramètres supplémentaires
        if desc ~= '' then
            return desc
        end
    end
    
    -- PRIORITÉ 2 : Chercher dans un champ description d'infobox
    desc = content:match('|%s*description%s*=%s*([^\n|]+)')
    if desc then
        desc = mw.text.trim(desc)
        if desc ~= '' and #desc > 10 then
            return desc
        end
    end
    
    -- PRIORITÉ 3 : Extraire le premier paragraphe après l'infobox
    local afterInfobox = content:match('}}%s*\n(.+)')
    
    if afterInfobox then
        local beforeSection = afterInfobox:match('^(.-)%s*\n%s*==')
        
        if not beforeSection then
            beforeSection = afterInfobox
        end
        
        local cleaned = beforeSection
        
        -- Supprimer les magic words et templates
        cleaned = cleaned:gsub('{{SHORTDESC:[^}]+}}', '')
        cleaned = cleaned:gsub('{{[^}]+}}', '')
        cleaned = cleaned:gsub('%[%[[Cc]ategor[yi]e?:[^%]]+%]%]', '')
        cleaned = cleaned:gsub('<[^>]+>', '')
        cleaned = cleaned:gsub('\n\n+', '\n')
        cleaned = cleaned:gsub("'''", '')
        cleaned = cleaned:gsub("''", '')
        
        for line in cleaned:gmatch('[^\n]+') do
            line = mw.text.trim(line)
            
            if line ~= '' 
               and not line:match('^[*#:;]') 
               and not line:match('^%s*{|')
               and not line:match('^%s*|}')
               and not line:match('^%s*|[^%[]')
               and #line > 30 then
                
                if #line > 300 then
                    local cut = line:sub(1, 297)
                    local lastPeriod = cut:match('.*()%.%s')
                    if lastPeriod and lastPeriod > 200 then
                        line = cut:sub(1, lastPeriod)
                    else
                        line = cut .. '...'
                    end
                end
                
                return line
            end
        end
    end
    
    return "''Aucune description disponible''"
end

-- Fonction pour obtenir la taille de la page
function p.getSize(frame)
    local pageName = frame.args[1]
    if not pageName or pageName == '' then
        return ''
    end
    
    local pageObj = mw.title.new(pageName)
    if not pageObj or not pageObj.exists then
        return "''Page inexistante''"
    end
    
    local content = pageObj:getContent()
    if not content then
        return '0'
    end
    
    return tostring(mw.ustring.len(content))
end

-- Fonction pour compter les sections
function p.countSections(frame)
    local pageName = frame.args[1]
    if not pageName or pageName == '' then
        return '0'
    end
    
    local pageObj = mw.title.new(pageName)
    if not pageObj or not pageObj.exists then
        return "''Page inexistante''"
    end
    
    local content = pageObj:getContent()
    if not content then
        return '0'
    end
    
    local _, count = content:gsub('\n==', '\n==')
    return tostring(count)
end

-- Fonction pour vérifier si une page est protégée
function p.isProtected(frame)
    local pageName = frame.args[1]
    if not pageName or pageName == '' then
        return 'Non'
    end
    
    local pageObj = mw.title.new(pageName)
    if not pageObj or not pageObj.exists then
        return "''Page inexistante''"
    end
    
    if pageObj.protectionLevels and next(pageObj.protectionLevels) then
        return 'Oui'
    else
        return 'Non'
    end
end

-- Fonction pour vérifier si une page est une redirection
function p.isRedirect(frame)
    local pageName = frame.args[1]
    if not pageName or pageName == '' then
        return 'Non'
    end
    
    local pageObj = mw.title.new(pageName)
    if not pageObj or not pageObj.exists then
        return "''Page inexistante''"
    end
    
    return pageObj.isRedirect and 'Oui' or 'Non'
end

-- Fonction pour obtenir l'ID de la page
function p.getId(frame)
    local pageName = frame.args[1]
    if not pageName or pageName == '' then
        return ''
    end
    
    local pageObj = mw.title.new(pageName)
    if not pageObj or not pageObj.exists then
        return "''Page inexistante''"
    end
    
    return tostring(pageObj.id)
end

-- Fonction pour obtenir le titre complet (avec namespace)
function p.getFullTitle(frame)
    local pageName = frame.args[1]
    if not pageName or pageName == '' then
        return ''
    end
    
    local pageObj = mw.title.new(pageName)
    if not pageObj or not pageObj.exists then
        return "''Page inexistante''"
    end
    
    return pageObj.prefixedText
end

-- Fonction pour extraire l'image principale de la page
function p.getMainImage(frame)
    local pageName = frame.args[1]
    if not pageName or pageName == '' then
        return ''
    end
    
    local pageObj = mw.title.new(pageName)
    if not pageObj or not pageObj.exists then
        return "''Page inexistante''"
    end
    
    local content = pageObj:getContent()
    if not content then
        return ''
    end
    
    -- Chercher dans l'infobox d'abord
    local image = content:match('|%s*image%s*=%s*([^\n|]+)')
    if image then
        image = mw.text.trim(image)
        -- Nettoyer les éventuels paramètres de taille
        image = image:gsub('%s*|.*$', '')
        if image ~= '' then
            return image
        end
    end
    
    -- Chercher la première image dans le contenu
    image = content:match('%[%[Fichier:([^%]|]+)')
    if not image then
        image = content:match('%[%[File:([^%]|]+)')
    end
    if not image then
        image = content:match('%[%[Image:([^%]|]+)')
    end
    
    if image then
        return mw.text.trim(image)
    end
    
    return "''Aucune image''"
end

-- Fonction pour obtenir la date de dernière modification
function p.getLastModified(frame)
    local pageName = frame.args[1]
    if not pageName or pageName == '' then
        return ''
    end
    
    local pageObj = mw.title.new(pageName)
    if not pageObj or not pageObj.exists then
        return "''Page inexistante''"
    end
    
    -- Utiliser l'API pour obtenir la date de dernière modification
    local revId = pageObj.latest
    if not revId then
        return "''Indisponible''"
    end
    
    return "Révision #" .. revId
end

return p