Module:Wikidata/Références : Différence entre versions

De Wikonsult
Sauter à la navigation Sauter à la recherche
w.fr>Lofhi
(Annulation de la modification de Lofhi (d) cela corrige bien le problème, mais certains résultats générés manuellement dans la console de debug ne sont pas identiques...)
(Aucune différence)

Version du 19 février 2019 à 20:30

Utilisation

Fonctions exportables :

  • citeitem(id, page, dateconsult) – formate au format Wikitexte, en utilisant les modèles de citation standard si possible, la référence.

Test :

  • invalid entity id
  • invalid entity id
  • invalid entity id, invalid entity id
  • invalid entity id
  • invalid entity id
  • invalid entity id
  • invalid entity id

Sandbox:

  • invalid entity id

Exemples



local reference = {}

local wd = require 'Module:Wikidata'
local refType = mw.loadData 'Module:Wikidata/Références/Types'

local linguistic = require 'Module:Linguistique'
local cite = require 'Module:Biblio'
local langcodes = mw.loadData 'Module:Dictionnaire Wikidata/Codes langue'

local function concatTables(t1,t2)
	local results = {}
	for _,e in pairs(t1) do
    	table.insert(results, e)
    end
    for _,e in pairs(t2) do
    	table.insert(results, e)
    end
    return results
end

local function getStringStatementValues(entity, propertyId)
	local statements = entity:getBestStatements(propertyId)
	for i, statement in pairs(statements) do
		statements[i] = statement.mainsnak.datavalue.value
	end
	return statements
end

local function getStringStatementValue(entity, propertyId)
	local statements = getStringStatementValues(entity, propertyId)
	if #statements > 0 then
		return statements[1]
	else
		return nil
	end
end

local function getDirectItemLang(workentity, property)
	local itemlangs = wd.getClaims{entity = workentity, property = property}
	if itemlangs ~= nil then
		return langcodes[wd.getNumericId(itemlangs[1].mainsnak)]
	end
end

local function hasRole(statement, roleId)
	return statement.qualifiers and (
		statement.qualifiers['P518'] and wd.getId(statement.qualifiers['P518'][1]) == roleId
		or statement.qualifiers['P794'] and wd.getId(statement.qualifiers['P794'][1]) == roleId
	)
end	

local function remove_same_isbn(isbns)
	-- input a table of isbns
	-- return a table of ibns without duplicate
	-- asked in https://fr.wikipedia.org/wiki/Discussion_mod%C3%A8le:Bibliographie#ISBN-10_et_ISBN-13
	local References = require( 'Module:Biblio/Références' )
	local result = {}
	for _, isbn1 in ipairs(isbns) do
		local same = false
		for index_isbn2, isbn2 in ipairs(result) do
			if  References.same_isbn(isbn1, isbn2) then
				if isbn2:gsub( '[ -]', '' ):len() == 13 then
					table.remove(result, index_isbn2)
					table.insert(result, isbn1)
				end
				same = true
				break
			end
		end
		if not same then
			table.insert(result, isbn1)
		end
	end
	return result
end

