پودمان:پدیدآورنده
توضیحات این پودمان میتواند در پودمان:پدیدآورنده/توضیحات قرار گیرد.
function errorMessage(text)
-- Return a html formated version of text stylized as an error.
local html = mw.html.create('div')
html:addClass('error')
:wikitext(text)
:wikitext('[[Catégorie:Pages faisant un appel erroné au modèle Auteur]]')
return tostring(html)
end
function createLinkRow(link, site)
-- Return some html stylised formated text of link
local html = mw.html.create('div')
html:tag('span')
:css({['color'] = '#232388', ['font-size'] = '140%', ['line-height'] = '150%'})
:wikitext('[[File:' .. site .. '-logo.svg|12px|alt=logo de ' .. site .. '|link=]] ')
html:wikitext(link)
return html
end
function categorization(baseName, parameter)
-- Return the categorisation wikitext for each element of parameter prefixed with baseName
if parameter == nil or mw.title.getCurrentTitle().namespace ~= 102 then
return ''
end
local wikitext = ''
for _,param in pairs(mw.text.split(parameter, '/', true)) do
wikitext = wikitext .. '[[Catégorie:' .. baseName .. ' ' .. param .. ']]'
end
return wikitext
end
function computeCenturyFromYear(year)
-- Return the correpsonding century for the given year
if year >= 0 then
return math.ceil(year / 100)
else
return -math.ceil(-year / 100)
end
end
function getTextForCentury(century, withHtml)
-- Return a roman ordinal of century appended with a trailing text precising
-- if the date is before of after the calendar reference point.
local romanNumbers1 = {'', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X'}
local romanNumbers2 = {'', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'}
local text = romanNumbers2[math.floor(math.abs(century) / 10) + 1] .. romanNumbers1[math.floor(math.abs(century) % 10) + 1]
if withHtml then
text = text .. '<sup>e</sup>'
else
text = text .. 'e'
end
if century > 0 then
return text .. ' siècle'
else
return text .. ' siècle av. J.-C.'
end
end
function getTextForYear(year)
local text = math.abs(year)
if year < 0 then
text = text .. ' av. J.-C.'
end
return text
end
function getDateFromArgs(args, field, fieldUpper)
local struct = {
year = nil,
century = nil,
text = nil,
precision = 0
}
--extract year or century
local date = args['annee' .. fieldUpper]
if date == nil then
date = args[field]
end
if tonumber(date) ~= nil then
struct.year = tonumber(date)
if struct.year == 0 then
struct.text = errorMessage("Le calendrier grégorien ne possède pas d’année 0 !")
return struct
end
struct.century = computeCenturyFromYear(struct.year)
struct.precision = 9
elseif args['siecle' .. fieldUpper] ~= nil then
struct.century = tonumber(args['siecle' .. fieldUpper])
struct.precision = 7
end
--build text
if struct.year ~= nil then
struct.text = getTextForYear(struct.year)
elseif struct.century ~= nil then
struct.text = getTextForCentury(struct.century, true)
else
struct.text = date
end
if args['text' .. fieldUpper] ~= nil then
struct.precision = 0 --we don't know anything
struct.text = args['text' .. fieldUpper] .. ' ' .. struct.text
end
if args['incertitude' .. fieldUpper] ~= nil and struct.text ~= nil then
struct.precision = 0 --we don't know anything
struct.text = args['incertitude' .. fieldUpper] .. ' ' .. struct.text
end
return struct
end
function getDateFromTimeStatements(statements, field)
if #statements == 0 then
return {
precision = 0
}
end
local time = nil
for _, statement in pairs(statements) do
local newTime = getDateFromTimeStatement(statement, field)
if time == nil then
time = newTime
elseif time.year ~= newTime.year then --années contradictoires
mw.addWarning('Plusieurs années de ' .. field .. ' possibles sur Wikidata. Une manière simple de résoudre se problème est de mettre la date à afficher au rang "préféré".')
end
end
if time == nil then
return {
precision = 0
}
end
return time
end
function parseWbTime(value)
local _,_, year = string.find(value.time, '([%+%-]%d%d%d+)%-')
year = tonumber(year)
return {
year = year,
century = computeCenturyFromYear(year),
text = nil,
precision = value.precision
}
end
function getDateFromTimeStatement(statement, field)
local struct = {
year = nil,
century = nil,
text = nil,
precision = 0
}
local snak = statement.mainsnak
if snak.snaktype == 'novalue' then
return struct
end
if snak.snaktype == 'somevalue' then
struct.text = '??'
return struct
end
struct = parseWbTime(snak.datavalue.value)
local prefix = ''
if struct.precision == 8 then
prefix = 'vers '
end
--Extract circa
if statement.qualifiers ~= nil and statement.qualifiers.P1480 ~= nil then
for _,qualifier in pairs(statement.qualifiers.P1480) do
if qualifier.datavalue.value.id == 'Q5727902' then
prefix = 'vers '
struct.precision = 8 --TODO: hacky
end
if qualifier.datavalue.value.id == 'Q79030196' then
prefix = 'avant '
struct.precision = 8 --TODO: hacky
end
end
end
--Use before and after if precision <= century
if statement.qualifiers ~= nil and struct.precision <= 7 then
if statement.qualifiers.P1319 ~= nil then
for _,qualifier in pairs(statement.qualifiers.P1319) do
struct = parseWbTime(qualifier.datavalue.value)
prefix = 'après '
struct.precision = 8 --TODO: hacky
end
elseif statement.qualifiers.P1326 ~= nil then
for _,qualifier in pairs(statement.qualifiers.P1326) do
struct = parseWbTime(qualifier.datavalue.value)
prefix = 'avant '
struct.precision = 8 --TODO: hacky
end
elseif statement.qualifiers.P1317 ~= nil then
for _,qualifier in pairs(statement.qualifiers.P1317) do
struct = parseWbTime(qualifier.datavalue.value)
prefix = 'floruit '
struct.precision = 8 --TODO: hacky
end
end
end
--Create text
if struct.precision >= 9 then
struct.text = prefix .. getTextForYear(struct.year)
elseif struct.precision == 8 then
struct.text = prefix .. getTextForYear(struct.year)
elseif struct.precision == 7 then
struct.text = prefix .. getTextForCentury(struct.century, true)
else
struct.text = errorMessage('La date de ' .. field .. ' a une précision trop faible sur Wikidata')
end
return struct
end
function formatDates(naissance, deces, class)
if naissance.text == nil and deces.text == nil then
return ''
end
local text = '('
if naissance.precision >= 9 then
local annotation = 'class="bday" itemprop="birthDate"'
if class ~= "Q5" and class ~= nil then
annotation = 'itemprop="foundingDate'
end
text = text .. '<time datetime="' .. naissance.year .. '" ' .. annotation .. '>' .. naissance.text .. '</time> '
elseif naissance.text ~= nil then
text = text .. naissance.text .. ' '
end
text = text .. '—'
if deces.precision >= 9 then
local annotation = 'class="dday" itemprop="deathDate"'
if class ~= "Q5" and class ~= nil then
annotation = 'itemprop="dissolutionDate'
end
text = text .. ' <time datetime="' .. deces.year .. '" ' .. annotation .. '>' .. deces.text .. '</time>'
elseif deces.text ~= nil then
text = text .. ' ' .. deces.text
end
return text .. ')'
end
function qidForProperty(item, property)
local statements = item:getBestStatements(property)
if statements[1] ~= nil and statements[1].mainsnak.datavalue ~= nil then
return statements[1].mainsnak.datavalue.value.id
end
return nil
end
function searchKey(key)
-- normally the key does not contain any diacritic but it's a common misuse
-- of the clef = so handle at least the most usual diacritics, note than
-- prenom can be empty
local nom, prenom = mw.ustring.match(key, '^([A-ZÉÈÀÇa-zéèàç-]*)[,]?[ ]*(.*)$')
return prenom .. ' ' .. 'intitle:' .. nom
end
function add_category(html, category)
if mw.title.getCurrentTitle().namespace == 102 then
html:wikitext('[[Catégorie:' .. category .. ']]')
end
end
function main(frame)
--create a clean table of parameters with blank parameters removed
local args = {}
for k,v in pairs(frame:getParent().args) do
if v ~= '' then
args[k] = v
end
end
local naissance = getDateFromArgs(args, 'naissance', 'Naissance')
local deces = getDateFromArgs(args, 'deces', 'Deces')
local sexe = nil
local class = nil
local html = mw.html.create()
--Utilise Wikidata si paramètres non renseignés
local item = mw.wikibase.getEntity()
if item == nil then
add_category(html, 'Pages « Auteur » sans élément sur Wikidata')
else
if args.nom == nil then
args.nom = item:getLabel()
else
add_category(html, 'Pages utilisant le modèle Auteur avec un nom local')
end
if args.description ~= nil then
add_category(html, 'Pages utilisant le modèle Auteur avec une description locale')
elseif item.descriptions ~= nil and item.descriptions.fr ~= nil then
args.description = mw.text.trim(string.gsub(item.descriptions.fr.value, "%s+%(.*%)%s*", " "))
if item.descriptions.fr.language ~= 'fr' then
args.descriptionLanguageCode = item.descriptions.fr.language
end
end
if args.image == nil then
local statements = item:getBestStatements('P154') -- logo
if next(statements) == nil then
statements = item:getBestStatements('P18') --image
end
if next(statements) == nil then
statements = item:getBestStatements('P6802') -- image en rapport
end
if statements[1] ~= nil and statements[1].mainsnak.datavalue ~= nil then
args.image = statements[1].mainsnak.datavalue.value
end
else
add_category(html, 'Pages utilisant le modèle Auteur avec une image locale')
end
local naissanceWikidata = getDateFromTimeStatements(item:getBestStatements('P569'), 'naissance')
if naissanceWikidata.precision == 0 then
naissanceWikidata = getDateFromTimeStatements(item:getBestStatements('P571'), 'création')
end
if naissance.text == nil then
naissance = naissanceWikidata
else
add_category(html, 'Pages utilisant le modèle Auteur avec une date locale')
if naissanceWikidata.text == nil then -- on utilise la date de création
add_category(html, 'Pages utilisant le modèle Auteur avec des données à migrer')
end
end
local decesWikidata = getDateFromTimeStatements(item:getBestStatements('P570'), 'deces')
if decesWikidata.precision == 0 then -- on utilise la date de dissolution
decesWikidata = getDateFromTimeStatements(item:getBestStatements('P576'), 'dissolution')
end
if deces.text == nil then
deces = decesWikidata
else
add_category(html, 'Pages utilisant le modèle Auteur avec une date locale')
if decesWikidata.text == nil then
add_category(html, 'Pages utilisant le modèle Auteur avec des données à migrer')
end
end
if args.pseudo == nil then
args.pseudo = item:formatPropertyValues( 'P742' ).value
if args.pseudo == '' then
args.pseudo = nil
end
elseif args.pseudo ~= '-' then
add_category(html, 'Pages utilisant le modèle Auteur avec un pseudo local')
end
--sexe
sexe = qidForProperty(item, 'P21')
--class
class = qidForProperty(item, 'P31')
end
if args.nom == nil then
return errorMessage('Le paramètre « nom » est obligatoire et doit contenir le nom de l’auteur')
end
--sort key and initiale
local firstName = ''
local familyName = ''
if item ~= nil then
--first name
local firstNameStatements = item:getBestStatements('P735')
if firstNameStatements[1] ~= nil then
if firstNameStatements[1].mainsnak.type == 'value' then
local firstNameId = firstNameStatements[1].mainsnak.datavalue.value.id
firstName = mw.wikibase.label(firstNameId) or ''
--TODO check if the first name is not an initial
elseif firstNameStatements[1].mainsnak.type == 'somevalue' then
add_category(html, 'Auteurs de prénom inconnu')
end
end
--family name
local familyNameId = qidForProperty(item, 'P734')
if familyNameId ~= nil then
familyName = mw.wikibase.label(familyNameId) or ''
end
end
if familyName == '' then
--We are in a simple case with first name and last name. TODO: bad hack, should be improved
local nameParts = mw.text.split(args.nom, ' ', true)
if #nameParts == 1 then
familyName = nameParts[1]
elseif #nameParts == 2 then
firstName = nameParts[1]
familyName = nameParts[2]
end
end
if args.cle == nil then
if familyName ~= '' then
local moduleClassement = require 'Module:Classement'
args.cle = moduleClassement.getSortKeyForName({args = {firstName, familyName}})
else
return errorMessage('Le paramètre « cle » est obligatoire et doit contenir une clé de tri pour l’auteur')
end
else
add_category(html, 'Pages utilisant le modèle Auteur avec une clé locale')
end
if args.initiale == nil then
if args.cle ~= nil then
args.initiale = mw.ustring.sub(args.cle, 1, 1)
else
return errorMessage('Le paramètre « initiale » est obligatoire et doit contenir l’initiale du nom de l’auteur en majuscule non accentuée')
end
else
add_category(html, 'Pages utilisant le modèle Auteur avec des données à migrer')
end
local main = html:tag('div')
:attr('itemscope', '')
:css({['background-color'] = '#F1F1DE', ['overflow'] = 'auto', ['border-radius'] = '0.7em', ['box-shadow'] = '0.2em 0.3em 0.2em #B7B7B7'})
if class == "Q5" or class == nil then
main = main:attr('itemtype', 'http://schema.org/Person'):addClass('vcard')
else
main = main:attr('itemtype', 'http://schema.org/Organization')
end
if item ~= nil and item.id ~= nil then
main:attr('itemid', 'http://www.wikidata.org/entity/' .. item.id)
end
--Image
local image = args.image
if image == nil then
if class == 'Q5' or class == nil then
if sexe == 'Q6581097' then
image = 'Silver - replace this image male.svg'
elseif sexe == 'Q6581072' then
image = 'Silver - replace this image female.svg'
else
image = 'Silver - replace this image female and male.svg'
end
else
image = 'Organization_icon.svg'
end
end
main:tag('div')
:css({['float'] = 'right', ['margin'] = '1em'})
:wikitext('[[Fichier:' .. image .. '|140px|alt=' .. args.nom .. '|class=photo]]')
--First row
local firstRow = main:tag('div')
--Categorie Auteur-X
firstRow:tag('div')
:css({['float'] = 'left', ['font-size'] = '115%', ['text-indent'] = '1em'})
:tag('span')
:css('color', '#aaaa66')
:wikitext('◄')
:done()
:wikitext(' [[:Catégorie:Auteurs-' .. args.initiale .. '|Auteurs ' .. args.initiale .. ']]')
--Title
firstRow:tag('h1')
:addClass('fn')
:attr('itemprop', 'name')
:css({['text-align'] = 'center', ['font-size'] = '160%', ['font-weight'] = 'bold', ['border-bottom'] = 'none'})
:wikitext(args.nom)
--Second row
local secondRow = main:tag('div')
--Interwikis
local interwikis = secondRow:tag('div')
:css({['float'] = 'left', ['height'] = '50%', ['font-size'] = '75%', ['text-indent'] = '2em'})
:node(createLinkRow('<span class="plainlinks">[//fr.wikisource.org/wiki/Spécial:IndexPages?key=' .. mw.uri.encode(searchKey(args.cle)) .. ' Fac-similés]</span>', 'Wikisource'))
if item ~= nil and item:getSitelink('frwiki') ~= nil then
interwikis:node(createLinkRow('[[w:' .. item:getSitelink('frwiki') .. '|Biographie]]', 'Wikipedia'))
else
interwikis:node(createLinkRow('[[w:' .. args.nom .. '|<span style="color:#BA0000;">Biographie</span>]]', 'Wikipedia'))
end
if item ~= nil and item:getSitelink('frwikiquote') ~= nil then
interwikis:node(createLinkRow('[[q:' .. item:getSitelink('frwikiquote') .. '|Citations]]', 'Wikiquote'))
else
interwikis:node(createLinkRow('[[q:' .. args.nom .. '|<span style="color:#BA0000;">Citations</span>]]', 'Wikiquote'))
end
if item ~= nil then
local commonsCat = item:formatPropertyValues('P373').value
if commonsCat ~= '' then
interwikis:node(createLinkRow('[[commons:Category:' .. commonsCat .. '|Médias]]', 'Commons'))
elseif item:getSitelink('commonswiki') ~= nil then
interwikis:node(createLinkRow('[[commons:' .. item:getSitelink('commonswiki') .. '|Médias]]', 'Commons'))
else
interwikis:node(createLinkRow('[[commons:' .. args.nom .. '|<span style="color:#BA0000;">Médias</span>]]', 'Commons'))
end
else
interwikis:node(createLinkRow('[[commons:' .. args.nom .. '|<span style="color:#BA0000;">Médias</span>]]', 'Commons'))
end
if item ~= nil and item.id ~= nil then
interwikis:node(createLinkRow('[[d:' .. item.id .. '|Données structurées]]', 'Wikidata'))
else
interwikis:node(createLinkRow('<span class="plainlinks">[//www.wikidata.org/w/index.php?title=Special:NewItem&site=frwikisource&page=' .. mw.uri.encode(mw.title.getCurrentTitle().fullText) .. '&label=' .. mw.uri.encode(args.nom) .. ' Données structurées</span>]</span>', 'Wikidata'))
end
--Description
local fullDescription = secondRow:tag('div')
:css({['text-align'] = 'center', ['font-size'] = '110%', ['line-height'] = '110%', ['padding'] = '1em'})
local description = fullDescription:tag('span')
:addClass('label')
:attr('itemprop', 'description')
:wikitext(args.description or '')
if args.descriptionLanguageCode ~= nil then
description:attr('lang', item.descriptions.fr.language)
:css('font-style', 'italic')
add_category(html, 'Pages utilisant le modèle Auteur sans description française')
elseif args.description == nil then
add_category(html, 'Pages utilisant le modèle Auteur sans description française')
end
fullDescription
:newline()
:wikitext(formatDates(naissance, deces, class))
if args.pseudo ~= nil and args.pseudo ~= '-' then
fullDescription:tag('br')
fullDescription:wikitext('Pseudonyme : ')
:tag('span')
:attr('itemprop', 'alternateName')
:css('font-style', 'italic')
:wikitext(args.pseudo)
end
--categories
add_category(html, 'Auteurs')
add_category(html, 'Auteurs-' .. args.initiale)
--genre
if args.genre ~= nil then
add_category(html, 'Pages utilisant le modèle Auteur avec un genre local')
html:wikitext(categorization('', args.genre))
end
html:wikitext(categorization('', args.genre))
--langue
if item ~= nil then
for _, statement in pairs(item:getBestStatements('P6886')) do
if statement.mainsnak.datavalue ~= nil then
local languageLabel = mw.wikibase.label(statement.mainsnak.datavalue.value.id)
if languageLabel ~= nil then
categoryName = 'Catégorie:Auteurs écrivant en ' .. mw.wikibase.label(statement.mainsnak.datavalue.value.id)
html:wikitext('[[' .. categoryName .. ']]')
if not mw.title.new( categoryName ).exists then
html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec une catégorie de langue non créée]]')
end
end
end
end
end
if args.langue ~= nil then
add_category(html, 'Pages utilisant le modèle Auteur avec une langue locale')
end
--nationalités
local categoryForCountry = mw.loadData('Module:Auteur2/nationalités')
local withNationality = false
if item ~= nil then
for _, statement in pairs(item:getBestStatements('P27')) do
if statement.mainsnak.datavalue ~= nil then
countryId = statement.mainsnak.datavalue.value.id
if categoryForCountry[countryId] == nil then
add_category(html, 'Pages utilisant le modèle Auteur avec une nationalité sans catégorie')
withNationality = true
elseif categoryForCountry[countryId] then
add_category(html, categoryForCountry[countryId])
withNationality = true
end
end
end
end
if args.pays ~= nil then
add_category(html, 'Pages utilisant le modèle Auteur avec une nationalité locale')
withNationality = true
end
if not withNationality then
add_category(html, 'Pages « Auteur » sans nationalité')
end
--occupation
categoryForOccupation = mw.loadData('Module:Auteur2/occupations')
if item ~= nil then
for _, statement in pairs(item:getBestStatements('P106')) do
if statement.mainsnak.datavalue ~= nil then
occupationId = statement.mainsnak.datavalue.value.id
if categoryForOccupation[occupationId] == nil then
add_category(html, 'Pages utilisant le modèle Auteur avec une occupation sans catégorie')
elseif categoryForOccupation[occupationId] then
add_category(html, categoryForOccupation[occupationId])
end
end
end
end
if args.metier ~= nil or args["métier"] ~= nil then
html:wikitext(categorization('', args.metier or args["métier"]))
add_category(html, 'Pages utilisant le modèle Auteur avec une occupation locale')
end
--prix
if args.prix ~= nil then
html:wikitext(categorization('Lauréats du', args.prix))
add_category(html, 'Pages utilisant le modèle Auteur avec un prix local')
end
if item ~= nil then
for _, awardStatement in pairs(item:getBestStatements('P166')) do
if awardStatement.mainsnak.datavalue ~= nil then
distinctionItem = mw.wikibase.getEntity(awardStatement.mainsnak.datavalue.value.id)
for _, awardeeCatStatement in pairs(distinctionItem:getBestStatements('P2517')) do
if awardeeCatStatement.mainsnak.datavalue ~= nil then
wikisourceCategory = mw.wikibase.sitelink(awardeeCatStatement.mainsnak.datavalue.value.id)
if wikisourceCategory then
html:wikitext('[[' .. wikisourceCategory .. ']]')
end
end
end
end
end
end
--categorie dates
if naissance.precision >= 9 and naissance.year > 1500 then
add_category(html, 'Naissance en ' .. naissance.year)
end
if deces.precision >= 9 and deces.year > 1500 then
add_category(html, 'Décès en ' .. deces.year)
end
local withoutEpoque = true
if naissance.century ~= nil and (naissance.precision < 9 or naissance.year <= naissance.century * 100 - 20) then
if 15 <= naissance.century then
add_category(html, 'Auteurs du ' .. getTextForCentury(naissance.century, false))
elseif 6 <= naissance.century and naissance.century <= 14 then
add_category(html, 'Auteurs du Moyen Âge')
else
add_category(html, 'Auteurs de l’Antiquité')
end
withoutEpoque = false
end
if deces.century ~= nil and (deces.precision < 9 or (deces.century - 1) * 100 + 5 <= deces.year) then
if 15 <= deces.century then
add_category(html, 'Auteurs du ' .. getTextForCentury(deces.century, false))
elseif 6 <= deces.century and deces.century <= 14 then
add_category(html, 'Auteurs du Moyen Âge')
else
add_category(html, 'Auteurs de l’Antiquité')
end
withoutEpoque = false
end
if withoutEpoque then
add_category(html, 'Époque inconnue')
end
if sexe == 'Q6581072' then
add_category(html, 'Autrices')
end
--droits
if args.droits == nil then
args.droits = '70'
end
droitsNumber = tonumber(args.droits)
if args.droits == 'mpf' then
if deces.precision >= 9 and tonumber(os.date("%Y")) <= deces.year + 95 then --TODO: guess 'mpf' from P166:Q3324507 in Wikidata?
html:wikitext(frame:expandTemplate({title = 'Auteur Mort pour la France'}))
end
add_category(html, 'Auteurs morts pour la France')
elseif args.droits == 'non' then
--rien à faire
elseif droitsNumber ~= nil then
if deces.year ~= nil and tonumber(os.date("%Y")) <= deces.year + droitsNumber then --XX ans on vérifie le DP-EU
if naissance.year == nil or 1923 - naissance.year > 20 then
html:wikitext(frame:expandTemplate({title = 'DP-EU-Auteur'}))
end
end
if args.droits ~= '70' then
add_category(html, 'Droits d’auteur ' .. args.droits .. ' ans')
end
else
return errorMessage('Le paramètre droit contient une valeur non supportés. Valeurs possibles : 70/60/50 (durée du droit d\'auteur), "mpf" (mort pour la france). Par défaut: 70')
end
--maintenance
if args.image == nil then
add_category(html, 'Pages « Auteur » sans image')
end
if args.cle ~= nil then
html:wikitext(frame:preprocess('{{DEFAULTSORT:' .. args.cle .. '}}'))
end
--contenu
html:wikitext('\n__NOTOC__')
:wikitext('\n')
:wikitext(args.contenu)
:wikitext('\n')
:wikitext((require 'Module:Autorité').autorite(item, args))
return tostring(html)
end
local p = {};
function p.auteur( frame )
return main( frame )
end
return p