Module:Bandeau

    De WikiPasokh
    Révision datée du 26 août 2023 à 05:09 par fr>Od1n (Catégorie:Ébauche inconnue contient actuellement seulement 12 pages, mais Huster a corrigé plusieurs dizaines de pages ; comme il peut être utile de repérer les pages utilisateur avec des thèmes non reconnus, mais que l'on ne veut pas polluer la catégorie, je les range dans une nouvelle sous-catégorie Catégorie:Ébauche inconnue dans une page utilisateur)
    (diff) ← Version précédente | Voir la version actuelle (diff) | Version suivante → (diff)

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

    --Ce module implémente les modèles de bandeau.
    
    --Standardisation des bandeaux ([[Catégorie:Modèle de bandeau]]).
    --Créer une fonction exportable pour le modèle {{Bandeau}} (ns:all).
    --Créer une fonction exportable pour les bandeaux d'article (ns:0).
    --Créer une fonction exportable pour les bandeaux de section (ns:0).
    --Créer une fonction exportable pour les bandeaux d'ébauche (ns:0).
    --Créer une fonction exportable pour les bandeaux de discussion (ns:1).
    --Créer une fonction exportable pour les bandeaux système (ns:8).
    --Gérer les images multiples.
    
    local p = {}
    
    local trim = require('Module:Outils').trim
    local yesno = require('Module:yesno')
    local classData = mw.loadData('Module:Bandeau/Class')
    local moduleEbauche = 'Module:Bandeau/Ébauche'
    -- local paramEbauche = mw.loadData(moduleEbauche) -- ne sera chargé que pour un bandeau d'ébauche.
    
    local cfg = {
    	forme = 'bandeau-simple',
    	niveau = 'bandeau-niveau-neutre',
    	formatLien = '[[Fichier:%s|%spx|alt=%s|class=noviewer]]',
    	tailleIcone = '45x45',
    	erreurArgument = 'Paramètre <code>|%s=</code> manquant',
    	erreurEbaucheParam = 'le thème « %s » du modèle [[Modèle:Ébauche|' .. mw.text.nowiki('{{ébauche}}') .. ']] n’est pas [[Aide:Ébauche/Aide paramètres|défini]].',
    	erreurEbaucheType = 'le thème « %s » doit apparaître en tête de liste du modèle [[Modèle:Ébauche|' .. mw.text.nowiki('{{ébauche}}') .. ']].',
    	ebaucheImage = '<span style="white-space:nowrap;word-spacing:5px">%s</span>',
    	ebaucheTitre = '%s est une [[Aide:Ébauche|ébauche]].',
    	ebaucheTitreSujet = '%s est une [[Aide:Ébauche|ébauche]] concernant %s.',
    	ebaucheCateg = '[[Catégorie:Wikipédia:ébauche %s]]',
    }
    
    -- CSS inline pour éviter FOUC sur le site mobile
    local rustineFoucMobile = {
    	['display'] = 'table-cell',
    	['padding-right'] = '0.5em',
    }
    
    local function erreur(texte, formatstring, tag)
    	local res = mw.html.create(tag or 'span')
    	res	:addClass('error')
    		:wikitext('Erreur : ')
    
    	if formatstring then
    		res:wikitext(formatstring:format(texte))
    	else
    		res:wikitext(texte)
    	end
    
    	return tostring(res)
    end
    
    function p._bandeau(args)
    	local res = mw.html.create('div')
    	local cells = mw.html.create()
    	local icone = trim(args.image) or trim(args['icône'])
    	local backgroundIcone = icone and classData.icones[icone:gsub('_', ' ')] or false
    	local texte = (trim(args.texte) or erreur('texte', cfg.erreurArgument))
    
    	if args.id and args.id ~= '' then
    		res:attr('id', args.id)
    	end
    
    	res	:addClass('bandeau-container metadata')
    		:addClass(classData.formes[args.forme] or cfg.forme)
    		:addClass(classData.niveau[args.niveau] or cfg.niveau)
    
    	if args.class and args.class ~= '' then
    		res:addClass(args.class)
    	end
    
    	if args.style and args.style ~= '' then
    		res:cssText(args.style)
    	end
    
    	if yesno(args.centrer) then
    		cells = mw.html.create('div')
    			:addClass('bandeau-centrer')
    	elseif trim(args.droite) then
    		cells = mw.html.create('div')
    			:css{ display = 'table', width = '100%' }
    	end
    
    	if args['icône bma'] and args['icône bma'] ~= 'non' then
    		if args['icône bma'] == 'oui' then
    			cells:wikitext( mw.getCurrentFrame():expandTemplate{ title = 'Bma' } )
    		else
    			cells:wikitext( mw.getCurrentFrame():expandTemplate{ title = 'Bma', args = {args['icône bma']} } )
    		end
    	end
    
    	if icone and not backgroundIcone then
    		local iconeWiki = icone
    		if not icone:match('%[') then
    			local alt = args.alt or args['légende'] or ''
    			if yesno( args['domaine public'] ) then
    				alt = alt .. '|link='
    			end
    			local taille = args['taille icône'] or cfg.tailleIcone
    			iconeWiki = cfg.formatLien:format(icone, taille, alt)
    		end
    		cells
    			:tag('div')
    				:addClass('bandeau-cell bandeau-icone')
    				:css(rustineFoucMobile)
    				:wikitext(iconeWiki)
    	end
    
    	cells
    		:tag('div')
    			:addClass('bandeau-cell')
    			:css(rustineFoucMobile)
    			:addClass(backgroundIcone and ('bandeau-icone-css ' .. backgroundIcone) or nil)
    			:newline() -- sert à la génération automatique de <p> encadrant le contenu
    			:wikitext(texte)
    			:newline() -- sert à la génération automatique de <p> encadrant le contenu
    
    	if trim(args.droite) then
    		cells
    			:tag('div')
    				:addClass('bandeau-cell')
    				:css(rustineFoucMobile)
    				:css( 'padding-left', '1em' )
    				:newline()
    				:wikitext(args.droite)
    	end
    
    	res	:node(cells)
    	if trim(args['supplément']) then
    		res	:tag('div')
    				:wikitext(args['supplément'])
    	end
    	return tostring(res)
    end
    
    function p._bandeauAvertissement(args)
    	local htmlTexte = mw.html.create()
    
    	local titre = trim(args.titre) or erreur('titre', cfg.erreurArgument)
    
    	local suffixeDate = trim(args.date)
    	if suffixeDate then
    		-- pour rendre insécable, seulement si le paramètre semble bien être une date valide
    		suffixeDate = (require 'Module:Date').modeleDate{suffixeDate, nolinks=true, afficherErreurs=false, categoriserErreurs=false}
    
    		titre = titre:gsub('%.$', '')
    		suffixeDate = ' <small>(' .. suffixeDate .. ').</small>'
    	elseif not titre:match('[.,;:!?]$') then
    		titre = titre .. '.'
    	end
    
    	htmlTexte
    		:tag('strong')
    			:addClass('bandeau-titre')
    			:wikitext(titre)
    		:done()
    		:wikitext(suffixeDate)
    
    	local texte = trim(args.texte)
    	if texte then
    		htmlTexte
    			:newline()
    			:newline()
    			:wikitext(texte)
    	end
    
    	local parametres = {
    		forme = 'article',
    		niveau = args.niveau,
    		id = args.id,
    		class = args.class,
    		['icône'] = trim(args['icône']) or trim(args['icône-complexe']) or args.niveau,
    		alt = args.alt or args['légende'],
    		['domaine public'] = args['domaine public'],
    		texte = tostring(htmlTexte),
    		['icône bma'] = args['icône bma'],
    		['supplément'] = args['supplément'],
    	}
    
    	return p._bandeau(parametres)
    end
    
    --[[
    	TODO - fusionner ces deux méthodes :
    	* p._bandeau() avec forme=section
    	* p._bandeauSection()
    ]]--
    
    function p._bandeauSection(args)
    	local res = mw.html.create('div')
    	local icone = trim(args.image) or trim(args['icône'])
    	local backgroundIcone = icone and classData.icones[icone:gsub('_', ' ')] or false
    	local texte = (trim(args.texte) or erreur('texte', cfg.erreurArgument))
    
    	res	:addClass('bandeau-container bandeau-section metadata')
    		:addClass(classData.niveau[args.niveau] or cfg.niveau)
    
    	if icone and not backgroundIcone then
    		local iconeWiki = icone
    		if not icone:match('%[') then
    			local alt = args.alt or args['légende'] or ''
    			if yesno( args['domaine public'] ) then
    				alt = alt .. '|link='
    			end
    			iconeWiki = cfg.formatLien:format(icone, 'text-top|20x17', alt)
    		end
    		res	:tag('div')
    				:addClass('bandeau-cell bandeau-icone')
    				:wikitext(iconeWiki)
    	end
    	res	:tag('div')
    			:addClass('bandeau-cell')
    			:addClass(backgroundIcone and ('bandeau-icone-css ' .. backgroundIcone) or nil)
    			:wikitext(texte)
    
    	return tostring(res)
    end
    
    -- fonction qui inverse la casse du premier caractère d'une chaine
    local function inverserCasse( str )
    	if type( str ) == 'string' then
    		local premierCar = mw.ustring.sub( str, 1, 1 )
    		if mw.ustring.lower( premierCar ) == premierCar then
    			return mw.ustring.upper( premierCar ) .. mw.ustring.sub( str, 2 )
    		else
    			return mw.ustring.lower( premierCar ) .. mw.ustring.sub( str, 2 )
    		end
    	end
    end
    
    -- fonction qui récupètre la ou les tables d'ébauche correspondant au thème
    local function getEbaucheTable( paramEbauche, theme, feminin )
    	-- suprime les marques de direction ltr
    	theme = theme:gsub( '\226\128\142', '' ):gsub( '_', ' ' )
    	-- récupére les paramètres lié au theme, à partir du module:Bandeau/Ébauche
    	local params = {}
    	local ebauche = paramEbauche[ theme ] or paramEbauche[ inverserCasse( theme ) ]
    	if not ebauche and theme:find( ' ' ) then
    		-- teste si l'un des mots du thème correspond à un adjectif existant
    		for adj in theme:gmatch( ' ([^ ]+)' ) do
    			paramsAdj = getEbaucheTable( paramEbauche, adj, feminin )
    			if paramsAdj and paramsAdj.adjectif == true then
    				local nom = theme:gsub( ' ' .. adj:gsub( '(%p)', '%%%1'), '' )
    				params = getEbaucheTable( paramEbauche, nom, feminin )
    				if params then
    					return params, paramsAdj
    				end
    			end
    		end
    		-- aucun mot ne correspond à un adjectif, on essait une autre methode pour trouver une correspondance avec plusieurs mots
    		if theme:find( ' .+ ' ) then
    			for adj, paramsAdj in pairs( paramEbauche ) do
    				if paramsAdj.adjectif == true and theme:find( ' ' .. adj, 2, true ) then
    					local nom = theme:gsub( ' ' .. adj:gsub( '(%p)', '%%%1'), '' )
    					params = getEbaucheTable( paramEbauche, nom, feminin )
    					if params then
    						return params, paramsAdj
    					end
    				end
    			end
    		end
    	end
    	if feminin and ebauche and ebauche.feminin then
    		ebauche = paramEbauche[ ebauche.feminin ]
    	end
    	if ebauche then
    		for n, v in pairs( ebauche ) do
    			params[ n ] = v
    		end
    	else
    		params = nil
    	end
    	return params, nil
    end
    p.getEbaucheTable = getEbaucheTable
    
    local function femininFromWikidata()
    	local entity = mw.wikibase.getEntity()
    	if entity then
    		local p31 = entity:getBestStatements( 'P31' )
    		local estHumain = type( p31 ) == 'table'
    			and #p31 == 1
    			and type( p31[ 1 ].mainsnak ) == 'table'
    			and type( p31[ 1 ].mainsnak.datavalue ) == 'table'
    			and type( p31[ 1 ].mainsnak.datavalue.value ) == 'table'
    			and p31[ 1 ].mainsnak.datavalue.value['numeric-id'] == 5
    		local p21 = entity:getBestStatements( 'P21' )
    		local estFeminin = type( p21 ) == 'table'
    			and #p21 == 1
    			and type( p21[ 1 ].mainsnak ) == 'table'
    			and type( p21[ 1 ].mainsnak.datavalue ) == 'table'
    			and type( p21[ 1 ].mainsnak.datavalue.value ) == 'table'
    			and p21[ 1 ].mainsnak.datavalue.value['numeric-id'] == 6581072
    		return estHumain, estFeminin
    	end
    	return false, false
    end
    
    p['_ébauche'] = function ( args )
    	local paramEbauche = mw.loadData( moduleEbauche )
    	local page = mw.title.getCurrentTitle()
    	local ebauches, gestionErreur = {}, {}
    	local humain, feminin = femininFromWikidata()
    	if args['féminin'] and args['féminin'] ~= '' then
    		feminin = yesno( args['féminin'], true )
    	end
    	local estFeminin
    
    	-- fonction qui retourne la valeur de param pour l'ébauche i, ou une valeur par défaut
    	local ebaucheParam = function( i, param )
    		return ebauches[ i ] and ebauches[ i ][ param ] or paramEbauche[''][ param ]
    	end
    
    	-- récupération des paramètres de tous les thèmes
    	for i, theme in ipairs( args ) do
    		theme = trim( theme )
    		if theme then
    			local t, tAdj = getEbaucheTable( paramEbauche, theme, feminin )
    			if t then
    				table.insert( ebauches, t )
    				table.insert( ebauches, tAdj )
    			else
    				table.insert(
    					gestionErreur,
    					erreur( theme, cfg.erreurEbaucheParam, 'div' )
    				)
    			end
    		end
    	end
    
    	-- récupération des différents titres, images et catégories
    	local images, titres, categs = {}, {}, {}
    	local tailleIcone = '45x35'
    	if #ebauches > 3 then
    		tailleIcone = '35x25'
    	end
    	for i, ebauche in ipairs( ebauches ) do
    		-- création du lien de l'image
    		local alt = ''
    		if ebauche.icone then
    			local image = cfg.formatLien:format( ebauche.icone, tailleIcone, alt )
    			table.insert( images, image )
    		end
    		if math.fmod( #ebauches, 3 ) == 1 and ( #ebauches - i ) == 2
    			or math.fmod( i, 3 ) == 0 and ( #ebauches - i ) > 1
    		then
    			-- sur plusieurs lignes s'il y a plus de 3 images, avec minimum deux images sur la dernière ligne
    			table.insert( images, '<br> ' )
    		end
    
    		if i > 1 and ebauche.type and ebauche.type ~= paramEbauche[''].type then
    			-- remplace "Cet article par "Ce portail" ou autre en fonction du premier thème
    			table.insert(
    				gestionErreur,
    				erreur( ebauche.nom, cfg.erreurEbaucheType, 'div' )
    			)
    		end
    
    		-- récupères les différents noms de thème
    		if ebauche.adjectif and #titres > 0 then
    			local sujet = ebauche.sujet or ebauche.nom
    			if estFeminin then
    				sujet = ebauche.sujetF or sujet:gsub(
    					ebauche.nom:gsub( '(%p)', '%%%1') .. '%f[%W]',
    					ebauche.feminin
    				)
    			end
    			-- ajout du sujet de l'adjectif dans le sujet de l'ébauche précédente
    			local titre, subst = titres[ #titres ]:gsub(
    				'<(adj[^>]*)>',
    				{ adjectif = sujet, adj = ebauche.nom, adjF = ebauche.feminin }
    			)
    			if subst > 0 then
    				titres[ #titres ] = titre
    			else
    				titres[ #titres ] = titre .. ' ' .. sujet
    			end
    		else
    			table.insert( titres, ebauche.sujet )
    			estFeminin = ebauche.estFeminin or ( ebauche.sujet == '' and estFeminin )
    		end
    
    		-- mise en forme des catégories
    		if ebauche.adjectif then
    			-- tentative d'ajout du nom de l'adjectif dans les catégories précédentes
    			local modif = false
    			for k, v in ipairs( categs ) do
    				local cat, subst = v:gsub(
    					'<(adj[^>]*)>',
    					{ adj = ebauche.nom, adjF =  ebauche.feminin,  adjectif = ebauche.nom }
    				)
    				if subst == 0 then
    					cat = v .. ' ' .. ebauche.nom
    				end
    				if mw.title.new( 'Catégorie:Wikipédia:ébauche ' .. cat ).exists then
    					categs[ k ] = cat
    					modif = true
    				end
    			end
    			if not modif
    				and humain
    				and mw.title.new( 'Catégorie:Wikipédia:ébauche personnalité ' .. ebauche.feminin ).exists
    			then
    				table.insert( categs, 'personnalité ' .. ebauche.feminin )
    			end
    		end
    		table.insert( categs, ebauche.categ )
    	end
    
    	-- mise en forme des images
    	local image
    	if args['icône'] and args['icône'] ~= '' then
    		local theme = getEbaucheTable( paramEbauche, args['icône'] )
    		if theme and theme.icone then
    			image = cfg.formatLien:format(
    				theme.icone,
    				tailleIcone,
    				theme.altIcone or ( 'image illustrant ' .. theme.sujet )
    			)
    		end
    	elseif #images == 1 then
    		image = images[ 1 ]
    	elseif #images > 1 then
    		image = cfg.ebaucheImage:format( table.concat( images, ' ' ) )
    	end
    
    	-- mise en forme du titre
    	local titre
    	if #titres > 0 then
    		titre = cfg.ebaucheTitreSujet:format(
    			ebaucheParam( 1, 'type' ),
    			mw.text.listToText( titres )
    		)
    	else
    		titre = cfg.ebaucheTitre:format( ebaucheParam( 1, 'type' ) )
    	end
    
    	-- mise en forme du texte
    	local texte
    	if #ebauches == 0 then
    		texte = ( ebaucheParam( 1, 'message' ) ) .. '.'
    	else
    		local message = ebaucheParam( 1, 'message' )
    		local selon = ebaucheParam( 1, 'selon' )
    		-- ajout d'un point si le paramètre selon commence par un retour ligne ou une majuscule
    		if message:sub( -1 ) == ')' and ( selon:sub( 1, 3 ) == '<br' or mw.ustring.match( selon, '^%u' ) ) then
    			texte = ( ebaucheParam( 1, 'message' ) ) .. '. ' .. ( ebaucheParam( 1, 'selon' ) ) .. '.'
    		else
    			texte = ( ebaucheParam( 1, 'message' ) ) .. ' ' .. ( ebaucheParam( 1, 'selon' ) ) .. '.'
    		end
    	end
    	-- ajout d'un texte s'il y a une liste de tâches
    	local todo = page.talkPageTitle and mw.title.new( page.talkPageTitle.fullText .. '/À faire' ) or nil
    	if todo and todo.exists then
    		texte = texte .. '\n\n'
    			.. 'Consultez la liste des <b>tâches à accomplir</b> en [['
    			.. page.talkPageTitle.prefixedText
    			.. '|page de discussion]].'
    	end
    
    	-- paramètres pour le bandeau
    	local parametres = {
    		niveau = 'ébauche',
    		['icône'] = image,
    		titre = titre:gsub( ' <adj[^>]*>', '' ),
    		texte = texte,
    		id = args.id
    	}
    
    	-- concaténation des différentes catégories (pas de catégorisation si nocat, ou page de discussion, ou espace utilisateur)
    	local categ = ''
    	if not ( yesno( args.nocat, true, false ) or page.isTalkPage or page.namespace == 2 ) then
    		for i = 1, #categs do
    			categs[ i ] = cfg.ebaucheCateg:format( categs[ i ] )
    		end
    		categ = table.concat( categs ):gsub( ' <[^>]*>', '' )
    		if categ == '' then
    			categ = cfg.ebaucheCateg:format('')
    		end
    	end
    
    	local messageErreur = table.concat( gestionErreur )
    	if #gestionErreur > 0 then
    		if page.namespace == 2 then
    			messageErreur = messageErreur .. '[[Catégorie:Ébauche inconnue dans une page utilisateur]]'
    		else
    			messageErreur = messageErreur .. '[[Catégorie:Ébauche inconnue]]'
    		end
    	end
    
    	return p._bandeauAvertissement( parametres ) .. categ .. messageErreur
    end
    
    ---
    -- fonction retournant un paramètre d'une table d'ébauche.
    -- Elle est prévue pour être appelée directement par #invoke:
    -- avec pour paramètres le thème et le paramètre désiré
    -- Cette fonction est principalement destinée à la page d'aide.
    function p.parametreEbauche( frame )
    	local paramEbauche = mw.loadData( moduleEbauche )
    	local theme = frame.args[1]
    	local param = frame.args[2]
    	if paramEbauche[ theme ] then
    		return paramEbauche[ theme ][ param ]
    	elseif paramEbauche[ inverserCasse( theme ) ] then
    		return paramEbauche[ inverserCasse( theme ) ][ param ]
    	end
    end
    
    ---
    -- Fonction retournant le féminin d'un théme d'ébauche
    -- Elle est prévue pour être appelée directement par #invoke:
    -- avec pour paramètres le thème et le paramètre désiré
    -- Cette fonction est principalement destinée au modèle {{Catégorie d'ébauche}}, donc une valeur n'est retournée que si les catégories sont identiques
    function p.femininEbauche( frame )
    	local paramEbauche = mw.loadData( moduleEbauche )
    	local theme = frame.args[1]
    	local themeF
    	if theme then
    		local t = getEbaucheTable( paramEbauche, theme )
    		local tF, tAdjF = getEbaucheTable( paramEbauche, theme, true )
    		if t and tF and t.feminin and tF.categ == t.categ then
    			if tAdjF then
    				themeF = tF.nom .. ' ' .. tAdjF.feminin
    			else
    				themeF = tF.nom
    			end
    			return themeF
    		end
    	end
    end
    
    ---
    -- fonction qui contruit deux tableaux récapitulatif de l'ensemble des paramètres d'ébauche
    function p.tableParametresEbauches( frame )
    	local paramEbauche = mw.loadData( moduleEbauche )
    
    	local currentFrame = mw.getCurrentFrame()
    	local languageObj = mw.getContentLanguage()
    	function pagesInCategory( category )
    		return languageObj:formatNum( tonumber( currentFrame:callParserFunction( 'PAGESINCATEGORY', { category, 'R' } ) ) )
    	end
    
    	local params, paramAdj, paramType = {}, {}, {}
    	for clef, ebauche in pairs( paramEbauche ) do
    		local kEbauche = {}
    		for k, v in pairs( ebauche ) do
    			kEbauche[ k ] = v
    		end
    		kEbauche.clef = clef
    		if ebauche.type then
    			table.insert( paramType, kEbauche )
    		elseif ebauche.adjectif then
    			if clef == ebauche.nom or clef ~= ebauche.feminin then
    				table.insert( paramAdj, kEbauche )
    			end
    		else
    			table.insert( params, kEbauche )
    		end
    	end
    	local comp = function( eb1, eb2 )
    		return eb1.clef < eb2.clef
    	end
    	table.sort( params, comp )
    	table.sort( paramAdj, comp )
    	table.sort( paramType, comp )
    
    	local wikiTab = { '<table class="wikitable sortable" style="table-layout:fixed;">' }
    	wikiTab.insert = function ( t, value )
    		table.insert( t, value )
    		return t
    	end
    
    	wikiTab
    		:insert('\n=== Ébauches normales ===\n')
    		:insert('<caption>Liste des paramètres d\'ébauche</caption>')
    		:insert('<th scope=col style="width:15%;">nom</th>')
    		:insert('<th scope=col style="width:50px; box-sizing:border-box;">i</th>')
    		:insert('<th scope=col style="width:20%;">sujet</th>')
    		:insert('<th scope=col style="width:20%;">catégorie</th>')
    		:insert('<th scope=col style="width:20%;">compteur</th>')
    		:insert('<th scope=col>selon</th>')
    	for k, ebauche in ipairs( params ) do
    		wikiTab
    			:insert('<tr><td>')
    			:insert( ebauche.clef )
    			:insert('</td><td>')
    		if ebauche.icone then
    			wikiTab:insert( cfg.formatLien:format( ebauche.icone, '45x35', ebauche.altIcone or '' ) )
    		end
    		wikiTab
    			:insert('</td><td>')
    			:insert( ebauche.sujet )
    			:insert('</td><td>')
    		if ebauche.categ then
    			wikiTab
    				:insert( '[[:Catégorie:Wikipédia:ébauche ' .. ebauche.categ .. '|' .. ebauche.categ .. ']]' )
    		end
    		wikiTab
    			:insert('</td><td>')
    		if ebauche.categ then
    			wikiTab
    				:insert( pagesInCategory( 'Wikipédia:ébauche ' .. ebauche.categ ) )
    		end
    		wikiTab
    			:insert('</td><td>')
    			:insert( ebauche.selon )
    			:insert('</td></tr>')
    	end
    	wikiTab:insert('</table>')
    
    	-- seconde table pour les adjectifs
    	wikiTab
    		:insert('\n=== Adjectifs ===\n')
    		:insert('<table class="wikitable">')
    		:insert('<caption>Liste des adjectifs</caption>')
    		:insert('<th scope=col>adjectif</th>')
    		:insert('<th scope=col>féminin</th>')
    		:insert('<th scope=col style="width:50px;">icone</th>')
    		:insert('<th scope=col>sujet</th>')
    		:insert('<th scope=col>sujet féminin</th>')
    		:insert('<th scope=col>catégorie</th>')
    	for k, ebauche in ipairs( paramAdj ) do
    		wikiTab
    			:insert('<tr><td>')
    			:insert( ebauche.clef )
    			:insert('</td><td>')
    			:insert( ebauche.feminin )
    			:insert('</td><td>')
    		if ebauche.icone then
    			wikiTab
    				:insert( cfg.formatLien:format( ebauche.icone, '45x35', ebauche.altIcone or '' ) )
    		end
    		wikiTab
    			:insert('</td><td>')
    			:insert( ebauche.sujet )
    			:insert('</td><td>')
    			:insert( ebauche.sujetF or ebauche.sujet:gsub( ebauche.nom .. '%f[%W]', ebauche.feminin ) )
    			:insert('</td><td>')
    		if ebauche.categ then
    			wikiTab
    				:insert( '[[:Catégorie:Wikipédia:ébauche ' .. ebauche.categ .. '|' .. ebauche.categ .. ']]' )
    		end
    		wikiTab
    			:insert('</td></tr>')
    	end
    	wikiTab:insert('</table>')
    
    	-- troisième table pour les types
    	wikiTab
    		:insert('\n=== Types ===\n')
    		:insert('<table class="wikitable">')
    		:insert('<caption>Liste des paramètres de type</caption>')
    		:insert('<th scope=col style="width:15%;">nom</th>')
    		:insert('<th scope=col style="width:50px;">icone</th>')
    		:insert('<th scope=col style="width:20%;">type</th>')
    		:insert('<th scope=col style="width:15%;">sujet</th>')
    		:insert('<th scope=col style="width:15%;">catégorie</th>')
    		:insert('<th scope=col>message</th>')
    	for k, ebauche in ipairs( paramType ) do
    		wikiTab
    			:insert('<tr><td>')
    			:insert( ebauche.clef )
    			:insert('</td><td>')
    		if ebauche.icone then
    			wikiTab:insert( cfg.formatLien:format( ebauche.icone, '45x35', ebauche.altIcone or '' ) )
    		end
    		wikiTab
    			:insert('</td><td>')
    			:insert ( ebauche.type )
    			:insert('</td><td>')
    			:insert( ebauche.sujet )
    			:insert('</td><td>')
    		if ebauche.categ then
    			wikiTab:insert( '[[:Catégorie:Wikipédia:ébauche ' .. ebauche.categ .. '|' .. ebauche.categ .. ']]' )
    		end
    		wikiTab
    			:insert('</td><td>')
    			:insert( ebauche.message )
    			:insert('</td></tr>')
    	end
    	wikiTab:insert('</table>')
    
    	-- parenthèses pour enlever la 2e valeur retournée par gsub (le nombre de remplacements effectués)
    	return (table.concat( wikiTab ):gsub( ' <adjF?>', '' ))
    end
    
    -- fonction destinée au gadget [[MediaWiki:Gadget-BandeauxEbauches.js]]
    function p.listeEbauches( frame )
    	local paramEbauche = mw.loadData( moduleEbauche )
    	local liste = {}
    	for k in pairs( paramEbauche ) do
    		if k ~= "" then
    			table.insert( liste, k )
    		end
    	end
    	table.sort( liste )
    	return table.concat( liste, '\n' )
    end
    
    
    
    -- Insertion dans la table p des fonctions appelées par les
    -- modèles à l'aide d'un adaptateur de fonction.
    local function adaptateur(nomFonction)
    	return function (frame)
    		local args
    		if frame.args.texte or frame.args.titre then
    			args = frame.args
    		else
    			args = frame:getParent().args
    		end
    		return p[nomFonction](args)
    	end
    end
    
    local nomsFonction = {'bandeau', 'bandeauAvertissement', 'bandeauSection', 'ébauche' }
    for _, nomFonction in ipairs(nomsFonction) do
    	p[nomFonction] = adaptateur('_' .. nomFonction)
    end
    
    return p