« Module:Date » : différence entre les versions
Contenu supprimé Contenu ajouté
retouche de la modification précédente : classification par valeur de décalage |
modeleDate : séparation des fonctions d'analyse du décalage, d'analyse des paramètres jour, mois, année et de l'affichage de la date. Amélioration de separationJourMoisAnnee. |
||
Ligne 21 :
end
local modelePremier = '<abbr class="abbr" title="premier">1<sup>er</sup></abbr>'
-- liste des mois, écriture exacte et simplifiée, en minuscule
Ligne 192 ⟶ 193 :
---
--
-- la date doit contenir le mois.
function fun.separationJourMoisAnnee( date )
date = trim( date )
if date then
Ligne 199 ⟶ 201 :
return false, Outils.erreur( periode .. ' invalide (' .. valeur .. ')' )
end
local jour, mois, annee, masquerMois, masquerAnnee
-- variable pour construire les regex
local j = '([0-3]?%d)' -- jour
local m = '([01]?%d)' -- mois numérique
local mmm = '([^%s%p%d]+)' -- mois en toute lettre
local aj = '(%-?%d+)' -- année ou jour
local s = '[ ./-]+' -- séparateur simple
local sep = '([ ./-]+)' -- séparateur avec capture, pour le détecter deux fois
local moins = '(%-?)' -- signe moins pour signifier qu'il ne faut pas afficher cette donnée
local regexb = {
jmmm = '^'..j..s..mmm..moins..'$',
mmmjva = '^'..mmm..s..j..', ?'..aj..'$',
}
date = fun.nettoyageJour( date )
-- réduction av. J-C pour simplifier un peu les regex :
date = date:gsub( '(%d+) ?[Aa][Vv]%.? ?[Jj][ .-]*[Cc]%.?', '-%1' )
-- gestion de 1er
date = date:gsub( modelePremier, '1' ):gsub( '%f[%d]1er', '1' )
-- supression de l'heure dans les date ISO
-- test année seule
if date:match( '^'..aj..'$' ) then
annee = date:match( '^'..aj..'$' )
elseif date:match( '^'..aj..s..aj..moins..'$' ) then
--
local a,
a, b = tonumber( a ), tonumber( b )
if a > 12 and ( b < 1 or b > 31 ) or
b > 12 and ( a < 1 or a > 31 ) then
return erreur( 'Date', date )
elseif b < 1 or b > 31 then
mois, annee, masquerAnnee = a, b, sb
elseif b > 12 then
return erreur( 'Mois', b )
else
jour, mois, masquerMois = a, b, sb
end
elseif date:match( '^'..aj..sep..m..moins..'%2'..aj..moins..'$' ) then
-- jj/mm/aaaa ou aaaa/mm/jj
jour, sep, mois, masquerMois, annee, masquerAnnee = date:match( '^'..aj..sep..m..moins..'%2'..aj..moins..'$' )
if sep == '-' and masquerMois == '-' and masquerAnnee == '' and tonumber( annee ) > 0 then
-- date au format jj-mm--aaaa type 17-06--44 pour 17 juin 44 av. JC
masquerMois = nil
annee = 0 - annee
end
elseif date:match( '^'..j..sep..mmm..moins..'%2'..aj..moins..'$' ) then
-- jj mmm aaaa
jour, sep, mois, masquerMois, annee, masquerAnnee = date:match( '^'..j..sep..mmm..moins..'%2'..aj..moins..'$' )
elseif date:match( '^'..mmm..s..aj..moins..'$' ) then
-- mmm aaaa
mois, annee, masquerAnnee = date:match( '^'..mmm..s..aj..moins..'$' )
elseif date:match( '^'..j..s..mmm..moins..'$' ) then
-- jj mmmm
jour, mois, masquerMois = date:match( '^'..j..s..mmm..moins..'$' )
elseif date:match( '^'..mmm..s..j..', ?'..aj..'$') then
-- mmm jj, aaaa (format anglo-saxon)
mois, jour, annee = date:match( '^'..mmm..s..j..', ?'..aj..'$')
elseif date:match( '^'..mmm..'$' ) then
mois = date
else
return erreur( 'Date', date )
end
if ( tonumber( jour ) or 0 ) > 31 and ( tonumber( annee ) or 0 ) < 31 then
-- inversion du jour et de l'année
local temp = annee
annee = jour
jour = temp
end
decalage = decalage or 0
if decalage < 0 then
decalage = decalage + 2
end
args = args or {}
return fun.validationJourMoisAnnee{
jour, mois, annee,
masquerAnnee = trim( masquerAnnee ) and true or nil,
masquerMois = ( trim( masquerAnnee ) or not annee ) and trim( masquerMois ) and true or nil,
-- or nil sert juste à éviter de trainer une valeur false dans tous les tests unitaires.
}
else
return true, {}
end
end
---
-- separationJourMoisAnnee prend jusqu'a cinq paramètre et essaie de les séparer en jour, mois, annee et qualificatif
Ligne 247 ⟶ 299 :
function fun.validationJourMoisAnnee( frame, ... )
local args = Outils.extractArgs( frame, ... )
local jour, mois, numMois, annee
local function erreur( periode, valeur )
return false, Outils.erreur( periode .. ' invalide (' .. valeur .. ')' )
end
-- on traite l'année
if Outils.notEmpty( bannee ) then
annee = tonumber( bannee )
if annee == nil and type( bannee ) == 'string' then
-- test si l'année contient av. J.-C.
annee = string.match( string.upper( bannee ), '^(%d+)
annee = tonumber( annee )
if annee then
annee = 0 - annee
else
return erreur( 'Année', bannee )
Ligne 298 ⟶ 326 :
-- on traite le mois
if Outils.notEmpty( bmois ) then
mois, numMois = fun.determinationMois( bmois )
Ligne 304 ⟶ 331 :
mois = fun.valideSaison( bmois )
if mois == nil then
return erreur( 'Mois', bmois )
end
else
-- on traite le jour si présent
if Outils.notEmpty( bjour ) then
jour = tonumber( bjour )
Ligne 330 ⟶ 347 :
return erreur( 'Jour', bjour )
elseif jour > liste_mois[numMois].nJour then
return erreur( 'Jour', bjour ..
elseif jour == 29 and numMois == 2 and annee and ( math.fmod( annee, 4 ) ~= 0 ) then
-- l'année bisextile sur les siècles est toujours acceptée pour être compatible avec les dates juliennes.
return erreur( 'Jour', '29 février ' .. annee )
end
else
-- S'il n'y a pas de jour on regarde si la première lettre du mois est en majuscule
if
-- oui, on passe la première lettre en majuscule
mois = ucfirst( mois )
Ligne 342 ⟶ 361 :
end
end
else
-- on teste le jour si présent
local bjour = args[1
if Outils.notEmpty( bjour ) then
if annee then
Ligne 356 ⟶ 375 :
jour = nil
else
return erreur( '
end
else
return
end
end
Ligne 365 ⟶ 384 :
end
local resultat = {
jour = jour,
mois = mois,
numMois = numMois,
annee = annee,
masquerAnnee = args.masquerAnnee,
}
return true,
end
function fun.determinationDecalage( args )
local decalage = 0
-- si pas de jour mais que args[2] est un mois on décale tout et on
-- n'affiche pas l'année
local arg1, arg2, arg3 = trim( args[1] ), trim( args[2] ), trim( args[3] )
if arg1 == nil and fun.determinationMois( args[3] ) then
decalage = 1
elseif arg1 == nil and arg2 == nil and arg3 and fun.determinationMois( args[4] ) then
decalage = 2
elseif arg1 == nil and arg2 and arg2:match( '[^ ./-][ ./-]+[^ ./-]' ) then
decalage = 'D'
elseif arg1 and arg3 == nil and ( arg1:match( '[^ ./-][ ./-]+[^ ./-]' ) or arg2 == nil or arg2:match( '[^ ./-][ ./-]+[^ ./-]' ) ) then
-- l'année est dans le premier paramètre
decalage = -2
elseif not tonumber( arg3 ) and fun.determinationMois( arg1 ) then
arg2 = arg2 and arg2:gsub( '%-$', '' )
if tonumber( arg2 ) and tonumber( arg2 ) > 12 then
-- le mois est dans le premier paramètre et l'année dans le deuxième
decalage = -1
end
end
return decalage
end
function fun._modeleDateParam( args, decalage )
local function analyseParam( p )
-- sépare le signe moins final éventuel signifiant que le paramètre ne soit pas être affiché.
p = trim( p )
if p then
local d, s = p:match( '^%-?([^-]*)(%-?)$' )
if s == '-' then
return d, true
end
return d
end
end
local param, resultat, test, mM, mA
if decalage == 0 then
param = { trim( args[ 1 + decalage ] ), }
param[2], mM = analyseParam( args[ 2 + decalage ] )
param[3], mA = analyseParam( args[ 3 + decalage ] )
test, resultat = fun.validationJourMoisAnnee( param )
elseif decalage == -2 then
test, resultat = fun.separationJourMoisAnnee( args[1] )
elseif decalage == 'D' then
test, resultat = fun.separationJourMoisAnnee( args[2] )
mA = true
decalage = -1
else
param = { trim( args[ 1 + decalage ] ), trim( args[ 2 + decalage ] ), trim( args[ 3 + decalage ] ) }
test, resultat = fun.validationJourMoisAnnee( param )
if decalage > 0 then
mA = true
if decalage == 2 then
mM = true
end
end
end
if test then
resultat.qualificatif = trim( args[ 4 + decalage ] )
resultat.masquerAnnee = resultat.masquerAnnee or mA
resultat.masquerMois = resultat.masquerMois or mM
end
return test, resultat
end
---
Ligne 392 ⟶ 474 :
function fun.modeleDate( frame )
local args = Outils.extractArgs( frame )
local decalage = fun.determinationDecalage(args)
local test, resultat = fun._modeleDateParam( args, decalage )
local cat = ''
if
for n, v in pairs( resultat ) do
args[n] = v
end
resultat = fun._modeleDate( args )
if decalage ~= 0 then
decalage = ( decalage == -2 ) and 'P' or decalage
cat = '[[Catégorie:Page utilisant le modèle Date avec un décalage|' .. decalage .. ']]' -- catégorisation temporaire
end
else
local namespaceCategorisation = { [0] = true, [4] = true, [10] = true, [14] = true, [100] = true }
if namespaceCategorisation[ mw.title.getCurrentTitle().namespace ] and not Outils.notEmpty( args.nocat ) then
cat = '[[Catégorie:Page utilisant le modèle date avec une syntaxe erronée]]'
end
end
return ( resultat or '' ) .. cat
end
function fun._modeleDate( args )
local annee, mois, numMois, jour = args.annee, args.mois, args.numMois, args.jour
local qualificatif = args.qualificatif
if ( annee or mois or jour ) == nil then
Ligne 488 ⟶ 581 :
if args.nolinks then
if jour == 1 then
jour = modelePremier
end
wikiListe.insert( jour )
Ligne 509 ⟶ 602 :
-- le mois
if mois then
if #wikiListe == 0 and
return mois
end
if args.nolinks then
if
wikiListe.insert( mois )
end
Ligne 525 ⟶ 618 :
end
end
if lien or
-- s'il y a un lien on retire le lien affichant 'jour mois' pour ajouter '[[mois annee|mois']]
wikiListe.remove()
if
wikiListe.insert( wikiLien( lien, mois ) )
end
elseif #wikiListe > 0 then
-- sinon on retire le lien affichant 'jour' pour ne garder que le lien 'jour mois'
wikiListe.remove( #wikiListe - 1 )
elseif args.masquerAnnee then
--
end
end
Ligne 551 ⟶ 642 :
-- l'année
if annee then
if not args.masquerAnnee then
local
local lien
if args.avJC == 'non' then
texteAnnee = annneeAvJc
else
.. annneeAvJc .. ' avant Jésus-Christ">av. J.-C.</abbr>'
end
end
if args.nolinks then -- seulement si on doit l'affichée
wikiListe.insert( texteAnnee )
lien = existDate( dataQualificatif, annee ) or existDate( dataCat, annee ) or lien or annee
if mois and #wikiListe == 0 then
-- si le mois n'a pas de lien et n'est pas affiché avec le jour, il est affiché avec l'année.
texteAnnee = mois .. ' ' .. texteAnnee
end
wikiListe.insert( wikiLien( lien, texteAnnee ) )
end
end
if gannee > 999 then
iso.insert( 1, gannee )
Ligne 638 ⟶ 726 :
:wikitext( age )
:done()
end
return tostring( wikiHtml )
end
---
|