Wikipedia
diqwiki
https://diq.wikipedia.org/wiki/Pela_Seri
MediaWiki 1.47.0-wmf.7
first-letter
Medya
Xısusi
Werênayış
Karber
Werênayışê karberi
Wikipediya
Werênayışê Wikipediya
Dosya
Werênayışê dosya
MedyaWiki
Werênayışê MedyaWikiyi
Şablon
Werênayışê şabloni
Peşti
Werênayışê peşti
Kategoriye
Werênayışê kategoriye
Portal
Werênayışê portali
TimedText
TimedText talk
Modul
Werênayışê moduli
Event
Event talk
Şablon:Melumatê dewleta Peruy
10
38909
549219
312167
2026-06-23T11:09:20Z
CommonsDelinker
48
Replacing Flag_of_Peru_(state).svg with [[File:War_flag_of_Peru.svg]] (by [[:c:User:CommonsDelinker|CommonsDelinker]] because: [[:c:COM:FR|File renamed]]: [[:c:COM:FR#FR3|Criterion 3]] (obvious error) · This is not the State flag, this is the war flag [ht
549219
wikitext
text/x-wiki
{{ {{{1<noinclude>|country showdata</noinclude>}}}
| alias = Peru
| flag alias = Flag of Peru.svg
| flag alias-1825 = Flag of Peru (1825 - 1950).svg
| flag alias-state = War flag of Peru.svg
| flag alias-naval = War flag of Peru.svg
| link alias-naval = Peruvian Navy
| size = {{{size|}}}
| name = {{{name|}}}
| altlink = {{{altlink|}}}
| variant = {{{variant|}}}
<noinclude>
| var1 = 1825
| var2 = state
| redir1 = PER
</noinclude>
}}
o319fupxuczwxh0xeaqg2a6sq26fxz2
Modul:Wikidata
828
42723
549210
549195
2026-06-22T21:15:13Z
Mirzali
16
549210
Scribunto
text/plain
--script that retrieves basic data stored in Wikidata, for the datamodel, see https://www.mediawiki.org/wiki/Extension:Wikibase_Client/Lua
local wd = {}
local modules = { }
local modulesNames = {
reference = 'Module:Wikidata/Références',
i18n = 'Module:Wikidata/I18n',
globes = 'Module:Wikidata/Globes',
langcodes = 'Module:Dictionnaire Wikidata/Codes langue', -- big, infrequently useda
invertedlangcodes = 'Module:Dictionnaire Wikidata/Codes langue/inversé',
linguistic = 'Module:Linguistique',
formatDate = 'Module:Date complexe',
formatNum = 'Module:Conversion',
langmodule = 'Module:Langue',
cite = 'Module:Biblio',
weblink = 'Module:Weblink'
}
local function loadModule( t, key )
if modulesNames[key] then
local m = require( modulesNames[key] )
t[key] = m
return m
end
end
setmetatable( modules, { __index = loadModule } )
local datequalifiers = {'P585', 'P571', 'P575', 'P580', 'P582', 'P1319', 'P1326'}
-- === I18n ===
local defaultlang = mw.getContentLanguage():getCode()
function wd.translate(str, rep1, rep2)
str = modules.i18n[str] or str
if rep1 and (type (rep1) == 'string') then
str = str:gsub('$1', rep1)
end
if rep2 and (type (rep2) == 'string')then
str = str:gsub('$2', rep2)
end
return str
end
local function addCat(cat, sortkey)
if sortkey then
return '[[Category:' .. cat .. '|' .. sortkey .. ']]'
end
return '[[Category:' .. cat .. ']]'
end
local function formatError( key , category, debug)
if debug then
return error(modules.i18n[key] or key)
end
if category then
return addCat(category, key)
else
return addCat('cat-unsorted-issue', key)
end
end
--
function wd.isSpecial(snak)
return (snak.snaktype ~= 'value')
end
function wd.getId(snak)
if (snak.snaktype == 'value') then
return 'Q' .. snak.datavalue.value['numeric-id']
end
end
function wd.getNumericId(snak)
if (snak.snaktype == 'value') then
return snak.datavalue.value['numeric-id']
end
end
function wd.getMainId(claim)
return wd.getId(claim.mainsnak)
end
function wd.entityId(entity)
if type(entity) == 'string' then
return entity
elseif type(entity) == 'table' then
return entity.id
end
end
function wd.getEntityIdForCurrentPage()
return mw.wikibase.getEntityIdForCurrentPage()
end
-- function that returns true if the "qid" parameter is the qid
-- of the item that is linked to the calling page
function wd.isPageOfQId(qid)
local self_id = mw.wikibase.getEntityIdForCurrentPage()
return self_id ~= nil and qid == self_id
end
function wd.getEntity( val )
if type(val) == 'table' then
return val
end
if val == '-' then
return nil
end
if val == '' then
val = nil
end
return mw.wikibase.getEntity(val)
end
function wd.splitStr(val) -- transforme en table les chaînes venant du Wikitexte qui utilisent des virgules de séparation
if type(val) == 'string' then
val = mw.text.split(val, ",")
end
return val
end
function wd.isHere(searchset, val)
for i, j in pairs(searchset) do
if val == j then
return true
end
end
return false
end
local function wikidataLink(entity)
local name =':d:'
if type(entity) == 'string' then
if entity:match("P[0-9+]") then
entity = "Property:" .. entity
end
return name .. entity
elseif type(entity) == 'table' then
if entity["type"] == "property" then
name = ":d:Property:"
end
return name .. entity.id
elseif type(entity) == nil then
return formatError('entity-not-found')
end
end
function wd.siteLink(entity, project, lang)
-- returns 3 values: a sitelink (with the relevant prefix) a project name and a language
lang = lang or defaultlang
if (type(project) ~= 'string') then
project = 'wiki'
end
project = project:lower()
if project == 'wikipedia' then
project = 'wiki'
end
if type(entity) == 'string' and (project == 'wiki') and ( (not lang or lang == defaultlang) ) then -- évite de charger l'élément entier
return mw.wikibase.sitelink(entity), 'wiki', defaultlang
end
if project == 'wikidata' then
return wikidataLink(entity), 'wikidata'
end
local projects = {
-- nom = {préfixe sur Wikidata, préfix pour les liens sur Wikipédia, ajouter préfixe de langue}
wiki = {'wiki', nil, true}, -- wikipedia
commons = {'commonswiki', 'commons', false},
commonswiki = {'commonswiki', 'commons', false},
wikiquote = {'wikiquote', 'q', true},
wikivoyage = {'wikivoyage', 'voy', true},
wikibooks = {'wikibooks', 'b', true},
wikinews = {'wikinews', 'n', true},
wikiversity = {'wikiversity', 'v', true},
wikisource = {'wikisource', 's', true},
wiktionary = {'wiktionary', 'wikt', true},
specieswiki = {'specieswiki', 'species', false},
metawiki = {'metawiki', 'm', false},
incubator = {'incubator', 'incubator', false},
outreach = {'outreach', 'outreach', false},
mediawiki = {'mediawiki', 'mw', false}
}
local entityid = entity.id or entity
local projectdata = projects[project:lower()]
if not projectdata then -- defaultlink might be in the form "enwiki" rather than "project: 'wiki', lang: 'en' "
for k, v in pairs(projects) do
if project:match( k .. '$' )
and mw.language.isKnownLanguageTag(project:sub(1, #project-#k))
then
lang = project:sub(1, #project-#k)
project = project:sub(#lang + 1, #project)
projectdata = projects[project]
break
end
end
if not mw.language.isKnownLanguageTag(lang) then
return --formatError('invalid-project-code', projet or 'nil')
end
end
if not projectdata then
return -- formatError('invalid-project-code', projet or 'nil')
end
local linkcode = projectdata[1]
local prefix = projectdata[2]
local multiversion = projectdata[3]
if multiversion then
linkcode = lang .. linkcode
end
local link = mw.wikibase.getSitelink(entityid, linkcode)
if not link then
return nil
end
if prefix then
link = prefix .. ':' .. link
end
if multiversion then
link = ':' .. lang .. ':' .. link
end
return link, project, lang
end
-- add new values to a list, avoiding duplicates
function wd.addNewValues(olditems, newitems, maxnum, stopval)
if not newitems then
return olditems
end
for _, qid in pairs(newitems) do
if stopval and (qid == stopval) then
table.insert(olditems, qid)
return olditems
end
if maxnum and (#olditems >= maxnum) then
return olditems
end
if not wd.isHere(olditems, qid) then
table.insert(olditems, qid)
end
end
return olditems
end
--=== FILTER CLAIMS ACCORDING TO VARIOUS CRITERIA : FUNCTION GETCLAIMS et alii ===
local function notSpecial(claim)
local type
if claim.mainsnak ~= nil then
type = claim.mainsnak.snaktype
else
-- condition respectée quand showonlyqualifier est un paramètre renseigné
-- dans ce cas, claim n'est pas une déclaration entière, mais UNE snak qualifiée du main snak
type = claim.snaktype
end
return type == 'value'
end
local function hasTargetValue(claim, targets) -- retourne true si la valeur est dans la liste des target, ou si c'est une valeur spéciale filtrée séparément par excludespecial
local id = wd.getMainId(claim)
local targets = wd.splitStr(targets)
return wd.isHere(targets, id) or wd.isSpecial(claim.mainsnak)
end
local function excludeValues(claim, values) -- true si la valeur n'est pas dans la liste, ou si c'est une valeur spéciale (filtrée à part par excludespecial)
return wd.isSpecial(claim.mainsnak) or not ( hasTargetValue(claim, values) )
end
local function bestRanked(claims)
if not claims then
return nil
end
local preferred, normal = {}, {}
for i, j in pairs(claims) do
if j.rank == 'preferred' then
table.insert(preferred, j)
elseif j.rank == 'normal' then
table.insert(normal, j)
end
end
if #preferred > 0 then
return preferred
else
return normal
end
end
local function withRank(claims, target)
if target == 'best' then
return bestRanked(claims)
end
local newclaims = {}
for pos, claim in pairs(claims) do
if target == 'valid' then
if claim.rank ~= 'deprecated' then
table.insert(newclaims, claim)
end
elseif claim.rank == target then
table.insert(newclaims, claim)
end
end
return newclaims
end
function wd.hasQualifier(claim, acceptedqualifs, acceptedvals, excludequalifiervalues)
local claimqualifs = claim.qualifiers
if (not claimqualifs) then
return false
end
acceptedqualifs = wd.splitStr(acceptedqualifs)
acceptedvals = wd.splitStr( acceptedvals)
local function ok(qualif) -- vérification pour un qualificatif individuel
if not claimqualifs[qualif] then
return false
end
if not (acceptedvals) then -- si aucune valeur spécifique n'est demandée, OK
return true
end
for i, wanted in pairs(acceptedvals) do
for j, actual in pairs(claimqualifs[qualif]) do
if wd.getId(actual) == wanted then
return true
end
end
end
end
for i, qualif in pairs(acceptedqualifs) do
if ok(qualif) then
return true
end
end
return false
end
function wd.hasQualifierNumber(claim, acceptedqualifs, acceptedvals, excludequalifiervalues)
local claimqualifs = claim.qualifiers
if (not claimqualifs) then
return false
end
acceptedqualifs = wd.splitStr(acceptedqualifs)
acceptedvals = wd.splitStr( acceptedvals)
local function ok(qualif) -- vérification pour un qualificatif individuel
if not claimqualifs[qualif] then
return false
end
if not (acceptedvals) then -- si aucune valeur spécifique n'est demandée, OK
return true
end
for i, wanted in pairs(acceptedvals) do
for j, actual in pairs(claimqualifs[qualif]) do
if mw.wikibase.renderSnak(actual) == wanted then
return true
end
end
end
end
for i, qualif in pairs(acceptedqualifs) do
if ok(qualif) then
return true
end
end
return false
end
local function hasSource(claim, targetsource, sourceproperty)
sourceproperty = sourceproperty or 'P248'
if targetsource == "-" then
return true
end
if (not claim.references) then return
false
end
local candidates = claim.references[1].snaks[sourceproperty] -- les snaks utilisant la propriété demandée
if (not candidates) then
return false
end
if (targetsource == "any") then -- si n'importe quelle valeur est acceptée tant qu'elle utilise en ref la propriété demandée
return true
end
targetsource = wd.splitStr(targetsource)
for _, source in pairs(candidates) do
local s = wd.getId(source)
for i, target in pairs(targetsource) do
if s == target then return true end
end
end
return false
end
local function excludeQualifier(claim, qualifier, qualifiervalues)
return not wd.hasQualifier(claim, qualifier, qualifiervalues)
end
function wd.hasDate(claim)
if not claim then
return false --error() ?
end
if wd.getDateFromQualif(claim, 'P585') or wd.getDateFromQualif(claim, 'P580') or wd.getDateFromQualif(claim, 'P582') then
return true
end
return false
end
local function hasLink(claim, site, lang)
if (claim.mainsnak.snaktype ~= 'value') then -- ne pas supprimer les valeurs spéciales, il y a une fonction dédiée pour ça
return true
end
local id = wd.getMainId(claim)
local link = wd.siteLink(id, site, lang)
if link then
return true
end
end
local function isInLanguage(claim, lang) -- ne fonctionne que pour les monolingualtext / étendre aux autres types en utilisant les qualifiers ?
if type(lang) == 'table' then -- si c'est une table de language séparées par des virgules, on les accepte toutes
for i, l in pairs(lang) do
local v = isInLanguage(claim, l)
if v then
return true
end
end
end
if type(lang) ~= ('string') then
return --?
end
if (lang == '-') then
return true
end
if (lang == 'locallang') then
lang = mw.getContentLanguage():getCode()
end
-- pour les monolingual text
local snak = claim.mainsnak or claim
if snak.snaktype == 'value' and snak.datavalue.type == 'monolingualtext' then
if snak.datavalue.value.language == lang then
return true
end
return false
end
-- pour les autres types de données : recherche dans les qualificatifs
if (lang == 'diq') then
lang = 'Q150'
elseif (lang == 'en') then
lang = 'Q1860'
else
lang = invertedlangcodes[lang]
end
if claim.qualifiers and claim.qualifiers.P407 then
if wd.hasQualifier(claim, {'P407'}, {lang}) then
return true
else
return false
end
end
return true -- si on ne ne sait pas la langue, on condière que c'est bon
end
local function firstVals(claims, numval) -- retourn les numval premières valeurs de la table claims
local numval = tonumber(numval) or 0 -- raise a error if numval is not a positive integer ?
if not claims then
return nil
end
while (#claims > numval) do
table.remove(claims)
end
return claims
end
local function lastVals(claims, numval2) -- retourn les valeurs de la table claims à partir de numval2
local numval2 = tonumber(numval2) or 0 -- raise a error if numval is not a positive integer ?
if not claims then
return nil
end
for i=1,numval2 do
table.remove(claims, 1)
end
return claims
end
local function timeFromQualifs(claim, qualifs)
local claimqualifs = claim.qualifiers
if not claimqualifs then
return nil
end
for i, qualif in pairs(qualifs or timequalifiers) do
local vals = claimqualifs[qualif]
if vals and (vals[1].snaktype == 'value') then
return vals[1].datavalue.value.time
end
end
end
local function atDate(claim, mydate, precision)
if mydate == "today" then
mydate = os.date("!%Y-%m-%dT%TZ")
end
-- with point in time
local d = timeFromQualifs(claim, {'P585'})
if d then
return modules.formatDate.equal(mydate, d, precision)
end
-- with start or end date
local mindate = timeFromQualifs(claim, {'P580'})
local maxdate = timeFromQualifs(claim, {'P582'})
if modules.formatDate.before(mydate, mindate) and modules.formatDate.before(maxdate, mydate) then
return true
end
return false
end
local function check(claim, condition)
if type(condition) == 'function' then -- cas standard
return condition(claim)
end
return formatError('invalid type', 'function', type(condition))
end
local function minPrecision(claim, minprecision)
local snack
if claim.qualifiers then -- si une date est donnée en qualificatif, c'est elle qu'on utilise de préférence au mainsnak
for i, j in ipairs(datequalifiers) do
if claim.qualifiers[j] then
snack = claim.qualifiers[j][1]
break
end
end
end
if not snack then
snack = claim.mainsnak or claim
end
if (snack.snaktype == 'value') and (snack.datatype == 'time') and (snack.datavalue.value.precision < minprecision) then
return false
end
return true
end
function wd.sortClaims(claims, sorttype)
if not claims then
return nil
end
if sorttype == 'chronological' then
return wd.chronoSort(claims)
elseif sorttype == 'inverted' then
return wd.chronoSort(claims, true)
elseif sorttype == 'order' then
return wd.chronoSort(claims)
elseif type(sorttype) == 'function' then
table.sort(claims, sorttype)
return claims
elseif type(sorttype) == 'string' and sorttype:sub(1, 1) == 'P' then
return wd.numericPropertySort(claims, sorttype)
end
return claims
end
local alreadyFiltered = false
function wd.filterClaims(claims, args) --retire de la tables de claims celles qui sont éliminés par un des filters de la table des filters
local function filter(condition, filterfunction, funargs)
if not args[condition] then
return
end
for i = #claims, 1, -1 do
if not( filterfunction(claims[i], args[funargs[1]], args[funargs[2]], args[funargs[3]]) ) then
table.remove(claims, i)
end
end
end
filter('isinlang', isInLanguage, {'isinlang'} )
filter('excludespecial', notSpecial, {} )
filter('condition', check, {'condition'} )
if claims[1] and claims[1].mainsnak then
filter('targetvalue', hasTargetValue, {'targetvalue'} )
filter('atdate', atDate, {'atdate'} )
filter('qualifier', wd.hasQualifier, {'qualifier', 'qualifiervalue'} )
filter('qualifiernumber', wd.hasQualifierNumber, {'qualifiernumber', 'qualifiernumbervalue'} )
filter('excludequalifier', excludeQualifier, {'excludequalifier', 'excludequalifiervalue'} )
filter('withsource', hasSource, {'withsource', 'sourceproperty'} )
filter('withdate', wd.hasDate, {} )
filter('excludevalues', excludeValues, {'excludevalues'})
filter('withlink', hasLink, {'withlink', 'linklang'} )
filter('minprecision', minPrecision, {'minprecision'} )
claims = withRank(claims, args.rank or 'best')
end
if args.sorttype then
claims = wd.sortClaims(claims, args.sorttype)
end
if #claims == 0 then
return nil
end
if args.numval2 then
claims = lastVals(claims, args.numval2)
end
if args.numval then
claims = firstVals(claims, args.numval)
end
return claims
end
function wd.loadEntity(entity, cache)
if type(entity) ~= 'table' then
if cache then
if not cache[entity] then
cache[entity] = mw.wikibase.getEntity(entity)
mw.log("cached")
end
return cache[entity]
else
if entity == '' or (entity == '-') then
entity = nil
end
return mw.wikibase.getEntity(entity)
end
else
return entity
end
end
function wd.getClaims( args ) -- returns a table of the claims matching some conditions given in args
if args.claims then -- if claims have already been set, return them
return args.claims
end
local properties = args.property
if type(properties) == 'string' then
properties = wd.splitStr(string.upper(args.property))
end
if not properties then
return formatError( 'property-param-not-provided' )
end
--Get entity
local entity = args.entity
if type(entity) == 'string' then
if entity == '' then
entity = nil
end
elseif type(entity) == 'table' then
entity = entity.id
end
if (not entity) then
entity = mw.wikibase.getEntityIdForCurrentPage()
end
if (not entity) or (entity == '-') then
return nil
end
local claims = {}
if #properties == 1 then
claims = mw.wikibase.getAllStatements(entity, properties[1]) -- do not use mw.wikibase.getBestStatements at this stage, as it may remove the best ranked values that match other criteria in the query
else
for i, prop in ipairs(properties) do
local newclaims = mw.wikibase.getAllStatements(entity, prop)
if newclaims and #newclaims > 0 then
for j, claim in ipairs(newclaims) do
table.insert(claims, claim)
end
end
end
end
if (not claims) or (#claims == 0) then
return nil
end
return wd.filterClaims(claims, args)
end
--=== ENTITY FORMATTING ===
function wd.getLabel(entity, lang, labelformat)
if (not entity) then
return nil -- ou option de gestion des erreurs ?
end
lang = lang or defaultlang
if type(labelformat) == 'function' then
return labelformat(entity)
end
entity = entity.id or ( type(entity) == "string" and entity)
if (type(entity) == 'string') and (lang == defaultlang) then -- le plus économique
local str = mw.wikibase.label(entity)
if str then -- mw.wikibase.label() ne fonctionne pas avec les redirect https://phabricator.wikimedia.org/T157868
return str
end
end
return mw.wikibase.getLabelByLang(entity, lang)
end
function wd.formatEntity( entity, params )
if (not entity) then
return nil --formatError('entity-not-found')
end
local id = entity
if type(id) == 'table' then
id = id.id
end
params = params or {}
local lang = params.lang or defaultlang
local speciallabels = params.speciallabels
local displayformat = params.displayformat
local labelformat = params.labelformat
local defaultlabel = params.defaultlabel or id
local linktype = params.link
local defaultlink = params.defaultlink
local defaultlinkquery = params.defaultlinkquery
if speciallabels and speciallabels[id] then --speciallabels override the standard label + link combination
return speciallabels[id]
end
if params.displayformat == 'raw' then
return id
end
local link, label
label = wd.getLabel(entity, lang, labelformat)
-- détermination du fait qu'on soit ou non en train de rendre l'élément sur la page de son article
local rendering_entity_on_its_page = wd.isPageOfQId(id)
if not label then
if (defaultlabel == '-') then
return nil
end
link = wd.siteLink(id, 'wikidata')
return '[[' .. link .. '|' .. id .. ']]' .. addCat(modules.i18n['to translate'])
-- si pas de libellé, on met un lien vers Wikidata pour qu'on comprenne à quoi ça fait référence
end
if (linktype == '-') or rendering_entity_on_its_page then
return label
end
local link = wd.siteLink(entity, linktype, lang)
-- defaultlinkquery will try to link to another page on this Wiki
if (not link) and defaultlinkquery then
if type(defaultlinkquery) == 'string' then
defaultlinkquery = {property = defaultlinkquery}
end
defaultlinkquery.excludespecial = true
defaultlinkquery.entity = entity
local claims = wd.getClaims(defaultlinkquery)
if claims then
for i, j in pairs(claims) do
local id = wd.getMainId(j)
link = wd.siteLink(id, linktype, lang)
if link then
break
end
end
end
end
if link then
return '[[' .. link .. '|' .. label .. ']]'
end
-- if not link, you can use defaultlink: a sidelink to another Wikimedia project
if (not defaultlink) then
defaultlink = {'enwiki'}
end
if defaultlink and (defaultlink ~= '-') then
local linktype
local sidelink, site, langcode
if type(defaultlink) == 'string' then
defaultlink = {defaultlink}
end
for i, j in ipairs(defaultlink) do
sidelink, site, langcode = wd.siteLink(entity, j, lang)
if sidelink then
break
end
end
if not sidelink then
sidelink, site = wd.siteLink(entity, 'wikidata')
end
local icon, class, title = site, nil, nil -- le texte affiché du lien
if site == 'wiki' then
icon, class, title = langcode, "indicateur-langue", wd.translate('see-another-language', mw.language.fetchLanguageName(langcode, defaultlang))
elseif site == 'wikidata' then
icon, class, title = 'd', "indicateur-langue", wd.translate('see-wikidata')
else
title = wd.translate('see-another-project', site)
end
local val = '[[' .. sidelink .. '|' .. ']]'
return label .. ''
end
return label
end
function wd.addTrackingCat(prop, cat) -- doit parfois être appelé par d'autres modules
if type(prop) == 'table' then
prop = prop[1] -- devrait logiquement toutes les ajouter
end
if not prop and not cat then
return formatError("property-param-not-provided")
end
if not cat then
cat = wd.translate('trackingcat', prop or 'P??')
end
return addCat(cat )
end
local function unknownValue(snak, label)
local str = label
if type(str) == "function" then
str = str(snak)
end
if (not str) then
if snak.datatype == 'time' then
str = wd.translate('sometime')
else
str = wd.translate('somevalue')
end
end
if type(str) ~= "string" then
return formatError(snak.datatype)
end
return str
end
local function noValue(displayformat)
if not displayformat then
return wd.translate('novalue')
end
if type(displayformat) == 'string' then
return displayformat
end
return formatError()
end
local function getLangCode(entityid)
return modules.langcodes[tonumber(entityid:sub(2))]
end
local function showLang(statement) -- retourne le code langue entre paranthèse avant la valeur (par exemple pour les biblios et liens externes)
local mainsnak = statement.mainsnak
if mainsnak.snaktype ~= 'value' then
return nil
end
local langlist = {}
if mainsnak.datavalue.type == 'monolingualtext' then
langlist = {mainsnak.datavalue.value.language}
elseif (not statement.qualifiers) or (not statement.qualifiers.P407) then
return
else
for i, j in pairs( statement.qualifiers.P407 ) do
if j.snaktype == 'value' then
local langentity = wd.getId(j)
local langcode = getLangCode(langentity)
table.insert(langlist, langcode)
end
end
end
if (#langlist > 1) or (#langlist == 1 and langlist[1] ~= defaultlang) then -- si c'est en français, pas besoin de le dire
return modules.langmodule.indicationMultilingue(langlist)
end
end
-- === DATE HANDLING ===
function wd.addStandardQualifs(str, statement)
if (not statement) or (not statement.qualifiers) then
return str
end
if not str then
return error()-- what's that ?
end
if statement.qualifiers.P1480 then
for i, j in pairs(statement.qualifiers.P1480) do
local v = wd.getId(j)
if (v == "Q21818619") then
str = wd.translate('approximate-place', str)
elseif (v == "Q18122778") or (v == "Q18912752") then
str = wd.translate('uncertain-information', str)
elseif (v == "Q5727902") then
if (statement.mainsnak.datatype == 'time') then
str = modules.formatDate.fuzzydate(str)
else
str = wd.translate('approximate-value', str)
end
end
end
end
return str
end
local function rangeObject(begin, ending, params)
--[[
objet comportant un timestamp pour le classement chronologique et deux dateobject (begin et ending)
]]--
local timestamp
if begin then
timestamp = begin.timestamp
else
timestamp = ending.timestamp
end
return {begin = begin, ending = ending, timestamp = timestamp, type = 'rangeobject'}
end
local function dateObject(orig, params)
--[[ transforme un snak en un nouvel objet utilisable par Module:Date complexe
{type = 'dateobject', timestamp = str, era = '+' ou '-', year = number, month = number, day = number, calendar = calendar}
]]--
if not params then
params = {}
end
local newobj = modules.formatDate.splitDate(orig.time, orig.calendarmodel)
newobj.precision = params.precision or orig.precision
newobj.type = 'dateobject'
return newobj
end
local function objectToText(obj, params)
if obj.type == 'dateobject' then
return modules.formatDate.simplestring(obj, params)
elseif obj.type == 'rangeobject' then
return modules.formatDate.daterange(obj.begin, obj.ending, params)
end
end
function wd.getDateFromQualif(statement, qualif)
if (not statement) or (not statement.qualifiers) or not (statement.qualifiers[qualif]) then
return nil
end
local v = statement.qualifiers[qualif][1]
if v.snaktype ~= 'value' then -- que faire dans ce cas ?
return nil
end
return dateObject(v.datavalue.value)
end
function wd.getDate(statement)
local period = wd.getDateFromQualif(statement, 'P585') -- retourne un dateobject
if period then
return period
end
local begin, ending = wd.getDateFromQualif(statement, 'P580'), wd.getDateFromQualif(statement, 'P582')
if begin or ending then
return rangeObject(begin, ending) -- retourne un rangeobject fait de deux dateobject
end
return nil
end
function wd.getFormattedDate(statement, params)
if not statement then
return nil
end
local str
--cherche la date avec les qualifs P580/P582
local datetable = wd.getDate(statement)
if datetable then
str = objectToText(datetable, params)
end
-- puis limite intérieur / supérieur
if not str then
local start, ending = wd.getDateFromQualif(statement, 'P1319'), wd.getDateFromQualif(statement, 'P1326')
str = modules.formatDate.between(start, ending, params, 'P575')
end
-- sinon, le mainsnak, pour les données de type time
if (not str) and (statement.mainsnak.datatype == 'time') then
local mainsnak = statement.mainsnak
if (mainsnak.snaktype == 'value') or (mainsnak.snaktype == 'somevalue') then
str = wd.formatSnak(mainsnak, params)
end
end
if str and params and (params.addstandardqualifs ~= '-') then
str = wd.addStandardQualifs(str, statement)
end
return str
end
-- Fonction qui trie des Claims de type time selon l'ordre chronologique
-- Une clé de tri nomée « dateSortKey » est ajouté à chaque claim.
-- Si des clés de tri de ce nom existent déjà, elles sont utilisées sans modification.
function wd.chronoSort( claims, inverted )
for _, claim in ipairs( claims ) do
if not claim.dateSortKey then
local snack = claim.mainsnak or claim
local iso
if (snack.snaktype == 'value') and (snack.datatype == 'time') then
iso = snack.datavalue.value.time
else
iso = timeFromQualifs(claim, datequalifiers) or '0'
end
-- transformation en nombre (indication de la base car gsub retourne deux valeurs)
iso = tonumber( iso:gsub( '(%d)%D', '%1' ), 10 )
claim.dateSortKey = iso
end
end
table.sort(
claims,
function ( c1, c2 )
if inverted then
return c2.dateSortKey < c1.dateSortKey
end
return c1.dateSortKey < c2.dateSortKey
end
)
return claims
end
-- Fonction qui trie des Claims de type value selon l'ordre de la propriété fournit
-- Une clé de tri nomée « dateSortKey » est ajouté à chaque claim.
-- Si des clés de tri de ce nom existent déjà, elles sont utilisées sans modification.
function wd.numericPropertySort( claims, propertySort )
for _, claim in ipairs( claims ) do
if not claim.dateSortKey then
local val
local claimqualifs = claim.qualifiers
if claimqualifs then
local vals = claimqualifs[propertySort]
if vals and vals[1].snaktype == 'value' then
val = vals[1].datavalue.value
end
end
claim.dateSortKey = tonumber(val or 0)
end
end
table.sort(
claims,
function ( c1, c2 )
return c1.dateSortKey < c2.dateSortKey
end
)
return claims
end
-- ===================
function wd.getReferences(statement)
local refdata = statement.references
if not refdata then
return nil
end
local refs = {}
local hashes = {}
for i, ref in pairs(refdata) do
local s
local function hasValue(prop) -- checks that the prop is here with valid value
if ref.snaks[prop] and ref.snaks[prop][1].snaktype == 'value' then
return true
end
return false
end
if ref.snaks.P248 then -- cas lorsque P248 (affirmé dans) est utilisé
for j, source in pairs(ref.snaks.P248) do
if source.snaktype == 'value' then
local page, accessdate, quotation
if hasValue('P304') then -- page
page = wd.formatSnak(ref.snaks.P304[1])
end
if hasValue('P813') then -- date de consultation
accessdate = wd.formatSnak(ref.snaks.P813[1])
end
if hasValue('P1683') then -- citation
quotation = wd.formatSnak(ref.snaks.P1683[1])
end
local sourceId = wd.getId(source)
s = modules.reference.citeitem(sourceId, {['page'] = page, ['accessdate'] = accessdate, ['citation'] = quotation})
table.insert(refs, s)
table.insert(hashes, ref.hash .. sourceId)
end
end
elseif hasValue('P854') then -- cas lorsque P854 (URL de la référence) est utilisé
local url, title, author, publisher, accessdate, publishdate, publishlang, quotation
url = wd.formatSnak(ref.snaks.P854[1], {text = "-"})
if hasValue('P1476') then
title = wd.formatSnak(ref.snaks.P1476[1])
else
title = mw.ustring.gsub(url, '^[Hh][Tt][Tt][Pp]([Ss]?):(/?)([^/])', 'http%1://%3')
end
--todo : handle multiple values for author, etc.
if hasValue('P813') then -- date de consultation
accessdate = wd.formatSnak(ref.snaks.P813[1])
end
if hasValue('P50') then -- author (item type)
author = wd.formatSnak(ref.snaks.P50[1])
elseif hasValue('P2093') then -- author (string type)
author = wd.formatSnak(ref.snaks.P2093[1])
end
if hasValue('P123') then -- éditeur
publisher = wd.formatSnak(ref.snaks.P123[1])
end
if hasValue('P1683') then -- citation
quotation = wd.formatSnak(ref.snaks.P1683[1])
end
if hasValue('P577') then -- date de publication
publishdate = wd.formatSnak(ref.snaks.P577[1])
end
if hasValue('P407') then -- langue de l'œuvre
local id = wd.getId(ref.snaks.P407[1])
publishlang = getLangCode(id)
end
s = modules.cite.lienWeb{titre = title, url = url, auteur = author, editeur = publisher, langue = publishlang, ['en ligne le'] = publishdate, ['consulté le'] = accessdate, ['citation'] = quotation}
table.insert(hashes, ref.hash)
table.insert(refs, s)
elseif ref.snaks.P854 and ref.snaks.P854[1].snaktype == 'value' then
s = wd.formatSnak(ref.snaks.P854[1], {text = "-"})
table.insert(hashes, ref.snaks.P854[1].hash)
table.insert(refs, s)
end
end
if #refs > 0 then
if #hashes == #refs then
return refs, hashes
end
return refs
end
end
function wd.sourceStr(sources, hashes)
if not sources or (#sources == 0) then
return nil
end
local useHashes = hashes and #hashes == #sources
for i, j in ipairs(sources) do
local refArgs = {name = 'ref', content = j}
if useHashes and hashes[i] ~= '-' then
refArgs.args = {name = 'wikidata-' .. hashes[i]}
end
sources[i] = mw.getCurrentFrame():extensionTag(refArgs)
end
return table.concat(sources)
end
function wd.getDataValue(snak, params)
if not params then
params = {}
end
local speciallabels = params.speciallabels -- parfois on a besoin de faire une liste d'éléments pour lequel le libellé doit être changé, pas très pratique d'utiliser une fonction pour ça
if snak.snaktype ~= 'value' then
return nil
end
local datatype = snak.datatype
local value = snak.datavalue.value
local displayformat = params.displayformat
if type(displayformat) == 'function' then
return displayformat(snak, params)
end
if datatype == 'wikibase-item' then
return wd.formatEntity(wd.getId(snak), params)
end
if datatype == 'url' then
return modules.weblink.makelink(value, params.text)
end
if datatype == 'math' then
return mw.getCurrentFrame():extensionTag( "math", value)
end
if (datatype == 'string') or (datatype == 'external-id') or (datatype == 'commonsMedia') then -- toutes les données de type string sauf "math"
if params.urlpattern then
local urlpattern = params.urlpattern
if type(urlpattern) == 'function' then
urlpattern = urlpattern(value)
end
local url = mw.ustring.gsub(urlpattern, '$1', (value:gsub('%%', '%%%%'))):gsub(' ', '%%20')
value = '[' .. url .. ' ' .. (params.text or value) .. ']'
end
return value
end
if datatype == 'time' then -- format example: +00000001809-02-12T00:00:00Z
if displayformat == 'raw' then
return value.time
else
local dateobject = dateObject(value, {precision = params.precision})
return objectToText(dateobject, params)
end
end
if datatype == 'globe-coordinate' then
-- retourne une table avec clés latitude, longitude, précision et globe à formater par un autre module (à changer ?)
if displayformat == 'latitude' then
return value.latitude
elseif displayformat == 'longitude' then
return value.longitude
else
local coordvalue = mw.clone( value )
coordvalue.globe = modules.globes[value.globe] -- transforme l'ID du globe en nom anglais utilisable par geohack
return coordvalue -- note : les coordonnées Wikidata peuvent être utilisée depuis Module:Coordinates. Faut-il aussi autoriser à appeler Module:Coordiantes ici ?
end
end
if datatype == 'quantity' then -- todo : gérer les paramètres précision
local amount, unit = value.amount, value.unit
if unit then
unit = unit:match('Q%d+')
end
local raw
if displayformat == "raw" then
raw = true
end
return modules.formatNum.displayvalue(amount, unit,
{targetunit = params.targetunit, raw = raw, rounding = params.rounding, showunit = params.showunit or 'short', showlink = params.showlink}
)
end
if datatype == 'monolingualtext' then
if value.language == defaultlang then
return value.text
else
return modules.langmodule.langue({value.language, value.text})
end
end
return formatError('unknown-datavalue-type' )
end
function wd.stringTable(args) -- like getClaims, but get a list of string rather than a list of snaks, for easier manipulation
local claims = args.claims
if not claims then
claims = wd.getClaims(args)
end
if not claims or claims == {} then
return {}, {}
end
local props = {} -- liste des propriétés associété à chaque string pour catégorisation et linkback
for i, j in pairs(claims) do
claims[i] = wd.formatStatement(j, args)
table.insert(props, j.mainsnak.property)
end
if args.removedupes and (args.removedupes ~= '-') then
claims = wd.addNewValues({}, claims) -- devrait aussi supprimer de props celles qui ne sont pas utilisées
end
return claims, props
end
function wd.getQualifiers(statement, qualifs, params)
if not statement.qualifiers then
return nil
end
local vals = {}
if type(qualifs) == 'string' then
qualifs = wd.splitStr(qualifs)
end
for i, j in pairs(qualifs) do
if statement.qualifiers[j] then
for k, l in pairs(statement.qualifiers[j]) do
table.insert(vals, l)
end
end
end
if #vals == 0 then
return nil
end
return vals
end
function wd.getFormattedQualifiers(statement, qualifs, params)
if not params then params = {} end
local qualiftable = wd.getQualifiers(statement, qualifs)
if not qualiftable then
return nil
end
qualiftable = wd.filterClaims(qualiftable, params) or {}
for i, j in pairs(qualiftable) do
qualiftable[i] = wd.formatSnak(j, params)
end
return modules.linguistic.conj(qualiftable, params.conjtype)
end
function wd.showQualifiers(str, statement, args)
local qualifs = args.showqualifiers
if not qualifs then
return str -- or error ?
end
if type(qualifs) == 'string' then
qualifs = wd.splitStr(qualifs)
end
local qualifargs = args.qualifargs or {}
-- formatage des qualificatifs = args commençant par "qualif", ou à défaut, les mêmes que pour la valeur principale
qualifargs.displayformat = args.qualifdisplayformat or args.displayformat
qualifargs.labelformat = args.qualiflabelformat or args.labelformat
qualifargs.link = args.qualiflink or args.link
qualifargs.linktopic = args.qualiflinktopic or args.linktopic
qualifargs.conjtype = args.qualifconjtype
qualifargs.defaultlink = args.qualifdefaultlink or args.defaultlink
qualifargs.defaultlinkquery = args.qualifdefaultlinkquery or args.defaultlinkquery
local formattedqualifs = wd.getFormattedQualifiers(statement, qualifs, qualifargs)
if formattedqualifs and formattedqualifs ~= "" then
str = str .. " (" .. formattedqualifs .. ")"
end
return str
end
function wd.formatSnak( snak, params )
if not params then params = {} end -- pour faciliter l'appel depuis d'autres modules
if snak.snaktype == 'somevalue' then
return unknownValue(snak, params.unknownlabel)
elseif snak.snaktype == 'novalue' then
return noValue(params.novaluelabel)
elseif snak.snaktype == 'value' then
return wd.getDataValue( snak, params)
else
return formatError( 'unknown-snak-type' )
end
end
function wd.formatStatement( statement, args )
if not args then
args = {}
end
if not statement.type or statement.type ~= 'statement' then
return formatError( 'unknown-claim-type' )
end
local prop = statement.mainsnak.property
local str
-- special displayformat f
if args.statementformat and (type(args.statementformat) == 'function') then
str = args.statementformat(statement, args)
elseif (statement.mainsnak.datatype == 'time') and (statement.mainsnak.dateformat ~= '-') then
if args.displayformat == 'raw' and statement.mainsnak.snaktype == 'value' then
str = statement.mainsnak.datavalue.value.time
else
str = wd.getFormattedDate(statement, args)
end
elseif args.showonlyqualifier and (args.showonlyqualifier ~= '') then
str = wd.getFormattedQualifiers(statement, args.showonlyqualifier, args)
if not str then
return nil
end
if args.addstandardqualifs ~= '-' then
str = wd.addStandardQualifs(str, statement)
end
else
str = wd.formatSnak( statement.mainsnak, args )
if args.addstandardqualifs ~= '-' then
str = wd.addStandardQualifs(str, statement)
end
end
-- ajouts divers
if args.showlang == true then
local indicateur = showLang(statement)
if indicateur then
str = indicateur .. ' ' .. str
end
end
if args.showqualifiers then
str = wd.showQualifiers(str, statement, args)
end
if args.showdate then -- when "showdate and chronosort are both set, date retrieval is performed twice
local period = wd.getFormattedDate(statement, args, "-") -- 3 arguments indicate the we should not use additional qualifiers, alrady added by wd.formatStatement
if period then
str = str .. " <small>(" .. period .. ")</small>"
end
end
if args.showsource then
local sources, hashes = wd.getReferences(statement)
if sources then
local source = wd.sourceStr(sources, hashes)
if source then
str = str .. source
end
end
end
return str
end
function wd.addLinkBack(str, id, property)
if not id then
id = wd.getEntityIdForCurrentPage()
end
if not id then
return str
end
if type(property) == 'table' then
property = property[1]
end
id = wd.entityId(id)
local class = ''
if property then
class = 'wd_' .. string.lower(property)
end
local icon = '[[File:Blue pencil.svg|%s|10px|baseline|class=noviewer|link=%s]]'
local title = wd.translate('see-wikidata-value')
local url = mw.uri.fullUrl('d:' .. id, 'uselang=diq')
url.fragment = property -- ajoute une #ancre si paramètre "property" défini
url = tostring(url)
local v = mw.html.create('span')
:addClass(class)
:wikitext(str)
:tag('span')
:addClass('noprint wikidata-linkback')
:wikitext(icon:format(title, url))
:allDone()
return tostring(v)
end
function wd.addRefAnchor(str, id)
--[[
Insère une ancre pour une référence générée à partir d'un élément wd.
L'id Wikidata sert d'identifiant à l'ancre, à utiliser dans les modèles type "harvsp"
--]]
return tostring(
mw.html.create('span')
:attr('id', id)
:attr('class', "ouvrage")
:wikitext(str)
)
end
--=== FUNCTIONS USING AN ENTITY AS ARGUMENT ===
local function formatStatementsGrouped(args, type)
-- regroupe les affirmations ayant la même valeur en mainsnak, mais des qualificatifs différents
-- (seulement pour les propriétés de type élément)
local claims = wd.getClaims(args)
if not claims then
return nil
end
local groupedClaims = {}
-- regroupe les affirmations par valeur de mainsnak
local function addClaim(claim)
local id = wd.getMainId(claim)
for i, j in pairs(groupedClaims) do
if (j.id == id) then
table.insert(groupedClaims[i].claims, claim)
return
end
end
table.insert(groupedClaims, {id = id, claims = {claim}})
end
for i, claim in pairs(claims) do
addClaim(claim)
end
local stringTable = {}
-- instructions ad hoc pour les paramètres concernant la mise en forme d'une déclaration individuelle
local funs = {
{param = "showqualifiers", fun = function(str, claims)
local qualifs = {}
for i, claim in pairs(claims) do
local news = wd.getFormattedQualifiers(claim, args.showqualifiers, args)
if news then
table.insert(qualifs, news)
end
end
local qualifstr = modules.linguistic.conj(qualifs, "qualif-separator")
if qualifstr and qualifstr ~= "" then
str = str .. " (" .. qualifstr .. ")"
end
return str
end
},
{param = "showdate", fun = function(str, claims)
-- toutes les dates sont regroupées à l'intérieur des mêmes parenthèses ex "médaille d'or (1922, 1924)"
local dates = {}
for i, statement in pairs(claims) do
local s = wd.getFormattedDate(statement, args, true)
if statement then table.insert(dates, s) end
end
local datestr = modules.linguistic.conj(dates)
if datestr and datestr ~= "" then
str = str .. " <small>(" .. datestr .. ")</small>"
end
return str
end
},
{param = "showsource", fun = function(str, claims)
-- les sources sont toutes affichées au même endroit, à la fin
-- si deux affirmations ont la même source, on ne l'affiche qu'une fois
local sources = {}
local hashes = {}
local function dupeRef(old, new)
for i, j in pairs(old) do
if j == new then
return true
end
end
end
for i, claim in pairs(claims) do
local refs, refHashes = wd.getReferences(claim)
if refs then
for i, j in pairs(refs) do
if not dupeRef(sources, j) then
table.insert(sources, j)
local hash = (refHashes and refHashes[i]) or '-'
table.insert(hashes, hash)
end
end
end
end
return str .. (wd.sourceStr(sources, hashes) or "")
end
}
}
for i, group in pairs(groupedClaims) do -- bricolage pour utiliser les arguments de formatStatements
local str = wd.formatEntity(group.id, args)
for i, fun in pairs(funs) do
if args[fun.param] then
str = fun.fun(str, group.claims, args)
end
end
table.insert(stringTable, str)
end
args.valuetable = stringTable
return wd.formatStatements(args)
end
function wd.formatStatements( args )--Format statement and concat them cleanly
if args.value == '-' then
return nil
end
-- If a value is already set: use it, except if it's the special value {{WD}} (use wikidata)
if args.value and args.value ~= '' then
local valueexpl = wd.translate("activate-query")
if args.value ~= valueexpl then
return args.value
end
-- There is no value set, and args.expl disables wikidata on empty values
elseif args.expl then
return nil
end
if args.grouped and args.grouped ~= '' then
args.grouped = false
return formatStatementsGrouped(args)
end
local valuetable = args.valuetable -- dans le cas où les valeurs sont déjà formtées
local props -- les prorpriétés réellement utilisées (dans certainse cas, ce ne sont pas toutes celles de ags.property
if not valuetable then -- cas le plus courant
valuetable, props = wd.stringTable(args)
end
local str = modules.linguistic.conj(valuetable, args.conjtype)
if not str then
return args.default
end
if not props then
props = wd.splitStr(args.property)[1]
end
if args.ucfirst ~= '-' then
str = modules.linguistic.ucfirst(str)
end
if args.addcat and (args.addcat ~= '-') then
str = str .. wd.addTrackingCat(props)
end
if args.linkback and (args.linkback ~= '-') then
str = wd.addLinkBack(str, args.entity, props)
end
if args.returnnumberofvalues then
return str, #valuetable
end
return str
end
function wd.formatAndCat(args)
if not args then
return nil
end
args.linkback = args.linkback or true
args.addcat = true
if args.value then -- do not ignore linkback and addcat, as formatStatements do
if args.value == '-' then
return nil
end
local val = args.value .. wd.addTrackingCat(args.property)
val = wd.addLinkBack(val, args.entity, args.property)
return val
end
return wd.formatStatements( args )
end
function wd.getTheDate(args)
local claims = wd.getClaims(args)
if not claims then
return nil
end
local formattedvalues = {}
for i, j in pairs(claims) do
local v = wd.getFormattedDate(j, args)
if v then
table.insert(formattedvalues, v )
end
end
local val = modules.linguistic.conj(formattedvalues)
if not val then
return nil
end
if args.addcat == true then
val = val .. wd.addTrackingCat(args.property)
end
val = wd.addLinkBack(val, args.entity, args.property)
return val
end
function wd.keyDate (event, item, params)
params = params or {}
params.entity = item
if type(event) == 'table' then
for i, j in pairs(event) do
params.targetvalue = nil -- réinitialisation barbare des paramètres modifiés
local s = wd.keyDate(j, item, params)
if s then
return s
end
end
elseif type(event) ~= 'string' then
return formatError('invalid-datatype', type(event), 'string')
elseif string.sub(event, 1, 1) == 'Q' then -- on demande un élément utilisé dans P:P793 (événement clé)
params.property = 'P793'
params.targetvalue = event
params.addcat = params.addcat or true
return wd.getTheDate(params)
elseif string.sub(event, 1, 1) == 'P' then -- on demande une propriété
params.property = event
return wd.formatAndCat(params)
else
return formatError('invalid-entity-id', event)
end
end
function wd.mainDate(entity)
-- essaye P580/P582
local args = {entity = entity, addcat = true}
args.property = 'P580'
local startpoint = wd.formatStatements(args)
args.property = 'P582'
local endpoint = wd.formatStatements(args)
local str
if (startpoint or endpoint) then
str = modules.formatDate.daterange(startpoint, endpoint, params)
str = wd.addLinkBack(str, entity, 'P582')
return str
end
-- défaut : P585
args.property = {'P585', 'P571'}
args.linkback = true
return wd.formatStatements(args)
end
-- === FUNCTIONS FOR TRANSITIVE PROPERTIES ===
function wd.getIds(item, query)
query.excludespecial = true
query.displayformat = 'raw'
query.entity = item
query.addstandardqualifs = '-'
return wd.stringTable(query)
end
-- recursively adds a list of qid to an existing list, based on the results of a query
function wd.addVals(list, query, maxdepth, maxnodes, stopval)
maxdepth = tonumber(maxdepth) or 10
maxnodes = tonumber(maxnodes) or 100
if (maxdepth < 0) then
return list
end
if stopval and wd.isHere(list, stopval) then
return list
end
local origsize = #list
for i = 1, origsize do
-- tried a "checkpos" param instead of starting to 1 each time, but no impact on performance
local candidates = wd.getIds(list[i], query)
list = wd.addNewValues(list, candidates, maxnodes, stopval)
if list[#list] == stopval then
return list
end
if #list >= maxnodes then
return list
end
end
if (#list == origsize) then
return list
end
return wd.addVals(list, query, maxdepth - 1, maxnodes, stopval, origsize + 1)
end
-- returns a list of items transitively matching a query (orig item is not included in the list)
function wd.transitiveVals(item, query, maxdepth, maxnodes, stopval)
maxdepth = tonumber(maxdepth) or 5
if type(query) == "string" then
query = {property = query}
end
-- récupération des valeurs
local vals = wd.getIds(item, query)
if not vals then
return nil
end
local v = wd.addVals(vals, query, maxdepth - 1, maxnodes, stopval)
if not v then
return nil
end
-- réarrangement des valeurs
if query.valorder == "inverted" then
local a = {}
for i, j in pairs(v) do
table.insert(a, 1, j)
end
v = a
end
return v
end
-- returns true if an item is the value of a query, transitively
function wd.inTransitiveVals(searchedval, sourceval, query, maxdepth, maxnodes )
local vals = wd.transitiveVals(sourceval, query, maxdepth, maxnodes, searchedval )
if (not vals) then
return false
end
for _, val in ipairs(vals) do
if (val == searchedval) then
return true
end
end
return false
end
-- returns true if an item is a superclass of another, based on P279
function wd.isSubclass(class, item, maxdepth)
local query = {property = 'P279'}
if class == item then -- item is a subclass of itself iff it is a class
if wd.getIds(item, query) then
return true
end
return false
end
return wd.inTransitiveVals(class, item, query, maxdepth )
end
-- returns true if one of the best ranked P31 values of an item is the target or a subclass of the target
-- rank = 'valid' would seem to make sense, but it would need to check for date qualifiers as some P31 values have begin or end date
function wd.isInstance(targetclass, item, maxdepth)
maxdepth = maxdepth or 10
local directclasses = wd.transitiveVals(item, {property = 'P31'}, 1)
if not directclasses then
return false
end
for i, class in pairs(directclasses) do
if wd.isSubclass(targetclass, class, maxdepth - 1) then
return true
end
end
return false
end
-- return the first value in a transitive query that belongs to a particular class. For instance find a value of P131 that is a province of Canada
function wd.findVal(sourceitem, targetclass, query, recursion, instancedepth)
if type(query) == "string" then
query = {property = query}
end
local candidates = wd.getIds(sourceitem, query)
if candidates then
for i, j in pairs(candidates) do
if wd.isInstance(targetclass, j, instancedepth) then
return j
end
end
if not recursion then
recursion = 3
else
recursion = recursion - 1
end
if recursion < 0 then
return nil
end
for i, candidate in pairs(candidates) do
return wd.findVal(candidate, targetclass, query, recursion, instancedepth)
end
end
end
-- === VARIA ===
function wd.getDescription(entity, lang)
lang = lang or defaultlang
local description
if lang == defaultlang then
return mw.wikibase.descriptionl(qid)
end
if not entity.descriptions then
return wd.translate('no description')
end
local descriptions = entity.descriptions
if not descriptions then
return nil
end
if descriptions[lang] then
return descriptions[delang].value
end
return entity.id
end
function wd.Dump(entity)
entity = wd.getEntity(entity)
if not entity then
return formatError("entity-param-not-provided")
end
return "<pre>"..mw.dumpObject(entity).."</pre>"
end
function wd.frameFun(frame)
local args = frame.args
local funname = args[1]
table.remove(args, 1)
return wd[funname](args)
end
return wd
5xo4qpd4rdcmp6dexrr9nq5wkf4w68z
549213
549210
2026-06-23T06:22:01Z
Mirzali
16
549213
Scribunto
text/plain
--script that retrieves basic data stored in Wikidata, for the datamodel, see https://www.mediawiki.org/wiki/Extension:Wikibase_Client/Lua
local wd = {}
local modules = { }
local modulesNames = {
reference = 'Module:Wikidata/Références',
i18n = 'Module:Wikidata/I18n',
globes = 'Module:Wikidata/Globes',
langcodes = 'Module:Dictionnaire Wikidata/Codes langue', -- big, infrequently useda
invertedlangcodes = 'Module:Dictionnaire Wikidata/Codes langue/inversé',
linguistic = 'Module:Linguistique',
formatDate = 'Module:Date complexe',
formatNum = 'Module:Conversion',
langmodule = 'Module:Langue',
cite = 'Module:Biblio',
weblink = 'Module:Weblink'
}
local function loadModule( t, key )
if modulesNames[key] then
local m = require( modulesNames[key] )
t[key] = m
return m
end
end
setmetatable( modules, { __index = loadModule } )
local datequalifiers = {'P585', 'P571', 'P580', 'P582', 'P1319', 'P1326'}
-- === I18n ===
local defaultlang = mw.getContentLanguage():getCode()
function wd.translate(str, rep1, rep2)
str = modules.i18n[str] or str
if rep1 and (type (rep1) == 'string') then
str = str:gsub('$1', rep1)
end
if rep2 and (type (rep2) == 'string')then
str = str:gsub('$2', rep2)
end
return str
end
local function addCat(cat, sortkey)
if sortkey then
return '[[Category:' .. cat .. '|' .. sortkey .. ']]'
end
return '[[Category:' .. cat .. ']]'
end
local function formatError( key , category, debug)
if debug then
return error(modules.i18n[key] or key)
end
if category then
return addCat(category, key)
else
return addCat('cat-unsorted-issue', key)
end
end
--
function wd.isSpecial(snak)
return (snak.snaktype ~= 'value')
end
function wd.getId(snak)
if (snak.snaktype == 'value') then
return 'Q' .. snak.datavalue.value['numeric-id']
end
end
function wd.getNumericId(snak)
if (snak.snaktype == 'value') then
return snak.datavalue.value['numeric-id']
end
end
function wd.getMainId(claim)
return wd.getId(claim.mainsnak)
end
function wd.entityId(entity)
if type(entity) == 'string' then
return entity
elseif type(entity) == 'table' then
return entity.id
end
end
function wd.getEntityIdForCurrentPage()
return mw.wikibase.getEntityIdForCurrentPage()
end
-- function that returns true if the "qid" parameter is the qid
-- of the item that is linked to the calling page
function wd.isPageOfQId(qid)
local self_id = mw.wikibase.getEntityIdForCurrentPage()
return self_id ~= nil and qid == self_id
end
function wd.getEntity( val )
if type(val) == 'table' then
return val
end
if val == '-' then
return nil
end
if val == '' then
val = nil
end
return mw.wikibase.getEntity(val)
end
function wd.splitStr(val) -- transforme en table les chaînes venant du Wikitexte qui utilisent des virgules de séparation
if type(val) == 'string' then
val = mw.text.split(val, ",")
end
return val
end
function wd.isHere(searchset, val)
for i, j in pairs(searchset) do
if val == j then
return true
end
end
return false
end
local function wikidataLink(entity)
local name =':d:'
if type(entity) == 'string' then
if entity:match("P[0-9+]") then
entity = "Property:" .. entity
end
return name .. entity
elseif type(entity) == 'table' then
if entity["type"] == "property" then
name = ":d:Property:"
end
return name .. entity.id
elseif type(entity) == nil then
return formatError('entity-not-found')
end
end
function wd.siteLink(entity, project, lang)
-- returns 3 values: a sitelink (with the relevant prefix) a project name and a language
lang = lang or defaultlang
if (type(project) ~= 'string') then
project = 'wiki'
end
project = project:lower()
if project == 'wikipedia' then
project = 'wiki'
end
if type(entity) == 'string' and (project == 'wiki') and ( (not lang or lang == defaultlang) ) then -- évite de charger l'élément entier
return mw.wikibase.sitelink(entity), 'wiki', defaultlang
end
if project == 'wikidata' then
return wikidataLink(entity), 'wikidata'
end
local projects = {
-- nom = {préfixe sur Wikidata, préfix pour les liens sur Wikipédia, ajouter préfixe de langue}
wiki = {'wiki', nil, true}, -- wikipedia
commons = {'commonswiki', 'commons', false},
commonswiki = {'commonswiki', 'commons', false},
wikiquote = {'wikiquote', 'q', true},
wikivoyage = {'wikivoyage', 'voy', true},
wikibooks = {'wikibooks', 'b', true},
wikinews = {'wikinews', 'n', true},
wikiversity = {'wikiversity', 'v', true},
wikisource = {'wikisource', 's', true},
wiktionary = {'wiktionary', 'wikt', true},
specieswiki = {'specieswiki', 'species', false},
metawiki = {'metawiki', 'm', false},
incubator = {'incubator', 'incubator', false},
outreach = {'outreach', 'outreach', false},
mediawiki = {'mediawiki', 'mw', false}
}
local entityid = entity.id or entity
local projectdata = projects[project:lower()]
if not projectdata then -- defaultlink might be in the form "enwiki" rather than "project: 'wiki', lang: 'en' "
for k, v in pairs(projects) do
if project:match( k .. '$' )
and mw.language.isKnownLanguageTag(project:sub(1, #project-#k))
then
lang = project:sub(1, #project-#k)
project = project:sub(#lang + 1, #project)
projectdata = projects[project]
break
end
end
if not mw.language.isKnownLanguageTag(lang) then
return --formatError('invalid-project-code', projet or 'nil')
end
end
if not projectdata then
return -- formatError('invalid-project-code', projet or 'nil')
end
local linkcode = projectdata[1]
local prefix = projectdata[2]
local multiversion = projectdata[3]
if multiversion then
linkcode = lang .. linkcode
end
local link = mw.wikibase.getSitelink(entityid, linkcode)
if not link then
return nil
end
if prefix then
link = prefix .. ':' .. link
end
if multiversion then
link = ':' .. lang .. ':' .. link
end
return link, project, lang
end
-- add new values to a list, avoiding duplicates
function wd.addNewValues(olditems, newitems, maxnum, stopval)
if not newitems then
return olditems
end
for _, qid in pairs(newitems) do
if stopval and (qid == stopval) then
table.insert(olditems, qid)
return olditems
end
if maxnum and (#olditems >= maxnum) then
return olditems
end
if not wd.isHere(olditems, qid) then
table.insert(olditems, qid)
end
end
return olditems
end
--=== FILTER CLAIMS ACCORDING TO VARIOUS CRITERIA : FUNCTION GETCLAIMS et alii ===
local function notSpecial(claim)
local type
if claim.mainsnak ~= nil then
type = claim.mainsnak.snaktype
else
-- condition respectée quand showonlyqualifier est un paramètre renseigné
-- dans ce cas, claim n'est pas une déclaration entière, mais UNE snak qualifiée du main snak
type = claim.snaktype
end
return type == 'value'
end
local function hasTargetValue(claim, targets) -- retourne true si la valeur est dans la liste des target, ou si c'est une valeur spéciale filtrée séparément par excludespecial
local id = wd.getMainId(claim)
local targets = wd.splitStr(targets)
return wd.isHere(targets, id) or wd.isSpecial(claim.mainsnak)
end
local function excludeValues(claim, values) -- true si la valeur n'est pas dans la liste, ou si c'est une valeur spéciale (filtrée à part par excludespecial)
return wd.isSpecial(claim.mainsnak) or not ( hasTargetValue(claim, values) )
end
local function bestRanked(claims)
if not claims then
return nil
end
local preferred, normal = {}, {}
for i, j in pairs(claims) do
if j.rank == 'preferred' then
table.insert(preferred, j)
elseif j.rank == 'normal' then
table.insert(normal, j)
end
end
if #preferred > 0 then
return preferred
else
return normal
end
end
local function withRank(claims, target)
if target == 'best' then
return bestRanked(claims)
end
local newclaims = {}
for pos, claim in pairs(claims) do
if target == 'valid' then
if claim.rank ~= 'deprecated' then
table.insert(newclaims, claim)
end
elseif claim.rank == target then
table.insert(newclaims, claim)
end
end
return newclaims
end
function wd.hasQualifier(claim, acceptedqualifs, acceptedvals, excludequalifiervalues)
local claimqualifs = claim.qualifiers
if (not claimqualifs) then
return false
end
acceptedqualifs = wd.splitStr(acceptedqualifs)
acceptedvals = wd.splitStr( acceptedvals)
local function ok(qualif) -- vérification pour un qualificatif individuel
if not claimqualifs[qualif] then
return false
end
if not (acceptedvals) then -- si aucune valeur spécifique n'est demandée, OK
return true
end
for i, wanted in pairs(acceptedvals) do
for j, actual in pairs(claimqualifs[qualif]) do
if wd.getId(actual) == wanted then
return true
end
end
end
end
for i, qualif in pairs(acceptedqualifs) do
if ok(qualif) then
return true
end
end
return false
end
function wd.hasQualifierNumber(claim, acceptedqualifs, acceptedvals, excludequalifiervalues)
local claimqualifs = claim.qualifiers
if (not claimqualifs) then
return false
end
acceptedqualifs = wd.splitStr(acceptedqualifs)
acceptedvals = wd.splitStr( acceptedvals)
local function ok(qualif) -- vérification pour un qualificatif individuel
if not claimqualifs[qualif] then
return false
end
if not (acceptedvals) then -- si aucune valeur spécifique n'est demandée, OK
return true
end
for i, wanted in pairs(acceptedvals) do
for j, actual in pairs(claimqualifs[qualif]) do
if mw.wikibase.renderSnak(actual) == wanted then
return true
end
end
end
end
for i, qualif in pairs(acceptedqualifs) do
if ok(qualif) then
return true
end
end
return false
end
local function hasSource(claim, targetsource, sourceproperty)
sourceproperty = sourceproperty or 'P248'
if targetsource == "-" then
return true
end
if (not claim.references) then return
false
end
local candidates = claim.references[1].snaks[sourceproperty] -- les snaks utilisant la propriété demandée
if (not candidates) then
return false
end
if (targetsource == "any") then -- si n'importe quelle valeur est acceptée tant qu'elle utilise en ref la propriété demandée
return true
end
targetsource = wd.splitStr(targetsource)
for _, source in pairs(candidates) do
local s = wd.getId(source)
for i, target in pairs(targetsource) do
if s == target then return true end
end
end
return false
end
local function excludeQualifier(claim, qualifier, qualifiervalues)
return not wd.hasQualifier(claim, qualifier, qualifiervalues)
end
function wd.hasDate(claim)
if not claim then
return false --error() ?
end
if wd.getDateFromQualif(claim, 'P585') or wd.getDateFromQualif(claim, 'P580') or wd.getDateFromQualif(claim, 'P582') then
return true
end
return false
end
local function hasLink(claim, site, lang)
if (claim.mainsnak.snaktype ~= 'value') then -- ne pas supprimer les valeurs spéciales, il y a une fonction dédiée pour ça
return true
end
local id = wd.getMainId(claim)
local link = wd.siteLink(id, site, lang)
if link then
return true
end
end
local function isInLanguage(claim, lang) -- ne fonctionne que pour les monolingualtext / étendre aux autres types en utilisant les qualifiers ?
if type(lang) == 'table' then -- si c'est une table de language séparées par des virgules, on les accepte toutes
for i, l in pairs(lang) do
local v = isInLanguage(claim, l)
if v then
return true
end
end
end
if type(lang) ~= ('string') then
return --?
end
if (lang == '-') then
return true
end
if (lang == 'locallang') then
lang = mw.getContentLanguage():getCode()
end
-- pour les monolingual text
local snak = claim.mainsnak or claim
if snak.snaktype == 'value' and snak.datavalue.type == 'monolingualtext' then
if snak.datavalue.value.language == lang then
return true
end
return false
end
-- pour les autres types de données : recherche dans les qualificatifs
if (lang == 'diq') then
lang = 'Q150'
elseif (lang == 'en') then
lang = 'Q1860'
else
lang = invertedlangcodes[lang]
end
if claim.qualifiers and claim.qualifiers.P407 then
if wd.hasQualifier(claim, {'P407'}, {lang}) then
return true
else
return false
end
end
return true -- si on ne ne sait pas la langue, on condière que c'est bon
end
local function firstVals(claims, numval) -- retourn les numval premières valeurs de la table claims
local numval = tonumber(numval) or 0 -- raise a error if numval is not a positive integer ?
if not claims then
return nil
end
while (#claims > numval) do
table.remove(claims)
end
return claims
end
local function lastVals(claims, numval2) -- retourn les valeurs de la table claims à partir de numval2
local numval2 = tonumber(numval2) or 0 -- raise a error if numval is not a positive integer ?
if not claims then
return nil
end
for i=1,numval2 do
table.remove(claims, 1)
end
return claims
end
local function timeFromQualifs(claim, qualifs)
local claimqualifs = claim.qualifiers
if not claimqualifs then
return nil
end
for i, qualif in pairs(qualifs or timequalifiers) do
local vals = claimqualifs[qualif]
if vals and (vals[1].snaktype == 'value') then
return vals[1].datavalue.value.time
end
end
end
local function atDate(claim, mydate, precision)
if mydate == "today" then
mydate = os.date("!%Y-%m-%dT%TZ")
end
-- with point in time
local d = timeFromQualifs(claim, {'P585'})
if d then
return modules.formatDate.equal(mydate, d, precision)
end
-- with start or end date
local mindate = timeFromQualifs(claim, {'P580'})
local maxdate = timeFromQualifs(claim, {'P582'})
if modules.formatDate.before(mydate, mindate) and modules.formatDate.before(maxdate, mydate) then
return true
end
return false
end
local function check(claim, condition)
if type(condition) == 'function' then -- cas standard
return condition(claim)
end
return formatError('invalid type', 'function', type(condition))
end
local function minPrecision(claim, minprecision)
local snack
if claim.qualifiers then -- si une date est donnée en qualificatif, c'est elle qu'on utilise de préférence au mainsnak
for i, j in ipairs(datequalifiers) do
if claim.qualifiers[j] then
snack = claim.qualifiers[j][1]
break
end
end
end
if not snack then
snack = claim.mainsnak or claim
end
if (snack.snaktype == 'value') and (snack.datatype == 'time') and (snack.datavalue.value.precision < minprecision) then
return false
end
return true
end
function wd.sortClaims(claims, sorttype)
if not claims then
return nil
end
if sorttype == 'chronological' then
return wd.chronoSort(claims)
elseif sorttype == 'inverted' then
return wd.chronoSort(claims, true)
elseif sorttype == 'order' then
return wd.chronoSort(claims)
elseif type(sorttype) == 'function' then
table.sort(claims, sorttype)
return claims
elseif type(sorttype) == 'string' and sorttype:sub(1, 1) == 'P' then
return wd.numericPropertySort(claims, sorttype)
end
return claims
end
local alreadyFiltered = false
function wd.filterClaims(claims, args) --retire de la tables de claims celles qui sont éliminés par un des filters de la table des filters
local function filter(condition, filterfunction, funargs)
if not args[condition] then
return
end
for i = #claims, 1, -1 do
if not( filterfunction(claims[i], args[funargs[1]], args[funargs[2]], args[funargs[3]]) ) then
table.remove(claims, i)
end
end
end
filter('isinlang', isInLanguage, {'isinlang'} )
filter('excludespecial', notSpecial, {} )
filter('condition', check, {'condition'} )
if claims[1] and claims[1].mainsnak then
filter('targetvalue', hasTargetValue, {'targetvalue'} )
filter('atdate', atDate, {'atdate'} )
filter('qualifier', wd.hasQualifier, {'qualifier', 'qualifiervalue'} )
filter('qualifiernumber', wd.hasQualifierNumber, {'qualifiernumber', 'qualifiernumbervalue'} )
filter('excludequalifier', excludeQualifier, {'excludequalifier', 'excludequalifiervalue'} )
filter('withsource', hasSource, {'withsource', 'sourceproperty'} )
filter('withdate', wd.hasDate, {} )
filter('excludevalues', excludeValues, {'excludevalues'})
filter('withlink', hasLink, {'withlink', 'linklang'} )
filter('minprecision', minPrecision, {'minprecision'} )
claims = withRank(claims, args.rank or 'best')
end
if args.sorttype then
claims = wd.sortClaims(claims, args.sorttype)
end
if #claims == 0 then
return nil
end
if args.numval2 then
claims = lastVals(claims, args.numval2)
end
if args.numval then
claims = firstVals(claims, args.numval)
end
return claims
end
function wd.loadEntity(entity, cache)
if type(entity) ~= 'table' then
if cache then
if not cache[entity] then
cache[entity] = mw.wikibase.getEntity(entity)
mw.log("cached")
end
return cache[entity]
else
if entity == '' or (entity == '-') then
entity = nil
end
return mw.wikibase.getEntity(entity)
end
else
return entity
end
end
function wd.getClaims( args ) -- returns a table of the claims matching some conditions given in args
if args.claims then -- if claims have already been set, return them
return args.claims
end
local properties = args.property
if type(properties) == 'string' then
properties = wd.splitStr(string.upper(args.property))
end
if not properties then
return formatError( 'property-param-not-provided' )
end
--Get entity
local entity = args.entity
if type(entity) == 'string' then
if entity == '' then
entity = nil
end
elseif type(entity) == 'table' then
entity = entity.id
end
if (not entity) then
entity = mw.wikibase.getEntityIdForCurrentPage()
end
if (not entity) or (entity == '-') then
return nil
end
local claims = {}
if #properties == 1 then
claims = mw.wikibase.getAllStatements(entity, properties[1]) -- do not use mw.wikibase.getBestStatements at this stage, as it may remove the best ranked values that match other criteria in the query
else
for i, prop in ipairs(properties) do
local newclaims = mw.wikibase.getAllStatements(entity, prop)
if newclaims and #newclaims > 0 then
for j, claim in ipairs(newclaims) do
table.insert(claims, claim)
end
end
end
end
if (not claims) or (#claims == 0) then
return nil
end
return wd.filterClaims(claims, args)
end
--=== ENTITY FORMATTING ===
function wd.getLabel(entity, lang, labelformat)
if (not entity) then
return nil -- ou option de gestion des erreurs ?
end
lang = lang or defaultlang
if type(labelformat) == 'function' then
return labelformat(entity)
end
entity = entity.id or ( type(entity) == "string" and entity)
if (type(entity) == 'string') and (lang == defaultlang) then -- le plus économique
local str = mw.wikibase.label(entity)
if str then -- mw.wikibase.label() ne fonctionne pas avec les redirect https://phabricator.wikimedia.org/T157868
return str
end
end
return mw.wikibase.getLabelByLang(entity, lang)
end
function wd.formatEntity( entity, params )
if (not entity) then
return nil --formatError('entity-not-found')
end
local id = entity
if type(id) == 'table' then
id = id.id
end
params = params or {}
local lang = params.lang or defaultlang
local speciallabels = params.speciallabels
local displayformat = params.displayformat
local labelformat = params.labelformat
local defaultlabel = params.defaultlabel or id
local linktype = params.link
local defaultlink = params.defaultlink
local defaultlinkquery = params.defaultlinkquery
if speciallabels and speciallabels[id] then --speciallabels override the standard label + link combination
return speciallabels[id]
end
if params.displayformat == 'raw' then
return id
end
local link, label
label = wd.getLabel(entity, lang, labelformat)
-- détermination du fait qu'on soit ou non en train de rendre l'élément sur la page de son article
local rendering_entity_on_its_page = wd.isPageOfQId(id)
if not label then
if (defaultlabel == '-') then
return nil
end
link = wd.siteLink(id, 'wikidata')
return '[[' .. link .. '|' .. id .. ']]' .. addCat(modules.i18n['to translate'])
-- si pas de libellé, on met un lien vers Wikidata pour qu'on comprenne à quoi ça fait référence
end
if (linktype == '-') or rendering_entity_on_its_page then
return label
end
local link = wd.siteLink(entity, linktype, lang)
-- defaultlinkquery will try to link to another page on this Wiki
if (not link) and defaultlinkquery then
if type(defaultlinkquery) == 'string' then
defaultlinkquery = {property = defaultlinkquery}
end
defaultlinkquery.excludespecial = true
defaultlinkquery.entity = entity
local claims = wd.getClaims(defaultlinkquery)
if claims then
for i, j in pairs(claims) do
local id = wd.getMainId(j)
link = wd.siteLink(id, linktype, lang)
if link then
break
end
end
end
end
if link then
return '[[' .. link .. '|' .. label .. ']]'
end
-- if not link, you can use defaultlink: a sidelink to another Wikimedia project
if (not defaultlink) then
defaultlink = {'enwiki'}
end
if defaultlink and (defaultlink ~= '-') then
local linktype
local sidelink, site, langcode
if type(defaultlink) == 'string' then
defaultlink = {defaultlink}
end
for i, j in ipairs(defaultlink) do
sidelink, site, langcode = wd.siteLink(entity, j, lang)
if sidelink then
break
end
end
if not sidelink then
sidelink, site = wd.siteLink(entity, 'wikidata')
end
local icon, class, title = site, nil, nil -- le texte affiché du lien
if site == 'wiki' then
icon, class, title = langcode, "indicateur-langue", wd.translate('see-another-language', mw.language.fetchLanguageName(langcode, defaultlang))
elseif site == 'wikidata' then
icon, class, title = 'd', "indicateur-langue", wd.translate('see-wikidata')
else
title = wd.translate('see-another-project', site)
end
local val = '[[' .. sidelink .. '|' .. ']]'
return label .. ''
end
return label
end
function wd.addTrackingCat(prop, cat) -- doit parfois être appelé par d'autres modules
if type(prop) == 'table' then
prop = prop[1] -- devrait logiquement toutes les ajouter
end
if not prop and not cat then
return formatError("property-param-not-provided")
end
if not cat then
cat = wd.translate('trackingcat', prop or 'P??')
end
return addCat(cat )
end
local function unknownValue(snak, label)
local str = label
if type(str) == "function" then
str = str(snak)
end
if (not str) then
if snak.datatype == 'time' then
str = wd.translate('sometime')
else
str = wd.translate('somevalue')
end
end
if type(str) ~= "string" then
return formatError(snak.datatype)
end
return str
end
local function noValue(displayformat)
if not displayformat then
return wd.translate('novalue')
end
if type(displayformat) == 'string' then
return displayformat
end
return formatError()
end
local function getLangCode(entityid)
return modules.langcodes[tonumber(entityid:sub(2))]
end
local function showLang(statement) -- retourne le code langue entre paranthèse avant la valeur (par exemple pour les biblios et liens externes)
local mainsnak = statement.mainsnak
if mainsnak.snaktype ~= 'value' then
return nil
end
local langlist = {}
if mainsnak.datavalue.type == 'monolingualtext' then
langlist = {mainsnak.datavalue.value.language}
elseif (not statement.qualifiers) or (not statement.qualifiers.P407) then
return
else
for i, j in pairs( statement.qualifiers.P407 ) do
if j.snaktype == 'value' then
local langentity = wd.getId(j)
local langcode = getLangCode(langentity)
table.insert(langlist, langcode)
end
end
end
if (#langlist > 1) or (#langlist == 1 and langlist[1] ~= defaultlang) then -- si c'est en français, pas besoin de le dire
return modules.langmodule.indicationMultilingue(langlist)
end
end
-- === DATE HANDLING ===
function wd.addStandardQualifs(str, statement)
if (not statement) or (not statement.qualifiers) then
return str
end
if not str then
return error()-- what's that ?
end
if statement.qualifiers.P1480 then
for i, j in pairs(statement.qualifiers.P1480) do
local v = wd.getId(j)
if (v == "Q21818619") then
str = wd.translate('approximate-place', str)
elseif (v == "Q18122778") or (v == "Q18912752") then
str = wd.translate('uncertain-information', str)
elseif (v == "Q5727902") then
if (statement.mainsnak.datatype == 'time') then
str = modules.formatDate.fuzzydate(str)
else
str = wd.translate('approximate-value', str)
end
end
end
end
return str
end
local function rangeObject(begin, ending, params)
--[[
objet comportant un timestamp pour le classement chronologique et deux dateobject (begin et ending)
]]--
local timestamp
if begin then
timestamp = begin.timestamp
else
timestamp = ending.timestamp
end
return {begin = begin, ending = ending, timestamp = timestamp, type = 'rangeobject'}
end
local function dateObject(orig, params)
--[[ transforme un snak en un nouvel objet utilisable par Module:Date complexe
{type = 'dateobject', timestamp = str, era = '+' ou '-', year = number, month = number, day = number, calendar = calendar}
]]--
if not params then
params = {}
end
local newobj = modules.formatDate.splitDate(orig.time, orig.calendarmodel)
newobj.precision = params.precision or orig.precision
newobj.type = 'dateobject'
return newobj
end
local function objectToText(obj, params)
if obj.type == 'dateobject' then
return modules.formatDate.simplestring(obj, params)
elseif obj.type == 'rangeobject' then
return modules.formatDate.daterange(obj.begin, obj.ending, params)
end
end
function wd.getDateFromQualif(statement, qualif)
if (not statement) or (not statement.qualifiers) or not (statement.qualifiers[qualif]) then
return nil
end
local v = statement.qualifiers[qualif][1]
if v.snaktype ~= 'value' then -- que faire dans ce cas ?
return nil
end
return dateObject(v.datavalue.value)
end
function wd.getDate(statement)
local period = wd.getDateFromQualif(statement, 'P585') -- retourne un dateobject
if period then
return period
end
local begin, ending = wd.getDateFromQualif(statement, 'P580'), wd.getDateFromQualif(statement, 'P582')
if begin or ending then
return rangeObject(begin, ending) -- retourne un rangeobject fait de deux dateobject
end
return nil
end
function wd.getFormattedDate(statement, params)
if not statement then
return nil
end
local str
--cherche la date avec les qualifs P580/P582
local datetable = wd.getDate(statement)
if datetable then
str = objectToText(datetable, params)
end
-- puis limite intérieur / supérieur
if not str then
local start, ending = wd.getDateFromQualif(statement, 'P1319'), wd.getDateFromQualif(statement, 'P1326')
str = modules.formatDate.between(start, ending, params)
end
-- sinon, le mainsnak, pour les données de type time
if (not str) and (statement.mainsnak.datatype == 'time') then
local mainsnak = statement.mainsnak
if (mainsnak.snaktype == 'value') or (mainsnak.snaktype == 'somevalue') then
str = wd.formatSnak(mainsnak, params)
end
end
if str and params and (params.addstandardqualifs ~= '-') then
str = wd.addStandardQualifs(str, statement)
end
return str
end
-- Fonction qui trie des Claims de type time selon l'ordre chronologique
-- Une clé de tri nomée « dateSortKey » est ajouté à chaque claim.
-- Si des clés de tri de ce nom existent déjà, elles sont utilisées sans modification.
function wd.chronoSort( claims, inverted )
for _, claim in ipairs( claims ) do
if not claim.dateSortKey then
local snack = claim.mainsnak or claim
local iso
if (snack.snaktype == 'value') and (snack.datatype == 'time') then
iso = snack.datavalue.value.time
else
iso = timeFromQualifs(claim, datequalifiers) or '0'
end
-- transformation en nombre (indication de la base car gsub retourne deux valeurs)
iso = tonumber( iso:gsub( '(%d)%D', '%1' ), 10 )
claim.dateSortKey = iso
end
end
table.sort(
claims,
function ( c1, c2 )
if inverted then
return c2.dateSortKey < c1.dateSortKey
end
return c1.dateSortKey < c2.dateSortKey
end
)
return claims
end
-- Fonction qui trie des Claims de type value selon l'ordre de la propriété fournit
-- Une clé de tri nomée « dateSortKey » est ajouté à chaque claim.
-- Si des clés de tri de ce nom existent déjà, elles sont utilisées sans modification.
function wd.numericPropertySort( claims, propertySort )
for _, claim in ipairs( claims ) do
if not claim.dateSortKey then
local val
local claimqualifs = claim.qualifiers
if claimqualifs then
local vals = claimqualifs[propertySort]
if vals and vals[1].snaktype == 'value' then
val = vals[1].datavalue.value
end
end
claim.dateSortKey = tonumber(val or 0)
end
end
table.sort(
claims,
function ( c1, c2 )
return c1.dateSortKey < c2.dateSortKey
end
)
return claims
end
-- ===================
function wd.getReferences(statement)
local refdata = statement.references
if not refdata then
return nil
end
local refs = {}
local hashes = {}
for i, ref in pairs(refdata) do
local s
local function hasValue(prop) -- checks that the prop is here with valid value
if ref.snaks[prop] and ref.snaks[prop][1].snaktype == 'value' then
return true
end
return false
end
if ref.snaks.P248 then -- cas lorsque P248 (affirmé dans) est utilisé
for j, source in pairs(ref.snaks.P248) do
if source.snaktype == 'value' then
local page, accessdate, quotation
if hasValue('P304') then -- page
page = wd.formatSnak(ref.snaks.P304[1])
end
if hasValue('P813') then -- date de consultation
accessdate = wd.formatSnak(ref.snaks.P813[1])
end
if hasValue('P1683') then -- citation
quotation = wd.formatSnak(ref.snaks.P1683[1])
end
local sourceId = wd.getId(source)
s = modules.reference.citeitem(sourceId, {['page'] = page, ['accessdate'] = accessdate, ['citation'] = quotation})
table.insert(refs, s)
table.insert(hashes, ref.hash .. sourceId)
end
end
elseif hasValue('P854') then -- cas lorsque P854 (URL de la référence) est utilisé
local url, title, author, publisher, accessdate, publishdate, publishlang, quotation
url = wd.formatSnak(ref.snaks.P854[1], {text = "-"})
if hasValue('P1476') then
title = wd.formatSnak(ref.snaks.P1476[1])
else
title = mw.ustring.gsub(url, '^[Hh][Tt][Tt][Pp]([Ss]?):(/?)([^/])', 'http%1://%3')
end
--todo : handle multiple values for author, etc.
if hasValue('P813') then -- date de consultation
accessdate = wd.formatSnak(ref.snaks.P813[1])
end
if hasValue('P50') then -- author (item type)
author = wd.formatSnak(ref.snaks.P50[1])
elseif hasValue('P2093') then -- author (string type)
author = wd.formatSnak(ref.snaks.P2093[1])
end
if hasValue('P123') then -- éditeur
publisher = wd.formatSnak(ref.snaks.P123[1])
end
if hasValue('P1683') then -- citation
quotation = wd.formatSnak(ref.snaks.P1683[1])
end
if hasValue('P577') then -- date de publication
publishdate = wd.formatSnak(ref.snaks.P577[1])
end
if hasValue('P407') then -- langue de l'œuvre
local id = wd.getId(ref.snaks.P407[1])
publishlang = getLangCode(id)
end
s = modules.cite.lienWeb{titre = title, url = url, auteur = author, editeur = publisher, langue = publishlang, ['en ligne le'] = publishdate, ['consulté le'] = accessdate, ['citation'] = quotation}
table.insert(hashes, ref.hash)
table.insert(refs, s)
elseif ref.snaks.P854 and ref.snaks.P854[1].snaktype == 'value' then
s = wd.formatSnak(ref.snaks.P854[1], {text = "-"})
table.insert(hashes, ref.snaks.P854[1].hash)
table.insert(refs, s)
end
end
if #refs > 0 then
if #hashes == #refs then
return refs, hashes
end
return refs
end
end
function wd.sourceStr(sources, hashes)
if not sources or (#sources == 0) then
return nil
end
local useHashes = hashes and #hashes == #sources
for i, j in ipairs(sources) do
local refArgs = {name = 'ref', content = j}
if useHashes and hashes[i] ~= '-' then
refArgs.args = {name = 'wikidata-' .. hashes[i]}
end
sources[i] = mw.getCurrentFrame():extensionTag(refArgs)
end
return table.concat(sources)
end
function wd.getDataValue(snak, params)
if not params then
params = {}
end
local speciallabels = params.speciallabels -- parfois on a besoin de faire une liste d'éléments pour lequel le libellé doit être changé, pas très pratique d'utiliser une fonction pour ça
if snak.snaktype ~= 'value' then
return nil
end
local datatype = snak.datatype
local value = snak.datavalue.value
local displayformat = params.displayformat
if type(displayformat) == 'function' then
return displayformat(snak, params)
end
if datatype == 'wikibase-item' then
return wd.formatEntity(wd.getId(snak), params)
end
if datatype == 'url' then
return modules.weblink.makelink(value, params.text)
end
if datatype == 'math' then
return mw.getCurrentFrame():extensionTag( "math", value)
end
if (datatype == 'string') or (datatype == 'external-id') or (datatype == 'commonsMedia') then -- toutes les données de type string sauf "math"
if params.urlpattern then
local urlpattern = params.urlpattern
if type(urlpattern) == 'function' then
urlpattern = urlpattern(value)
end
local url = mw.ustring.gsub(urlpattern, '$1', (value:gsub('%%', '%%%%'))):gsub(' ', '%%20')
value = '[' .. url .. ' ' .. (params.text or value) .. ']'
end
return value
end
if datatype == 'time' then -- format example: +00000001809-02-12T00:00:00Z
if displayformat == 'raw' then
return value.time
else
local dateobject = dateObject(value, {precision = params.precision})
return objectToText(dateobject, params)
end
end
if datatype == 'globe-coordinate' then
-- retourne une table avec clés latitude, longitude, précision et globe à formater par un autre module (à changer ?)
if displayformat == 'latitude' then
return value.latitude
elseif displayformat == 'longitude' then
return value.longitude
else
local coordvalue = mw.clone( value )
coordvalue.globe = modules.globes[value.globe] -- transforme l'ID du globe en nom anglais utilisable par geohack
return coordvalue -- note : les coordonnées Wikidata peuvent être utilisée depuis Module:Coordinates. Faut-il aussi autoriser à appeler Module:Coordiantes ici ?
end
end
if datatype == 'quantity' then -- todo : gérer les paramètres précision
local amount, unit = value.amount, value.unit
if unit then
unit = unit:match('Q%d+')
end
local raw
if displayformat == "raw" then
raw = true
end
return modules.formatNum.displayvalue(amount, unit,
{targetunit = params.targetunit, raw = raw, rounding = params.rounding, showunit = params.showunit or 'short', showlink = params.showlink}
)
end
if datatype == 'monolingualtext' then
if value.language == defaultlang then
return value.text
else
return modules.langmodule.langue({value.language, value.text})
end
end
return formatError('unknown-datavalue-type' )
end
function wd.stringTable(args) -- like getClaims, but get a list of string rather than a list of snaks, for easier manipulation
local claims = args.claims
if not claims then
claims = wd.getClaims(args)
end
if not claims or claims == {} then
return {}, {}
end
local props = {} -- liste des propriétés associété à chaque string pour catégorisation et linkback
for i, j in pairs(claims) do
claims[i] = wd.formatStatement(j, args)
table.insert(props, j.mainsnak.property)
end
if args.removedupes and (args.removedupes ~= '-') then
claims = wd.addNewValues({}, claims) -- devrait aussi supprimer de props celles qui ne sont pas utilisées
end
return claims, props
end
function wd.getQualifiers(statement, qualifs, params)
if not statement.qualifiers then
return nil
end
local vals = {}
if type(qualifs) == 'string' then
qualifs = wd.splitStr(qualifs)
end
for i, j in pairs(qualifs) do
if statement.qualifiers[j] then
for k, l in pairs(statement.qualifiers[j]) do
table.insert(vals, l)
end
end
end
if #vals == 0 then
return nil
end
return vals
end
function wd.getFormattedQualifiers(statement, qualifs, params)
if not params then params = {} end
local qualiftable = wd.getQualifiers(statement, qualifs)
if not qualiftable then
return nil
end
qualiftable = wd.filterClaims(qualiftable, params) or {}
for i, j in pairs(qualiftable) do
qualiftable[i] = wd.formatSnak(j, params)
end
return modules.linguistic.conj(qualiftable, params.conjtype)
end
function wd.showQualifiers(str, statement, args)
local qualifs = args.showqualifiers
if not qualifs then
return str -- or error ?
end
if type(qualifs) == 'string' then
qualifs = wd.splitStr(qualifs)
end
local qualifargs = args.qualifargs or {}
-- formatage des qualificatifs = args commençant par "qualif", ou à défaut, les mêmes que pour la valeur principale
qualifargs.displayformat = args.qualifdisplayformat or args.displayformat
qualifargs.labelformat = args.qualiflabelformat or args.labelformat
qualifargs.link = args.qualiflink or args.link
qualifargs.linktopic = args.qualiflinktopic or args.linktopic
qualifargs.conjtype = args.qualifconjtype
qualifargs.defaultlink = args.qualifdefaultlink or args.defaultlink
qualifargs.defaultlinkquery = args.qualifdefaultlinkquery or args.defaultlinkquery
local formattedqualifs = wd.getFormattedQualifiers(statement, qualifs, qualifargs)
if formattedqualifs and formattedqualifs ~= "" then
str = str .. " (" .. formattedqualifs .. ")"
end
return str
end
function wd.formatSnak( snak, params )
if not params then params = {} end -- pour faciliter l'appel depuis d'autres modules
if snak.snaktype == 'somevalue' then
return unknownValue(snak, params.unknownlabel)
elseif snak.snaktype == 'novalue' then
return noValue(params.novaluelabel)
elseif snak.snaktype == 'value' then
return wd.getDataValue( snak, params)
else
return formatError( 'unknown-snak-type' )
end
end
function wd.formatStatement( statement, args )
if not args then
args = {}
end
if not statement.type or statement.type ~= 'statement' then
return formatError( 'unknown-claim-type' )
end
local prop = statement.mainsnak.property
local str
-- special displayformat f
if args.statementformat and (type(args.statementformat) == 'function') then
str = args.statementformat(statement, args)
elseif (statement.mainsnak.datatype == 'time') and (statement.mainsnak.dateformat ~= '-') then
if args.displayformat == 'raw' and statement.mainsnak.snaktype == 'value' then
str = statement.mainsnak.datavalue.value.time
else
str = wd.getFormattedDate(statement, args)
end
elseif args.showonlyqualifier and (args.showonlyqualifier ~= '') then
str = wd.getFormattedQualifiers(statement, args.showonlyqualifier, args)
if not str then
return nil
end
if args.addstandardqualifs ~= '-' then
str = wd.addStandardQualifs(str, statement)
end
else
str = wd.formatSnak( statement.mainsnak, args )
if args.addstandardqualifs ~= '-' then
str = wd.addStandardQualifs(str, statement)
end
end
-- ajouts divers
if args.showlang == true then
local indicateur = showLang(statement)
if indicateur then
str = indicateur .. ' ' .. str
end
end
if args.showqualifiers then
str = wd.showQualifiers(str, statement, args)
end
if args.showdate then -- when "showdate and chronosort are both set, date retrieval is performed twice
local period = wd.getFormattedDate(statement, args, "-") -- 3 arguments indicate the we should not use additional qualifiers, alrady added by wd.formatStatement
if period then
str = str .. " <small>(" .. period .. ")</small>"
end
end
if args.showsource then
local sources, hashes = wd.getReferences(statement)
if sources then
local source = wd.sourceStr(sources, hashes)
if source then
str = str .. source
end
end
end
return str
end
function wd.addLinkBack(str, id, property)
if not id then
id = wd.getEntityIdForCurrentPage()
end
if not id then
return str
end
if type(property) == 'table' then
property = property[1]
end
id = wd.entityId(id)
local class = ''
if property then
class = 'wd_' .. string.lower(property)
end
local icon = '[[File:Blue pencil.svg|%s|10px|baseline|class=noviewer|link=%s]]'
local title = wd.translate('see-wikidata-value')
local url = mw.uri.fullUrl('d:' .. id, 'uselang=diq')
url.fragment = property -- ajoute une #ancre si paramètre "property" défini
url = tostring(url)
local v = mw.html.create('span')
:addClass(class)
:wikitext(str)
:tag('span')
:addClass('noprint wikidata-linkback')
:wikitext(icon:format(title, url))
:allDone()
return tostring(v)
end
function wd.addRefAnchor(str, id)
--[[
Insère une ancre pour une référence générée à partir d'un élément wd.
L'id Wikidata sert d'identifiant à l'ancre, à utiliser dans les modèles type "harvsp"
--]]
return tostring(
mw.html.create('span')
:attr('id', id)
:attr('class', "ouvrage")
:wikitext(str)
)
end
--=== FUNCTIONS USING AN ENTITY AS ARGUMENT ===
local function formatStatementsGrouped(args, type)
-- regroupe les affirmations ayant la même valeur en mainsnak, mais des qualificatifs différents
-- (seulement pour les propriétés de type élément)
local claims = wd.getClaims(args)
if not claims then
return nil
end
local groupedClaims = {}
-- regroupe les affirmations par valeur de mainsnak
local function addClaim(claim)
local id = wd.getMainId(claim)
for i, j in pairs(groupedClaims) do
if (j.id == id) then
table.insert(groupedClaims[i].claims, claim)
return
end
end
table.insert(groupedClaims, {id = id, claims = {claim}})
end
for i, claim in pairs(claims) do
addClaim(claim)
end
local stringTable = {}
-- instructions ad hoc pour les paramètres concernant la mise en forme d'une déclaration individuelle
local funs = {
{param = "showqualifiers", fun = function(str, claims)
local qualifs = {}
for i, claim in pairs(claims) do
local news = wd.getFormattedQualifiers(claim, args.showqualifiers, args)
if news then
table.insert(qualifs, news)
end
end
local qualifstr = modules.linguistic.conj(qualifs, "qualif-separator")
if qualifstr and qualifstr ~= "" then
str = str .. " (" .. qualifstr .. ")"
end
return str
end
},
{param = "showdate", fun = function(str, claims)
-- toutes les dates sont regroupées à l'intérieur des mêmes parenthèses ex "médaille d'or (1922, 1924)"
local dates = {}
for i, statement in pairs(claims) do
local s = wd.getFormattedDate(statement, args, true)
if statement then table.insert(dates, s) end
end
local datestr = modules.linguistic.conj(dates)
if datestr and datestr ~= "" then
str = str .. " <small>(" .. datestr .. ")</small>"
end
return str
end
},
{param = "showsource", fun = function(str, claims)
-- les sources sont toutes affichées au même endroit, à la fin
-- si deux affirmations ont la même source, on ne l'affiche qu'une fois
local sources = {}
local hashes = {}
local function dupeRef(old, new)
for i, j in pairs(old) do
if j == new then
return true
end
end
end
for i, claim in pairs(claims) do
local refs, refHashes = wd.getReferences(claim)
if refs then
for i, j in pairs(refs) do
if not dupeRef(sources, j) then
table.insert(sources, j)
local hash = (refHashes and refHashes[i]) or '-'
table.insert(hashes, hash)
end
end
end
end
return str .. (wd.sourceStr(sources, hashes) or "")
end
}
}
for i, group in pairs(groupedClaims) do -- bricolage pour utiliser les arguments de formatStatements
local str = wd.formatEntity(group.id, args)
for i, fun in pairs(funs) do
if args[fun.param] then
str = fun.fun(str, group.claims, args)
end
end
table.insert(stringTable, str)
end
args.valuetable = stringTable
return wd.formatStatements(args)
end
function wd.formatStatements( args )--Format statement and concat them cleanly
if args.value == '-' then
return nil
end
-- If a value is already set: use it, except if it's the special value {{WD}} (use wikidata)
if args.value and args.value ~= '' then
local valueexpl = wd.translate("activate-query")
if args.value ~= valueexpl then
return args.value
end
-- There is no value set, and args.expl disables wikidata on empty values
elseif args.expl then
return nil
end
if args.grouped and args.grouped ~= '' then
args.grouped = false
return formatStatementsGrouped(args)
end
local valuetable = args.valuetable -- dans le cas où les valeurs sont déjà formtées
local props -- les prorpriétés réellement utilisées (dans certainse cas, ce ne sont pas toutes celles de ags.property
if not valuetable then -- cas le plus courant
valuetable, props = wd.stringTable(args)
end
local str = modules.linguistic.conj(valuetable, args.conjtype)
if not str then
return args.default
end
if not props then
props = wd.splitStr(args.property)[1]
end
if args.ucfirst ~= '-' then
str = modules.linguistic.ucfirst(str)
end
if args.addcat and (args.addcat ~= '-') then
str = str .. wd.addTrackingCat(props)
end
if args.linkback and (args.linkback ~= '-') then
str = wd.addLinkBack(str, args.entity, props)
end
if args.returnnumberofvalues then
return str, #valuetable
end
return str
end
function wd.formatAndCat(args)
if not args then
return nil
end
args.linkback = args.linkback or true
args.addcat = true
if args.value then -- do not ignore linkback and addcat, as formatStatements do
if args.value == '-' then
return nil
end
local val = args.value .. wd.addTrackingCat(args.property)
val = wd.addLinkBack(val, args.entity, args.property)
return val
end
return wd.formatStatements( args )
end
function wd.getTheDate(args)
local claims = wd.getClaims(args)
if not claims then
return nil
end
local formattedvalues = {}
for i, j in pairs(claims) do
local v = wd.getFormattedDate(j, args)
if v then
table.insert(formattedvalues, v )
end
end
local val = modules.linguistic.conj(formattedvalues)
if not val then
return nil
end
if args.addcat == true then
val = val .. wd.addTrackingCat(args.property)
end
val = wd.addLinkBack(val, args.entity, args.property)
return val
end
function wd.keyDate (event, item, params)
params = params or {}
params.entity = item
if type(event) == 'table' then
for i, j in pairs(event) do
params.targetvalue = nil -- réinitialisation barbare des paramètres modifiés
local s = wd.keyDate(j, item, params)
if s then
return s
end
end
elseif type(event) ~= 'string' then
return formatError('invalid-datatype', type(event), 'string')
elseif string.sub(event, 1, 1) == 'Q' then -- on demande un élément utilisé dans P:P793 (événement clé)
params.property = 'P793'
params.targetvalue = event
params.addcat = params.addcat or true
return wd.getTheDate(params)
elseif string.sub(event, 1, 1) == 'P' then -- on demande une propriété
params.property = event
return wd.formatAndCat(params)
else
return formatError('invalid-entity-id', event)
end
end
function wd.mainDate(entity)
-- essaye P580/P582
local args = {entity = entity, addcat = true}
args.property = 'P580'
local startpoint = wd.formatStatements(args)
args.property = 'P582'
local endpoint = wd.formatStatements(args)
local str
if (startpoint or endpoint) then
str = modules.formatDate.daterange(startpoint, endpoint, params)
str = wd.addLinkBack(str, entity, 'P582')
return str
end
-- défaut : P585
args.property = {'P585', 'P571'}
args.linkback = true
return wd.formatStatements(args)
end
-- === FUNCTIONS FOR TRANSITIVE PROPERTIES ===
function wd.getIds(item, query)
query.excludespecial = true
query.displayformat = 'raw'
query.entity = item
query.addstandardqualifs = '-'
return wd.stringTable(query)
end
-- recursively adds a list of qid to an existing list, based on the results of a query
function wd.addVals(list, query, maxdepth, maxnodes, stopval)
maxdepth = tonumber(maxdepth) or 10
maxnodes = tonumber(maxnodes) or 100
if (maxdepth < 0) then
return list
end
if stopval and wd.isHere(list, stopval) then
return list
end
local origsize = #list
for i = 1, origsize do
-- tried a "checkpos" param instead of starting to 1 each time, but no impact on performance
local candidates = wd.getIds(list[i], query)
list = wd.addNewValues(list, candidates, maxnodes, stopval)
if list[#list] == stopval then
return list
end
if #list >= maxnodes then
return list
end
end
if (#list == origsize) then
return list
end
return wd.addVals(list, query, maxdepth - 1, maxnodes, stopval, origsize + 1)
end
-- returns a list of items transitively matching a query (orig item is not included in the list)
function wd.transitiveVals(item, query, maxdepth, maxnodes, stopval)
maxdepth = tonumber(maxdepth) or 5
if type(query) == "string" then
query = {property = query}
end
-- récupération des valeurs
local vals = wd.getIds(item, query)
if not vals then
return nil
end
local v = wd.addVals(vals, query, maxdepth - 1, maxnodes, stopval)
if not v then
return nil
end
-- réarrangement des valeurs
if query.valorder == "inverted" then
local a = {}
for i, j in pairs(v) do
table.insert(a, 1, j)
end
v = a
end
return v
end
-- returns true if an item is the value of a query, transitively
function wd.inTransitiveVals(searchedval, sourceval, query, maxdepth, maxnodes )
local vals = wd.transitiveVals(sourceval, query, maxdepth, maxnodes, searchedval )
if (not vals) then
return false
end
for _, val in ipairs(vals) do
if (val == searchedval) then
return true
end
end
return false
end
-- returns true if an item is a superclass of another, based on P279
function wd.isSubclass(class, item, maxdepth)
local query = {property = 'P279'}
if class == item then -- item is a subclass of itself iff it is a class
if wd.getIds(item, query) then
return true
end
return false
end
return wd.inTransitiveVals(class, item, query, maxdepth )
end
-- returns true if one of the best ranked P31 values of an item is the target or a subclass of the target
-- rank = 'valid' would seem to make sense, but it would need to check for date qualifiers as some P31 values have begin or end date
function wd.isInstance(targetclass, item, maxdepth)
maxdepth = maxdepth or 10
local directclasses = wd.transitiveVals(item, {property = 'P31'}, 1)
if not directclasses then
return false
end
for i, class in pairs(directclasses) do
if wd.isSubclass(targetclass, class, maxdepth - 1) then
return true
end
end
return false
end
-- return the first value in a transitive query that belongs to a particular class. For instance find a value of P131 that is a province of Canada
function wd.findVal(sourceitem, targetclass, query, recursion, instancedepth)
if type(query) == "string" then
query = {property = query}
end
local candidates = wd.getIds(sourceitem, query)
if candidates then
for i, j in pairs(candidates) do
if wd.isInstance(targetclass, j, instancedepth) then
return j
end
end
if not recursion then
recursion = 3
else
recursion = recursion - 1
end
if recursion < 0 then
return nil
end
for i, candidate in pairs(candidates) do
return wd.findVal(candidate, targetclass, query, recursion, instancedepth)
end
end
end
-- === VARIA ===
function wd.getDescription(entity, lang)
lang = lang or defaultlang
local description
if lang == defaultlang then
return mw.wikibase.descriptionl(qid)
end
if not entity.descriptions then
return wd.translate('no description')
end
local descriptions = entity.descriptions
if not descriptions then
return nil
end
if descriptions[lang] then
return descriptions[delang].value
end
return entity.id
end
function wd.Dump(entity)
entity = wd.getEntity(entity)
if not entity then
return formatError("entity-param-not-provided")
end
return "<pre>"..mw.dumpObject(entity).."</pre>"
end
function wd.frameFun(frame)
local args = frame.args
local funname = args[1]
table.remove(args, 1)
return wd[funname](args)
end
return wd
dpvnumy5zupnmafj3h7h8nxf2so54d7
Modul:Date complexe
828
60929
549216
549191
2026-06-23T07:07:57Z
Wikihez
19275
Restored revision 438552 by [[Special:Contributions/Xorasan|Xorasan]] ([[User talk:Xorasan|talk]]): Testing ([[:m:User:Xiplus/TwinkleGlobal|TwinkleGlobal]])
549216
Scribunto
text/plain
-- TODO: améliorer les synergies avec Module:Date (gestion par module:Date de dates sans lien et de "XIe siècle en astronautique"
local datemodule = require 'Module:Date'
local linguistic -- = require 'Module:Linguistique' -- chargé uniquement si nécessaire
local roman -- = require 'Module:Romain' -- chargé uniquement si nécessaire
local p = {}
local numericprecision = { -- convertir les précisions en valeurs numériques = à celles utilisées par Wikidata
gigayear = 0,
megayear = 3,
millenium = 6,
century = 7,
decade = 8,
year = 9,
month = 10,
day = 11,
hour = 12,
minute = 13,
second = 14,
}
local function vowelfirst(str)
linguistic = require 'Module:Linguistique'
return linguistic.vowelfirst(str)
end
local function setprecision(obj, maxprecision)
local precision
if type(obj) == "string" then
precision = tonumber(obj)
elseif type(obj) == "number" then
precision = obj
elseif type(obj) == "table" then
precision = tonumber(obj.precision) or numericprecision[obj.precision]
end
if not precision then
precision = 0
end
-- maxprecision, surtout pour données Wikidata quand on veut afficher avec moins de précision que l'input (par exemple afficher seulement l'année)
if maxprecision then
maxprecision = tonumber(maxprecision) or numericprecision[maxprecision]
end
if maxprecision then
return math.min(precision, maxprecision)
end
return precision
end
local function bigDate(year, precision) -- TODO : gestion de la précision
local format = require "Module:Format"
local val, unit = 0, ""
if year > 999999999 then
unit = " [[giga|G]][[Année julienne|a]]"
val = year / 1000000000
elseif year > 999999 then
unit = " [[méga|M]][[Année julienne|a]]"
val = year / 1000000
end
val = format.do_formatnum({val})
return val .. unit
end
local function milleniumString(millenium, era, hideera)
roman = roman or require 'Module:Romain'
local str = roman.toRoman(millenium) .. 'hezar'
if era == '-' and (not hideera) then
str = str .. 'İR '
end
return str
end
local function centuryString(century, era, hideera)
roman = roman or require 'Module:Romain'
local str = 'Seserra' .. roman.toRoman(century)
if era == '-' and (not hideera) then
str = str .. 'İR'
end
return str
end
local function decadeString(decade, era, hideera)
local str = ' ' .. decade .. '0'
if era == '-' and (not hideera) then
str = str .. ' İR '
end
return '[[' .. str .. ']]'
end
function p.simplestring(dateobject, displayformat)
-- transforme un object date ponctuel en texte
-- les dates de type ISO devraient passer par Module:Date, mais il faut pouvoir désactiver les liens
if type(dateobject) == 'string' or type(dateobject) == 'nil' then
return dateobject
end
if (not dateobject.year) and (not dateobject.month) and dateobject.day then -- si seul le jour est passé, par exemple à cause de removeclutter, le format n'est pas pris en charge par module:Date
if displayformat.precision and numericprecision[displayformat.precision] < 11 then
return ''
else
return tostring(dateobject.day)
end
end
local era = dateobject.era
if not displayformat then
displayformat = {}
end
local linktopic = displayformat.linktopic
local nolinks
if linktopic == '-' then
nolinks = true
end
local str
local precision = setprecision(dateobject, displayformat.precision)
-- formats gérés par ce module
local year = tonumber( dateobject.year) or 0
if year > 999999 then -- grosses dates pour l'astronomie, la paléontologie
return bigDate(year, precision)
end
local hideera = displayformat.hideera
if precision == 6 then
local millenium = math.floor((year - 1)/1000) + 1
str = milleniumString(millenium, era, hideera)
elseif precision == 7 then
local century = math.floor((year - 1)/100) + 1
str = centuryString(century, era, hideera)
elseif precision == 8 then
local decade = tostring(math.floor(year/10))
str = decadeString(decade, era, hideera)
end
if str then
return str
end
-- formats gérés par Module:Date
local year = dateobject.year
if year and (era == '-') then
year = 0 - year
end
local month, day
if precision > 9 then
month = dateobject.month
if precision > 10 then
day = dateobject.day
end
end
local avJC -- équivalent de hideera pour modeleDate
if displayformat.hideera then
avJC = 'non'
end
str = datemodule.modeleDate{jour = day, mois = month, annee = year, qualificatif = linktopic, nolinks = nolinks, avJC = avJC}
return str or ''
end
local function fromToNow(d, datestr, precision) -- retourne "depuis" plutôt que "à partir de" quand c'est pas terminé
if (precision >= 11) or (precision == 7) or (precision == 6) then -- ont dit "à partir du pour les dates avec jour, les siècles, les millénaires
if vowelfirst(datestr) then -- suppose l'absence de lien interne
return "depuis l'" .. datestr
else
return "depuis le " .. datestr
end
end
return "depuis " .. datestr
end
local function fromdate(d, displayformat) -- retourne "à partir de date" en langage naturel
displayformat = displayformat or {}
local precision = setprecision(d, displayformat.precision)
local datestr = p.simplestring(d, displayformat)
if displayformat and displayformat.textformat == 'minimum' then
return datestr -- par exemple pour les classements MH, juste afficher la date de début
end
if displayformat and displayformat.textformat == 'short' then
return datestr .. ' – ' -- pour certaines infobox (footballeur par exemple), afficher date de début et un tiret
end
if p.before ( os.date("!%Y-%m-%dT%TZ"), d) then return
fromToNow(d, datestr, precision)
end
if (precision >= 11) or (precision == 7) or (precision == 6) then -- ont dit "à partir du pour les dates avec jour, les siècles, les millénaires
return 'à partir du ' .. datestr
end
if (precision == 10) and (vowelfirst(datemodule.determinationMois(d.month))) then
return "à partir d'" .. datestr
end
return 'à partir de ' .. datestr
end
local function upto(d, displayformat) -- retourne "jusqu'à date' en langage naturel
displayformat = displayformat or {}
local datestring = p.simplestring(d, displayformat)
local precision = setprecision(d, displayformat.precision)
if displayformat and displayformat.textformat == 'infobox' then
return ' – '.. datestring-- pour certaines infobox (footballeur par exemple), afficher date de début et un tiret
end
if displayformat and displayformat.textformat == 'short' then
return' – ' .. datestring -- pour certaines infobox (footballeur par exemple), afficher date de début et un tiret
end
if (precision >= 11) or (precision == 7) or (precision == 6) then --on dit "jusqu'au" pour les dates avec jour, et pour les siècles
return "jusqu'au " .. datestring
elseif (precision > 9) then
return "jusqu'à " .. datestring
else
return "jusqu'en " .. datestring
end
end
local function fromuntillong(startstr, endstr, era, precision)
-- on dit "du 3 au 14 janvier" mais "de septembe à octobre
if precision >= 11 then -- >= day
return "du " .. startstr .. " au " .. endstr .. era
else
if vowelfirst(startstr) then
return "d'" .. startstr .. " à ".. endstr .. era
else
return "de " .. startstr .. " à " .. endstr .. era
end
end
end
local function removeclutter(startpoint, endpoint, precision, displayformat) -- prépare à rendre la date plus jolie : "juin 445 av-JC-juillet 445 av-JC -> juin-juillet 445-av-JC"
if (type(startpoint) ~= 'table') or (type(endpoint) ~= 'table') then
return startpoint, endpoint, precision, displayformat
end
local era = endpoint.era
local sameera
if startpoint.era == endpoint.era then
sameera = true
end
if sameera and (endpoint.year == startpoint.year) then
startpoint.year = nil
if (startpoint.month == endpoint.month) then
startpoint.month = nil
if (startpoint.day == endpoint.day) then
startpoint.day = nil
end
end
end
return startpoint, endpoint, era, displayformat, sameera
end
function p.between(startpoint, endpoint, displayformat)
displayformat = displayformat or {}
local precision = setprecision(endpoint, displayformat.precision) or 9
local startpoint = p.simplestring(startpoint, displayformat)
local endpoint = p.simplestring(endpoint, displayformat)
if not (startpoint or endpoint) then
return nil
end
if not endpoint then
if precision <= 10 then
return "après " .. startpoint
else
return "après le " .. startpoint
end
end
if not startpoint then
if precision <= 10 then
return "avant " .. endpoint
else
return "avant le " .. endpoint
end
end
-- analyse les paramètres pour éviter les redondances
local startpoint, endpoint, era, displayformat, sameera = removeclutter(startpoint, endpoint, precision, displayformat)
local startstr, endstr = p.simplestring(startpoint, displayformat), p.simplestring(endpoint, displayformat)
displayformat.hideera = true
if (startstr == '') or (startstr == endstr) then
if (not sameera) then
displayformat.hideera = false --sinon c'est incompréhensible
return p.simplestring(endpoint, displayformat)
end
return endstr
end
-- pour éviter les tournures répétitives comme "du 13 septembre 2006 au 18 september 2006"
if era == "-" then
era = " av J-C"
else
era = ""
end
if precision <= 10 then
return "mabênê " .. startstr .. " ya zi " .. endstr .. " " .. era
else
return "entre le " .. startstr .. " et le " .. endstr .. " " .. era
end
end
local function fromuntil(startpoint, endpoint, displayformat)
displayformat = displayformat or {}
local precision = setprecision(endpoint, displayformat.precision)
-- analyse les paramètres pour éviter les redondances
local startpoint, endpoint, era, displayformat, sameera = removeclutter(startpoint, endpoint, precision, displayformat)
local hideera= displayformat.hideera
displayformat.hideera = true -- pour les chaînes intermédiaires
local startstr, endstr = p.simplestring(startpoint, displayformat), p.simplestring(endpoint, displayformat)
if (startstr == '') or (startstr == endstr) then
displayformat.hideera = hideera -- on va faire une chaîne simple, on reprend donc le format initialement demandé
if (not sameera) then
displayformat.hideera = false --sinon c'est incompréhensible
end
return p.simplestring(endpoint, displayformat)
end
-- pour éviter les tournures répétitives comme "du 13 septembre 2006 au 18 september 2006"
if era == '-' then
era = ' İR'
else
era = ''
end
if displayformat.textformat == 'long' then
return fromuntillong(startstr, endstr, era, precision)
elseif (type(precision) == "number") and (precision > 9) then -- si les date contiennent des mois ou jours, il vaut mieux un espace
return startstr .. ' -<wbr> ' .. endstr .. era
else
return startstr .. '-<wbr>' .. endstr .. era
end
end
function p.fuzzydate(dateobject, displayformat)
local str = p.simplestring(dateobject, displayformat)
if not str then
return nil
end
return "verê " .. str
end
function p.daterange(startpoint, endpoint, displayformat)
if startpoint and endpoint then
return fromuntil(startpoint, endpoint, displayformat)
elseif startpoint then
return fromdate(startpoint, displayformat)
elseif endpoint then
return upto(endpoint, displayformat)
else
return nil
end
end
function p.duration(start, ending)
if (not start) or (not ending) then
return nil -- ?
end
return datemodule.age(start.year, start.month, start.day, ending.year, ending.month, ending.day)
end
local function splitWDdate(str) -- depuis datavalue.value.time de Wikidata, fonctionnerait aussi en utilisant simplement splitISO
local pattern = "(%W)(%d+)%-(%d+)%-(%d+)"
local era, year, month, day = str:match(pattern)
return era, year, month, day
end
local function splitISO(str)
local era, year, month, day
era = string.sub(str, 1, 1)
if tonumber(era) then
era = '+'
end
local f = string.gmatch(str, '%d+')
year, month, day = f(), f(), f()
return era, year, month, day
end
function p.splitDate(orig, calendar)
if not orig then
return nil
end
if type(orig) == 'table' then
return orig
end
if type(orig) ~= 'string' then
return error("bad datatype for date, string expected, got " .. type(orig))
end
local era, y, m, d = splitWDdate(orig)
if not era then
era, y, m, d = splitISO(orig)
end
y, m, d = tonumber(y or 1), tonumber(m or 1), tonumber(d or 1)
return {day = d, month = m, year = y, era = era, type = 'dateobject', calendar = calendar}
end
function p.before(a, b) -- return true if b is before a or if at least one of a or b is missing
a = p.splitDate(a)
b = p.splitDate(b)
if (not a) or (not b) then
return true
end
local order = {'era', 'year', 'month', 'day'}
for i, j in pairs(order) do
if b[j] < a[j] then
return true
elseif b[j] > a[j] then
return false
end
end
return true
end
return p
td175s5n84uloefhesobgbdefhml4b3
Modul:Date
828
60930
549217
548299
2026-06-23T07:12:21Z
Wikihez
19275
Reverted 1 edit by [[Special:Contributions/~2026-18379-86|~2026-18379-86]] ([[User talk:~2026-18379-86|talk]]) ([[:m:User:Xiplus/TwinkleGlobal|TwinkleGlobal]])
549217
Scribunto
text/plain
local fun = {}
local Outils = require 'Module:Outils'
-- chargement de la base de données répertoriant certaines pages existant ou n'existant pas pour éviter les "ifexist".
local dataLiens
local success, resultat = pcall ( mw.loadData, 'Module:Date/Data' )
if success then
dataLiens = resultat
else
-- protection au cas où le sous-module serait mal modifié
dataLiens = { [''] = { mois = { aucun = 1000, tous = { 1773, 1774 } }, } }
end
-- nettoie un paramètre non nommé (vire les espaces au début et à la fin)
-- retourne nil si le texte est vide ou n'est pas du texte. Attention c'est important pour les fonctions qui l'utilisent.
local trim = Outils.trim
-- Fonction destinée à mettre la première lettre du mois en majuscule :
-- utilisation de string car aucun mois ne commence par une lettre non ascii en français ou anglais.
local function ucfirst( str )
return str:sub( 1, 1 ):upper() .. str:sub( 2 )
end
local modelePremier = '<abbr class="abbr" title="premier">1<sup>ê</sup></abbr>'
-- liste des mois, écriture exacte et alias, en minuscule
local listeMois = {
{ num = 1, nJour = 31, abrev = 'janv.', nom = 'Çele', alias = { 'jan.', 'janv.', 'jan', 'janv', 'january' } },
{ num = 2, nJour = 29, abrev = 'fév.', nom = 'Şıbate', alias = { 'fevrier', 'fev.', 'fev', 'fév.', 'fév', 'févr', 'févr.', 'february', 'feb', 'feb.' } },
{ num = 3, nJour = 31, abrev = 'mars', nom = 'Adar', alias = { 'mar.', 'mar', 'march' } },
{ num = 4, nJour = 30, abrev = 'avr.', nom = 'Nisane', alias = { 'avr.', 'avr', 'apr', 'april'} },
{ num = 5, nJour = 31, abrev = 'mai', nom = 'Gulane', alias = { 'may' } },
{ num = 6, nJour = 30, abrev = 'juin', nom = 'Heziran', alias = { 'jun', 'june' } },
{ num = 7, nJour = 31, abrev = 'juill.', nom = 'Temuz', alias = { 'juil.', 'juil', 'juill.', 'juill', 'jul', 'july' } },
{ num = 8, nJour = 31, abrev = 'août', nom = 'Tebaxe', alias = { 'aoû', 'aug', 'august' } },
{ num = 9, nJour = 30, abrev = 'sept.', nom = 'Keşkelun', alias = { 'sept.', 'sept', 'sep.', 'sep', 'september' } },
{ num = 10, nJour = 31, abrev = 'oct.', nom = 'Tışrino Verên ', alias = { 'oct.', 'oct', 'october' } },
{ num = 11, nJour = 30, abrev = 'nov.', nom = 'Tışrino Peyên ', alias = { 'nov.', 'nov', 'november' } },
{ num = 12, nJour = 31, abrev = 'déc.', nom = 'Kanun ', alias = { 'decembre', 'déc.', 'dec.', 'dec', 'déc', 'december' } },
aout = { num = 8, nJour = 31, abrev = 'aout', nom = 'Ağustos ', alias = { 'aou' } },
}
-- ajoute les noms, abréviations et alias en tant que clés de listeMois
for i = 1, 12 do
local mois = listeMois[i]
listeMois[tostring( i )] = mois
if i < 10 then
listeMois['0' .. i] = mois
end
listeMois[mois.nom] = mois
listeMois[mois.abrev] = mois
for _, n in ipairs( mois.alias ) do
listeMois[n] = mois
end
end
for _, n in ipairs( listeMois.aout.alias ) do
listeMois[n] = listeMois.aout
end
local liste_saisons = {
{ 'printemps', 'spring', },
{ 'été', 'summer', },
{ 'automne', 'autumn', },
{ 'hiver', 'winter', },
}
-- à partir d'un nom de saison (en français ou en anglais),
-- retourne son nom canonique (exemple : "été")
-- si non reconnu, retourne nil
function fun.determinationSaison( saison )
local s = trim( saison )
if s then
s = mw.ustring.lower( s )
for i = 1, 4 do
for _, n in ipairs( liste_saisons[i] ) do
if s == n then
return liste_saisons[i][1]
end
end
end
end
end
---
-- à partir d'un nom de mois (en français ou en anglais), de son numéro ou d'une abréviation,
-- retourne son nom canonique (exemple : "juin") et son numéro (exemple : 6)
-- si non reconnu, retourne nil, nil
function fun.determinationMois( mois )
local result
local num = tonumber( mois )
if num then
result = listeMois[num]
else
local str = trim( mois )
if str then
result = listeMois[str]
if not result then
result = listeMois[mw.ustring.lower( str )]
end
end
end
if result then
return result.nom, result.num
else
return nil, nil
end
end
-- fonction interne à modeleDate, pour déterminer si on peut se passer de faire un ifexist
local function existDate( dataQualificatif, annee, mois )
local data
if mois then
data = dataQualificatif.mois
else
data = dataQualificatif.annee
end
if type( data ) ~= 'table' then
-- si data n'existe pas c'est que l'on considère qu'il n'y a pas de lien.
return
end
-- le qualificatif est remplacé par celui de la base de données, ce qui permet des alias.
local lien = annee
if dataQualificatif.qualificatif then
lien = lien .. ' ' .. dataQualificatif.qualificatif
end
local seul = annee
if mois then
lien = mois .. ' ' .. lien
seul = ucfirst( mois ) .. ' ' .. annee
end
local aucun = tonumber( data.aucun )
if aucun and annee <= aucun then
-- si l'année est dans la partie 'aucun' on teste s'il y a malgré tout un lien isolé
if type( data.seul ) == 'table' then
for i, v in ipairs( data.seul ) do
if seul == v or seul == tonumber( v ) then
return lien
end
end
end
-- partie aucun et pas de lien => nil
return nil
elseif type( data.tous ) == 'table' then
local tous1, tous2 = tonumber( data.tous[1] ), tonumber( data.tous[2] )
if tous1 and tous2 and annee >= tous1 and annee <= tous2 then
-- l'année est dans la partie 'tous' donc on retourne le lien
return lien
end
end
-- l'année n'est ni dans la partie aucun, ni dans la partie tous donc il faut tester si la page existe.
local cibleLien = mw.title.new( lien )
if cibleLien and cibleLien.exists then
return lien
end
end
---
-- Supprime le jour de la semaine, et "le" avant une date
function fun.nettoyageJour( jour )
if type( jour ) == 'string' then
local nomJour = { '[Ll]undi', '[Mm]ardi', '[Mm]ercredi', '[Jj]eudi', '[Vv]endredi',
'[Ss]amedi', '[Dd]imanche', '^ *[Ll]e' }
local premier = { '<abbr class="abbr ?" title="[Pp]remier" ?>1<sup></sup></abbr>', '1<sup></sup>', '1' }
for i, v in ipairs( nomJour ) do
jour = jour:gsub( v, '' )
end
for i, v in ipairs( premier ) do
jour = jour:gsub( v, '1' )
end
jour = trim( jour )
end
return jour
end
---
-- Sépare une chaine date en une table contenant les champs jour, mois et annee.
-- la date doit contenir le mois.
function fun.separationJourMoisAnnee( date )
date = trim( date )
if date then
local function erreur( periode, valeur )
return false, '<span class="error">' .. periode .. ' invalide (' .. valeur .. ')</span>'
end
local jour, mois, annee, masquerMois, masquerAnnee, separateur
-- 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 mmm2 = '([^%s%p%d]+[.]?[-/][^%s%p%d]+[.]?)' -- mois-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
date = fun.nettoyageJour( date )
-- suppression catégorie, liens, balises
date = mw.ustring.gsub( date, '%[%[[Cc]at[ée]gor[yi]e?:.-%]%]', '' )
date = date :gsub( '%b<>', '' )
:gsub( '%[%[([^%[%]|]*)|?([^%[%]]*)%]%]', function ( l, t ) return trim( t ) or l end )
-- suppression des espaces insécables
-- nbsp
:gsub( '\194\160', ' ' )
:gsub( ' ', ' ' )
:gsub( ' ', ' ' )
-- narrow nbsp
:gsub( '\226\128\175', ' ' )
:gsub( ' ', ' ' )
-- thin space
:gsub( '\226\128\137', ' ' )
:gsub( ' ', ' ' )
:gsub( ' ', ' ' )
-- simple space
:gsub( ' ', ' ' )
-- plusieurs espaces
:gsub( ' +', ' ' )
-- réduction av. J-C pour simplifier un peu les regex :
:gsub( '?[İR]%? (%d+)' , '-%1' )
-- suppression de l'heure dans les dates ISO
:gsub( '^+?([%d-]*%d%d%-%d%d)T%d%d[%d:,.+-]*Z?$' , '%1')
-- test année seule
if date:match( '^'..aj..'$' ) then
annee = date:match( '^'..aj..'$' )
elseif date:match( '^'..aj..s..aj..moins..'$' ) then
-- jj/mm, mm/aaaa ou aaaa/mm
local a, separateur, b, sb = date:match( '^'..aj..sep..aj..moins..'$' )
a, b = tonumber( a ), tonumber( b )
if separateur:match( '^.+%-$' ) then
-- probablement mm/-aaaa, année av.JC
b = 0 - b
end
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 a < 1 or a > 31 then
annee, mois = a, b
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, separateur, mois, masquerMois, annee, masquerAnnee = date:match( '^'..aj..sep..m..moins..'%2'..aj..moins..'$' )
if separateur == '-' 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, separateur, mois, masquerMois, annee, masquerAnnee = date:match( '^'..j..sep..mmm..moins..'%2'..aj..moins..'$' )
elseif date:match( '^'..mmm..s..aj..moins..'$' ) then
-- mmm aaaa
mois, separateur, annee, masquerAnnee = date:match( '^'..mmm..sep..aj..moins..'$' )
if separateur:match( '^.+%-$' ) then
annee = '-' .. annee
end
elseif date:match( '^'..mmm2..s..aj..moins..'$' ) then
-- mmm-mmm aaaa
mois, separateur, annee, masquerAnnee = date:match( '^'..mmm2..sep..aj..moins..'$' )
if separateur:match( '^.+%-$' ) then
annee = '-' .. annee
end
elseif date:match( '^'..j..s..mmm..moins..'$' ) then
-- jj mmm
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
local jn, an = tonumber( jour ), tonumber( annee )
if jn and an and ( jn > 31 or jn < 0 or #jour >= 3 ) and an <= 31 then
-- cas notamment des date ISO 2015-06-17, -0044-06-17 et -0002-06-17
-- inversion du jour et de l'année
local temp = annee
annee = jour
jour = temp
end
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
---
-- validationJourMoisAnnee vérifie que les paramètres correspondent à une date valide.
-- la date peut être dans les paramètres 1 à 3, ou dans des paramètres jour, mois et annee.
-- La fonction retourne true suivi d'une table avec la date en paramètres nommés (sans accent sur année)
-- ou false suivi d'un message d'erreur.
function fun.validationJourMoisAnnee( frame )
local args = Outils.extractArgs( frame )
local jour, mois, numMois, annee
local bjour = args[1] or args['jour'] or ''
local bmois = tostring( args[2] or args['mois'] or '' )
local bannee = args[3] or args['annee'] or args['année'] or ''
local function erreur( periode, valeur )
return false, '<span class="error">' .. periode .. ' invalide (' .. valeur .. ')</span>'
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 = bannee:upper():match( '?[İR]%? ^(%d+) ' )
annee = tonumber( annee )
if annee then
annee = 0 - annee
else
return erreur( 'Année', bannee )
end
elseif annee == 0 then
return erreur( 'Année', 0 )
end
else
annee = nil
end
-- on traite le mois
if Outils.notEmpty( bmois ) then
mois, numMois = fun.determinationMois( bmois )
if mois == nil then
mois = fun.determinationSaison( bmois )
if mois == nil then
local mois1, sep, mois2 = bmois:match( '^([^%s%p%d]+[.]?)([-/])([^%s%p%d]+[.]?)$' )
if mois1 then
mois1 = fun.determinationMois( mois1 )
mois2 = fun.determinationMois( mois2 )
if mois1 == nil or mois2 == nil then
return erreur( 'Mois', bmois )
end
mois = mois1 .. sep .. mois2
else
return erreur( 'Mois', bmois )
end
end
end
-- on traite le jour si présent
if Outils.notEmpty( bjour ) then
if not numMois then
erreur( 'Date', 'jour avec saison ou plusieurs mois' )
end
jour = tonumber( bjour )
if jour == nil then
jour = tonumber( fun.nettoyageJour( bjour ) )
end
if jour == nil then
return erreur( 'Jour', bjour )
end
-- on valide que le jour est correct
if jour < 1 or jour > 31 then
return erreur( 'Jour', bjour )
elseif jour > listeMois[numMois].nJour then
return erreur( 'Jour', bjour .. ' ' .. mois )
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 bmois:match( '^%u' ) then
-- oui, on passe la première lettre en majuscule
mois = ucfirst( mois )
end
-- s'il n'y a pas d'année non plus on retourne le mois simple
end
else
-- on teste le jour si présent
if Outils.notEmpty( bjour ) then
if annee then
return erreur( 'Mois', 'absent' )
else
bjour = fun.nettoyageJour( bjour )
jour = tonumber( bjour )
if jour then
if jour > 31 or jour < 1 then
annee = jour
jour = nil
else
return erreur( 'Date', 'jour seul : ' .. bjour )
end
else
return erreur( 'Jour', bjour )
end
end
end
end
-- vérification de l'absence d'un décalage
if annee and annee < 13 and annee > 0 and not jour and ( tonumber( bmois ) or ( not mois and tonumber( args[4] ) ) ) then
return false, '<span class="error">année improbable (' .. annee .. ')</span>'
end
local resultat = {
jour = jour,
mois = mois,
numMois = numMois,
annee = annee,
masquerAnnee = args.masquerAnnee,
masquerMois = args.masquerMois,
}
return true, resultat
end
---
-- émule le modèle {{m|Date}}.
-- Paramètres :
-- 1 : jour (numéro ou "1") ou la date complète
-- 2 : mois (en toutes lettres) ou spécialité de l'année
-- 3 : année (nombre)
-- 4 : spécialité de l'année
-- julien : date dans le calendrier julien
-- compact : affiche le mois sous forme d'abréviation
-- avJC : non pour désactiver l'affichage de « av. J.-C. » pour les dates négatives
-- âge : ajoute la durée depuis cette date
-- nolinks : ne met pas de lien sur la date
-- onerror : en cas d'erreur, valeur à retourner à la place du message d'erreur ; la valeur spéciale "input" fait retourner le 1er argument inchangé
-- naissance : ajoute la class "bday"
-- mort : ajoute la class "dday"
function fun.modeleDate( frame )
local args = Outils.extractArgs( frame )
local cat, resultat = ''
-- analyse des paramètres non nommés (ou paramètres de la date jour, mois, annee)
local test, params
local arg1, arg2, arg3 = fun.nettoyageJour( args[1] ), trim( args[2] ), trim( args[3] )
if type( arg1 ) == 'string' and arg3 == nil and ( arg1:match( '[^ ./-][ ./-]+[^ ./-]' ) or arg2 == nil or dataLiens[arg2] or mw.ustring.match( arg2, '%a %a' ) ) then
-- la date est dans le premier paramètre
test, params = fun.separationJourMoisAnnee( arg1 )
if test then
params.qualificatif = arg2
end
else
local function masquerParam( p )
-- sépare le signe moins final éventuel signifiant que le paramètre ne doit pas être affiché.
if type( p ) ~= 'string' then
return p, nil
end
local value, mask = p:match( '^%s*(.-)(%-?)%s*$' )
return value, ( mask == '-' or nil )
end
local cleanArgs = { arg1 or args.jour }
cleanArgs[2], cleanArgs.masquerMois = masquerParam( args[2] or args.mois )
cleanArgs[3], cleanArgs.masquerAnnee = masquerParam( args[3] or args.annee or args['annee'] )
test, params = fun.validationJourMoisAnnee( cleanArgs )
if test then
params.qualificatif = trim( args[4] )
end
end
-- analyse des paramètres nommés
if test then
local Yesno = require 'Module:Yesno'
params.qualificatif = params.qualificatif or args.qualificatif
-- julien peut avoir trois valeurs : inactif, format standard (true), format court
params.julien = Yesno( args.julien, 'court', false )
params.avJC = Yesno( args.avJC )
params.republicain = Yesno( args['républicain'], 'liens', false)
local listeParam = {
age = 'âge',
['âge'] = 'âge',
naissance = 'naissance',
mort = 'mort',
['décès'] = 'mort',
apJC = 'apJC',
nolinks = 'nolinks',
compact = 'compact',
compacte = 'compact',
}
for n, v in pairs( listeParam ) do
params[v] = params[v] or Yesno( args[n], true, false ) or nil
end
-- sortie pour les tests unitaire, ou pour débugger
if args.debug then
return params
end
resultat = fun._modeleDate( params )
elseif args.onerror then
if args.onerror == 'input' then
return args[1]
else
return args.onerror
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
resultat = params .. cat
end
return resultat or ''
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
return
end
-- on traite l'âge, naissance et mort
local age = args['âge'] and fun.age( annee, numMois, jour )
local naissance = args.naissance
local mort = args.mort
-- on traite le calendrier
local gannee, gmois, gjour = annee, numMois, jour -- date suivant le calendrier grégorien pour <time>
local jannee, jmois, jjour = annee, mois, jour -- date suivant le calendrier julien si necessaire
local julienDate, julienSup, julienSep -- servira éventuellement à afficher la date selon le calendrier julien
local gregAprMois, gregAprAn, gregFin -- message de calendrier grégorien lorsque la date est selon le calendrier julien
if annee and jour then
local amj = annee * 10000 + numMois * 100 + jour
if amj < 15821014 then
if annee > 0 then
gannee, gmois, gjour = fun.julianToGregorian( annee, numMois, jour )
else
-- calendrier grégorien proleptique avec année 0.
gannee, gmois, gjour = fun.julianToGregorian( annee + 1, numMois, jour )
end
args.julien = false
elseif args.julien then
gannee, gmois, gjour = fun.julianToGregorian( annee, numMois, jour )
annee, mois, jour = gannee, listeMois[gmois].nom, gjour
if jjour == 1 then
jjour = modelePremier
end
if args.compact then
jmois = listeMois[jmois].abrev
end
if args.julien == 'court' then
julienDate = jjour .. ' ' .. jmois .. ' '
julienSup = '<sup>[[calendrier julien|jul.]]</sup>'
if jannee == annee then
gregAprMois = '<sup>[[calendrier grégorien|grég.]]</sup>'
else
julienDate = julienDate .. jannee .. ' '
gregAprAn = '<sup>[[calendrier grégorien|grég.]]</sup>'
end
julienSep = ' / '
else
julienDate = jjour .. ' ' .. jmois .. ' ' .. jannee
julienSep = ' ('
gregFin = ' [[Passage du calendrier julien au calendrier grégorien|dans le calendrier grégorien]])'
end
elseif args.republicain then
local DateRep = require 'Module:Date républicaine'
if args.republicain == 'liens' then
RepSansLiens = false
else
RepSansLiens = true
end
dateRepublicaine = DateRep._date_republicaine(
RepSansLiens,
{ fun.formatRepCal( fun.do_toRepCal{gannee, gmois, gjour} ) }
)
end
else
if annee and annee < 0 then
gannee = gannee + 1
end
args.julien = false
args.republicain = false
end
-- on génère le résultat
-- Déclarations des variables
local wikiListe = {} -- reçoit le texte affiché pour chaque paramètre
local iso = {} -- reçoit le format date ISO de ce paramètre
local texteMois = mois -- texte du mois qui sera affiché (éventuellement l'abréviation)
if args.compact then
if not numMois then
-- mois est autre chose qu'un simple mois : saison, mois-mois... auquel cas, pas d'abréviation (provoquait erreur Lua)
-- (les abréviations pour le cas "mois[-/]mois" seraient théoriquement possibles, mais ça reste à implémenter)
else
if args.nolinks then
texteMois = '<abbr class=abbr title="' .. mois .. '">' .. listeMois[mois].abrev .. '</abbr>'
else
texteMois = listeMois[mois].abrev
end
end
end
mois = mois and mois:gsub( 'aout', 'août' )
local dataQualificatif, dataCat
if not args.nolinks then
dataQualificatif = dataLiens[qualificatif or '']
if type( dataQualificatif ) ~= 'table' then
-- si le qualificatif n'est pas dans la base de données, on crée une table minimum,
-- qui imposera un test sur l'année, mais considère qu'il n'y a pas de lien sur le jour ou le mois
dataQualificatif = { qualificatif = ' ' .. qualificatif, annee = { } }
end
dataCat = dataLiens[dataQualificatif.cat]
if type( dataCat ) ~= 'table' or dataCat == dataQualificatif then
dataCat = { qualificatif = '' }
end
end
local function wikiLien( lien, texte )
if lien == texte then
return '[[' .. texte .. ']]'
else
return '[[' .. lien .. '|' .. texte .. ']]'
end
end
-- le jour si présent
local qualifJour = ''
if jour then
local texteJour = jour
if args.nolinks then
if jour == 1 then
jour = modelePremier
end
table.insert( wikiListe, jour )
else
qualifJour = dataQualificatif.jour and dataQualificatif.qualificatif
or dataCat.jour and dataCat.qualificatif
or ''
local lien = jour .. ' ' .. mois .. ' ' .. qualifJour
if jour == 1 then
jour = '1<sup></sup>'
lien = '1 ' .. mois .. ' ' .. qualifJour
end
-- s'il n'y a pas de lien sur le mois, il sera affiché avec le jour.
table.insert( wikiListe, wikiLien( lien, jour ) )
table.insert( wikiListe, wikiLien( lien, jour .. ' '.. texteMois ) )
end
table.insert( iso, 1, string.sub( '0' .. gjour, -2 ) )
end
-- le mois
if mois then
if #wikiListe == 0 and annee == nil then
return texteMois
end
if args.nolinks then
if not args.masquerMois then
table.insert( wikiListe, texteMois )
end
else
local lien
if annee then
if not numMois then
-- mois est autre chose qu'un simple mois : saison, mois-mois... auquel cas, pas de lien
else
lien = existDate( dataQualificatif, annee, mois ) or existDate( dataCat, annee, mois )
if lien == nil and qualificatif and qualifJour == '' then
-- nouveau test sans le qualificatif uniquement s'il n'y a pas d'éphémérides pour ce qualificatif.
lien = existDate( dataLiens[''], annee, mois )
end
end
end
if lien or args.masquerMois then
-- s'il y a un lien on retire le lien affichant 'jour mois' pour ajouter '[[mois annee|mois']]
table.remove( wikiListe )
if not args.masquerMois then
table.insert( wikiListe, wikiLien( lien, texteMois ) )
end
elseif #wikiListe > 0 then
-- sinon on retire le lien affichant 'jour' pour ne garder que le lien 'jour mois'
table.remove( wikiListe, #wikiListe - 1 )
elseif args.masquerAnnee then
-- s'il n'y a pas de jour et que l'année n'est pas affichée, on insère le mois seul.
table.insert( wikiListe, texteMois )
end
end
if gmois then
table.insert( iso, 1, string.sub( '0' .. gmois, -2 ) )
end
table.insert( wikiListe, gregAprMois )
end
-- l'année
if annee and not (args.julien == true and args.nolinks and jannee == annee ) then
if not args.masquerAnnee then
local texteAnnee = annee
local lien
if annee < 0 then
local annneeAvJc = 0 - annee
lien = lien or ( 'İR ' .. annneeAvJc)
if args.avJC == false then
texteAnnee = annneeAvJc
else
texteAnnee = annneeAvJc .. ' <abbr class="abbr" title="'
.. annneeAvJc .. ' İsay Raver">İR</abbr>'
end
elseif args.apJC then
texteAnnee = texteAnnee .. ' <abbr class="abbr" title="'
.. texteAnnee .. ' après Jésus-Christ">apr. J.-C.</abbr>'
end
if args.nolinks then -- seulement si on doit l'afficher
table.insert( wikiListe, texteAnnee )
else
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 = texteMois .. ' ' .. texteAnnee
end
table.insert( wikiListe, wikiLien( lien, texteAnnee ) )
end
end
end
if annee then
if gannee > 999 then
table.insert( iso, 1, gannee )
elseif gannee > -1 then
table.insert( iso, 1, string.sub( '000' .. gannee , -4 ) )
elseif gannee > -999 then
-- calendrier grégorien proleptique avec année 0.
table.insert( iso, 1, 'U-' .. string.sub( '000' .. ( 0 - gannee ), -4 ) )
else
table.insert( iso, 1, 'U' .. gannee )
end
end
table.insert( wikiListe, gregAprAn )
-- l'age
if type( age ) == 'number' and age >= 0 and ( not naissance or age < 120 ) then
if age == 0 then
age = '(moins d’un\194\160an)'
elseif age == 1 then
age = '(1\194\160an)'
else
age = '(' .. age .. '\194\160ans)'
end
else
age = false
end
-- compilation du résultat
local wikiTexte = table.concat( wikiListe, ' ' )
local isoTexte = table.concat( iso, '-' )
-- On ajoute un peu de sémantique.
local wikiHtml = mw.html.create( '' )
if julienDate then
wikiHtml:tag( 'span')
:addClass( 'nowrap' )
:attr( 'data-sort-value', isoTexte )
:wikitext( julienDate )
:node( julienSup )
:done()
:wikitext( julienSep )
end
local dateHtml = wikiHtml:tag( 'time' )
:wikitext( wikiTexte )
if wikiTexte:match( ' ' ) then
dateHtml:addClass( 'nowrap' )
end
if isoTexte ~= wikiTexte then
dateHtml:attr( 'datetime', isoTexte )
:attr( 'data-sort-value', isoTexte )
end
if not args.nolinks then
dateHtml:addClass( 'date-lien' )
end
if naissance then
dateHtml:addClass( 'bday' )
elseif mort then
dateHtml:addClass( 'dday' )
end
wikiHtml:wikitext( gregFin )
if args.republicain then
wikiHtml:wikitext( ' (', dateRepublicaine, ')' )
end
if age then
wikiHtml:wikitext( ' ' )
:tag( 'span' )
:addClass( 'noprint')
:wikitext( age )
:done()
end
return tostring( wikiHtml )
end
---
-- fonction destinée aux infobox, notamment pour afficher les dates de naissance et de mort
-- les liens présent dans les dates fournies sont automatiquement supprimés pour gérer les cas où
-- le paramètre contient déjà un modèle date.
-- Paramètres :
-- 1 : type de date à afficher (naissance / n, mort / m, ou date / d)
-- 1 : Date ou date de naissance
-- 2 : Date de mort si type n ou m
-- qualificatif = suffixe des page de date à lier (exemple : en musique)
-- nolinks : n'affiche pas de lien
-- préfixe : préfixe à afficher s'il y a un jour (par défaut '')
-- préfixe sans jour : préfixe à afficher s'il n'y a pas de jour (par défaut : '')
function fun.dateInfobox( frame )
local args = frame.args
if type( args ) ~= 'table' or not ( args[1] and args[2] ) then
return
end
-- analyseDate sépare la date du contenu qui suit, supprime les liens, et retourne si possible une table avec jour mois année
local function analyseDate( d )
if trim( d ) then
local analyse = d:match( ' ou ') or d:match( 'entre ' ) or d:match( 'vers ' ) or d:match( 'après ' ) or d:match( 'avant ' )
if analyse then
return d
end
analyse = d:match( 'datetime="([%d-]+)"' ) or d
-- sépare la date (avec ses liens) d'une référence ou contenu commençant par un espace)
local debut, fin = analyse:match( '(.-%d%d%d%]*%-?)([\127 ].+)' )
if not debut then
-- sépare la date du contenu commençant par <br>
debut, fin = analyse:match( '(.-%d%d%d%]*%-?)(<br ?/?>.+)' )
end
analyse = debut or analyse
-- supprime les liens
analyse = analyse:gsub(
'%[%[([^%[%]|]*)|?([^%[%]]*)%]%]',
function ( l, t )
return trim( t ) or l
end
)
local t, r = fun.separationJourMoisAnnee( analyse )
if t then
return r, fin
else
return d, fin
end
end
end
-- prefix ajoute un préfixe en fonction de la présence ou non du jour si le paramètre "préfixe sans jour" est défini
local function prefix( dateString )
if dateString then
local datetime = dateString:match( 'datetime="([U%d%-]+)"' )
if datetime and datetime:match('%-%d%d%-%d%d') and trim( args['préfixe'] ) then
return args['préfixe'] .. ' ' .. dateString
end
if trim( args['préfixe sans jour'] ) then
return args['préfixe sans jour'] .. ' ' .. dateString
end
end
return dateString
end
local naissance = args[1]:match( '^n' ) == 'n'
local mort = args[1]:match( '^m' ) or args[1]:match( 'décès' )
local affichageDate, qualificatif = args[2], args[4]
local affichageDateTab, resultatDate, complementDate
local dateNaissance, dateMort
if mort then
affichageDate = args[3]
end
if not trim( affichageDate ) then
return
end
if affichageDate:match( '</time>' ) then
-- S'il y a des liens il y a probablement déjà un modèle date, évitons de l'exécuter une 2e fois
if ( naissance or mort ) and ( affichageDate:match( 'wikidata%-linkback' )) then
dateNaissance = analyseDate( args[2] )
dateMort = analyseDate( args[3] )
resultatDate = affichageDate
else
return prefix( affichageDate )
end
else
affichageDateTab, complementDate = analyseDate( affichageDate )
if type( affichageDateTab ) ~= 'table' then
return affichageDateTab
else
if naissance then
dateNaissance = affichageDateTab
dateMort = analyseDate( args[3] )
elseif mort then
dateNaissance = analyseDate( args[2] )
dateMort = affichageDateTab
else
qualificatif = args[3]
end
affichageDateTab.naissance = naissance
affichageDateTab.mort = mort
affichageDateTab.qualificatif = args.qualificatif or qualificatif
affichageDateTab.nolinks = args.nolinks
affichageDateTab.nocat = args.nocat
affichageDateTab.julien = args.julien
end
end
resultatDate = resultatDate or fun.modeleDate( affichageDateTab )
local age, prefixAge, suffixAge, calculAge = '', ' <span class="noprint">(', ')</span>', nil
if naissance and
dateNaissance and
not dateMort and
type( dateNaissance ) == 'table'
then
calculAge = fun.age( dateNaissance.annee, dateNaissance.numMois, dateNaissance.jour )
if calculAge and calculAge > 120 then
calculAge = nil
end
elseif mort and
dateNaissance and
dateMort and
type( dateNaissance ) == 'table'
and type( dateMort ) == 'table'
then
calculAge = fun.age(
dateNaissance.annee,
dateNaissance.numMois,
dateNaissance.jour,
dateMort.annee,
dateMort.numMois,
dateMort.jour
)
prefixAge = ' (à '
suffixAge = ')'
end
if tonumber( calculAge ) then
if calculAge > 1 then
age = prefixAge .. calculAge .. '\194\160ans' .. suffixAge
elseif calculAge == 1 then
age = prefixAge .. 'un\194\160an' .. suffixAge
elseif calculAge == 0 then
age = prefixAge .. 'moins d’un\194\160an' .. suffixAge
end
if complementDate and complementDate:match( 'ans?%)' ) then
complementDate = ''
end
end
return prefix( resultatDate ) .. ( complementDate or '' ) .. age
end
---
-- la fonction dateISO renvoie un date au format aaaa-mm-jj (sans liens)
-- l'année peut être sous la forme 2013 ou [[2013 en litérature|2013]]
-- le mois peut être en lettres ou en chiffres
-- le jour peut être sous la forme '05', '{{1er}}' ou 'vendredi 13'
function fun.dateISO( frame )
local args = Outils.extractArgs( frame )
local annee = Outils.notEmpty( args['année'], args.annee, args.year, args.date )
-- extraction de l'année
if type( annee ) == 'string' then
annee = ( tonumber( annee ) -- match '2013'
or string.match ( annee, '%D(%d%d%d%d)%D' ) -- match '[[2013 en musique|2013]]'
or string.match ( annee, '%D(%d%d%d%d)$' ) -- match '17 septembre 2013'
or string.match ( annee, '^(%d%d%d%d)%D' ) -- match '2013-09-17'
)
end
annee = tonumber( annee )
-- le format de date iso est défini suivant le calendrier grégorien.
-- Avant l'année 1583 la date est calendrier est probablement du calendrier julien,
-- donc autant s'abstenir.
if annee and annee > 1582 then
local mois = Outils.notEmpty( args.mois, args.month )
-- num mois trouve le numéro du mois, qu'il soit numérique ou texte, complet ou abrégé.
local nomMois, numMois = fun.determinationMois( mois )
if numMois then
mois = '-' .. string.sub( '0' .. numMois, -2 )
local jour = Outils.notEmpty( args.jour, args.day, args['quantième'] )
if type( jour ) == 'string' then
jour = tonumber( jour ) or tonumber( string.match ( jour, '%d+') )
end
jour = tonumber( jour )
if jour and jour <= listeMois[numMois].nJour then
jour = '-' .. string.sub( '0' .. jour, -2 )
return annee .. mois .. jour
else
return annee .. mois
end
else
return tostring( annee )
end
end
end
---
-- Rang du jour dans l'année
-- Usage : do_dayRank{année,mois,jour}
function fun.do_dayRank(arguments)
local yr = tonumber(arguments.year or arguments[1]) or 1
local mt = tonumber(arguments.month or arguments[2]) or 1
local dy = tonumber(arguments.day or arguments[3]) or 1
-- Rangs des premiers des mois
local ranks = {0,31,59,90,120,151,181,212,243,273,304,334}
local rank = (ranks[mt] or 0) + dy - 1
if(fun.isLeapYear(yr) and (mt >= 3)) then
rank = rank+1
end
return rank
end
-- Nombre de jours entre deux années (du 1er janvier au 1er janvier)
-- Suit le calendrier grégorien
function fun.do_daysBetween(arguments)
local yr1 = tonumber(arguments[1]) or 0
local yr2 = tonumber(arguments[2]) or 0
return fun.daysSinceOrigin(yr2) - fun.daysSinceOrigin(yr1)
end
-- Nombre de jours depuis l'année 1 (du 1er janvier au 1er janvier)
function fun.daysSinceOrigin(year)
local yr = year-1
return 365*yr + math.floor(yr/4) - math.floor(yr/100) + math.floor(yr/400)
end
-- Test d'année bissextile (Suit le calendrier grégorien)
function fun.isLeapYear(year)
local yr = tonumber(year) or 1
return (yr%4 == 0) and ((yr%100 ~= 0) or (yr%400 == 0))
end
-- Conversion d'un nombre en chiffres romains
function fun.toRoman(number)
local n = math.floor(number)
local letters = {"I","V","X","L","C","D","M","",""}
local pattern = {"","0","00","000","01","1","10","100","1000","02"}
local result = ""
if(n<=0 or n>=4000) then
result = "---"
else
for i=1,7,2 do
local p = pattern[n%10 + 1]
for j=0,2 do
p = string.gsub(p,tostring(j),letters[i+j])
end
result = p .. result
n = math.floor(n/10)
end
end
return result
end
-- Conversion et affichage d'une date dans le calendrier républicain
function fun.dateRepublicain(frame)
local pframe = frame:getParent()
local arguments = pframe.args
return fun.formatRepCal(fun.do_toRepCal(arguments))
end
---
-- Calcul d'une date dans le calendrier républicain
-- On suppose que les années 4n+3 sont sextiles (3, 7, 11...)
function fun.do_toRepCal(arguments)
local yr = tonumber(arguments.year or arguments[1]) or 2000
-- rang absolu du jour demandé, le jour 0 étant le 22 septembre 1792 (1er jour de l'an I)
local repDays = fun.do_dayRank(arguments) + fun.do_daysBetween{1792,yr} - fun.do_dayRank{1792,9,22}
local repYear = math.floor((repDays+731)/365.25) - 1
local repDayRank = repDays - 365*(repYear-1) - math.floor(repYear/4)
local repMonth, repDay = math.floor(repDayRank/30)+1, (repDayRank%30)+1
return {repYear, repMonth, repDay}
end
---
-- Formatage d'une date selon le calendrier républicain
-- Usage : fun.formatRepCal{année,mois,jour}
function fun.formatRepCal(arguments)
local months = {"Vendémiaire","Brumaire","Frimaire","Nivôse","Pluviôse","Ventôse","Germinal","Floréal","Prairial","Messidor","Thermidor","Fructidor"}
local extras = {"de la vertu","du génie","du travail","des récompenses","de l'opinion","de la révolution"}
local result = ""
if(arguments[2] < 13) then
result = result .. tostring(arguments[3]) .. "\194\160" .. months[arguments[2]]
else
result = result .. "jour " .. extras[arguments[3]]
end
result = result .. " de l'an " .. fun.toRoman(arguments[1])
return result
end
---
-- Voir Modèle:Âge
-- retourne l'âge en fonction de la ou les dates fournies. La valeur retournée est de type 'number'
-- Paramètres :
-- 1, 2, 3 : année, mois jour de naissance (supposé dans le calendrier grégorien)
-- 4, 5, 6 : année, mois, jour du calcul (facultatif, par défaut la date UTC courante).
function fun.age( an, mn, jn, ac, mc, jc )
if ac == nil then
local today = os.date( '!*t' )
ac = today.year
mc = today.month
jc = today.day
else
ac = tonumber( ac )
mc = tonumber( mc )
jc = tonumber( jc )
end
local an = tonumber( an )
local mn = tonumber( mn )
local jn = tonumber( jn )
if an == nil or ac == nil or mn == nil or mc == nil then
-- pas de message d'erreur qui risque de faire planter la fonction appelante
-- à elle de gérer ce retour.
return
end
local age = ac - an
if mc == mn then
if jc == nil or jn == nil then
return
end
return age-tonumber( jc < jn and 1 or 0 )
else
return age-tonumber( mc < mn and 1 or 0 )
end
end
function fun.modeleAge( frame )
local args = frame:getParent().args
local age = fun.age (
args[1] or args['année'],
args[2] or args['mois'],
args[3] or args['jour'],
args[4],
args[5],
args[6]
)
if age then
return age
else
return '<span class="error">Paramètres incorrects ou insuffisants pour calculer l\'âge précis</span>'
end
end
---
-- calcul du jour julien à partir d'une date du calendrier grégorien
function fun.julianDay( year, month, day, hour, min, sec )
local julian
julian = math.floor( math.floor( ( year * 12 + month + 57609 ) / 12 - 1 ) * 1461 / 4 )
- math.floor( math.floor( ( year * 12 + month + 57609 ) / 12 - 1 ) / 100 )
+ math.floor( math.floor( ( year * 12 + month + 57609 ) / 12 - 1 ) / 400 )
+ math.floor( ( math.fmod( month + 57609, 12 ) + 4 ) * 153 / 5 )
+ day + ( hour or 12 ) / 24 + ( min or 0 ) / 1440 + ( sec or 0 ) / 86400
- 32167.5
return julian
end
---
-- calcul du jour julien à partir d'une date du calendrier julien
function fun.julianDayJulian( year, month, day, hour, min, sec )
local julian
julian = math.floor( math.floor( ( year * 12 + month + 57609 ) / 12 - 1 ) * 1461 / 4 )
+ math.floor( ( math.fmod( month + 57609, 12 ) + 4 ) * 153 / 5 )
+ day + ( hour or 12 ) / 24 + ( min or 0 ) / 1440 + ( sec or 0 ) / 86400
- 32205.5
return julian
end
---
-- calcul d'une date dans le calendrier grégorien à partir du jour julien
function fun.julianDayToGregorian( julianDay )
local base = math.floor( julianDay + 32044.5 ) -- 1 March -4800 (proleptic Gregorian date)
local nCentury = math.floor( ( base * 4 + 3 ) / 146097 )
local sinceCentury = base - math.floor( nCentury * 146097 / 4 )
local nYear = math.floor( ( sinceCentury * 4 + 3 ) / 1461 )
local sinceYear = sinceCentury - math.floor( nYear * 1461 / 4 )
local nMonth = math.floor( ( sinceYear * 5 + 2 ) / 153 )
local day = sinceYear - math.floor( ( nMonth * 153 + 2 ) / 5 ) + 1
local month = nMonth - math.floor( nMonth / 10 ) * 12 + 3
local year = math.floor( sinceYear / 306 ) + nYear + 100 * nCentury - 4800
return year, month, day
end
---
-- calcul d'une date dans le calendrier julien à partir du jour julien
-- calcul basé sur l'algorithme de la page fr.wikipedia.org/wiki/Jour_julien (1/10/2013)
function fun.julianDayToJulian( julianDay )
local year = math.modf( ( julianDay * 4 - 6884469 ) / 1461 )
local r2 = julianDay - math.modf( ( 1461 * year + 6884472 ) / 4 )
local month = math.modf( ( 5 * r2 + 461 ) / 153 )
local day = r2 - math.modf( ( 153 * month - 457 ) / 5 ) + 1
if month > 12 then
year = year + 1
month = month - 12
end
return year, month, day
end
---
-- calcul d'une date dans le calendrier grégorien à partir d'une date dans le calendrier julien
function fun.julianToGregorian( year, month, day )
return fun.julianDayToGregorian( fun.julianDayJulian( year, month, day ) )
end
---
-- calcul d'une date dans le calendrier julien à partir d'une date dans le calendrier grégorien
function fun.gregorianToJulian( year, month, day )
year = tonumber(year)
if month then month = tonumber(month) else month = 6 end --prend une valeur centrale pour donner un best "guess"
if day then day = tonumber(day) else day = 15 end
return fun.julianDayToJulian( fun.julianDay( year, month, day ) )
end
--[[
Cette fonction retourne "CET" ou "CEST" selon que dans la pseudo-timezone en cours
c'est l'heure d'été ou l'heure d'hiver.
Cette fonction n'a de sens a priori que pour des modèles utilisés en Europe
Paramètre optionnel non nommé : "sans lien" : retourne le texte CET/CEST. sinon
retourne ce même texte avec un wikilien vers les articles correspondants
--]]
function fun.CEST(frame)
-- option : ne pas créer de wikilien
local opt = trim(frame.args[1] or frame:getParent().args[1])
-- on récupère l'information dans la zone courante
local t = mw.getContentLanguage():formatDate("I", nil, true)
if (t == "1") then -- heure d'été
if (opt == "sans lien") then
return "CEST"
elseif (opt == "décalage") then
return "2"
else
return "[[Heure d'été d'Europe centrale|CEST]]"
end
else -- heure d'hiver (ou autre zone où ça ne s'applique pas)
if (opt == "sans lien") then
return "CET"
elseif (opt == "décalage") then
return "1"
else
return "[[Heure normale d'Europe centrale|CET]]"
end
end
end
return fun
k1jbssvdl4aemtmwbh2lbq7azsig0zb
NGC 7779
0
68232
549209
490378
2026-06-22T21:08:09Z
Mirzali
16
549209
wikitext
text/x-wiki
{{Galaksiye}}
'''NGC 7779''', yew cısmê [[Asmên|asmên]]io. No cısım [[Katalogo Pêroyiyo Newe|Katalogê Pêroyiyê Neweyi]] de, komê estareyanê {{Wikidata|P59}} miyan de ca gêno. {{Wikidata|P575}} de terefê {{Wikidata|P61}}i ra keşıf biyo.
== Bıvênên ==
* [[Asmên]]
* [[Galaksiye]]
* [[Estare]]
* [[Pulsar]]
* [[Nebula]]
* [[Lista cısmanê NGC]]
== Gıreyê teberi ==
* {{NASANED}}
* {{Simbad}}
* {{Leda}}
* {{Seds}}
* {{WikiSky}}
{{NGC|7779}}
[[Kategoriye:Asmênşınasiye]]
rwzi5gnfy88sdapwv47e6eg68u74vgr
.office
0
69765
549211
504685
2026-06-23T06:16:56Z
Mirzali
16
549211
wikitext
text/x-wiki
'''.office''', [[İnternet|internet]] de nameyê bandıra jeneriko (be zıwanê [[İngılızki]]: ''[[Bandıra sewiyaya serêna jenerike|Generic top-level domains]]'') ke yew kodê interneti rê bırriyayo a.
{{Generic top-level domain}}
{{ccTLD}}
[[Kategoriye:Bandıra sewiyaya serêna jenerike]]
l0onya1sdmpz0t38lwmb1njc77r943u
.off
0
70207
549208
504177
2026-06-22T21:06:06Z
Mirzali
16
549208
wikitext
text/x-wiki
'''.off''', [[İnternet|internet]] de nameyê bandıra jeneriko (be zıwanê [[İngılızki]]: {{langi|en|[[Bandıra sewiyaya serêna jenerike|Generic top-level domains]]}}) ke yew kodê interneti rê bırriyayo a.
== Bıvênên ==
* [[Domain]]
* [[Komputer]]
* [[Website]]
{{Generic top-level domain}}
{{ccTLD}}
[[Kategoriye:Bandıra sewiyaya serêna jenerike]]
0zt3e8mkzoyr6iwrsltlz1g9od83xpr
NGC 7756
0
73979
549212
490383
2026-06-23T06:19:16Z
Mirzali
16
549212
wikitext
text/x-wiki
{{Galaksiye}}
'''NGC 7756''', yew cısmê [[Asmên|asmên]]iyo. No cısım [[Katalogo Pêroyiyo Newe|Katalogê Pêroyiyê Neweyi]] de komê estareyanê {{Wikidata|P59}} miyan de ca gêno. {{Wikidata|P575}} de terefê {{Wikidata|P61}}i ra keşıf biyo.
== Bıvênên ==
* [[Asmên]]
* [[Galaksiye]]
* [[Estare]]
* [[Pulsar]]
* [[Nebula]]
* [[Lista cısmanê NGC]]
== Gıreyê teberi ==
* {{NASANED}}
* {{Simbad}}
* {{Leda}}
* {{Seds}}
* {{WikiSky}}
{{NGC|7756}}
[[Kategoriye:Asmênşınasiye]]
kej064xvyrxprcv7k2bweinzghgg9a8
GNK Dinamo Zagreb
0
83308
549200
520411
2026-06-22T14:12:18Z
Makenzis
17396
/* Şampiyoniya Ligê Xırvatıstani */
549200
wikitext
text/x-wiki
{{Klubi}}
'''Građanski nogometni klub Dinamo Zagreb''' ya zi '''GNK Dinamo Zagreb''', yew klubê [[futbol]]iyê dewleta [[Xırvatıstan]]iyo ke sûka Zagrebi de, serra 1945ıne de ameyo ronayene.
== Kupeyê ke gırewtê ==
=== Şampiyoniya Ligê Xırvatıstani ===
1992-93, 1995-96, 1996-97, 1997-98, 1998-99, 1999-00, 2002-03, 2005-06, 2006-07, 2007-08, 2008-09, 2009-10, 2010-11, 2011-12, 2012-13, 2013-14, 2014-15, 2015-16, 2017-18, 2018-19, 2019-20, 2020-21, 2021-22, 2022-23, 2023-24, 2025-26
==Linkê teberi==
{{Commons category|Category:NK Dinamo Zagreb}}
* [https://www.gnkdinamo.hr/ Siteyo resmi]
* [https://www.facebook.com/dinamo Facebook]
* [https://int.soccerway.com/teams/croatia/nk-dinamo-zagreb/479/ SOCCERWAY]
* [https://www.sofascore.com/team/football/gnk-dinamo-zagreb/2032 SOFASCORE]
* [https://www.flashscore.com/team/din-zagreb/8G5ufQTg/ FLASHSCORE]
* [https://www.transfermarkt.com/gnk-dinamo-zagreb/startseite/verein/419 Transfermarkt]
* [https://globalsportsarchive.com/team/soccer/gnk-dinamo-zagreb/1480/ Globalsportsarchive]
[[Kategoriye:Klubê futboliê Xırvatıstani]]
nd1gnrqlfkym53s7sthxk1cb8uc8sua
549201
549200
2026-06-22T14:12:27Z
Makenzis
17396
/* Linkê teberi */
549201
wikitext
text/x-wiki
{{Klubi}}
'''Građanski nogometni klub Dinamo Zagreb''' ya zi '''GNK Dinamo Zagreb''', yew klubê [[futbol]]iyê dewleta [[Xırvatıstan]]iyo ke sûka Zagrebi de, serra 1945ıne de ameyo ronayene.
== Kupeyê ke gırewtê ==
=== Şampiyoniya Ligê Xırvatıstani ===
1992-93, 1995-96, 1996-97, 1997-98, 1998-99, 1999-00, 2002-03, 2005-06, 2006-07, 2007-08, 2008-09, 2009-10, 2010-11, 2011-12, 2012-13, 2013-14, 2014-15, 2015-16, 2017-18, 2018-19, 2019-20, 2020-21, 2021-22, 2022-23, 2023-24, 2025-26
==Linkê teberi==
{{Commons category|Category:NK Dinamo Zagreb}}
* [https://www.gnkdinamo.hr/ Siteyo resmi]
* [https://www.facebook.com/dinamo Facebook]
* [https://int.soccerway.com/teams/croatia/nk-dinamo-zagreb/479/ SOCCERWAY]
* [https://www.flashscore.com/team/din-zagreb/8G5ufQTg/ FLASHSCORE]
* [https://www.transfermarkt.com/gnk-dinamo-zagreb/startseite/verein/419 Transfermarkt]
* [https://globalsportsarchive.com/team/soccer/gnk-dinamo-zagreb/1480/ Globalsportsarchive]
[[Kategoriye:Klubê futboliê Xırvatıstani]]
qh109rj3u00ijouwwwn2alicsvjotlr
549202
549201
2026-06-22T14:12:41Z
Makenzis
17396
/* Linkê teberi */
549202
wikitext
text/x-wiki
{{Klubi}}
'''Građanski nogometni klub Dinamo Zagreb''' ya zi '''GNK Dinamo Zagreb''', yew klubê [[futbol]]iyê dewleta [[Xırvatıstan]]iyo ke sûka Zagrebi de, serra 1945ıne de ameyo ronayene.
== Kupeyê ke gırewtê ==
=== Şampiyoniya Ligê Xırvatıstani ===
1992-93, 1995-96, 1996-97, 1997-98, 1998-99, 1999-00, 2002-03, 2005-06, 2006-07, 2007-08, 2008-09, 2009-10, 2010-11, 2011-12, 2012-13, 2013-14, 2014-15, 2015-16, 2017-18, 2018-19, 2019-20, 2020-21, 2021-22, 2022-23, 2023-24, 2025-26
==Linkê teberi==
{{Commons category|Category:NK Dinamo Zagreb}}
* [https://www.gnkdinamo.hr/ Siteyo resmi]
* [https://www.facebook.com/dinamo Facebook]
* [https://www.soccerway.com/team/din-zagreb/8G5ufQTg/ SOCCERWAY]
* [https://www.flashscore.com/team/din-zagreb/8G5ufQTg/ FLASHSCORE]
* [https://www.transfermarkt.com/gnk-dinamo-zagreb/startseite/verein/419 Transfermarkt]
* [https://globalsportsarchive.com/team/soccer/gnk-dinamo-zagreb/1480/ Globalsportsarchive]
[[Kategoriye:Klubê futboliê Xırvatıstani]]
di3ujmxj95cyer039k3aup8nokii9ov
549206
549202
2026-06-22T21:03:32Z
Mirzali
16
549206
wikitext
text/x-wiki
{{Klubi}}
'''Građanski nogometni klub Dinamo Zagreb''' ya zi '''GNK Dinamo Zagreb''', yew klubê [[futbol]]iyê dewleta [[Xırvatıstan]]iyo ke sûka Zagrebi de, serra 1945ıne de ameyo ronayene.
== Kupeyê ke gırewtê ==
=== Şampiyoniya Ligê Xırvatıstani ===
1992-93, 1995-96, 1996-97, 1997-98, 1998-99, 1999-00, 2002-03, 2005-06, 2006-07, 2007-08, 2008-09, 2009-10, 2010-11, 2011-12, 2012-13, 2013-14, 2014-15, 2015-16, 2017-18, 2018-19, 2019-20, 2020-21, 2021-22, 2022-23, 2023-24, 2025-26
== Gıreyê teberi ==
* [https://www.gnkdinamo.hr/ Siteyo resmi]
* [https://www.facebook.com/dinamo Facebook]
* [https://www.soccerway.com/team/din-zagreb/8G5ufQTg/ SOCCERWAY]
* [https://www.flashscore.com/team/din-zagreb/8G5ufQTg/ FLASHSCORE]
* [https://www.transfermarkt.com/gnk-dinamo-zagreb/startseite/verein/419 Transfermarkt]
* [https://globalsportsarchive.com/team/soccer/gnk-dinamo-zagreb/1480/ Globalsportsarchive]
{{Commons category|Kategoriye:NK Dinamo Zagreb}}
[[Kategoriye:Klubê futboliyê Xırvatıstani]]
gogu508two1aq87t8m25zzenhvrs9ku
Werênayışê karberi:Wikihez
3
95861
549214
534644
2026-06-23T06:48:04Z
Mirzali
16
Modul:Wikidata
549214
wikitext
text/x-wiki
== Tiştên ku divê werin guhertin ==
Pîrozbahî li ser botê!
: Tiştên ku divê bên guhertin ev in:
:: - Ain > [[En]]
:: - Galaksi > Galaks'''iye''' (''bi paşgira navê mê)
:: - namey > namey'''ê''' (''bi paşgira îzafe ya nêr'')
:: - u > û
__________________________________________________
:: * ''Gava ku ez li deverên din rast hatim ez ê li navnîşê zêde bikim.''
[[Karber:Mirzali|Mirzali]] ([[Karber vaten:Mirzali|mesac]]) 11:00, 21 Kanun 2022 ([[UTC]])
== Wergerandina peyaman ==
Tu dikarî di [https://translatewiki.net/wiki/Special:LanguageStats?language=diq&x=D wergerandina peyaman] de alîkariya min bikin? Gelek peyamên çewt hatine wergerandin ku berê ji hêla hin wêranker ve di bin navên cûda de hatine çêkirin. Ez êdî nikarim peyamên têkildar bibînim. Wekî din ez dikarim bi xwe bikim. Ji bo wê jî di pêş de spas.
: Tiştên ku divê bên guhertin:
[[Karber:Mirzali|Mirzali]] ([[Karber vaten:Mirzali|mesac]]) 12:27, 21 Kanun 2022 ([[UTC]])
::@[[Karber:Mirzali|Mirzali]] Navên "namespaces" li ser [[phab:]] tê guhartin. Bnr. [https://doc.wikimedia.org/mediawiki-core/master/php/MessagesKu__latn_8php.html#af2f5c876bcf2c2f36d673e49a40965a3] [[:ku:Wîkîpediya:Phabricator]].--[[Karber:Balyozxane|Balyozxane]] ([[Karber vaten:Balyozxane|mesac]]) 15:07, 22 Kanun 2022 ([[UTC]])
:::Mînak [https://phabricator.wikimedia.org/T321881] [https://incubator.wikimedia.org/wiki/Talk:Wp/guc/Ee%27iyalaaya_a%27la%C3%BClaas%C3%BC]--[[Karber:Balyozxane|Balyozxane]] ([[Karber vaten:Balyozxane|mesac]]) 15:38, 22 Kanun 2022 ([[UTC]])
== [https://diq.wikipedia.org/wiki/Modul:Wikidata Modul:Wikidata] ==
Ji kerema xwe hûn dikarin di vê pirsgirêka jêrîn de alîkariya min bikin? Di modula [https://diq.wikipedia.org/wiki/Modul:Wikidata Modul:Wikidata] de çewtiyek çêbûye ku ez nikarim rast bikim. Peyama çewtiyê ya jêrîn di gotaran de xuya dibe: '' Lua error Xetay pele Modul:Wikidata dı rêza 1004 de ya: attempt to call field 'between' (a nil value).'' Bi silav! -- [[Karber:Mirzali|Mirzali]] ([[Werênayışê karberi:Mirzali|mesac]]) 06:47, 23 Hezirane 2026 ([[UTC]])
2vhn8rqpzvfnuwt68v5reos35yoxcxy
549215
549214
2026-06-23T06:49:06Z
Mirzali
16
/* Modul:Wikidata */
549215
wikitext
text/x-wiki
== Tiştên ku divê werin guhertin ==
Pîrozbahî li ser botê!
: Tiştên ku divê bên guhertin ev in:
:: - Ain > [[En]]
:: - Galaksi > Galaks'''iye''' (''bi paşgira navê mê)
:: - namey > namey'''ê''' (''bi paşgira îzafe ya nêr'')
:: - u > û
__________________________________________________
:: * ''Gava ku ez li deverên din rast hatim ez ê li navnîşê zêde bikim.''
[[Karber:Mirzali|Mirzali]] ([[Karber vaten:Mirzali|mesac]]) 11:00, 21 Kanun 2022 ([[UTC]])
== Wergerandina peyaman ==
Tu dikarî di [https://translatewiki.net/wiki/Special:LanguageStats?language=diq&x=D wergerandina peyaman] de alîkariya min bikin? Gelek peyamên çewt hatine wergerandin ku berê ji hêla hin wêranker ve di bin navên cûda de hatine çêkirin. Ez êdî nikarim peyamên têkildar bibînim. Wekî din ez dikarim bi xwe bikim. Ji bo wê jî di pêş de spas.
: Tiştên ku divê bên guhertin:
[[Karber:Mirzali|Mirzali]] ([[Karber vaten:Mirzali|mesac]]) 12:27, 21 Kanun 2022 ([[UTC]])
::@[[Karber:Mirzali|Mirzali]] Navên "namespaces" li ser [[phab:]] tê guhartin. Bnr. [https://doc.wikimedia.org/mediawiki-core/master/php/MessagesKu__latn_8php.html#af2f5c876bcf2c2f36d673e49a40965a3] [[:ku:Wîkîpediya:Phabricator]].--[[Karber:Balyozxane|Balyozxane]] ([[Karber vaten:Balyozxane|mesac]]) 15:07, 22 Kanun 2022 ([[UTC]])
:::Mînak [https://phabricator.wikimedia.org/T321881] [https://incubator.wikimedia.org/wiki/Talk:Wp/guc/Ee%27iyalaaya_a%27la%C3%BClaas%C3%BC]--[[Karber:Balyozxane|Balyozxane]] ([[Karber vaten:Balyozxane|mesac]]) 15:38, 22 Kanun 2022 ([[UTC]])
== [https://diq.wikipedia.org/wiki/Modul:Wikidata Modul:Wikidata] ==
Ji kerema xwe hûn dikarin di vê pirsgirêka jêrîn de alîkariya min bikin? Di modula [https://diq.wikipedia.org/wiki/Modul:Wikidata Wikidata] de çewtiyek çêbûye ku ez nikarim rast bikim. Peyama çewtiyê ya jêrîn di gotaran de xuya dibe: '' Lua error Xetay pele Modul:Wikidata dı rêza 1004 de ya: attempt to call field 'between' (a nil value).'' Bi silav! -- [[Karber:Mirzali|Mirzali]] ([[Werênayışê karberi:Mirzali|mesac]]) 06:47, 23 Hezirane 2026 ([[UTC]])
tcglvz1nij04y0oo0cxuojobjyzyku5
549218
549215
2026-06-23T07:13:38Z
Wikihez
19275
/* Modul:Wikidata */
549218
wikitext
text/x-wiki
== Tiştên ku divê werin guhertin ==
Pîrozbahî li ser botê!
: Tiştên ku divê bên guhertin ev in:
:: - Ain > [[En]]
:: - Galaksi > Galaks'''iye''' (''bi paşgira navê mê)
:: - namey > namey'''ê''' (''bi paşgira îzafe ya nêr'')
:: - u > û
__________________________________________________
:: * ''Gava ku ez li deverên din rast hatim ez ê li navnîşê zêde bikim.''
[[Karber:Mirzali|Mirzali]] ([[Karber vaten:Mirzali|mesac]]) 11:00, 21 Kanun 2022 ([[UTC]])
== Wergerandina peyaman ==
Tu dikarî di [https://translatewiki.net/wiki/Special:LanguageStats?language=diq&x=D wergerandina peyaman] de alîkariya min bikin? Gelek peyamên çewt hatine wergerandin ku berê ji hêla hin wêranker ve di bin navên cûda de hatine çêkirin. Ez êdî nikarim peyamên têkildar bibînim. Wekî din ez dikarim bi xwe bikim. Ji bo wê jî di pêş de spas.
: Tiştên ku divê bên guhertin:
[[Karber:Mirzali|Mirzali]] ([[Karber vaten:Mirzali|mesac]]) 12:27, 21 Kanun 2022 ([[UTC]])
::@[[Karber:Mirzali|Mirzali]] Navên "namespaces" li ser [[phab:]] tê guhartin. Bnr. [https://doc.wikimedia.org/mediawiki-core/master/php/MessagesKu__latn_8php.html#af2f5c876bcf2c2f36d673e49a40965a3] [[:ku:Wîkîpediya:Phabricator]].--[[Karber:Balyozxane|Balyozxane]] ([[Karber vaten:Balyozxane|mesac]]) 15:07, 22 Kanun 2022 ([[UTC]])
:::Mînak [https://phabricator.wikimedia.org/T321881] [https://incubator.wikimedia.org/wiki/Talk:Wp/guc/Ee%27iyalaaya_a%27la%C3%BClaas%C3%BC]--[[Karber:Balyozxane|Balyozxane]] ([[Karber vaten:Balyozxane|mesac]]) 15:38, 22 Kanun 2022 ([[UTC]])
== [https://diq.wikipedia.org/wiki/Modul:Wikidata Modul:Wikidata] ==
Ji kerema xwe hûn dikarin di vê pirsgirêka jêrîn de alîkariya min bikin? Di modula [https://diq.wikipedia.org/wiki/Modul:Wikidata Wikidata] de çewtiyek çêbûye ku ez nikarim rast bikim. Peyama çewtiyê ya jêrîn di gotaran de xuya dibe: '' Lua error Xetay pele Modul:Wikidata dı rêza 1004 de ya: attempt to call field 'between' (a nil value).'' Bi silav! -- [[Karber:Mirzali|Mirzali]] ([[Werênayışê karberi:Mirzali|mesac]]) 06:47, 23 Hezirane 2026 ([[UTC]])
:Merheba @[[User:Mirzali|Mirzali]] te ji bîr kiriye [https://diq.wikipedia.org/w/index.php?title=Modul:Date&diff=prev&oldid=548299 vê] guhartinê betal bikî, loma xeletî dida. Niha çêbû. Qewet be. --[[Karber:Wikihez|Wikihez]] ([[Werênayışê karberi:Wikihez|mesac]]) 07:13, 23 Hezirane 2026 ([[UTC]])
1pq1iin58lp3nyhguh7g674oldfgla7
Clifford Edmund Bosworth
0
100221
549198
2026-06-22T12:49:13Z
Deylemic
33409
Ebe zerrekê '{{Merdumi}} '''Clifford Edmund Bosworth''' 29 Kanun 1928 – 28 Şıbat 2015), yew tarixwan û oryantilist İngılız biyo. C.E. Bosworth, yew nuştışe xo de qalê Zazayan kerdo: Ena nuştışede Zazaki lehçeye Deylemiya nuşto. <ref>The medieval history of Iran, Afghanistan, and Central Asia s.74</ref> == Bibliyografi == *''The [[Gazneliler|Ghaznavids]], their empire in Afghanistan and Eastern Iran 994–1040'', Edinburgh University Press 1963, 2...' ra pela newiye vıraziye
549198
wikitext
text/x-wiki
{{Merdumi}}
'''Clifford Edmund Bosworth''' 29 Kanun 1928 – 28 Şıbat 2015), yew tarixwan û oryantilist İngılız biyo. C.E. Bosworth, yew nuştışe xo de qalê Zazayan kerdo: Ena nuştışede Zazaki lehçeye Deylemiya nuşto. <ref>The medieval history of Iran, Afghanistan, and Central Asia s.74</ref>
== Bibliyografi ==
*''The [[Gazneliler|Ghaznavids]], their empire in Afghanistan and Eastern Iran 994–1040'', Edinburgh University Press 1963, 2nd ed. Beirut 1973, repr. New Delhi 1992 (Persian tr.).
*''The Islamic dynasties, a chronological and genealogical handbook'', Edinburgh University Press 1967, revised ed. 1980 (Russian, Persian, Turkish, Arabic and French trs.).
*''[[Sistan]] under the Arabs, from the Islamic conquest to the rise of the [[Saffârîler|Saffarids]] (30-250/651-864)'', IsMEO, Rome 1968 (Persian tr.).
*''The Book of curious and entertaining information, the Lata'if al-ma'arif of [[Tha'ālibī]] translated into English'', Edinburgh University Press 1968.
*(Editor) ''Iran and Islam'', in memory of the late [[Vladimir Minorsky]], Edinburgh University Press 1971.
*(Editor, with [[Joseph Schacht]]) ''The legacy of Islam'', new edition, Clarendon Press, Oxford 1974 (Arabic tr. Kuwait, 1998).
*''The mediaeval Islamic underworld, the Banu Sasan in Arabic society and literature'', 2 vols., Brill, Leiden 1976.
*''The medieval history of Iran, Afghanistan and Central Asia'', Variorum, Collected Studies Series, London 1977.
*''The later Ghaznavids, splendour and decay: the dynasty in Afghanistan and northern India 1040–1186'', Edinburgh University Press 1977, repr. New Delhi 1992 (Persian tr.)
*''[[Makrîzî|Al-Maqrizi]]'s "Book of contention and strife concerning the relations between the [[Emevî halifeler listesi|Banu Umayya]] and the [[Benî Haşim|Banu Hashim]]" translated into English'', [[Journal of Semitic Studies]] Monographs, 3, Manchester 1981.
*''Medieval Arabic culture and administration'', [[Variorum]], Collected Studies Series, London 1982.
*(Editor, with [[Carole Hillenbrand]]) ''Qajar Iran, political, social and cultural change 1800–1925'' [= Festschrift for [[L.P. Elwell-Sutton]]], Edinburgh University Press 1984.
*''The History of al-Tabari''. Vol. XXXII. ''The reunification of the [[Abbâsîler|Abbasid Caliphate]]. The caliphate of [[Memûn|al-Ma'mun]] A.D. 812-833/A.H. 198–213'', translated and annotated by C.E. Bosworth, SUNY Press, Albany 1987.
*''The History of al-Tabari''. Vol. XXX. ''The Abbasid Caliphate in equilibrium. The caliphates of [[Hâdî|Musa al-Hadi]] and [[Harun Reşid|Harun al-Rashid]] A.D. 785-809/A.H. 169–193'', translated and annotated by C.E.Bosworth, SUNY Press, Albany 1989.
*''[[Bahaüddin Amilî|Baha' al-Din al-Amili]] and his literary anthologies'', Journal of Semitic Studies Monographs 10, Manchester 1989.
*''The History of [[Taberî|al-Tabari]]''. Vol. XXXIII. ''Storm and stress along the northern frontiers of the Abbasid Caliphate. The caliphate of al-Mu'tas'im A.D. 833-842/A.H. 218–227'', translated and annotated by C.E. Bosworth, SUNY Press, Albany 1991.(editor, with M.E.J. Richardson) [[Richard Bell (Arabist)|Richard Bell]], A commentary on the Qur'an, [[Manchester Üniversitesi|University of Manchester]] (Journal of Semitic Studies) 1991, 2 vols.
*''The History of the Saffarids of Sistan and the Maliks of [[Nimruz]] (247/861 to 949/1452-3)'', Columbia Lectures on Iranian Studies no. 7, Costa Mesa, Calif. and New York 1994.
*''The Arabs, Byzantium and Iran. Studies in early Islamic history and culture'', Variorum, Collected Studies Series, Ashgate Publishing, Aldershot 1996.
*''The New Islamic dynasties. A chronological and genealogical manual'', Edinburgh University Press 1996.
*(Editor, with Muhammad Asim, and contributor) ''The UNESCO history of civilizations of Central Asia, Vol. IV, The age of achievement. A.D. 750 to the end of the fifteenth century''. ''Part 1, The historical, social and economic setting'', Paris 1998. ''Part 2, The literary, cultural, artistic and scientific achievements'', Paris 2000.
*''The History of al-Tabari''. Vol. V. ''The Sasanids, the Byzantines, the Lakhmids and Yemen'', translated and annotated by C.E. Bosworth, SUNY Press, Albany 1999 (editor, and contributor of four chapters)
*''A century of British orientalists 1902–2001'' [= Centennial Volume of the Oriental and African Studies Section of the British Academy], Oxford University Press for the [[British Academy]] 2001.
*''Abu 'l-Fadl [[Muhammed b. Hüseyin el-Beyhaki|Bayhaqi]]'s Tarkh-i Mas'udi translated into English with a historical, geographical and linguistic commentary'', to appear in the Persian Heritage Series, Columbia University, 3 volumes, New York, 2006; ''An intrepid Scot: [[William Lithgow (traveller and author)|William Lithgow]] of Lanark's travels in the Ottoman Empire and Mediterranean lands 1609–21'', Aldershot 2006.
== Referansi ==
{{Reflist}}
== Gıreyê teberi ==
* [https://web.archive.org/web/20080528163603/http://www.huss.ex.ac.uk/iais/downloads/cv_edmunds.doc Biyografiye]
[[Kategoriye:İngılızi]]
[[Kategoriye:Merdumê ke 1928 de biyê]]
[[Kategoriye:Merdumê ke 2015 de merdê]]
[[Kategoriye:Zıwanşınasi]]
[[Kategoriye:Zıwanşınasê İngılızi]]
1g86uwxomznphjcn93g347fecspzzx4
549203
549198
2026-06-22T20:58:56Z
Mirzali
16
549203
wikitext
text/x-wiki
{{Merdumi}}
'''Clifford Edmund Bosworth''' 29 Kanun 1928 – 28 Şıbat 2015), yew tarixwan û oryantilist İngılız biyo. C.E. Bosworth, yew nuştışe xo de qalê Zazayan kerdo: Enê nuştışi de Zazaki lehçeyê Deylemiyan nuşto.<ref>The medieval history of Iran, Afghanistan, and Central Asia s.74</ref>
== Bibliyografiye ==
*''The [[Gazneliler|Ghaznavids]], their empire in Afghanistan and Eastern Iran 994–1040'', Edinburgh University Press 1963, 2nd ed. Beirut 1973, repr. New Delhi 1992 (Persian tr.).
*''The Islamic dynasties, a chronological and genealogical handbook'', Edinburgh University Press 1967, revised ed. 1980 (Russian, Persian, Turkish, Arabic and French trs.).
*''[[Sistan]] under the Arabs, from the Islamic conquest to the rise of the [[Saffârîler|Saffarids]] (30-250/651-864)'', IsMEO, Rome 1968 (Persian tr.).
*''The Book of curious and entertaining information, the Lata'if al-ma'arif of [[Tha'ālibī]] translated into English'', Edinburgh University Press 1968.
*(Editor) ''Iran and Islam'', in memory of the late [[Vladimir Minorsky]], Edinburgh University Press 1971.
*(Editor, with [[Joseph Schacht]]) ''The legacy of Islam'', new edition, Clarendon Press, Oxford 1974 (Arabic tr. Kuwait, 1998).
*''The mediaeval Islamic underworld, the Banu Sasan in Arabic society and literature'', 2 vols., Brill, Leiden 1976.
*''The medieval history of Iran, Afghanistan and Central Asia'', Variorum, Collected Studies Series, London 1977.
*''The later Ghaznavids, splendour and decay: the dynasty in Afghanistan and northern India 1040–1186'', Edinburgh University Press 1977, repr. New Delhi 1992 (Persian tr.)
*''[[Makrîzî|Al-Maqrizi]]'s "Book of contention and strife concerning the relations between the [[Emevî halifeler listesi|Banu Umayya]] and the [[Benî Haşim|Banu Hashim]]" translated into English'', [[Journal of Semitic Studies]] Monographs, 3, Manchester 1981.
*''Medieval Arabic culture and administration'', [[Variorum]], Collected Studies Series, London 1982.
*(Editor, with [[Carole Hillenbrand]]) ''Qajar Iran, political, social and cultural change 1800–1925'' [= Festschrift for [[L.P. Elwell-Sutton]]], Edinburgh University Press 1984.
*''The History of al-Tabari''. Vol. XXXII. ''The reunification of the [[Abbâsîler|Abbasid Caliphate]]. The caliphate of [[Memûn|al-Ma'mun]] A.D. 812-833/A.H. 198–213'', translated and annotated by C.E. Bosworth, SUNY Press, Albany 1987.
*''The History of al-Tabari''. Vol. XXX. ''The Abbasid Caliphate in equilibrium. The caliphates of [[Hâdî|Musa al-Hadi]] and [[Harun Reşid|Harun al-Rashid]] A.D. 785-809/A.H. 169–193'', translated and annotated by C.E.Bosworth, SUNY Press, Albany 1989.
*''[[Bahaüddin Amilî|Baha' al-Din al-Amili]] and his literary anthologies'', Journal of Semitic Studies Monographs 10, Manchester 1989.
*''The History of [[Taberî|al-Tabari]]''. Vol. XXXIII. ''Storm and stress along the northern frontiers of the Abbasid Caliphate. The caliphate of al-Mu'tas'im A.D. 833-842/A.H. 218–227'', translated and annotated by C.E. Bosworth, SUNY Press, Albany 1991.(editor, with M.E.J. Richardson) [[Richard Bell (Arabist)|Richard Bell]], A commentary on the Qur'an, [[Manchester Üniversitesi|University of Manchester]] (Journal of Semitic Studies) 1991, 2 vols.
*''The History of the Saffarids of Sistan and the Maliks of [[Nimruz]] (247/861 to 949/1452-3)'', Columbia Lectures on Iranian Studies no. 7, Costa Mesa, Calif. and New York 1994.
*''The Arabs, Byzantium and Iran. Studies in early Islamic history and culture'', Variorum, Collected Studies Series, Ashgate Publishing, Aldershot 1996.
*''The New Islamic dynasties. A chronological and genealogical manual'', Edinburgh University Press 1996.
*(Editor, with Muhammad Asim, and contributor) ''The UNESCO history of civilizations of Central Asia, Vol. IV, The age of achievement. A.D. 750 to the end of the fifteenth century''. ''Part 1, The historical, social and economic setting'', Paris 1998. ''Part 2, The literary, cultural, artistic and scientific achievements'', Paris 2000.
*''The History of al-Tabari''. Vol. V. ''The Sasanids, the Byzantines, the Lakhmids and Yemen'', translated and annotated by C.E. Bosworth, SUNY Press, Albany 1999 (editor, and contributor of four chapters)
*''A century of British orientalists 1902–2001'' [= Centennial Volume of the Oriental and African Studies Section of the British Academy], Oxford University Press for the [[British Academy]] 2001.
*''Abu 'l-Fadl [[Muhammed b. Hüseyin el-Beyhaki|Bayhaqi]]'s Tarkh-i Mas'udi translated into English with a historical, geographical and linguistic commentary'', to appear in the Persian Heritage Series, Columbia University, 3 volumes, New York, 2006; ''An intrepid Scot: [[William Lithgow (traveller and author)|William Lithgow]] of Lanark's travels in the Ottoman Empire and Mediterranean lands 1609–21'', Aldershot 2006.
== Referansi ==
{{Reflist}}
== Gıreyê teberi ==
* [https://web.archive.org/web/20080528163603/http://www.huss.ex.ac.uk/iais/downloads/cv_edmunds.doc Biyografiye]
[[Kategoriye:İngılızi]]
[[Kategoriye:Merdumê ke 1928 de biyê]]
[[Kategoriye:Merdumê ke 2015 de merdê]]
[[Kategoriye:Zıwanşınasi]]
[[Kategoriye:Zıwanşınasê İngılızi]]
anrr64c7pwzhf6u7cq87dudid4x1vqu
Jos. Schrijnen
0
100222
549199
2026-06-22T13:12:49Z
~2026-36100-06
34192
Ebe zerrekê '{{Merdumi}} '''Joseph Charles François Hubert (Jos.) Schrijnen''' (3 Gulan1869 – Nijmegen - 26 Çele 1938), yew zıwanşınaso [[Holanda]] biyo. Schrijnen, yew nuştışe xo de qalê Zazayan kerdo: Ena nuştışede Zazaki zıwane Deylemicano nuşto.<ref> Josef Schrijnen: Introduction to the Study of Indo-European Linguistics with special consideration of the classical and Germanic languages. Heidelberg, 1921. (Reviewed in: Philological Weekly [Phil...' ra pela newiye vıraziye
549199
wikitext
text/x-wiki
{{Merdumi}}
'''Joseph Charles François Hubert (Jos.) Schrijnen''' (3 Gulan1869 – Nijmegen - 26 Çele 1938), yew zıwanşınaso [[Holanda]] biyo. Schrijnen, yew nuştışe xo de qalê Zazayan kerdo: Ena nuştışede Zazaki zıwane Deylemicano nuşto.<ref>
Josef Schrijnen: Introduction to the Study of Indo-European Linguistics with special consideration of the classical and Germanic languages. Heidelberg, 1921.
(Reviewed in: Philological Weekly [Philologische Wochenschrift], ed. by F. Poland, Vol. 42, No. 16, Leipzig: April 22, 1922, Col. 365–366.)</ref>
== Referansi ==
{{Reflist}}
== Çımey ==
* https://resources.huygens.knaw.nl/bwn1880-2000/lemmata/bwn1/schrijnenjcfh
{{Kontrolê otoriteyi}}
[[Kategoriye:Zıwanşınasi]]
[[Kategoriye:Merdumê ke 1869 de biyê]]
[[Kategoriye:Merdumê ke 1938 de merdê]]
368tm3g4xunpv21ouf9lrc9d2ug3hxy
549204
549199
2026-06-22T21:01:07Z
Mirzali
16
549204
wikitext
text/x-wiki
{{Merdumi}}
'''Joseph Charles François Hubert (Jos.) Schrijnen''' (3 Gulan1869 – Nijmegen - 26 Çele 1938), yew zıwanşınaso [[Holanda]]yıc biyo. Schrijnen, yew nuştışê xo de qalê Zazayan kerdo: Enê nuştışi de Zazaki zıwanê Deylemıcano nuşto.<ref>Josef Schrijnen: Introduction to the Study of Indo-European Linguistics with special consideration of the classical and Germanic languages. Heidelberg, 1921.(Reviewed in: Philological Weekly [Philologische Wochenschrift], ed. by F. Poland, Vol. 42, No. 16, Leipzig: April 22, 1922, Col. 365–366.)</ref>
== Referansi ==
{{Reflist}}
== Çıme ==
* https://resources.huygens.knaw.nl/bwn1880-2000/lemmata/bwn1/schrijnenjcfh
{{Kontrolê otoriteyi}}
[[Kategoriye:Zıwanşınasi]]
[[Kategoriye:Merdumê ke 1869 de biyê]]
[[Kategoriye:Merdumê ke 1938 de merdê]]
o7k5j7kzw6p74oqzfpt0du4o5h1gens
549205
549204
2026-06-22T21:01:21Z
Mirzali
16
549205
wikitext
text/x-wiki
{{Merdumi}}
'''Joseph Charles François Hubert (Jos.) Schrijnen''' (3 Gulan1869 – Nijmegen - 26 Çele 1938), yew zıwanşınaso [[Holanda]]yıc biyo. Schrijnen, yew nuştışê xo de qalê Zazayan kerdo: Enê nuştışi de Zazaki zıwanê Deylemıcano nuşto.<ref>Josef Schrijnen: Introduction to the Study of Indo-European Linguistics with special consideration of the classical and Germanic languages. Heidelberg, 1921.(Reviewed in: Philological Weekly [Philologische Wochenschrift], ed. by F. Poland, Vol. 42, No. 16, Leipzig: April 22, 1922, Col. 365–366.)</ref>
== Referansi ==
{{Reflist}}
== Çıme ==
* https://resources.huygens.knaw.nl/bwn1880-2000/lemmata/bwn1/schrijnenjcfh
{{Kontrolê otoriteyi}}
[[Kategoriye:Zıwanşınasi]]
[[Kategoriye:Merdumê ke 1869 de biyê]]
[[Kategoriye:Merdumê ke 1938 de merdê]]
j5imvk9q4unqernc00nwargvqnua1mt
Kategoriye:Klubê futboliyê Xırvatıstani
14
100223
549207
2026-06-22T21:05:10Z
Mirzali
16
Ebe zerrekê '[[Kategoriye:Xırvatıstan]]' ra pela newiye vıraziye
549207
wikitext
text/x-wiki
[[Kategoriye:Xırvatıstan]]
hsh8j961ioua0uxncviykcx3r3d36ht