মডিউল:WikidataF/Dates
এই মডিউলের জন্য মডিউল:WikidataF/Dates/নথি-এ নথিপত্র তৈরি করা হয়ে থাকতে পারে
-- sert à récupérer des données usuelles sur Wikidata (les fonctions élémentaires pour l'extraction des données se fait sur Module:Wikidata
-- ce module peut-être appelé par Module:InfoboxBuilder/Helpers qui les met en infobox
local wikidata = require( 'Module:Wikidata')
local formatdate = require( 'Module:Date')
local p = {}
function p.keydate( event, item, formatting ) -- récupère les valeurs contenues dans des qualificatifs, logique assez différente de pour les propriété principales
if event == 'all' then event = nil end
if not formatting then formatting = {} end -- pour ne pas avoir à vérifer à chaque fois que la table existe
local claims = wikidata.getClaims({property = 'p793', targetvalue = event})
if not claims or not claims[1] then
return nil
end
local datelist = {} -- crée une liste d'objets dateobject et daterange
--[[accepte plusieurs date pour un même événement, mais doivent être dans des déclarations distinctes
note: les tables Wikidata on une clé 0 #table n'est donc pas fiable ]]--
for i, j in pairs(claims) do
local qualif = j.qualifiers
if not j.qualifiers then break end
local label = mw.wikibase.label( "Q" .. j.mainsnak.datavalue.value['numeric-id'])
if qualif['p805'] then -- dedicated item - create a link
dedicated = 'Q' .. qualif['p805'][0].datavalue.value['numeric-id']
link = mw.wikibase.sitelink( dedicated )
if not link then link = 'wikidata:' .. dedicated end
label = '[[' .. link .. '|' .. label .. ']]'
end
if qualif['p585'] and not qualif['p585'][1] then
object = qualif['p585'][0].datavalue.value
object.label = label
object = p.dateobject(object)
table.insert(datelist, object)
elseif qualif['p580'] and qualif['p582'] and not qualif['p580'][1] and not qualif['p582'][1] then
begin = p.dateobject(qualif['p580'][0].datavalue.value)
ending = p.dateobject(qualif['p582'][0].datavalue.value)
object = p.daterange(begin, ending, label)
table.insert(datelist, object)
elseif qualif['p580'] and not qualif['p580'][1] then
begin = p.dateobject(qualif['p580'][0].datavalue.value)
ending = nil
object = p.daterange(begin, ending, label)
table.insert(datelist, object )
elseif qualif['p582'] and not qualif['p582'][1] then
begin = nil
ending = p.dateobject(qualif['p582'][0].datavalue.value)
object = p.daterange(begin, ending, label)
table.insert(datelist, object)
end
end
table.sort(datelist, function(a,b) return a.timestamp < b.timestamp end)
for i, j in pairs(datelist) do
datelist[i] = p.objecttotext(j, formatting)
end
return mw.text.listToText(datelist, formatting.separator, formatting.conjunction)
end
function p.keydatewithfallback(event, fallback)
local firstevent = p.keydate(event)
if firstevent then
return firstevent
end
if not fallback then
return nil
end
local eventlist = {} -- liste tous les événement pertinents (créer une option pour ne retourner que le premier dans la liste ?)
for i, j in pairs(fallback) do
local current = p.keydate(j)
if current and current ~= '' then
table.insert(eventlist, wikidata.formatEntityId(j) .. ' : ' .. current)-- indique le nom du l'événement pour éviter les imprécisions
end
end
return mw.text.listToText(eventlist)
end
function p.from(d) -- retourne "à partir de date" en langage naturel
if d.year then year = d.year end
if d.month then month = d.month end
if d.day then day = d.day end
if day then
return 'à partir du ' .. datestring
elseif tonumber(month) == 4 or tonumber(month) == 8 or tonumber(month) == 10 then -- mois commençant par une voyelle
return 'à partir d\'' .. datestring
else return
'à partir de ' .. datestring
end
end
function p.todate(d) -- retourne "jusqu'à date' en langage naturel
local year = d.year
local month = d.month
local day = d.day
local datestring = d.datestring
if day then
return 'jusqu\'au ' .. datestring
else return
'jusqu\'à' .. datestring
end
end
function p.rangetotext(begin, ending)
if not begin or not ending then return error end
local beginstring = begin.datestring
local endstring = ending.datestring
if begin.day then day1 = begin.day end
if begin.month then month1 = begin.month end
if begin.year then year1 = begin.year end
if ending.day then day2 = ending.day end
if ending.month then month2 = ending.month end
if ending.year then year2 = ending.year end
if year1 and year2 and (year1 == year2) then -- évite de répéter l'année si c'est deux fois la même
return formatdate.modeleDate({day1, month1}) .. '-' .. endstring
else
return beginstring .. '-' .. endstring
end
end
function p.dateobject(orig) --prend une table de date Wikibase, et la retourne sous un format plus manipulable
local label = orig.label
local timestamp = orig.time
local precision = orig.precision
local era = '+' -- (after Christ)
if string.sub(timestamp,1,1) == '-' or string.sub(timestamp,2,12) == '00000000000' then -- Before Christ or year 0 (see datamodel)
era = '-'
end
local year = nil
local datestring = ''
local calendar = 'gregorian' -- calendar for display, not storage
if orig.calendarmodel == 'http://www.wikidata.org/entity/Q1985786' then
calendar = 'julian'
end
if precision == 7 or precision == 8 then
-- texte spécial pour précision = décennie
--[[ noter que précision = "decade" sur Wikidata, l'équivalenet GUI de precision == 8, ne veut pas forcément dire une décennie ronde
1957, precision = 8 est affiché comme 1950s sur Wikidata, mais il parait préférable de l'afficher comme "vers 1957"
mais que faire pour precision == 7 ?
]]
if mw.ustring.len(timestamp) ~= 28 then -- catégorie temporaire à cause d'un bug wikidata
return {type='dateobject', datestring = [[Catégorie:Date Wikidata au mauvais format]], datestring = datestring}
end
local decade = string.sub(timestamp, 9, 12)
if era == '-' then -- remove one Year for BC years because of year 0
decade = tostring(tonumber(decade) + 1)
end
if string.find(decade, '0') == 1 then -- enlève les zéros au début, à corriger pour enlever 2 zéros si besoin
decade = string.sub(decade, 2, 4)
end
datestring = 'vers ' .. decade
return {type='dateobject', timestamp = timestamp, era= era, calendar=calendar, label=label, datestring = datestring}
end
if precision >= 9 then
year = string.sub(timestamp, 9, 12)
if era == '-' then -- remove one Year for BC years because of year 0
year = tostring(tonumber(year) + 1)
end
end
local month = nil
if precision >= 10 then
month = string.sub(timestamp, 14, 15)
end
local day = nil
if precision >= 11 then
day = string.sub(timestamp, 17, 18)
end
if calendar == 'julian' then
year, month, day = formatdate.gregorianToJulian( era .. year, month, day )
end
datestring = formatdate.modeleDate({day, month, year})
return {type='dateobject', timestamp = timestamp, year=year, month=month, day=day, era= era, calendar=calendar, label=label, datestring = datestring}
end
function p.daterange(date1, date2, label)
if date1 then
if date1.type ~= 'dateobject' then return error end
end
if date2 then
if date2.type ~= 'dateobject' then return error end
end
if date1 and date2 then
if date1.timestamp > date2.timestamp then return error end -- ne pas inverser les dates, c'est sans doute un erreur
end
if date1 then timestamp = date1.timestamp else timestamp = date2.timestamp end
return {type='daterange', timestamp = timestamp, begin = date1, ending = date2, label = label}
end
function p.objecttotext(object, formatting)
text = ''
if object.type == 'dateobject' then
text = text .. object.datestring
elseif object.type == 'daterange' then
if object.begin and object.ending then
text = text .. p.rangetotext(object.begin, object.ending)
elseif object.begin then
rtext = text .. p.from(object.begin)
elseif object.ending then
text = text .. p.todate(object.ending)
end
else
return error
end
if formatting and formatting.showlabel == 'true' then
text = text .. ' : ' .. object.label
end
return text
end
function p.duration(range)
if not range.begin and range.ending then
return nil
else
a, b = range.begin, range.ending
end
return formatdate.age(a.year, a.month, a.day, b.year, b.month, b.day)
end
return p