Abrir menu principal

Módulo:Info/biografia

< Módulo:Info
Revisão de 10h29min de 21 de abril de 2021 por Campari (discussão | contribs) (Criação do Módulo Info/biografia)
(dif) ← Edição anterior | Revisão atual (dif) | Versão posterior → (dif)

Descrição

Este módulo estende o Módulo:Info com funções para campos de nascimento e morte em biografias

Uso

Use os rótulos #biografia e #morte para chamar as funções que preenchem esses campos. A {{dni}} e {{morte}} podem ser usadas para preencher os campos, mas é possível preencher somente com a data no formato dd/mm/aaaa, e o módulo irá colocar o mês por extenso e colocar link na data, o local pode ser colocado após a data. Se a data e o local não forem informados esses dados serão automaticamente buscados no Wikidata. A idade é automaticamente colocada após a data de nascimento se não existir data de morte ou se existir é colocada após a data de morte. A Categoria:Pessoas vivas é também automaticamente inserida quando não existe data de morte ou removida se existir data de morte e a categoria estiver no campo nascimento. Erro em Lua em Módulo:Info na linha 369: attempt to index field 'wikibase' (a nil value).

{{#invoke:Info|biografia
| cor      = 13.3
| título   = Título
| Rótulo A : dados A
| #nascimento : 10/01/1872
| #morte   : 11/12/1922
| #tópico  : Tópico 1
| Rótulo B : dados B
| Rótulo C : {{{campo C|}}}
| : dados D sem rótulo
| #tópico  : Tópico 2
| Rótulo E : dados E
}}

Ver também


-- Extensão do Módulo:Info para adicionar funções relacionadas a biografias

local ext = {}
ext.especial = {}
debug.biografia = {}

local meses = {'janeiro', 'fevereiro', 'março', 'abril', 'maio', 'junho', 'julho', 'agosto',
  'setembro', 'outubro', 'novembro', 'dezembro'}

-- Busca as informações de data, idade e local dentro do campo
ext.data_local = function(str)
    if not str or str == '' then
        return nil
    end
    local inicio, fim, pos, dia, mes, ano, data, idade, link
    -- dia e mês
    inicio, fim, link, dia, mes = string.find(str, '^(%[?%[?)(%d%d?) de ([%aç]+)%]*')
    if link == '[[' and string.match(str, '^%[%[[^%]|%[]+|') then
        inicio, fim, dia, mes = string.find(str, '|(%d%d?) de ([%aç]+)%]%]')
    end
    if inicio then -- tem '<dia> de <mês>'
        mes = mes:lower()
        for n, m in ipairs(meses) do
            if m == mes then
                mes = n -- transforma mês para número
                break
            end
        end
    else -- não tem '<dia> de <mês>'
        inicio, fim, dia, mes = string.find(str, '^(%d%d?)/(%d%d?)/')
        if inicio and tonumber(mes) <= 12 and tonumber(dia) <= 31 then -- tem 'dd/mm'
            mes = tonumber(mes)
            data = '[[' .. dia .. ' de ' .. meses[mes] .. ']]' -- data a ser inserida
        end
    end
    if inicio and type(mes) == 'string' then
        table.insert(debug.erros, 'mês em formato desconhecido em ' .. str)
        dia, mes, data = nil, nil, nil
    end
    pos = fim and fim + 1 or 1
    -- ano
    local inicio, fim, link, ano = string.find(str, '(%[?%[?)(%d+)', pos)
    if inicio then -- tem ano
        pos = fim + 1
        if string.match(str, '^ a%.C%.', pos) then
            ano = ano * -1
            pos = pos + 5
            data = data and data .. ' de [[' .. ano .. ' a.C.]]'
        else
            ano = tonumber(ano)
            data = data and data .. ' de [[' .. ano .. ']]'
        end
        if link == '[[' then -- ano tem ligação interna
            local inicio, fim = string.find(str, '^%[%[[^%]]-%]%]', inicio)
            pos = fim + 1 -- coloca posição de leitura após ligação
        end
    end
    local args = {['dia']=dia, ['mês']=mes, ['ano']=ano, ['data']=data, ['fim_data']=pos - 1}
    -- idade
    local inicio, fim = string.find(str, '&nbsp;%(%d+&nbsp;anos?%)', pos)
    if inicio then -- tem idade
        args['idade'] = string.sub(str, inicio, fim)
        pos = fim + 1
    end
    -- categorias
    local inicio, fim, categoria = string.find(str, '^%[%[[Cc]ategoria:([^%]]+)%]%]', pos)
    if categoria == 'Pessoas vivas' then -- tem [[Categoria:Pessoas vivas]]
        args['catpv'] = true
        pos = fim + 1
        inicio, fim, categoria = string.find(str, '^%[%[[Cc]ategoria:([^%]]+)%]%]', pos)
    end
    if inicio then -- tem outra categoria
        pos = fim + 1
        args['cat'] = categoria
    end
    -- pular eventuais referências
    local inicio, fim, fecha, fechado  = string.find(str, '^ *<(/?)ref[^>]*(/?)>', pos)
    while inicio do
        if fecha ~= '' or fechado ~= '' then
            pos = fim + 1
            inicio, fim, fecha, fechado  = string.find(str, '^ *<(/?)ref[^>]*(/?)>', pos)
        else
            inicio, fim, fecha = string.find(str, '<(/)ref>', pos)
        end
    end
    -- local (ou qualquer coisa após a data)
    args['local'] = string.sub(str, pos)
    for k, v in pairs(args) do
        table.insert(debug.biografia, k .. ' -> ' .. v)
    end
    return args
