Aller au contenu

« Module:Liste des corrections » : différence entre les versions

La bibliothèque libre.
Contenu supprimé Contenu ajouté
rechercher les modèles corr dans la page avec string.gmatch() ne suffit pas, car le 2e argument peut contenir un autre modèle (voir Sujet:W86nf9vbqyrh5633)
détection des erreurs avec le modèle corr sur une page
 
Ligne 101 : Ligne 101 :
if NS == "Page" then
if NS == "Page" then
for _, c in ipairs(corr) do
if corr == false then
corr = frame:expandTemplate{
-- le deuxième argument peut contenir du wikicode
local cm = frame:expandTemplate{
title = 'rouge' ,
args = { frame:preprocess('Une erreur avec un modèle {{m|corr}} a été détectée sur cette page.') }
title = 'CorrDiscussion' ,
args = { c[1], frame:preprocess(c[2]), nombre=c[3] }
}
}
td_corr:node(cm)
td_corr:wikitext(corr)
else
for _, c in ipairs(corr) do
-- le deuxième argument peut contenir du wikicode
local cm = frame:expandTemplate{
title = 'CorrDiscussion' ,
args = { c[1], frame:preprocess(c[2]), nombre=c[3] }
}
td_corr:node(cm)
end
end
end
else
else
Ligne 198 : Ligne 206 :
if corr_args ~= nil then
if corr_args ~= nil then
local fist_pipe_pos = mw.ustring.find(corr_args, "|", 1, true)
local fist_pipe_pos = mw.ustring.find(corr_args, "|", 1, true)
local corr_arg1 = mw.ustring.sub(corr_args,1,fist_pipe_pos-1)
if fist_pipe_pos ~= nil then
local corr_arg1 = mw.ustring.sub(corr_args,1,fist_pipe_pos-1)
local corr_arg2 = mw.ustring.sub(corr_args,fist_pipe_pos+1)
local corr_arg2 = mw.ustring.sub(corr_args,fist_pipe_pos+1)
-- si la correction est multiple on ne la stocke qu'une fois
-- si la correction est multiple on ne la stocke qu'une fois
local m = false
local m = false
for i, v in ipairs(corr) do
for i, v in ipairs(corr) do
if corr_arg1==v[1] and corr_arg2==v[2] then
if corr_arg1==v[1] and corr_arg2==v[2] then
corr[i][3] = v[3]+1
corr[i][3] = v[3]+1
m=true
m=true
end
end
end
if not m then
end
table.insert(corr, {corr_arg1, corr_arg2, 1})
if not m then
end
table.insert(corr, {corr_arg1, corr_arg2, 1})
else
return false -- erreur
end
end
end
end

Dernière version du 3 mai 2021 à 06:39

La documentation pour ce module peut être créée à Module:Liste des corrections/Documentation

local p = {}

