Module:Palette Dates
Aller à la navigation
Aller à la recherche
La documentation pour ce module peut être créée à Module:Palette Dates/doc
--[[ Navigation entre des dates. ]] --[[ Table retournée par le module. ]] local p = {} --[[ Arguments passés au #invoke. Un argument sera cherché en priorité dans cette table. S'il n'est pas trouvé, on le cherchera dans les arguments passés au modèle. ]] local args0 = {} --[[ Arguments passés au modèle. Un argument sera cherché dans cette table, s'il n'est pas passé au #invoke. ]] local args1 = {} local Romains = require('Module:Chiffres romains') --[[ Traitement d'une erreur. Argument: message d'erreur en texte simple Résultat: la fonction ne retourne pas à l'appelant, mais après le pcall() Lorsqu'une erreur est détectée, par exemple un argument invalide dans l'appel du modèle, cette fonction est appelée. Elle termine tous les appels de fonction, jusqu'à atteindre un appel à la fonction pcall(), qui retourne false et le message (s'il n'y avait pas eu d'erreur dans le traitement, pcall retournait true et les valeurs retournées par la fonction qu'on lui passe en premier argument). Cette méthode a l'intérêt de rendre le code nettement plus lisible en ne traînant pas partout des codes et des messages d'erreur, et accessoirement de gagner un brin de performance. Dans ce module, la fonction erreur() peut être appelée à peu près n'importe quand. ]] local function erreur (msg) if string.sub(msg, 1, 5) ~= '<span' then -- Romains.conversion() inclut déjà le <span> msg = '<span class="error">' .. msg .. '</span>' end error(msg, 0) end --[[ Extraction d'un argument. Arguments: nom nom de l'argument defaut valeur par défaut de l'argument Résultat: la valeur de l'argument Comme mediawiki trimme les valeurs des arguments, un argument peut être inclus entre "double apostrophes" qui sont éliminées ici. Cela permet de spécifier un argument qui commence ou se termine par une espace. Une autre solution pour les textes qui apparaissent comme liens, est d'utiliser un souligné _ qui n'est pas éliminé par mediawiki. ]] local function arg (nom, defaut) local x = nil if not x then x = args0[nom] end if not x then x = args1[nom] end if not x then x = defaut end if not x then return x elseif string.sub(x, 1, 1) ~= '"' then return x elseif string.sub(x, -1) ~= '"' then return x else return string.sub(x, 2, -2) end end --[[ Conversion de chiffres romains en nombre Arguments: chaine avec des chiffres romains Résultat: la chaine convertie en nombre ]] local function nombre (chaine) local test, msg, resultat = Romains.conversion(chaine) if not test then erreur(msg) end return resultat end --[[ Conversion de nombre en chiffres romains Arguments: nombre Résultat: le nombre écrit en chiffres romains ]] local function romains (nombre) return Romains._ChiffresRomains(nombre) end --[[ Détection du type et de la valeur de la date. Arguments: chaine avec une date éventuelle Résultat: type, valeur type: 0 = pas de correspondance, 1 = millénaire avant J-C, 2 = millénaire après J-C, 3 = siècle avant J-C, 4 = siècle après J-C, 5 = décennie avant J-C, 6 = décennie après J-C, 7 = année avant J-C, 8 = année après J-C valeur: millénaire, siècle, décennie ou année exacte Les patterns utilisés dans cette fonction ne contiennent pas de classes de caractères unicode, il n'est donc pas nécessaire d'utiliser mw.ustring. Il n'y a pas lieu de s'effrayer du grand nombre de patterns testés: les tests de pattern sont très performants en Lua tant qu'on n'utilise pas des patterns unicode, et ce module sera probablement appelé une seule fois dans un article Wikipédia donné. ]] local function detection (chaine) if not chaine or chaine == "" then return 0, 0 end local capture -- Ier millénaire av. J.-C. capture = string.match(chaine, "([IVXLCDM]+)er? millénaire av[ant]*[ %.%-]-J[ %.%-]-C[%.]?") if capture then return 1, nombre(capture) end capture = string.match(chaine, "([IVXLCDM]+)er? millénaire av[ant]*[ %.%-]-Jésus[ %.%-]-Christ[%.]?") if capture then return 1, nombre(capture) end capture = string.match(chaine, "%-([IVXLCDM]+)er? millénaire") if capture then return 1, nombre(capture) end -- IIe millénaire capture = string.match(chaine, "([IVXLCDM]+)er? millénaire") if capture then return 2, nombre(capture) end -- Xe siècle av. J.-C. capture = string.match(chaine, "([IVXLCDM]+)er? siècle av[ant]*[ %.%-]-J[ %.%-]-C[%.]?") if capture then return 3, nombre(capture) end capture = string.match(chaine, "([IVXLCDM]+)er? siècle av[ant]*[ %.%-]-Jésus[ %.%-]-Christ[%.]?") if capture then return 3, nombre(capture) end capture = string.match(chaine, "%-([IVXLCDM]+)er? siècle") if capture then return 3, nombre(capture) end -- XIVe siècle capture = string.match(chaine, "([IVXLCDM]+)er? siècle") if capture then return 4, nombre(capture) end -- Années 970 av. J.-C. capture = string.match(chaine, "Années (%d+)0 av[ant]*[ %.%-]-J[ %.%-]-C[%.]?") if capture then return 5, tonumber(capture) end capture = string.match(chaine, "Années (%d+)0 av[ant]*[ %.%-]-Jésus[ %.%-]-Christ[%.]?") if capture then return 5, tonumber(capture) end capture = string.match(chaine, "Années %-(%d+)0") if capture then return 5, tonumber(capture) end capture = string.match(chaine, "Années 0 av[ant]*[ %.%-]-J[ %.%-]-C[%.]?") if capture then return 5, 0 end capture = string.match(chaine, "Années 0 av[ant]*[ %.%-]-Jésus[ %.%-]-Christ[%.]?") if capture then return 5, 0 end capture = string.match(chaine, "Années %-0") if capture then return 5, 0 end -- Années 1360 capture = string.match(chaine, "Années (%d+)0") if capture then return 6, tonumber(capture) end capture = string.match(chaine, "Années 0") if capture then return 6, 0 end -- 970 av. J.-C. capture = string.match(chaine, "(%d+) av[ant]*[ %.%-]-J[ %.%-]-C[%.]?") if capture then if tonumber(capture) == 0 then erreur("L'année 0 n'existe pas") end return 7, tonumber(capture) end capture = string.match(chaine, "(%d+) av[ant]*[ %.%-]-Jésus[ %.%-]-Christ[%.]?") if capture then if tonumber(capture) == 0 then erreur("L'année 0 n'existe pas") end return 7, tonumber(capture) end -- Pour éviter de détecter par exemple "test-1" dans le titre de la page, -- on utilise un pattern plus précis, avec caractères unicode. capture = mw.ustring.match(" " .. chaine .. " ", "[^%w%-_]%-(%d+)[^%w%-_]") if capture then if tonumber(capture) == 0 then erreur("L'année 0 n'existe pas") end return 7, tonumber(capture) end -- 1363 -- Pour éviter de détecter par exemple "test1" dans le titre de la page, -- on utilise un pattern plus précis, avec caractères unicode. capture = mw.ustring.match(" " .. chaine .. " ", "[^%w%-_](%d+)[^%w%-_]") if capture then if tonumber(capture) == 0 then erreur("L'année 0 n'existe pas") end return 8, tonumber(capture) end -- on abandonne return 0, 0 end --[[ Extraction du type et de la valeur de la date. Arguments: aucun Résultat: type, valeur La date est prise de l'argument date, ou sinon de l'argument 1, ou sinon du titre de la page, ou sinon de l'année courante. ]] local function date () local typ, val = 0, 0 typ, val = detection(arg("date", nil)) if typ > 0 then return typ, val end typ, val = detection(arg("année", nil)) if typ > 0 then return typ, val end typ, val = detection(arg("1", nil)) if typ > 0 then return typ, val end typ, val = detection(mw.title.getCurrentTitle().text) if typ > 0 then return typ, val end typ, val = 8, tonumber(os.date("%Y")) if typ > 0 then return typ, val end erreur("Impossible de déterminer la date") end --[[ Extraction de l'année. Arguments: frame Résultat: l'année sous le format attendu par Palette Années, une chaîne vide si la date représente une décennie, un siècle ou un millénaire. ]] local function param_annee (frame) args0 = frame.args args1 = frame:getParent().args local typ, val = date() if typ == 7 then return -val end if typ == 8 then return val end return "" end --[[ Extraction de l'année. Arguments: frame Résultat: l'année sous le format attendu par Palette Années, une chaîne vide si la date représente une décennie, un siècle ou un millénaire. ]] function p.param_annee (frame) local ok, texte = pcall(param_annee, frame) return texte end --[[ Formate le lien pour un mois, pour p.liste et p.mensuelle. Arguments: date numéro de l'année nom nom complet, p ex Janvier abr nom abrégé, p ex Jan Résultat: le mois sous la forme d'un lien ]] local function mois (date, nom, abr) local base = nom .. " " .. date local x = arg(base, nil) if x then return "[[" .. x .. "|" .. abr .. "]]" end return "[[" .. arg("préfixe", "") .. arg("avant mois", "") .. base .. arg("après mois", "") .. "|" .. abr .. "]]" end --[[ Formate la ligne pour les mois, pour p.liste et p.mensuelle. Arguments: date date à formater Résultat: la ligne avec les mois ]] local function mensuelle (date) return "" .. mois(date, "Janvier", "Jan") .. " - " .. mois(date, "Février", "Fév") .. " - " .. mois(date, "Mars", "Mar") .. " - " .. mois(date, "Avril", "Avr") .. " - " .. mois(date, "Mai", "Mai") .. " - " .. mois(date, "Juin", "Juin") .. " <br> " .. mois(date, "Juillet", "Juil") .. " - " .. mois(date, "Août", "Aoû") .. " - " .. mois(date, "Septembre", "Sep") .. " - " .. mois(date, "Octobre", "Oct") .. " - " .. mois(date, "Novembre", "Nov") .. " - " .. mois(date, "Décembre", "Déc") end --[[ Génération de la liste des mois, pour p.mensuelle uniquement. Arguments: typ le type de date, voir detection() val la valeur de la date ]] local function l_mensuelle (typ, val) if arg("mensuelle", "non") == "non" then return "" end if typ ~= 8 then return "" end if val < 1000 then return "" end return '<td style="text-align:center;">' .. mensuelle(val) .. '</td>' end --[[ Génération de la ligne des mois, pour p.mensuelle uniquement. ]] local function p_mensuelle (frame) args0 = frame.args args1 = frame:getParent().args local typ, val = date() return l_mensuelle(typ, val) end --[[ Génération de la ligne des mois. ]] function p.mensuelle (frame) local ok, texte = pcall(p_mensuelle, frame) return texte end --[[ Génération de la liste des mois, pour p.liste uniquement. Arguments: typ le type de date, voir detection() val la valeur de la date ]] local function l_mois (typ, val) if arg("mois", "non") == "non" then return "" end if typ ~= 8 then return "" end if val < 1000 then return "" end local titre = arg("titre mois", "Mois :") if titre ~= "" then titre = "<small>'''" .. titre .. "'''</small><br>" end return titre .. mensuelle(val) end --[[ Génération de la ligne des mois. ]] local function p_mois (frame) args0 = frame.args args1 = frame:getParent().args local typ, val = date() return l_mois(typ, val) end --[[ Génération de la ligne des mois. ]] function p.mois (frame) local ok, texte = pcall(p_mois, frame) return texte end --[[ Ajoute un nombre à une date. Arguments: date date de base nombre valeur à ajouter Résultat: la date de base plus le nombre ]] local function date_plus (date, nombre) if date > 0 or date + nombre < 0 then return date + nombre else return date + nombre + 1 end end --[[ Soustrait un nombre d'une date. Arguments: date date de base nombre valeur à soustraire Résultat: la date de base moins le nombre ]] local function date_moins (date, nombre) if date < 0 or date - nombre > 0 then return date - nombre else return date - nombre - 1 end end --[[ Formate le lien pour une année. Arguments: date date à formater Résultat: l'année sous la forme d'un lien ]] local function annee (date) local x = arg("année " .. date, nil) if x then return "[[" .. x .. "|" .. date .. "]]" end local apres = arg("après année", "") if arg("années", "") == "Québec" then if date < 1763 then apres = " en Nouvelle-France" elseif date < 1791 then apres = " au Québec" elseif date < 1841 then apres = " au Bas-Canada" elseif date < 1867 then apres = " au Canada-Est" else apres = " au Québec" end end if date > 0 then return "[[" .. arg("préfixe", "") .. arg("avant année", "") .. date .. arg("suite année", "") .. apres .. "|" .. date .. "]]" else return "[[" .. arg("préfixe", "") .. arg("avant année", "") .. - date .. arg("suite année", "") .. " av. J.-C." .. apres .. "|" .. date .. "]]" end end --[[ Formate la ligne pour les années. Arguments: date date à formater Résultat: la ligne avec les années ]] local function annees (date) local titre = arg("titre années", "Années :") if titre ~= "" then titre = "<small>'''" .. titre .. "'''</small><br>" end return titre .. annee(date_moins(date, 3)) .. " " .. annee(date_moins(date, 2)) .. " " .. annee(date_moins(date, 1)) .. " " .. "''' " .. annee(date) .. " '''" .. " " .. annee(date_plus(date, 1)) .. " " .. annee(date_plus(date, 2)) .. " " .. annee(date_plus(date, 3)) end --[[ Formate les années d'une décennie. Arguments: date décennie à formater Résultat: la ligne avec les années ]] local function anndec (date) local texte = arg("titre années", "Années :") if texte ~= "" then texte = "<small>'''" .. texte .. "'''</small><br>" end local base if date > 0 then base = date * 10 - 10 else base = date * 10 + 1 end if base ~= 0 then texte = texte .. annee(base) .. " " end texte = texte .. annee(base + 1) .. " " texte = texte .. annee(base + 2) .. " " texte = texte .. annee(base + 3) .. " " texte = texte .. annee(base + 4) .. "<br>" texte = texte .. annee(base + 5) .. " " texte = texte .. annee(base + 6) .. " " texte = texte .. annee(base + 7) .. " " texte = texte .. annee(base + 8) if base + 9 ~= 0 then texte = texte .. " " .. annee(base + 9) end return texte end --[[ Génération de la ligne des années. Arguments: typ le type de date, voir detection() val la valeur de la date ]] local function l_annees (typ, val) if arg("années", "oui") == "non" then return "" end if typ == 5 then return anndec(-val - 1) end if typ == 6 then return anndec( val + 1) end if typ == 7 then return annees(-val) end if typ == 8 then return annees( val) end end --[[ Génération de la ligne des années. ]] local function p_annees (frame) args0 = frame.args args1 = frame:getParent().args local typ, val = date() return l_annees(typ, val) end --[[ Génération de la ligne des années. ]] function p.annees (frame) local ok, texte = pcall(p_annees, frame) return texte end --[[ Formate le lien pour une décennie. Arguments: date date à formater Résultat: la décennie sous la forme d'un lien Dans les calculs, nous numérotons les décennies comme les années, donc sans décennie 0 sinon il y aurait une décennie +0 après J.-C. et une décennie -0 avant J.-C., trop compliqué pour les calculs. Donc: - la décennie -1 couvre les années -9 à -1 - la décennie 1 couvre les années 1 à 9 - la décennie 2 couvre les années 10 à 19 - la décennie 193 couvre les années 1920 à 1929 - etc. L'affichage en tiendra compte bien entendu. ]] local function decennie (date) local affichage if date > 0 then affichage = "" .. (date - 1) * 10 else affichage = "-" .. (-date - 1) * 10 end local x = arg("décennie " .. affichage, nil) if x then return "[[" .. x .. "|" .. affichage .. "]]" end if date > 0 then return "[[" .. arg("préfixe", "") .. arg("avant décennie","Années ") .. (date - 1) * 10 .. arg("suite décennie","") .. arg("après décennie","") .. "|" .. affichage .. "]]" else return "[[" .. arg("préfixe", "") .. arg("avant décennie","Années ") .. (-date - 1) * 10 .. arg("suite décennie","") .. " av. J.-C." .. arg("après décennie","") .. "|" .. affichage .. "]]" end end --[[ Formate la ligne pour les décennies. Arguments: date date à formater Résultat: la ligne avec les décennies ]] local function decennies (date) local titre = arg("titre décennies", "Décennies :") if titre ~= "" then titre = "<small>'''" .. titre .. "'''</small><br>" end return titre .. decennie(date_moins(date, 3)) .. " " .. decennie(date_moins(date, 2)) .. " " .. decennie(date_moins(date, 1)) .. " " .. "''' " .. decennie(date) .. " '''" .. " " .. decennie(date_plus(date, 1)) .. " " .. decennie(date_plus(date, 2)) .. " " .. decennie(date_plus(date, 3)) end --[[ Génération de la ligne des décennies. Arguments: typ le type de date, voir detection() val la valeur de la date ]] local function l_decennies (typ, val) if arg("décennies", "oui") == "non" then return "" end if typ <= 4 then return "" end if typ == 5 then return decennies(-val - 1) end if typ == 6 then return decennies( val + 1) end if typ == 7 then return decennies(-math.floor(val / 10) - 1) end if typ == 8 then return decennies( math.floor(val / 10) + 1) end end --[[ Génération de la ligne des décennies. ]] local function p_decennies (frame) args0 = frame.args args1 = frame:getParent().args local typ, val = date() return l_decennies(typ, val) end --[[ Génération de la ligne des décennies. ]] function p.decennies (frame) local ok, texte = pcall(p_decennies, frame) return texte end --[[ Formate le lien pour un siècle. Arguments: date date à formater Résultat: le siècle sous la forme d'un lien Dans les calculs, nous numérotons les siècles comme les années, donc sans siècle 0 sinon il y aurait un siècle +0 après J.-C. et un siècle -0 avant J.-C., trop compliqué pour les calculs. Donc: - le siècle -1 couvre les années -100 à -1 - le siècle 1 couvre les années 1 à 100 - le siècle 2 couvre les années 101 à 200 - le siècle 20 couvre les années 1901 à 2000 - etc. L'affichage en tiendra compte bien entendu. ]] local function siecle (date) local affichage if date > 0 then affichage = "" .. romains(date) else affichage = "-" .. romains(-date) end local suffixe if math.abs(date) == 1 then suffixe = "er" else suffixe = "e" end local x = arg("siècle " .. affichage, nil) if x then return "[[" .. x .. "|" .. affichage .. "<sup>" .. suffixe .. "</sup>" .. "]]" end if date > 0 then return "[[" .. arg("préfixe", "") .. arg("avant siècle", "") .. romains(date) .. arg("suite siècle", suffixe .. " siècle") .. arg("après siècle", "") .. "|" .. affichage .. "<sup>" .. suffixe .. "</sup>" .. "]]" else return "[[" .. arg("préfixe", "") .. arg("avant siècle", "") .. romains(-date) .. arg("suite siècle", suffixe .. " siècle") .. " av. J.-C." .. arg("après siècle","") .. "|" .. affichage .. "<sup>" .. suffixe .. "</sup>" .. "]]" end end --[[ Formate la ligne pour les siècles. Arguments: date date à formater Résultat: la ligne avec les siècles ]] local function siecles (date) local titre = arg("titre siècles", "Siècles :") if titre ~= "" then titre = "<small>'''" .. titre .. "'''</small><br>" end return titre .. siecle(date_moins(date, 2)) .. " " .. siecle(date_moins(date, 1)) .. " " .. "''' " .. siecle(date) .. " '''" .. " " .. siecle(date_plus(date, 1)) .. " " .. siecle(date_plus(date, 2)) end --[[ Génération de la ligne des siècles. Arguments: typ le type de date, voir detection() val la valeur de la date ]] local function l_siecles (typ, val) if arg("siècles", "oui") == "non" then return "" end if typ <= 2 then return "" end if typ == 3 then return siecles(-val) end if typ == 4 then return siecles( val) end if typ == 5 then return siecles(-math.floor(val / 10 ) - 1) end if typ == 6 then return siecles( math.floor(val / 10 ) + 1) end if typ == 7 then return siecles(-math.floor((val - 1) / 100) - 1) end if typ == 8 then return siecles( math.floor((val - 1) / 100) + 1) end end --[[ Génération de la ligne des siècles. ]] local function p_siecles (frame) args0 = frame.args args1 = frame:getParent().args local typ, val = date() return l_siecles(typ, val) end --[[ Génération de la ligne des siècles. ]] function p.siecles (frame) local ok, texte = pcall(p_siecles, frame) return texte end --[[ Formate le lien pour un millénaire. Arguments: date date à formater omet_si_futur si défini, renvoie une valeur vide pour les millénaires du futur qui n'ont pas d'article Résultat: le millénaire sous la forme d'un lien Dans les calculs, nous numérotons les millénaires comme les années, donc sans millénaire 0 sinon il y aurait un millénaire +0 après J.-C. et un millénaire -0 avant J.-C., trop compliqué pour les calculs. Donc: - le millénaire -1 couvre les années -1000 à -1 - le millénaire 1 couvre les années 1 à 1000 - le millénaire 2 couvre les années 1001 à 2000 - etc. L'affichage en tiendra compte bien entendu. ]] local function millenaire (date, omet_si_futur) if omet_si_futur and date >= 4 then return "" end local affichage if date > 0 then affichage = "" .. romains(date) else affichage = "-" .. romains(-date) end if math.abs(date) == 1 then suffixe = "er" else suffixe = "e" end local x = arg("millénaire " .. affichage, nil) if x then return "[[" .. x .. "|" .. affichage .. "<sup>" .. suffixe .. "</sup>" .. "]]" end if date > 0 then return "[[" .. arg("préfixe", "") .. arg("avant millénaire", "") .. romains(date) .. arg("suite millénaire", suffixe .. " millénaire") .. arg("après millénaire", "") .. "|" .. affichage .. "<sup>" .. suffixe .. "</sup>" .. "]]" else return "[[" .. arg("préfixe", "") .. arg("avant millénaire", "") .. romains(-date) .. arg("suite millénaire", suffixe .. " millénaire") .. " av. J.-C." .. arg("après millénaire", "") .. "|" .. affichage .. "<sup>" .. suffixe .. "</sup>" .. "]]" end end --[[ Formate la ligne pour les millénaires. Arguments: date date à formater Résultat: la ligne avec les millénaires ]] local function millenaires (date) local titre = arg("titre millénaires", "Millénaires :") if titre ~= "" then titre = "<small>'''" .. titre .. "'''</small><br>" end return titre .. millenaire(date_moins(date, 2)) .. " " .. millenaire(date_moins(date, 1)) .. " " .. "''' " .. millenaire(date) .. " '''" .. " " .. millenaire(date_plus(date, 1), true) .. " " .. millenaire(date_plus(date, 2), true) end --[[ Génération de la ligne des millénaires. Arguments: typ le type de date, voir detection() val la valeur de la date ]] local function l_millenaires(typ, val) if arg("millénaires", "oui") == "non" then return "" end if typ <= 0 then return "" end if typ == 1 then return millenaires(-val) end if typ == 2 then return millenaires( val) end if typ == 3 then return millenaires(-math.floor(val / 10 ) - 1) end if typ == 4 then return millenaires( math.floor(val / 10 ) + 1) end if typ == 5 then return millenaires(-math.floor(val / 100 ) - 1) end if typ == 6 then return millenaires( math.floor(val / 100 ) + 1) end if typ == 7 then return millenaires(-math.floor((val - 1) / 1000) - 1) end if typ == 8 then return millenaires( math.floor((val - 1) / 1000) + 1) end end --[[ Génération de la ligne des millénaires. ]] local function p_millenaires(frame) args0 = frame.args args1 = frame:getParent().args local typ, val = date() return l_millenaires(typ, val) end --[[ Génération de la ligne des millénaires. ]] function p.millenaires (frame) local ok, texte = pcall(p_millenaires, frame) return texte end --[[ Génération de la liste des années, décennies, siècles, millénaires. Arguments: typ le type de date, voir detection() val la valeur de la date ]] local function l_liste (typ, val) local x local t = {} x = l_annees (typ, val); if x ~= "" then table.insert(t, x) end x = l_decennies (typ, val); if x ~= "" then table.insert(t, x) end x = l_siecles (typ, val); if x ~= "" then table.insert(t, x) end x = l_millenaires(typ, val); if x ~= "" then table.insert(t, x) end x = l_mois (typ, val); if x ~= "" then table.insert(t, x) end x = table.concat(t, "<br>") if (x == "") then erreur("Aucune ligne à afficher") end return '<td style="text-align:center;">' .. x .. '</td>' end --[[ Génération de la liste des années, décennies, siècles, millénaires. ]] local function p_liste (frame) args0 = frame.args args1 = frame:getParent().args local typ, val = date() return l_liste(typ, val) end --[[ Génération de la liste des années, décennies, siècles, millénaires. ]] function p.liste (frame) local ok, texte = pcall(p_liste, frame) return texte end return p