Módulo:Wikidata/Referências

Documentação do módulo[ver] [editar] [histórico] [purgar]


Descrição editar

Este módulo tem funções auxiliares para criar referências.

Uso editar

Outra documentação:

local reference = {}

local wd = require 'Módulo:Infobox/Wikidata'
local refType = mw.loadData 'Módulo:Wikidata/Referências/Tipos'

local linguistic = require 'Módulo:Linguística'
local cite = require 'Módulo:Citação/CS1'
local langcodes = mw.loadData 'Módulo:Dicionário Wikidata/Códigos língua'

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 currentPageTitle = mw.title.getCurrentTitle().prefixedText

local function buildAuthorLink(statement)
    local author_label = nil
    local author_link = nil
    -- we extract the link and the label of the author if it is an entity
    if statement.mainsnak.snaktype == 'value' and statement.mainsnak.datatype == 'wikibase-item' then
        local author_id = statement.mainsnak.datavalue.value.id
        author_label = mw.wikibase.getLabel(author_id)
        author_link = mw.wikibase.getSitelink(author_id)
    end
    -- we use stated in to retrive the proper author label by setting it in statement.mainsnak
    if statement.qualifiers and statement.qualifiers['P1932'] then
        statement.mainsnak = statement.qualifiers['P1932'][1]
    end
    -- and then by getting the label from its value (supports also P2093)
    if statement.mainsnak.snaktype == 'value' and statement.mainsnak.datatype == 'string' then
        author_label = statement.mainsnak.datavalue.value
    end
  
    if author_link ~= nil and author_link ~= currentPageTitle then
        return '[[' ..author_link .. '|' .. author_label .. ']]'
    else
        return author_label
    end
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( 'Módulo:Citação/CS1' )
    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 = wd.formatStatements{entity = entity, property = 'P2679', defaultlink = '-'}
    local postface = wd.formatStatements{entity = entity, property = 'P2680', defaultlink = '-'}
    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 position = #authors + 1
        if statement.qualifiers and statement.qualifiers['P1545'] then
            position = tonumber(statement.qualifiers['P1545'][1].datavalue.value)
        end
      
        authors[position] = buildAuthorLink(statement)
        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, buildAuthorLink(statement))
        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 = buildAuthorLink(statement)
        elseif hasRole(statement, 'Q7234272') then --postface
            postface = buildAuthorLink(statement)
        elseif hasRole(statement, 'Q33231') or hasRole(statement, 'Q125191') then --photographe/photographie
            photographe = buildAuthorLink(statement)
        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'}
    if pagenum then
        pagenum = pagenum:gsub(' +p%.', '') -- on supprime l'unité p.
    end
   
    local title
    local titlestatement = wd.getClaims{entity = entity, property = 'P1476', numval = 1}
    if titlestatement  then
        title = wd.getFormattedQualifiers(titlestatement[1], 'P6833') -- htmltitle
    end
   
    title = title or 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')
    if wikisource ~= nil and url ~= nil and url:find('%.wikisource%.org') then
        url = nil -- we make sure to not have two links to Wikisource
    end
    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')
    local citation = wd.formatStatements{entity = entity, property = 'P1683'}

    -- 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

    -- cálculo do modelo a usar para fazer o elemento
 
    if (entitytype == 'Q3331189') then --book edition
        funtype = cite.livro
    
        -- TODO : gerenciar a edição e o elemento do trabalho.
    
    elseif refType.isLivro[entitytype] then -- livro sem edição conhecida ?
    
        -- TODO : gerenciar o caso em que um livro é citado, mas que o Wikidata conhece as edições.
        -- TODO : recusar tais itens ?
    
        funtype = cite.livro
    
    elseif refType.isPeriodico[entitytype] then -- periódico
        funtype = cite.livro
    else -- default: output a very simple display
        local parameters = authors
        if title then
            table.insert(parameters, '<i>' .. title .. '</i>')
        end
        if entitytype and wd.getLabel(entitytype) then
            table.insert(parameters, ' (' .. wd.getLabel(entitytype) .. ')')
    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, 'consultado em ' .. options['accessdate'])
        end
        parameters[#parameters] = wd.addLinkBack(parameters[#parameters], entity, "P31")
    return linguistic.conj(parameters, 'comma')
    end

 
    local parameters = {
        ['tradutor'] = translator,
        ['ilustrador'] = illustrator,
        ['prefácio'] = preface,
        ['posfácio'] = postface,
        ['fotografia'] = photographe,
        ['título'] = title,
        ['subtítulo'] = subtitle,
        --['volume'] = volume,
        ['data'] = publishdate,
        ['local'] = publishplace,
        ['periódico'] = journal,
        --['numéro'] = journalnumber,
        ["edição"] = ednumber,
        ['editor'] = publisher,
        ['total-páginas'] = pagenum,
        ['url'] = url,
        ['wikisource'] = wikisource,
        ['oclc'] = oclc,
        ['bnf'] = bnf,
        ['lccn'] = lccn,
        ['dnb'] = dnb,
        ['doi'] = doi,
        ['pmid'] = pmid,
        ['jstor'] = jstor,
        ['bibcode'] = bibcode,
        ['arxiv'] = arxiv,
        ['pmcid'] = pmcid,
        ['língua'] = language,
        ['transcrição'] = originalLanguage,
        ['título_translit'] = originalTitle,
        ['página'] = page,
        ['número'] = numero,
        ['volume'] = volume,
    ['citation'] = citation,
        ['pluma'] = options['pluma']
    }
 
    -- isbns = remove_same_isbn(isbns) não está implementado
    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['autor' .. i]  or options['editor' .. i] or options['responsabilidade' .. i] then
            setAuthors = false
        end
    end

    if setAuthors then
        for i, author in pairs(authors) do
            parameters['autor' .. i] = author
            parameters['editor' .. i] = are_director[i]
            parameters['responsabilidade' .. 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

-- para testar
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