-- Dresse la liste des corrections apportées dans un livre
function p.liste (frame)
	local args = frame.args
	local index = args[1]
	local section = "correction" -- nom de la section, par défaut celui du modèle {{Page Discussion}}
	local total = 0 -- nombre total de corrections
	local out = mw.html.create()
	local corrections = mw.html.create( 'table' )
	local NS = "Discussion_Page" -- par défaut les explications sont sur les pages de discussion de l'espace Page
	
	if not index or index == "" then
		return "Le nom du livre n’a pas été donné."	
	end
	
	-- on change le nom de la section des corrections si besoin
	if args[2] ~= nil and args[2] ~= "" then
		section = args[2]	
	end
	
	-- si on souhaite récupérer la liste des corrections
	-- directement avec le modèle {{corr}}
	if args.avec ~= nil and args.avec == "corr" then
		NS = "Page"
	end
	
	local l = mw.title.new(index, "Media")
	if l.exists then
		local pagelist = p.get_pagelist(index)
		local npages = #l.file.pages
		if npages then
			local i=1 -- page du fichier
			local n=1 -- page en fonction du décalage
			local nt= nil
			local pn = nil
			local page = nil
			
			while (i<=npages) do
				pn = pagelist["p"][tostring(i)]
				if pn ~= nil then
					if tonumber(pn) ~= nil then
						n = tonumber(pn)
						nt=n
					else 
						nt = pn
					end
				else
					nt=n
				end
				
				for _, r in ipairs( pagelist["r"] ) do
					if i>= r[1] and i<=r[2] then
						nt=p.int2roman(n)
					end
				end
				
				page = mw.title.new(index.."/"..i, NS)
				local content = page:getContent()
				-- BUG limite 500 appels (cf Sujet:Unmn96gkz9zox8uh)
				-- NE PAS UTILISER page.exists ci dessous, cette fonction coûteuse
				-- incrémente $wgExpensiveParserFunctionLimit et bloque le script à la 501ème page
				-- au lieu de cela, on teste si son contenu est différent de nil (la page n'existe pas) ou vide
				-- problème : la page est enregistrée comme une transclusion
				if content ~= nil and content ~="" then
					local corr = nil
					if NS == "Page" then
						corr = p.get_corr(content)
					else
						corr = frame:callParserFunction{ 
							name = '#lst:'..page.fullText , 
							args = { section } 
						}
					end
					
					if (corr ~= "" and corr ~= nil) then
						local tr =  mw.html.create( 'tr' )
						local td_page = mw.html.create( 'td' )
						local td_corr = mw.html.create( 'td' )
						local expl_txt = ""
						
						if NS == "Page" then
							-- on cherche si {{CorrBandeau}} est utilisé dans la page
							local explications = string.find(content, "{{[Cc]orrBandeau}}")
							if explications == nil then 
								-- on cherche si {{CorrDiscussion}} est utilisé dans la page de discussion
								page_d = mw.title.new(index.."/"..i, "Discussion_Page")
								content_d = page_d:getContent()
								if content_d ~= nil then
									explications = string.find(content_d, "{{[Cc]orrDiscussion")
								end
							end
							if explications ~= nil then 
								expl_txt = ' <sup>([[Discussion_Page:'..page.text..'|expl.]])</sup>'
							end
						end
						
						td_page:wikitext("'''Page [["..page.fullText.."|"..nt.."]]'''"..expl_txt.." :")
						       :css("padding","0.5em 0.5em 0 0")
						       :css("white-space","nowrap")
						
						if NS == "Page" then
							if corr == false then
								corr = frame:expandTemplate{ 
									title = 'rouge' , 
									args = { frame:preprocess('Une erreur avec un modèle {{m|corr}} a été détectée sur cette page.') } 
								}
								td_corr:wikitext(corr)
							else
								for _, c in ipairs(corr) do
										-- le deuxième argument peut contenir du wikicode
										local cm = frame:expandTemplate{ 
											title = 'CorrDiscussion' , 
											args = { c[1], frame:preprocess(c[2]), nombre=c[3] } 
										}
									td_corr:node(cm)
								end
							end
						else
							td_corr:wikitext(corr)
						end
						
						tr:node(td_page):node(td_corr)
						  :css("vertical-align","top")
						corrections:node(tr)
						total = total +1
					end
				end
				i = i+1
				n = n+1
			end
			
			if total > 0 then
				if next(pagelist["p"]) ~= nil then
					out:wikitext("''Les informations relatives aux pages (numéro, libellé) correspondent à ceux de la balise <pagelist/> provenant de [[Index:"..index.."|l’index]].''")
				else
					out:wikitext("''Les numéros de page correspondent à ceux du fichier.''")
				end
				if NS == "Page" then
					local mc = frame:expandTemplate{ title = 'm', args = {'corr'} }
					out:wikitext("<br/>''La liste des corrections est dressée à partir des modèles "..mc.." utilisés.''")
				end
				out:node(corrections)
				return out 
			else
				return "''Aucune correction n’a été apportée à ce livre."
			end
		end
	else
		return "Le livre « [[Livre:"..index.."|"..index.."]] » n’existe pas."	
	end
	
end

-- Récupère les différents <pagelist/> sur la page d'index
-- @param index string : nom de l'index sans le préfixe
-- @return array : tableau contenant les décalages (9=3) et libellés (2=TdM) des différents <pagelist/> 
function p.get_pagelist(index)
	local page = mw.title.new(index, "Index")
	local content = page:getContent()
	local pages = {}
	local roman={}
	for pl in string.gmatch(content, "<pagelist[^>]+/>") do 
		-- récupère et stocke la valeur la page (9=3, 2=Tdm,...)
		for pi,pv in string.gmatch(pl, "%s([1-9][0-9]*)=([^%s/]+)") do
			pages[pi]=mw.text.trim( pv, '"' ) -- enlève les "" en début et fin de chaine
		end
		-- récupère les pages devant apparaître comme des nombres romains
		for fr,to in string.gmatch(pl, "([1-9][0-9]*)to([1-9][0-9]*)=roman") do
			table.insert( roman, {tonumber(fr),tonumber(to)} ) 
		end
	end
	return {["p"]=pages,["r"]=roman}
end

-- Récupère tous les modèles {{corr}} sur une page.
-- Attention, le deuxième argument du modèle corr peut contenir un autre modèle
-- @param c string : contenu de la page
-- @return array|nil : tableau contenant les valeurs des corr, nil si aucun corr
function p.get_corr(c)
	local corr = {}
	local init= 1
	while true do
		p_start,p_end = mw.ustring.find(c, "{{[Cc]orr%|", init)
		-- si le motif n'est plus dans la chaine on stop la recherche
		if p_start == nil then break end
		-- on récupère ce qui est après le motif
		local after_p = mw.ustring.sub(c, p_end+1)
		-- on recherche la fin réelle du modèle
		-- correspond à 0 par addition et soustraction de { et }
		local corr_i = 2; -- les deux déjà dans le motif
		local corr_args = nil
		for i = 1, #after_p do
		    local char = mw.ustring.sub(after_p,i,i)
		    if char == "{" then 
		    	corr_i = corr_i+1
		    elseif char == "}" then
		    	corr_i = corr_i-1
		    end
		    if corr_i == 0 then
		    	corr_args = mw.ustring.sub(after_p,1,i-2)
		    	break
		    end
		end
		
		if corr_args ~= nil then
	    	local fist_pipe_pos = mw.ustring.find(corr_args, "|", 1, true)
	    	if fist_pipe_pos ~= nil then
		    	local corr_arg1 = mw.ustring.sub(corr_args,1,fist_pipe_pos-1)
		    	local corr_arg2 = mw.ustring.sub(corr_args,fist_pipe_pos+1)
		    	-- si la correction est multiple on ne la stocke qu'une fois
				local m = false
				for i, v in ipairs(corr) do
					if corr_arg1==v[1] and corr_arg2==v[2] then
						corr[i][3] = v[3]+1
						m=true
					end
				end
				if not m then
					table.insert(corr, {corr_arg1, corr_arg2, 1})
				end
			else
				return false -- erreur
			end
	    end
		init = p_end -- reprend la recherche à la fin du motif
	end
	if #corr == 0 then return nil else return corr end
end

-- Transforme un entier (5) en nombre romain minuscule (v)
-- honteusement copié de https://www.rosettacode.org/wiki/Roman_numerals/Encode#Lua
-- Module:MathRoman ne semble pas fonctionner
-- @param s integer|string : entier à transformer
-- @return string : nombre romain
function p.int2roman(s)
    romans = {
		{1000, "M"},
		{900, "CM"}, {500, "D"}, {400, "CD"}, {100, "C"},
		{90, "XC"}, {50, "L"}, {40, "XL"}, {10, "X"},
		{9, "IX"}, {5, "V"}, {4, "IV"}, {1, "I"} 
    }

	s = tonumber(s) -- donne nil si s n'est pas un nombre
	if not s then return s end -- renvoit nil
	
	out = ""
	for _, v in ipairs(romans) do --note that this is -not- ipairs.
	  val, let = unpack(v)
	  while s >= val do
	    s = s - val
		out = out .. let
	  end
	end
	return string.lower(out)
end

return p