Module:Date républicaine

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

local p = {}
local Outils = require( 'Module:Outils' )
local trim = Outils.trim
local OutilsDates = require( 'Module:Date' )
local modeleDate = OutilsDates.modeleDate

local type_romains = "[IVXL]+"
local type_nombre = "[0-9]+"
local type_1er = "1er"
local type_jour_complementaire = "[1-6]e%*?%-? [Jj]our compl[eé]mentaire"

-- Table des libellés à afficher pour 1er, 2e, 3e, 4e, 5e, 6e
local infobulle = {
	["1er"] = "Premier",
	["2e"] = "Deuxième",
	["3e"] = "Troisième",
	["4e"] = "Quatrième",
	["5e"] = "Cinquième",
	["6e"] = "Sixième"
}

-- Table des noms des mois républicains, avec la casse de la première lettre et les erreurs acceptables
local listeNomsMois = {
	{"vendémiaire", "vendémiaire"},
	{"vendemiaire", "vendémiaire"},
	{"Vendémiaire", "vendémiaire"},
	{"Vendemiaire", "vendémiaire"},
    {"brumaire", "brumaire"},
    {"Brumaire", "brumaire"},
    {"frimaire", "frimaire"},
    {"Frimaire", "frimaire"},
    {"nivôse", "nivôse"},
    {"nivose", "nivôse"},
    {"Nivôse", "nivôse"},
    {"Nivose", "nivôse"},
    {"pluviôse", "pluviôse"},
    {"pluviose", "pluviôse"},
    {"Pluviôse", "pluviôse"},
    {"Pluviose", "Pluviôse"},
    {"ventôse", "ventôse"},
    {"ventose", "ventôse"},
    {"Ventôse", "ventôse"},
    {"Ventose", "ventôse"},
    {"germinal", "germinal"},
    {"Germinal", "germinal"},
    {"floréal", "floréal"},
    {"floreal", "floréal"},
    {"Floréal", "floréal"},
    {"Floreal", "floréal"},
    {"prairial", "prairial"},
    {"Prairial", "prairial"},
    {"messidor", "messidor"},
    {"Messidor", "messidor"},
    {"thermidor", "thermidor"},
    {"Thermidor", "thermidor"},
    {"fructidor", "fructidor"},
    {"Fructidor", "fructidor"},
    {"jour complémentaire", "jour complémentaire"},
    {"jour complementaire", "jour complémentaire"},
    {"Jour complémentaire", "jour complémentaire"},
    {"Jour complementaire", "jour complémentaire"}
}

-- Table des noms des mois républicains, avec la casse de la première lettre et les erreurs acceptables
local listeOrdreMois = {
	["vendémiaire"] = 1,
    ["brumaire"] = 2,
    ["frimaire"] = 3,
    ["nivôse"] = 4,
    ["pluviôse"] = 5,
    ["ventôse"] = 6,
    ["germinal"] = 7,
    ["floréal"] = 8,
    ["prairial"] =9,
    ["messidor"] = 10,
    ["thermidor"] = 11,
    ["fructidor"] = 12,
    ["jour complémentaire"] = 13
}

-- Liste des jours complémentaires
local listeJoursComplementaires = {
	{"jour de la vertu", 1},
	{"Jour de la vertu", 1},
    {"jour du génie", 2},
    {"Jour du génie", 2},
    {"jour du travail", 3},
    {"Jour du travail", 3},
    {"jour de l'opinion", 4},
    {"Jour de l'opinion", 4},
    {"jour des récompenses", 5},
    {"Jour des récompenses", 5},
    {"jour de la Révolution", 6},
    {"Jour de la Révolution", 6},
    {"jour de la révolution", 6},
    {"Jour de la révolution", 6}
}

-- Table temporaire pour éviter les requêtes de test d'existence des articles.
-- Liste des articles existants sur les mois/année, à remplacer par un table externe
local listeArticlesMois = {
    ["floréal an LXXIX"] = true,
    ["prairial an LXXIX"] = true,
	["vendémiaire an II"] = true
}
   