end

ext.especial['nascimento'] = function(campo, i)
    ext.nasc = i
    local args = campo[1] and ext.data_local(campo[1])
    if args then
        if args['ano'] then
            ext.t1 = os.time({day=args['dia'] or 1, month=args['mês'] or 1, year=args['ano']})
        end
        if args['catpv'] then
            ext.catpv = true
        end
        if args['cat'] then
            ext.catnas = args['cat']
        end
        if args['local'] ~= '' and args['ano'] and args['idade'] then -- tem tudo
            ext.fim_data = args['fim_data']
            ext.idade = args['idade']
            return {['rótulo']='Nascimento', campo[1]}
        elseif args['data'] and args['local'] ~= '' then -- tem data no formato dd/mm/aaaa e local
            ext.idade = '&nbsp;(' .. math.floor((os.time() - ext.t1) / 31557600) .. '&nbsp;anos)'
            ext.fim_data = #args['data']
            return {['rótulo']='Nascimento', args['data'] .. ext.idade .. args['local']}
        elseif args['ano'] and args['local'] ~= '' then -- tem data e local
            ext.fim_data = args['fim_data']
            return {['rótulo']='Nascimento', campo[1]}
        elseif args['local'] == campo[1] then -- tem só local
            -- não adiciona nada pois pode existir uma data em formato não convencional
            return {['rótulo']='Nascimento', campo[1]}
        end
    end
    if not wd then
        require('Módulo:Info/wd')
    end
    if not args or campo[1] == '' then -- sem nada
        if wd.props and wd.props['P569'] then
            local ano, mes, dia = string.match(wd.props['P569'][1]['mainsnak']['datavalue']['value']['time'],
              '(%-?%d+)%-(%d%d)%-(%d%d)T')
            ano = tonumber(ano)
            mes = mes == '00' and 1 or tonumber(mes)
            dia = dia == '00' and 1 or tonumber(dia)
            ext.t1 = os.time({day=dia, month=mes, year=ano})
            ext.idade = '&nbsp;(' .. math.floor((os.time() - ext.t1) / 31557600) .. '&nbsp;anos)'
        end
        local dados = wd.expandir('P569:link' .. (ext.idade or '') .. '{ P19:link}')
        return {['rótulo']='Nascimento', dados, ['wikidata']=true}
    elseif args['ano'] and args['idade'] then -- tem data e idade
        ext.fim_data = args['fim_data']
        ext.idade = args['idade']
        local _local = wd.expandir(' P19:link')
        return {['rótulo']='Nascimento', campo[1] .. (_local or ''), ['wikidata']=_local and true}
    elseif args['data'] then -- tem data no formato dd/mm/aaaa
        ext.idade = '&nbsp;(' .. math.floor((os.time() - ext.t1) / 31557600) .. '&nbsp;anos)'
        ext.fim_data = #args['data']
        local _local = wd.expandir(' P19:link')
        return {['rótulo']='Nascimento', args['data'] .. ext.idade .. (_local or ''), ['wikidata']=_local and true}
    elseif args['ano'] then -- tem só data
        ext.fim_data = args['fim_data']
        ext.idade = '&nbsp;(' .. math.floor((os.time() - ext.t1) / 31557600) .. '&nbsp;anos)'
        local _local = wd.expandir(' P19:link')
        return {['rótulo']='Nascimento', campo[1]:sub(1, args['fim_data']) .. ext.idade ..
          campo[1]:sub(args['fim_data'] + 1) .. (_local or ''), ['wikidata']=_local and true}
    end
end