function reference.citeitem(entityId, options)
	if not entityId then
		return nil
	end
	local entity = wd.getEntity(entityId)
	if not entity then
		return 'invalid entity id'
	end
	if type( options ) ~= 'table' then
		options = {}
	end
	
	--work entity if it exists
	local workEntity = nil
	local workClaims = wd.getClaims{entity = entity, property = 'P629'} -- P629 : édition de
	if workClaims ~= nil then
		workEntity = wd.getEntity(wd.getMainId(workClaims[1]))
	end
	local journalEntity = nil
	local journalClaims = wd.getClaims{entity = entity, property = 'P1433'}
	if journalClaims ~= nil then
		journalEntity = wd.getEntity(wd.getMainId(journalClaims[1]))
	end

	local translator = wd.formatStatements{entity = entity, property = 'P655', defaultlink = '-'}
	local illustrator = wd.formatStatements{entity = entity, property = 'P110', defaultlink = '-'}
	local preface = ''
	local postface = ''
	local photographe = ''
	local authors = {}
	local are_director = {}
	local responsability = {}
	
	local author_statements = concatTables(entity:getBestStatements('P50'), entity:getBestStatements('P2093'))
	if next(author_statements) == nil and workEntity ~= nil then --Fallback to work
		author_statements = concatTables(workEntity:getBestStatements('P50'), workEntity:getBestStatements('P2093'))
	end
	for _, statement in pairs(author_statements) do
		local author = wd.formatStatement(statement, {defaultlink = '-'})
		local position = #authors + 1
		if statement.qualifiers and statement.qualifiers['P1545'] then
			position = tonumber(statement.qualifiers['P1545'][1].datavalue.value)
		end
		if statement.qualifiers and statement.qualifiers['P1932'] then
			statement.mainsnak = statement.qualifiers['P1932'][1]
		end
		authors[position] = wd.formatStatement(statement, {defaultlink = '-'})
		are_director[position] = ''
		--qualifier pour la responsabilité
		if statement.qualifiers and statement.qualifiers['P518'] then
			responsability[position] = wd.formatSnak(statement.qualifiers['P518'][1], {defaultlink = '-'})
		else
			responsability[position] = ''
		end
	end
	for _, statement in pairs(entity:getBestStatements('P98')) do
		table.insert(authors, wd.formatStatement(statement, {defaultlink = '-'}))
		table.insert(are_director, 'y')
		table.insert(responsability, '')
	end
	
	for _, statement in pairs(entity:getBestStatements('P767')) do
		if hasRole(statement, 'Q670787') or hasRole(statement, 'Q19839393') then --préface/préfacier
			preface = wd.formatStatement(statement, {defaultlink = '-'})
		elseif hasRole(statement, 'Q7234272') then --postface
			postface = wd.formatStatement(statement, {defaultlink = '-'})
		elseif hasRole(statement, 'Q33231') or hasRole(statement, 'Q125191') then --photographe/photographie
			photographe = wd.formatStatement(statement, {defaultlink = '-'})
		end
	end
	
	local isbns = getStringStatementValues(entity, 'P212')
	for _, isbn in pairs(getStringStatementValues(entity, 'P957')) do
		table.insert(isbns, isbn)
	end
	local issns = {}
	if journalEntity then
		issns = getStringStatementValues(journalEntity, 'P236')
	end
	if #issns == 0 then
		issns = getStringStatementValues(entity, 'P236')
	end
	local oclc = getStringStatementValue(entity, 'P243')
	local bnf = getStringStatementValue(entity, 'P268')
	local lccn = getStringStatementValue(entity, 'P1144')
	local dnb = getStringStatementValue(entity, 'P1292')
	local doi = getStringStatementValue(entity, 'P356')
	local pmid = getStringStatementValue(entity, 'P698')
	local jstor = getStringStatementValue(entity, 'P888')
	local bibcode = getStringStatementValue(entity, 'P1300')
	local arxiv = getStringStatementValue(entity, 'P818')
	local pmcid = getStringStatementValue(entity, 'P932')
	
	local ednumber = wd.formatStatements{entity = entity, property = 'P393'}
	local publisher = wd.formatStatements{entity = entity, property = 'P123', defaultlink = '-'}
	local journal = wd.formatStatements{entity = entity , property = 'P1433', defaultlink = '-'}
	--TODO fix local journalnumber = wd.formatStatements{entity = entity, property = 'P433'}
	--TODO fix local volume = wd.formatStatements{entity = entity, property = 'P478'}

	local publishdate = wd.formatStatements{entity = entity, property = 'P577', linktopic = '-'}
	local publishplace = wd.formatStatements{entity = entity, property = 'P291', defaultlink = '-'}

	--if no publisher, publication date or place, oclc or bnf: look for them in the item stored in P1433, misnamed here as  "journalEntity"
	if (not publisher) and journalEntity then
		publisher = wd.formatStatements{entity = journalEntity, property = "P123", defaultlink = "P577"}
	end
	if (not publishdate) and journalEntity then
		publishdate = wd.formatStatements{entity = journalEntity, property = "P577", linktopic = "P577"}
	end
	if (not publishplace) and journalEntity then
		publishplace = wd.formatStatements{entity = journalEntity, property = "P291", defaultlink = "P577"}
	end
	if (not oclc) and journalEntity then
		oclc = wd.formatStatements{entity = journalEntity, property = "P243", defaultlink = "P577"}
	end
	if (not bnf) and journalEntity then
		bnf = wd.formatStatements{entity = journalEntity, property = "P268", defaultlink = "P577"}
	end

	local pagenum = wd.formatStatements{entity = entity, property = 'P1104'}
	local title = wd.formatStatements{entity = entity, property = 'P1476', numval = 1 } or wd.getLabel(entity)
	local titlelink = wd.siteLink(entity)
	local subtitle = wd.formatStatements{entity = entity, property = 'P1680'}
	local url = getStringStatementValue(entity, 'P854') or getStringStatementValue(entity, 'P953')
	local wikisource = entity:getSitelink('frwikisource')
	local language = getDirectItemLang(entity, 'P407')
	if not language and journalEntity then
		language = getDirectItemLang(journalEntity, 'P407')
	end
	local originalLanguage = getDirectItemLang(entity, 'P364') --TODO: be clever? or getDirectItemLang(workEntity, 'P407') or getDirectItemLang(workEntity, 'P364')
	if not language or language == originalLanguage then
		originalLanguage = nil -- We are actually not sure if it has been translated from this language
	end
	local originalTitle = nil
	if workEntity and originalLanguage then
		originalTitle = wd.formatStatements{entity = workEntity, property = 'P1476', numval = 1 } or workEntity:getLabel(originalLanguage)
	end
	local page = getStringStatementValue(entity, 'P304')
	local numero = getStringStatementValue(entity, 'P433')
	local volume = getStringStatementValue(entity, 'P478')

	-- choose relevant cite type
	local entitytype = wd.formatStatements{property = 'P31', entity = entity, numval = 1, displayformat = 'raw'}
	local funtype
		
		
	-- calcul du rendu du titre de l'ouvrage, éventuellement avec un lien vers l'article de l'ouvrage

	-- pas de lien à générer si on est sur la page de l'ouvrage ou si l'élément cité est une édition de cet ouvrage
	if not ( wd.isPageOfQId(entityId) or 
	   workEntity and wd.isPageOfQId(wd.entityId(workEntity)) )
	then
		if not titlelink and workEntity then
			-- si pas de lien, on peut essayer de voir si c'est l'édition de quelque chose d'autre
			titlelink = wd.siteLink(workEntity)
		end
		if title and titlelink then
			title = '[[' .. titlelink .. '|' .. title .. ']]'
		end
	end

	-- calcul du modèle à utiliser pour rendre l'élémént
	
	if (entitytype == 'Q3331189') then --book edition
		funtype = cite.ouvrage
		
		-- TODO : gérer l'édition et l'élément de l'oeuvre. 
		
	elseif refType.isOuvrage[entitytype] then -- ouvrage sans édition connue ?
		
		-- TODO : gérer le cas ou un ouvrage est cité mais que Wikidata en connait des éditions.
		-- TODO : refuser ce genre d'items ?
		
		funtype = cite.ouvrage
		
	elseif refType.isArticle[entitytype] then -- article
		funtype = cite.article
	else -- default: output a very simple display
		local parameters = authors
		if title then 
			 table.insert(parameters, '<i>' .. title .. '</i>')
		end
		if publisher then
			table.insert(parameters, publisher)
		end
		if publishplace then
			table.insert(parameters, publishplace)
		end
		if publishdate then
			table.insert(parameters, publishdate)
		end
		if options['page'] then
			table.insert(parameters, 'p.' .. options['page'])
		end
		if options['accessdate'] then
			table.insert(parameters, 'consulté le ' .. options['accessdate'])
		end
		return linguistic.conj(parameters, 'comma')
	end

	
	local parameters = {
		['traducteur'] = translator,
		['illustrateur'] = illustrator,
		['préface'] = preface,
		['postface'] = postface,
		['photographe'] = photographe,
		['titre'] = title,
		['sous-titre'] = subtitle,
		--['volume'] = volume,
		['date'] = publishdate,
		['lieu'] = publishplace,
		['périodique'] = journal,
		--['numéro'] = journalnumber,
		["numéro d'édition"] = ednumber,
		['éditeur'] = publisher,
		['pages totales'] = pagenum,
		['lire en ligne'] = url,
		['wikisource'] = wikisource,
		['oclc'] = oclc,
		['bnf'] = bnf,
		['lccn'] = lccn,
		['dnb'] = dnb,
		['doi'] = doi,
		['pmid'] = pmid,
		['jstor'] = jstor,
		['bibcode'] = bibcode,
		['arxiv'] = arxiv,
		['pmcid'] = pmcid,
		['langue'] = language,
		['langue originale'] = originalLanguage,
		['titre original'] = originalTitle,
		['page'] = page,
		['numéro'] = numero,
		['volume'] = volume,
		['plume'] = options['plume']
	}
	
	isbns = remove_same_isbn(isbns)
	for i, isbn in pairs(isbns) do
		parameters['isbn' .. i] = isbn
	end
	
	for i, issn in pairs(issns) do
		parameters['issn' .. i] = issn
	end
	
	-- try to find if there is an author set in options
	local setAuthors = true
	for i=1, 15 do
		if options['auteur' .. i]  or options['directeur' .. i] or options['responsabilité' .. i] then
			setAuthors = false
		end
	end

	if setAuthors then
		for i, author in pairs(authors) do
			parameters['auteur' .. i] = author
			parameters['directeur' .. i] = are_director[i]
			parameters['responsabilité' .. i] = responsability[i]
		end
	end
	
	for parameter, value in pairs(options) do
		if value == '-' then
			parameters[parameter] = ''
		else
			parameters[parameter] = value
		end
	end
	local val = funtype(parameters)

	if val then
		return wd.addRefAnchor(wd.addLinkBack(val, entity), wd.entityId(entity))
	end
	
	return wd.formatError()
end

-- pour tester
function reference.citeItem(frame)
	local args = frame:getParent().args
	return reference.citeitem(args[1], args)
end


--used to test the duplicate isbn functions, use in the console like this
-- p.test()
reference.test = function()
	test_same_isbn()
	test_remove_same_isbn()
end

return reference