-- liste des chiffres romains pour contrôle mise en forme de l'infobulle
local listeRomains = {	["I"] = "1",
	["II"] = "2",
	["III"] = "3",
	["IV"] = "4",
	["V"] = "5",
	["VI"] = "6",
	["VII"] = "7",
	["VIII"] = "8",
	["IX"] = "9",
	["X"] = "10",
	["XI"] = "11", 
	["XII"] = "12",
	["XIII"] = "13",
	["XIV"] = "14",
	["XXVI"] = "26",
	["XXVII"] = "27",
	["LXXIX"] = "79"
}

-- extrait une chaîne de caractère (jour, mois ou année) du type passé en paramètre (string ou pattern),
-- en restituant :
-- § la chaîne exacte obtenue
-- § l'argument de départ délesté de cette chaîne
-- § un booléen indiquant la présence d'un indicateur d'affichage de l'éléments (-)
-- § un booléen indiquant la présence d'un indicateur de mise en place d'un lien sur l'élément (*)
function p.extraction_argument (argument, chaine)
	local x, position = 0, 0
	local lien, afficher = true, true
	local extrait = ''
	local chaine2 = ''
 	position = mw.ustring.find (argument, chaine)
 	if position	then
 		chaine2 = mw.ustring.match(argument, chaine)
	  	x = position + mw.ustring.len(chaine2)
	 	if x < (mw.ustring.len(argument) + 1) then
	 		if mw.ustring.sub(argument, x, x) == '*' then
	 			lien = false
	 			x=x+1
	 		else
	 			if mw.ustring.sub(argument, x, x) == '-' then
	 				afficher = false
	 				x=x+1
	 			end
	 		end
	 	end
	 	extrait = mw.ustring.sub(argument, position, x - 1)
		argument = mw.ustring.sub(argument, 1, position - 1)..mw.ustring.sub(argument, x)
	end
		
	return argument, extrait, afficher, lien
 end
 	
-- Extraction d'éventuels jour, mois et année du calendrier républicain.
--
-- Le paramètre en entrée est sous la forme d'une chaîne, le séparateur étant l'espace
-- l'année doit être en chiffres romains
-- "an" peut être omis devant l'année ;
--         si l'affichage de l'année seul est demandé, "an" sera omis également à l'affichage
--               Ce cas est utile pour les formes : ans I, II et III
-- sont acceptés : an, An, de l'an, de l'An, de l’an, de l’An
-- le jour doit être numérique, "er" est accepté pour le premier jour de chaque mois
-- les paramètres peuvent être présentés dans n'importe quel ordre
-- les mois doivent être orthographiés correctement, mais les accents peuvent être omis
-- La majuscule n'est prise en compte que pour les nots possiblement en début de phrase :
--   § le mois est affiché et il n'y a pas de numéro de jour devant
--   § l'année est affichée et il n'a a pas d'autre élément devant
function p.test_argument (argument)
	local tab = { test = true,
					message = '',
					quantieme = '',
					exposant_jour = '',
					test_quantieme = false,
					test_jour_complementaire = false,
					mois = '',
					test_mois = false,
					an = '',
					test_an = false,
					lien_jour = true,
					lien_mois = true,
					lien_an = true,
					afficher_jour = true,
					afficher_mois = true,
					afficher_an = true,
					jour_saisi = '',
					complementaire_saisi = '',
					mois_saisi = '',
					an_saisi = '',
					libelle_an = ''
					}
	local position = 0

-- On remplace les éventuels espaces insécables par des espaces simples pour simplifier le traitement qui suit
	argument = argument
		-- nbsp
		:gsub( '\194\160', ' ' )
		:gsub( '&nbsp;', ' ' )
		:gsub( '&#160;', ' ' )
		-- narrow nbsp
		:gsub( '\226\128\175', ' ' )
		:gsub( '&#8239;', ' ' )
		-- thin space
		:gsub( '\226\128\137', ' ' )
		:gsub( '&thinsp;', ' ' )
		:gsub( '&#8201;', ' ' )
		-- simple space
		:gsub( '&#32;', ' ' )
					
-- On retire l'éventuel "er" de "1er" pour simplifier le traitement qui suit
    if argument:match (type_1er) then
		argument=argument:gsub('1er', '1')
	end