-- Adiciona ou remove a idade e a [[Categoria:pessoas vivas]] do campo nascimento dependendo se existe data de morte
ext.rever_nasc = function(morte)
    if not ext.nasc then -- não tem campo nascimento
        return
    end
    if morte then
        if ext.idade then -- existe idade no campo nascimento
            local inicio, fim = string.find(campos[ext.nasc][1], ext.idade, 1, true)
            campos[ext.nasc][1] = campos[ext.nasc][1]:sub(1, inicio - 1) .. campos[ext.nasc][1]:sub(fim + 1)
        end
        if ext.catpv then -- existe [[Categoria:Pessoas vivas]] no campo nascimento
            local inicio, fim = string.find(campos[ext.nasc][1], '[[Categoria:Pessoas vivas]]', 1, true)
            campos[ext.nasc][1] = campos[ext.nasc][1]:sub(1, inicio - 1) .. campos[ext.nasc][1]:sub(fim + 1)
        end
    else
        if not ext.idade and ext.t1 then -- não existe idade no campo nascimento
            local idade = '&nbsp;(' .. math.floor((os.time() - ext.t1) / 31557600) .. '&nbsp;anos)'
            campos[ext.nasc][1] = campos[ext.nasc][1]:sub(1, ext.fim_data) .. idade ..
              campos[ext.nasc][1]:sub(ext.fim_data + 1)
        end
        if not ext.catpv and campos[ext.nasc][1] then -- não existe [[Categoria:Pessoas vivas]] no campo nascimento
            campos[ext.nasc][1] = campos[ext.nasc][1] .. '[[Categoria:Pessoas vivas]]'
        end
    end
end

ext.especial['morte'] = function(campo)
    local args = campo[1] and ext.data_local(campo[1])
    local idade, t2
    if args then
        ext.rever_nasc(true)
        if args['ano'] and ext.t1 then
            t2 = os.time({day=args['dia'] or 1, month=args['mês'] or 1, year=args['ano']})
            idade = '&nbsp;(' .. math.floor((t2 - ext.t1) / 31557600) .. '&nbsp;anos)'
        end
        if args['local'] ~= '' and args['ano'] and args['idade'] then -- tem tudo
            return {['rótulo']='Morte', campo[1]}
        elseif args['data'] and args['local'] ~= '' then -- tem data no formato dd/mm/aaaa e local
            return {['rótulo']='Morte', args['data'] .. (idade or '') .. args['local']}
        elseif args['ano'] and args['local'] ~= '' then -- tem data e local
            if idade then
                campo[1] = campo[1]:sub(1, args['fim_data']) .. idade .. campo[1]:sub(args['fim_data'] + 1)
            end
            return {['rótulo']='Morte', campo[1]}
        elseif args['local'] == campo[1] then -- tem só local
            -- não adiciona nada pois pode existir o século ou século aproximado no lugar da data
            return {['rótulo']='Morte', campo[1]}
        end
    end
    if not wd then
        require('Módulo:Info/wd')
    end
    if not args or campo[1] == '' then -- sem nada
        if ext.t1 and wd.props and wd.props['P570'] then
            local ano, mes, dia = string.match(wd.props['P570'][1]['mainsnak']['datavalue']['value']['time'],
              '(%-?%d+)%-(%d%d)%-(%d%d)T')
            ano = tonumber(ano)
            mes = mes == '00' and 1 or tonumber(mes)
            dia = dia == '00' and 1 or tonumber(dia)
            local t2 = os.time({day=dia, month=mes, year=ano})
            idade = '&nbsp;(' .. math.floor((t2 - ext.t1) / 31557600) .. '&nbsp;anos)'
            ext.rever_nasc(true)
        end
        local dados = wd.expandir('P570:link' .. (idade or '') .. '{ P20:link}')
        if not dados then
            ext.rever_nasc(false)
        end
        return {['rótulo']='Morte', dados, ['wikidata']=true}
    elseif args['ano'] and args['idade'] then -- tem data e idade
        local _local = wd.expandir(' P20:link')
        return {['rótulo']='Morte', campo[1] .. (_local or ''), ['wikidata']=_local and true}
    elseif args['data'] then -- tem data no formato dd/mm/aaaa
        local _local = wd.expandir(' P20:link')
        idade = '&nbsp;(' .. math.floor((t2 - ext.t1) / 31557600) .. '&nbsp;anos)'
        return {['rótulo']='Morte', args['data'] .. idade .. (_local or ''), ['wikidata']=_local and true}
    elseif args['ano'] then -- tem só data
        local _local = wd.expandir(' P20:link')
        idade = '&nbsp;(' .. math.floor((t2 - ext.t1) / 31557600) .. '&nbsp;anos)'
        return {['rótulo']='Morte', campo[1]:sub(1, args['fim_data']) .. idade ..
          campo[1]:sub(args['fim_data'] + 1) .. (_local or ''), ['wikidata']=_local and true}
    end
end

return ext