-- On recherche si c'est sous la forme "6e jour complémentaire" pour écarter le "e"
	if mw.ustring.find(argument, type_jour_complementaire) then
		tab.exposant_jour = 'e'
		position = mw.ustring.find (argument, type_jour_complementaire)
		if position	then
			if position == 1 then
				argument=mw.ustring.sub(argument, 1, 1)..mw.ustring.sub(argument, 3)
			else
				argument=mw.ustring.sub(argument, 1, position)..mw.ustring.sub(argument, position + 2)
			end
		end
	end

-- On recherche le mois, s'il existe il est retiré de la chaîne de caractère analysée
	for _, nomMois in ipairs( listeNomsMois ) do
 		if mw.ustring.find (argument, nomMois[1]) then
 			argument, tab.mois_saisi, tab.afficher_mois, tab.lien_mois = p.extraction_argument (argument, nomMois[1])
			tab.mois = nomMois[2]
			tab.test_mois = true
  			break
 		end
	end

-- On recherche s'il s'agit d'un des six "jours complémentaires", si c'est le cas il est retiré de la chaîne de caractère analysée
-- On conserve le libellé du jour
	for _, jourComplementaire in ipairs( listeJoursComplementaires ) do
		if mw.ustring.find (argument, jourComplementaire[1]) then
 			argument, tab.complementaire_saisi, tab.afficher_jour, tab.lien_jour = p.extraction_argument (argument, jourComplementaire[1])
			tab.test_jour_complementaire = true
			tab.quantieme = tab.complementaire_saisi
			if not(tab.afficher_jour and tab.lien_jour) then
				tab.quantieme = mw.ustring.sub (tab.quantieme, 1, mw.ustring.len(tab.quantieme) - 1)
			end
			break
		end
	end
	
-- On recherche le jour en chiffres. Si on le trouve, il est retiré de la chaîne analysée
	if argument:match (type_nombre)	then
		tab.test_quantieme = true
		tab.quantieme = argument:match (type_nombre)
		if tab.quantieme == '1'	then
			tab.exposant_jour = 'er'
		end
		argument, tab.jour_saisi, tab.afficher_jour, tab.lien_jour = p.extraction_argument (argument, tab.quantieme)
		if (tonumber(tab.quantieme) < 1) or (tonumber(tab.quantieme) > 30) then
			tab.test = false
			tab.message = '<span class="error">le jour doit être compris entre 1 et 30 (' .. tab.quantieme .. ')</span>'
			return tab
		end
	end

-- Si la chaîne analysée est vide, le traitement est terminé 
 	argument=trim(argument)
	if argument	then
-- On extrait l'année, donc on "élimine" les formulations du type "an" ou "de l'an" pour
-- récupérer le numéro d'année en chiffres romains
		argument, tab.libelle_an = p.extraction_argument (argument, "de l[%'’][Aa]n")
		if tab.libelle_an == '' then
			argument, tab.libelle_an = p.extraction_argument (argument, 'An')
			if tab.libelle_an == '' then
				argument, tab.libelle_an = p.extraction_argument (argument, 'an')
			end
		else
			tab.libelle_an = mw.ustring.lower (tab.libelle_an)
		end
-- On vérifie si la chaîne qui reste est une année sous la forme "XX"
		if argument:match (type_romains) then
			tab.test_an = true
			tab.an = argument:match (type_romains)
			argument, tab.an_saisi, tab.afficher_an, tab.lien_an = p.extraction_argument (argument, tab.an)
		end

		if tab.test_an then
			if not listeRomains[tab.an]	then
				tab.test = false
				tab.message = '<span class="error">année hors du calendrier républicain (' .. tab.an .. ')</span>'
				return tab
			end
		end
		argument=trim(argument)
		if argument	then
-- La chaîne n'est pas sous un format attendu, message d'erreur
 		 	tab.test = false
 			tab.message = '<span class="error">format de date incorrect (' .. argument .. ')</span>'
 		end
	end
	return tab
end

-- Mise en forme de l'année affichée
-- § le paramètre année en entrée doit être sous la forme de chiffres romains
-- § le paramètre lien_annee indique si faut formater un lien vers un article de wikipédia
-- § le paramètre libelle_an indique le format de présentation : exemples : "de l'an", "An", etc.
function p.annee_affichee(annee, lien_annee, libelle_an)
	local chaine = ''
	local annee_affichee = ''
	local premier_car = ''
	local avant_an = ''
	local test = true
	local message = ''

	if annee then
-- Vérification de la syntaxe en chiffres romains
		if annee:match(type_romains) then
			if libelle_an then
-- gestion du cas des formats du type "de l'an" pour récupérer la typo (apostrophe) et éviter que
-- le lien porte sur autre chose que "an NN" pour donner "de l'[[an NN]]" et non pas "[[An NN|de l'an NN]]"
				if mw.ustring.sub(libelle_an, 1, 1) == 'd' then
				    annee_affichee = 'an '
  				    avant_an = mw.ustring.sub(libelle_an, 1, 5)
				else
					annee_affichee = libelle_an..' '
				end
			else
				annee_affichee = 'an '
			end
-- Récupération de la valeur affichée dans l'infobulle
			annee_affichee = annee_affichee..'<abbr class="abbr" title="'..listeRomains[annee]..'">'..annee..'</abbr>'
			if lien_annee then
-- Cas particulier de l'an I
				if annee == 'I'	then
					chaine = '[[An I du calendrier républicain|'..annee_affichee..']]'
				else
					chaine = '[[An '..annee..'|'..annee_affichee..']]'
				end
			else
				chaine = annee_affichee
			end
			chaine = avant_an..chaine
			return test, chaine
		end
	else
		test = false
		message = '<span class="error">aucune année passée en paramètre (annee_affichee)</span>'
		return test, message
	end
end

-- Fonction calculant une date du calendrier grégorien à partir d'une date du calendrier républicain
function p.conversion_Gregorien (jour, mois, an)
-- table du nombre de jour écoulé depuis le début de l'année jusqu'au premier de chaque mois du calendrier grégorien
-- (sans tenir compte des années bissextiles)
	local rang_mois_Greg = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }
	local x = 0
	local jour_Rep, mois_Rep, an_Rep, jour_Greg, mois_Greg, an_Greg = '', '', '', '', '', ''
	local test = true
	local message = ''

-- Fonction permettant de connaître le nombre de jours bissextiles entre deux années
    local function nb_jours_complement_bissextile (an)
    	local nb = 0
    	for i = 1792, 1791+an do
    		if  OutilsDates.isLeapYear(i) then
    			nb = nb + 1
    		end
    	end
    	return nb
    end
    
-- Si la date se présente sous la forme "nom de jour complémentaire an XX", on détermine le rang chronologique du jour en question 
	if (mois == 'jour complémentaire') and (jour:match('^[Jj]our')) then
		for _, jourComplementaire in ipairs( listeJoursComplementaires ) do
			if jourComplementaire[1] == jour then
				jour_Rep = jourComplementaire[2]
				break
			end
		end
	else
		jour_Rep = tonumber(jour)
	end

-- Valeurs numériques de l'année et du mois républicains				
	an_Rep = tonumber(listeRomains[an])
	mois_Rep = listeOrdreMois[mois]

-- contrôles ?
--	if not (an_Rep < 14) and not (mois_Rep < 4)
--	then
--		if not (an_Rep == 79)
--		then
--			return false, 'Pas de conversion pour les dates non officielles'
--		end
--	end
	
-- On détermine le nombre de jour entre la date transmise et le 1er janvier 1792. On connaît le nombre de jour entre le 1er janvier
-- et le 22 septembre 1792, première journée du calendrier républicain : 265
-- On multiplie le nombre d'années écoulées avant l'année en cours par 365, et on ajoute un jour par année sextile (pour les périodes considérées,
-- durant lesquelles ce calendrier a été officiel, tous les quatre ans à partir de l'an III).
-- On multiplie le nomdre de mois écoulés avant le mois en cours par 30
-- On ajoute le quantième du jour transmis ou calculé
	jour_Greg = 365*(an_Rep -1) + 30*(mois_Rep - 1) + jour_Rep + math.floor(an_Rep/4) + 265
	
-- On ajoute le résultat de la division de la partie entière du nombre de jours trouvé par la durée d'une année,
-- en tenant compte des années bissextiles comprises dans la période
	an_Greg = 1792 + math.floor((jour_Greg - nb_jours_complement_bissextile (an_Rep)-1)/365)
	
-- On calcule le reste de jours en tenant compte des années bissextiles
-- (une toutes les 4 ans sauf celles qui sont divisibles par 4 et par cent mais pas par 400)
	jour_Greg = jour_Greg - (an_Greg-1792)*365 - math.floor((an_Greg-1789)/4) + math.floor(an_Greg/1801) + math.floor(an_Greg/1901)
	
-- On détermine le mois correspondant au résultat
	local n = 1
	local m = 1
	local r = 0
	local bissextile = OutilsDates.isLeapYear(an_Greg)
	for i = 1, 12 do
		r = rang_mois_Greg[i]
-- Prise en compte d'un éventuel 29 février (années bissextiles, via isLeapYear(year) du module Date)
		if bissextile then
			if i > 2 then
				r = r + 1
			end
		end
		if not(r < jour_Greg) then
			i = 12
		else
			n = r
			m = i
		end
	end
	
	mois_Greg = m
	jour_Greg = jour_Greg - n
	
	return test, message, jour_Greg, mois_Greg, an_Greg

end

-- Contrôle et mise en forme
function p._date_republicaine (aucun_lien, args)
	local tab = { test = true,
					nocat = false,
					message = '',
					quantieme = '',
					exposant_jour = '',
					test_quantieme = false,
					test_jour_complementaire = false,
					mois = '',
					test_mois = false,
					an = '',
					test_an = false,
					lien_jour = true,
					lien_mois = true,
					lien_an = true,
					afficher_jour = true,
					afficher_mois = true,
					afficher_an = true,
					jour_saisi = '',
					complementaire_saisi = '',
					mois_saisi = '',
					an_saisi = '',
					libelle_an = ''
					}
	local test_conversion, test_conversion_sans_lien = false, false
	local conv_jour_mois, conv_jour, conv_an, conv_mois_an = false, false, false, false
	local deux_points = false
	local parametres, chaine = '', ''

-- Test pour ne pas catégoriser les pages indésirables dans les catégories spéciales de maintenance
	if args.nocat then
		if args.nocat == '' then
			tab.nocat = true
		end
	end
-- § Les paramètres peuvent se présenter sous la forme d'une seule chaîne ou de 3 paramètres séparés.
-- Dans ce dernier cas, on constitue une chaîne en utilisant l'espace comme séparateur, ce qui permet un traitement unique pour les 2 cas
-- § Si "conversion" ou "grégorien" est spécifié, on stocke l'info mais on ne l'inclut pas dans la chaîne ; il faut en plus
-- vérifier :
-- §§ si * est présisé (dans ce cas, pas de liens sur la date grégorienne convertie)
-- §§ si le caractère ":" apparaît, pour savoir si le séparateur est ":", sinon ce sont des parenthèes
-- §§ si une des séquences "jm", "j", "ma" ou "a" sont présentes, pour déterminer quels éléments de la date grégorienne
--           doivent être affiché (j=jour, m=mois, a=an)
	for i = 1, 4 do
		if args[i] then
			if (mw.ustring.match (args[i], '[Kk]onvèsyon')) or (mw.ustring.match (args[i], '[Gg]regoryen')) then
				if not mw.ustring.match (args[i], 'jma') then
					if mw.ustring.match (args[i], 'jm') then
						conv_jour_mois = true
					elseif mw.ustring.match (args[i], 'j') then
						conv_jour = true
					elseif mw.ustring.match (args[i], 'ma') then
						conv_mois_an = true
					elseif mw.ustring.match (args[i], 'a') then
						conv_an = true
					end
				end
				if mw.ustring.match (args[i], ':') then
					deux_points = true
				end
				if mw.ustring.match (args[i], '%*') then
					test_conversion_sans_liens = true
				else
					test_conversion = true
				end
			else
				parametres = parametres..args[i]..' '
			end
		end
	end

 	if parametres then
 		tab = p.test_argument (parametres)
 	else
 		tab.test = false
 		tab.message = p.categorie_erreur (tab.nocat, '<span class="error">Aucun paramètre transmis</span>')
 		return tab.message
 	end

-- Contrôle sur le nombre de jours si c'est un jour complémentaire
	if tab.mois and tab.quantieme then
		if (tab.mois == 'jour complémentaire') then
			if (tonumber(tab.quantieme) > 6) then
				tab.test = false
				tab.message = '<span class="error">Il n\'y a que 6 jours complémentaires au maximum (' .. tab.quantieme .. ')</span>'
			else
				if tab.an then
					if (tonumber(tab.quantieme) == 6) and not ((tab.an == 'III') or (tab.an == 'VII') or (tab.an == 'XI')) then
						tab.test = false
						tab.message = '<span class="error">Il n\'y a que 5 jours complémentaires cette année là (' .. tab.quantieme .. ')</span>'
					end
				end
			end
		end
	end
	
	if not tab.test	then
		tab.message = p.categorie_erreur (tab.nocat, tab.message)
		return tab.message
	end
	
	if aucun_lien then
		tab.lien_jour, tab.lien_mois, tab.lien_an = false, false, false
	end

-- Début de la mise en forme typographique et de l'établissement des liens possibles sur une date du calendrier républicain
-- le paramètre "date_affiche" reçoit les éléments au fur et à mesure de l'analyse
	local date_affichee = ''
	local jour = ''
	local jour_affiche = ''
	local article = ''

-- Si on a le jour mais pas le mois, c'est un cas invalide
	if tab.test_quantieme and not(tab.test_mois) then
		tab.message = p.categorie_erreur (tab.nocat, '<span class="error">date invalide, mois manquant</span>')
		return tab.message
 	else
-- on ne peut pas avoir en même temps un jour complémentaire et un numéro de jour ou un mois
		if (tab.test_quantieme or tab.test_mois) and tab.test_jour_complementaire then
			tab.test = false
			tab.message = p.categorie_erreur (tab.nocat, '<span class="error">date invalide, paramètres incompatibles</span>')
			return tab.message
		end
	end
	
-- Cas où l'année n'est pas spécifiée
	if not tab.test_an then
-- Cas où on a le jour (en chiffres) et le mois
		if tab.test_quantieme and tab.test_mois then
			if tab.afficher_jour then
-- Cas particulier pour la mise en forme de "1er", "2e", etc.
				if not (tab.exposant_jour == '') then
					jour = tab.quantieme..tab.exposant_jour
					jour_affiche = '<abbr class="abbr" title="'..infobulle[jour]..'" >'..tab.quantieme..'<sup>'..tab.exposant_jour..'</sup></abbr>'
				else
					jour = tab.quantieme
					jour_affiche = tab.quantieme
				end
				if tab.lien_jour then
					article = jour..' '..tab.mois
					date_affichee = date_affichee..'[['..article..'|'..jour_affiche..']]'
				else
					date_affichee = date_affichee..jour_affiche
				end
			end
			if tab.afficher_mois then
				if date_affichee == '' then
					tab.mois = string.sub(tab.mois_saisi, 1, 1)..string.sub(tab.mois, 2)
				end
				if tab.lien_mois then
					date_affichee = date_affichee..' [['..tab.mois..']]'
				else
					date_affichee = date_affichee..' '..tab.mois
				end
			end
		else
-- Cas où seul le nom précis d'un des jours complémentaires est présent,
-- si demandé on affiche le lien (les articles sur ces jours existent dans tous les cas)
			if tab.test_jour_complementaire and tab.afficher_jour then
				if tab.lien_jour then
					date_affichee = '[['..tab.quantieme..']]'
				else
					date_affichee = tab.quantieme
				end
			else
-- Cas où seul le mois est présent, si demandé on affiche le lien (les articles sur les mois existent dans tous les cas)
				if tab.test_mois and tab.afficher_mois then
					tab.mois = string.sub(mois_saisi, 1, 1)..string.sub(tab_mois, 2)
					if tab.lien_mois then
						date_affichee = '[['..tab.mois..']]'
					else
						date_affichee = tab.mois
					end
				end
			end
		end
	else
-- Cas où l'année est renseignée

-- Cas des dates sous la forme jour_complémentaire année
-- Traitement du jour
		if tab.test_jour_complementaire and tab.afficher_jour then
			if tab.lien_jour then
-- On vérifie dans la table s'il existe un article dont le lien est de la forme [[jour complémentaire an XX]]
-- Si ce n'est pas le cas, on affiche un lien sur le jour seul
				article = tab.quantieme..' an '..tab.an
				if listeArticlesMois[article] then
					date_affichee = '[['..article..'|'..tab.quantieme..']]'
				else
					date_affichee = '[['..tab.quantieme..']]'
				end
			else
-- Pas de lien demandé
 				date_affichee = date_affichee..tab.quantieme
			end
			if tab.afficher_an then
-- Traitement de l'année
				tab.test, chaine = p.annee_affichee(tab.an, tab.lien_an)
				date_affichee = date_affichee..' '..chaine
			end
		end

-- Cas des dates sous la forme jour mois année
-- Traitement du jour
		if tab.test_quantieme and tab.test_mois	then
			if tab.afficher_jour then
-- Cas particulier pour la mise en forme de "1er", "2e", etc.
				if not (tab.exposant_jour == '') then
					jour = tab.quantieme..tab.exposant_jour
					jour_affiche = '<abbr class="abbr" title="'..infobulle[jour]..'" >'..tab.quantieme..'<sup>'..tab.exposant_jour..'</sup></abbr>'
				else
					jour = tab.quantieme
					jour_affiche = tab.quantieme
				end
				article = jour..' '..tab.mois
-- Si l'index formé par l'ensemble jour-mois existe dans la table, c'est qu'un article wikipédia existe => lien [[jour mois|jour]]
-- Sinon => lien sur le mois seulement (les articles sur les mois existent dans tous les cas)
				if tab.lien_jour then
					date_affichee = '[['..article..'|'..jour_affiche..']]'
				else
					date_affichee = jour_affiche
				end
			end
			if tab.afficher_mois then
				if tab.lien_mois then
					if date_affichee == '' then
						tab.mois = string.sub(tab.mois_saisi, 1, 1)..string.sub(tab.mois, 2)
					end
					article = tab.mois..' an '..tab.an
					if listeArticlesMois[article] then
						date_affichee = date_affichee..' [['..article..'|'..tab.mois..']]'
					else
						date_affichee = date_affichee..' [['..tab.mois..']]'
					end
				else
					date_affichee = date_affichee..' '..tab.mois
				end
			end
					
			if tab.afficher_an then
				if not (date_affichee == '')
				and ((string.upper(string.sub (tab.libelle_an, 1, 1)) == 'A') or (tab.libelle_an == '')) then
					tab.libelle_an = nil
				end
				tab.test, chaine = p.annee_affichee (tab.an, tab.lien_an, tab.libelle_an)
				if not tab.test	then
					return chaine
				else
					date_affichee = date_affichee..' '..chaine
				end
			end
		end
	
-- Cas où il n'y a pas de numéro de jour, date de la forme    mois année
-- On vérifie dans la table s'il existe un article dont le lien est de la forme [[mois an XX]]
-- Si ce n'est pas le cas, on affiche un lien sur le mois seul
		if tab.test_mois and not tab.test_quantieme and tab.afficher_mois then
			if date_affichee == '' then
				tab.mois = string.sub(tab.mois_saisi, 1, 1)..string.sub(tab.mois, 2)
			end
			article = tab.mois..' an '..tab.an
			if tab.lien_mois then
				if listeArticlesMois[article] then
					date_affichee = '[['..article..'|'..tab.mois..']]'
				else
					date_affichee = '[['..tab.mois..']]'
				end
			else
				date_affichee = tab.mois
			end
					
			if tab.afficher_an then
				tab.test, chaine = p.annee_affichee (tab.an, tab.lien_an)
				date_affichee = date_affichee..' '..chaine
			end
		end
-- Cas où on n'affiche que l'année
		if tab.afficher_an and (date_affichee == '') then
			tab.test, date_affichee = p.annee_affichee(tab.an, tab.lien_an, tab.libelle_an)
			if not tab.test then
				date_affichee = p.categorie_erreur (tab.nocat, date_affichee)
				return date_affichee
			end
 	 	end
	end

-- Si la date présente des espaces, on les rend insécables
	if date_affichee:match( ' ' ) then
		date_affichee = '<span class="nowrap">'..date_affichee..'</span>'
	end

-- Mise en forme de l'éventuelle date correspondante dans le calendrier grégorien

-- Cette possibilité est activée par le passage d'une chaine de caractère contenant "conversion" ou "grégorien"
	if test_conversion or test_conversion_sans_liens then
		if ((tab.test_quantieme and tab.test_mois) or tab.test_jour_complementaire) and tab.test_an	then
			if tab.test_jour_complementaire then
				tab.mois = 'jour complémentaire'
			end
			tab.test, tab.message, jour_Greg, mois_Greg, an_Greg = p.conversion_Gregorien(tab.quantieme, tab.mois, tab.an)
			if tab.test	then
-- Si le paramètre contenant la chaine conversion présente le caractère « : » (deux points),
-- le résultat est présenté sous la forme      date républicaine : date gégorienne
-- Sinon, le le résultat est présenté sous la forme      date républicaine (date gégorienne)
				if deux_points then
					date_affichee = date_affichee..' : '
				else
					date_affichee = date_affichee..' ('
				end
-- § La mention facultative de j, jm, a, etc. permet de selectionner ce qui est conservé à l'affichage de la date grégorienne
-- cela permet de faire appel au module date en utilisant les "-" qui masquent l'affichage des éléments non souhaités
-- § conversion* permet d'afficher la date grégorienne sans liens
				if test_conversion_sans_liens then
					if conv_jour_mois then
						date_affichee = date_affichee..modeleDate({jour_Greg, mois_Greg, an_Greg..'-', nolinks="oui"})
					elseif conv_jour then
						date_affichee = date_affichee..modeleDate({jour_Greg, mois_Greg..'-', an_Greg..'-', nolinks="oui"})
					elseif conv_mois_an then
						date_affichee = date_affichee..modeleDate({nil, mois_Greg, an_Greg, nolinks="oui"})
					elseif conv_an then
						date_affichee = date_affichee..an_Greg
					else
	 					date_affichee = date_affichee..modeleDate({jour_Greg, mois_Greg, an_Greg, nolinks="oui"})
	 				end
	 			else
					if conv_jour_mois then
						date_affichee = date_affichee..modeleDate({jour_Greg, mois_Greg, an_Greg..'-', liens="oui"})
					elseif conv_jour then
						date_affichee = date_affichee..modeleDate({jour_Greg, mois_Greg..'-', an_Greg..'-', liens="oui"})
					elseif conv_mois_an then
						date_affichee = date_affichee..modeleDate({nil, mois_Greg, an_Greg, liens="oui"})
					elseif conv_an then
						date_affichee = date_affichee..'[['..an_Greg..']]'
					else
	 					date_affichee = date_affichee..modeleDate({jour_Greg, mois_Greg, an_Greg, liens="oui"})
	 				end
	 			end
	 			if not deux_points then
					date_affichee = date_affichee..')'
				end
	 		else
	 			date_affichee = date_affichee..message
	 		end
	 	else
	 		tab.test = false
			date_affichee = '<span class="error">conversion impossible, date incomplète</span>'
		end
	end
	

			
	if not tab.test then
		date_affichee = p.categorie_erreur (date_affichee)
	end
	
	return date_affichee
end

function p.categorie_erreur (nocat, message)
 	local namespaceCategorisation = { [0] = true, [4] = true, [10] = true, [14] = true, [100] = true }
--	local namespaceCategorisation = { [4] = true }
	if namespaceCategorisation[ mw.title.getCurrentTitle().namespace ] and (nocat=='') then
		return message .. '[[Catégorie:Page avec une erreur de paramètre du modèle Date républicaine]]'
	else
		return message
	end
end

-- Fonction permettant la mie en forme typographique et l'établissement des liens possibles sur une date du calendrier républicain
-- en vigueur en France entre 1792 et 1806 ainsi qu'en 1871 pendant la Commune. Il est également possible de faire afficher
-- la date grégorienne correspondante en indiquant "conversion" en paramètre.
function p.date_republicaine (frame)
	local args = Outils.extractArgs(frame)
	local aucun_lien = false
	
	local chaine = p._date_republicaine (aucun_lien, args)

	return chaine
end

-- Fonction permettant la mie en forme typographique sur une date du calendrier républicain
-- en vigueur en France entre 1792 et 1806 ainsi qu'en 1871 pendant la Commune. Il est également possible de faire afficher
-- la date grégorienne correspondante en indiquant "conversion" en paramètre.
function p.date_republicaine_sans_liens (frame)
	local args = Outils.extractArgs(frame)
	local aucun_lien = true
	
	local chaine = p._date_republicaine (aucun_lien, args)

	return chaine
end

return p