Módulo:Biocitas
Esta documentación está transcluida desde Módulo:Biocitas/doc.
Los editores pueden experimentar en la zona de pruebas
Por favor, añade las categorías a la subpágina de documentación.
(subpáginas - enlaces)
Los editores pueden experimentar en la zona de pruebas
Por favor, añade las categorías a la subpágina de documentación.
(subpáginas - enlaces)
local p = {}
local Wikidata = require('Módulo:Wikidata')
local Enlaces = require('Módulo:Enlaces')
local Str = require('Módulo:String')
local Entidad = mw.wikibase.getEntityObject() or '' -- Tabla con los datos en Wikidata de la persona.
--parámetros reconocidos. 1 = vigente, 0 = obsoleto
local params ={['texto']=1,['obras']=1,['documentos']=1,['foto']=1,['wikipedia']=0,['wikiquote']=0,['wikinoticias']=0,['commons']=0,['wikispecies']=0,['wikidata']=1,['añomuerte']=1,['siglomuerte']=1,['añonacimiento']=1,['siglonacimiento']=1,['ordenar']=1,['inicial']=1,['añosmuerte']=0,['vivo']=1,['país']=1}
local categorias = ''
local withoutEpoque = true
function errorMessage(text)
-- Función que entrega un mensaje de error formateado como tal
local html = mw.html.create('div')
html:addClass('error')
:wikitext(text)
categorias=categorias..'[[Categoría:Wikisource:Artículos con errores en la plantilla Biocitas]]'
return tostring(html)
end
-- Función para eliminar contenido entre paréntesis
function remove_parentheses(text)
-- Sustituye todo lo que está entre paréntesis (incluyendo los paréntesis) por una cadena vacía
if text==nil then return "" end
local texto = text
texto = text:gsub("%b()", "")
if texto ~= nil then
return texto
else
return text
end
end
function computeCenturyFromYear(year)
-- Dado un año entrega el siglo
if year >= 0 then
return math.ceil(year / 100)
else
return -math.ceil(-year / 100)
end
end
function getTextForCentury(century)
-- Dado un siglo en número, entrega un texto preformateado con
-- números romanos y un indicador de antes de Cristo.
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 century > 0 then
return 'Siglo '..text
else
return 'Siglo '.. text .. ' a. C.'
end
end
function getTextForYear(year)
-- transforma un año de formato -45 a 45 a. C.
local text = math.abs(year)
if year < 0 then
text = text .. ' a. C.'
end
return text
end
function getDateFromArgs(args, field)
-- Obtiene datos (fecha de nacimiento, fallecimiento) de parámetros determinados en la plantilla {{Biocitas}}
-- con el formato AñoNacimiento, AñoMuerte, SigloNacimiento o SigloMuerte. TextoNacimiento o InciertoNacimiento también funciona
local struct = {
year = nil,
century = nil,
text = nil,
precision = 0
}
--extract year or century
local date = args['año' .. field]
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("¡El calendario gregoriano no tiene año 0!")
return struct
end
struct.century = computeCenturyFromYear(struct.year)
struct.precision = 9
elseif args['siglo' .. field] ~= nil then
struct.century = tonumber(args['siglo' .. field])
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['texto' .. field] ~= nil then
struct.precision = 0 --we don't know anything
struct.text = args['texto' .. field] .. ' ' .. struct.text
end
if args['incierto' .. field] ~= nil and struct.text ~= nil then
struct.precision = 0 --we don't know anything
struct.text = args['incierto' .. field] .. ' ' .. struct.text
end
return struct
end
function getDateFromTimeStatements(statements, field,html)
-- Función que obtiene las fechas desde Wikidata (copiada literal sin adaptaciones desde la frWS)
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 --si hay años contradictorios
time.precision = 8
--html:wikitext(errorMessage('Hay varios años de ' .. field .. ' posibles en Wikidata. Una manera de resolver este error es fijar una de las dos fechas como "preferida".'))
--return {
--text = errorMessage('Hay varios años de ' .. field .. ' posibles en Wikidata. Una manera de resolver este error es fijar una de las dos fechas como "preferida".'),
-- precision = 0
--}
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 prefix = ''
local snak = statement.mainsnak
if snak.snaktype == 'novalue' then
return struct
end
if statement.qualifiers ~= nil then
if statement.qualifiers.P1480 ~= nil then
for _,qualifier in pairs(statement.qualifiers.P1480) do
if qualifier.datavalue.value['numeric-id'] == 5727902 then
struct = parseWbTime(snak.datavalue.value)
prefix = 'circa '
struct.precision = 8 --TODO: hacky
end
end
end
if statement.qualifiers.P1319 ~= nil then
for _,qualifier in pairs(statement.qualifiers.P1319) do
struct = parseWbTime(qualifier.datavalue.value)
prefix = 'después de'
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 = 'antes de '
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
else
struct = parseWbTime(snak.datavalue.value)
end
elseif snak.snaktype == 'value' then
struct = parseWbTime(snak.datavalue.value)
else
return struct
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 fecha de ' .. field .. ' tiene muy poca precisión en Wikidata')
end
return struct
end
function resolverFecha(arg, wd)
local fecha = arg
if arg.text == nil and wd ~= nil then
fecha = wd
elseif arg.text ~= nil then
categorias = categorias..'[[Categoría:Wikisource:Artículos con datos locales]]'
if wd and wd.text == nil then
categorias = categorias..'[[Categoría:Wikisource:Artículos con datos por trasladar a Wikidata]]'
end
end
return fecha
end
function categoriaEpica(fecha, tol)
local categoria = ''
if fecha.century ~= nil and (fecha.year == nil or fecha.year <= fecha.century * 100 + tol or fecha.precision <=8 ) then
if 14 <= fecha.century then
categoria='[[Categoría:Autores del ' .. getTextForCentury(fecha.century, false) .. ']]'
end
if 6 <= fecha.century and fecha.century <= 14 then
categoria=categoria..'[[Categoría:Autores de la Edad Media]]'
end
if fecha.century < 6 then
categoria='[[Categoría:Autores de la Antigüedad]]'
end
withoutEpoque = false
end
return categoria
end
function p.biocitas( frame ) -- función principal para llamar desde {{biocitas}}
if mw.title.getCurrentTitle().namespace ~= 106 then
return errorMessage('La plantilla Biocitas se utiliza solo en espacios de nombres Autor, por ejemplo Autor:Miguel de Cervantes')
end
local argus = {}
for k,v in pairs(frame:getParent().args) do -- crea una tabla con los parámetros incluídos en la plantilla, y elimina parámetros vacíos
if v ~= '' and type(k) ~= 'number' then
argus[mw.ustring.lower(k)] = v -- todos los parámetros en minúsculas por defecto:
end
end
local html = mw.html.create() -- cuerpo principal de la plantilla
local tabla = html:tag('table'):addClass('divgrande')
local divgrande = tabla:tag('tr')--:addClass('divgrande') -- div principal que contiene al resto
-- WIKIDATA! --
if Entidad == '' and argus['wikidata'] then
Entidad = mw.wikibase.getEntityObject(argus['wikidata'])
end
if Entidad == '' then
categorias=categorias..'[[Categoría:Wikisource:Artículos de autores no conectados a Wikidata]]'
html:wikitext(errorMessage('<small>Error: Los artículos de autores deben estar enlazados en Wikidata. '..
'Agrega un enlace a otro proyecto usando el link en la columna izquierda, '..
'o '..frame:preprocess('[https://www.wikidata.org/wiki/Special:NewItem?site=eswikisource&page={{FULLPAGENAMEE}} crea un nuevo elemento en Wikidata]')..'</small>'))
end
---- variables para manejar fechas de muerte y nacimiento
local nacimientoArg = getDateFromArgs(argus, 'nacimiento')
local muerteArg = getDateFromArgs(argus, 'muerte')
local floruitArg = getDateFromArgs(argus, 'floruit')
local nacimientoWikidata = nil
local muerteWikidata = nil
local floruitWikidata = nil
if Entidad ~= nil and Entidad ~= '' then --si existe la entidad en Wikidata, obtiene las fechas desde ahí.
nacimientoWikidata = getDateFromTimeStatements(Entidad:getBestStatements('P569'), 'nacimiento')
muerteWikidata = getDateFromTimeStatements(Entidad:getBestStatements('P570'), 'muerte')
floruitWikidata = getDateFromTimeStatements(Entidad:getBestStatements('P1317'), 'floruit')
floruitWikidata.precision = 8
end
nacimiento = resolverFecha(nacimientoArg, nacimientoWikidata)
muerte = resolverFecha(muerteArg, muerteWikidata)
floruit = resolverFecha(floruitArg, floruitWikidata)
if nacimiento.precision >= 9 and nacimiento.year > 1300 then
categorias=categorias..'[[Categoría:N' .. nacimiento.year .. ']]'
end
if muerte.precision >= 9 and muerte.year > 1300 then
categorias=categorias..'[[Categoría:F' .. muerte.year .. ']]'
end
categorias=categorias..categoriaEpica(nacimiento, -20)
categorias=categorias..categoriaEpica(muerte, 5)
categorias=categorias..categoriaEpica(floruit, 0)
if withoutEpoque then
categorias=categorias..'[[Categoría:Época desconocida]]'
end
--año de la muerte, para las plantillas
local anomuerte
local anosmuerte = argus['añosmuerte']
if muerte.year then
anomuerte = getTextForYear(muerte.year)
elseif muerte.century then
anomuerte = muerte.century*100
elseif argus['añomuerte'] ~= '' and argus['añomuerte'] ~= nil then
anomuerte = argus['añomuerte']
elseif argus['siglomuerte'] ~= '' and argus['siglomuerte'] ~= nil then
anomuerte = (tonumber(argus['siglomuerte']))*100
elseif floruit.year then
--muerte presunta 70 años después de florecer
anomuerte = getTextForYear(floruit.year + 70)
elseif floruit.century then
--si sólo se conoce el siglo, murió a mediados de siglo
anomuerte = floruit.century*100 - 50
end
--artículos sin información de año de muerte
if (argus['vivo']==nil or argus['vivo']=='') and (anomuerte == '' or anomuerte ==nil) and (muerte.century == '' or muerte.century ==nil) then
categorias = categorias..'[[Categoría:Wikisource:Artículos de autores sin información de año de muerte]]'
end
-- texto fechas
local textofechas = ''
if nacimiento.text or muerte.text then
textofechas = (nacimiento.text or '')..' - '..(muerte.text or '')
elseif floruit.text then
textofechas = 'fl. '..floruit.text
end
-- esqueleto y CSS de los divs internos
local foto = divgrande:tag('td'):addClass('bc-foto')
local medio = divgrande:tag('td'):addClass('bc-medio')
--local divtitulo = medio:tag('div'):addClass('bc-titulo')
local enlaces = divgrande:tag('td'):addClass('bc-enlaces')
local derechos = html:tag('div'):addClass('bc-derechos')
--variables locales
local sep = "<span style='display:inline-block; width:.5em;'> </span>"
local nombre = frame:preprocess("{{PAGENAME}}")
--Contenido de los divs secundarios
--divtitulo:wikitext("Ficha de ".. nombre:gsub(' %(.*%)','')) --en el título nombres sin paréntesis
-- Lista de enlaces
if (not argus['wikidata'] or argus['wikidata'] == '') and Entidad~=nil then
argus['wikidata']=Entidad.id --enlazar a elemento wikidata
end
---- Enlaces uno por uno ---
listaenlaces = Enlaces.all(argus)
if argus['obras'] ~= 'none' then --Obras (aparece siempre por defecto a menos que se defina como none)
listaenlaces["obras"] = { ['name'] = 'Categoría de obras',
['image'] = 'Wikisource-logo.svg',
['text'] = 'Obras',
['prefix'] = ':Categoría:Obras de ',
['title'] = '',
}
if argus['obras'] ~= '' and argus['obras'] ~= nil then
listaenlaces["obras"]["title"] = argus['obras']
else
listaenlaces["obras"]["title"] = nombre
end
end
-- crea elementos para el resto de los enlaces
listaenlaces["documentos"] = { ['name'] = 'Categoría de documentos',
['image'] = 'Wikisource-logo.svg',
['text'] = 'Documentos ',
['prefix'] = ':Categoría:Documentos de ',
['title'] = argus['documentos'] or '',
}
-- texto propio de biocitas
listaenlaces["eswiki"]["text"] = "Biografía"
listaenlaces["eswikiquote"]["text"] = "Citas"
listaenlaces["eswikinews"]["text"] = "Noticias"
listaenlaces["commonswiki"]["text"] = "Multimedia"
listaenlaces["specieswiki"]["text"] = "Especies descritas"
listaenlaces["wikidata"]["text"] = "Metadatos"
orden = {'obras', 'documentos', 'eswiki', 'eswikiquote', 'eswikinews', 'commonswiki', 'specieswiki', 'wikidata'}
textoenlaces = Enlaces.formattedbiocitas(listaenlaces, orden)
enlaces:wikitext(textoenlaces)
--llave automágica
local apellidos = mw.text.trim((propiedad('p734',{['uno']='sí'}) or '')..' '..(propiedad('p1950',{['uno']='sí'}) ))
local nombres = (propiedad('P735',{['conjunción']=' '}) or '')
if apellidos == '' or apellidos == nil then --p.ej. Alonso de Villegas, Autor:Jerónimo Bécker, etc.
apellidos = nombres --Mejor que "Autores-," cuando no existe apellido
end
if string.sub(apellidos,1,3) == 'de ' then
apellidos = string.sub(apellidos,4)
end
local llave=(apellidos..', '..nombres) ~= ', ' and (apellidos..', '..nombres)
mw.log(llave)
-- Ordenar e Iniciales--
if argus['ordenar']==nil and llave then
argus['ordenar'] = llave
end
if argus['ordenar'] ~= nil then
if argus['inicial'] == nil then
argus['inicial'] = Str.CaracterParaOrdenar(argus['ordenar']) --Si no está especificada la inicial, la saca de la primera letra de la llave de ordenado.
end
html:wikitext(frame:preprocess('{{DEFAULTSORT:' .. argus['ordenar'] .. '}}'))
categorias=categorias..'[[Categoría:Autores-'..argus['inicial']..']]' --categoría Autores-X
else
html:wikitext(errorMessage("El parámetro «|Ordenar=» es obligatorio"))
categorias=categorias..'[[Categoría:Wikisource:Artículos de autores sin llave de ordenamiento]]' --categoría Autores-X
end
if argus['ordenar'] ~= nil then
veasetambien = enlaces:tag('div')
veasetambien
:addClass('bc-enlace')
:wikitext("◄"..sep.."[[:Categoría:Autores-"..argus['inicial'].."|Autores-"..argus['inicial'].."]]") --enlace a Autores-X
end
--- Índice de autores ---
--indice = enlaces:tag('div')
--indice
-- :addClass('bc-enlace')
-- :wikitext("[[:Categoría:Autores|Índice de autores]]")
-- Texto de al medio
if argus['texto'] ~= '' and argus['texto'] ~= nil then
medio:wikitext(argus['texto'])
else
local description = remove_parentheses(mw.wikibase.getDescription())
medio:wikitext("'''"..nombre.."'''<br/>("..textofechas..')<br/>'..(description or ''))
categorias = categorias..'[[Categoría:Wikisource:Autores con texto automático]]'
end
-- Firma ( aun no se puede conectar con otras Q de wikidata :( )
--if argus['wikidata']== '' then
if propiedad ('p109') ~= '' then
medio:wikitext("<br><br> [[File:"..propiedad('p109',{['uno']='sí'}).."|frameless|99999x50px|center|Firma]]")
end
--else
-- if propiedad ('p109',{['entidad']=argus['wikidata']}) ~= '' then
-- medio:wikitext("<br><br> [[File:"..propiedad('p109',{['uno']='sí',['entidad']=argus['wikidata']}).."|frameless|center|Firma]]")
-- end
-- end
-- Retrato autor --
local sexo = propiedad('p21')
if argus['foto'] ~= '' and argus['foto'] ~= nil then
foto:wikitext("[[File:"..argus['foto'].."|frameless|99999x150px|center]]")
elseif propiedad('p18') ~= '' then
foto:wikitext("[[File:"..propiedad('p18',{['uno']='sí'}).."|frameless|99999x150px|"..propiedad('p18',{['calificador']='P2096',['idioma']='es'}).."|center]]")
else
local faltaFoto
local fotos = {'Silver - replace this image male.svg', 'Silver - replace this image female.svg','Falta foto.jpg'}
if sexo == "masculino" then
faltaFoto = fotos[1]
elseif sexo == "femenino" then
faltaFoto = fotos[2]
else
faltaFoto = fotos[3]
end
foto:wikitext("[[File:"..faltaFoto.."|frameless|99999x150px|center]]")
end
--Plantilla de derechos
if anomuerte ~='' and anomuerte ~= nil then
derechos
:wikitext(frame:preprocess("{{DP-Autor|"..anomuerte.."}}"))
elseif anosmuerte ~='' and anosmuerte ~= nil then
derechos
:wikitext(frame:preprocess("{{DP-AUTOR-"..anosmuerte.."}}"))
else
derechos
:wikitext(frame:preprocess("{{DP-AUTOR-none}}"))
end
-- categorías--
categorias=categorias.."[[Categoría:Autores]]"
if argus['vivo'] and mw.ustring.lower(argus['vivo']) ~= 'no' then
categorias=categorias.."[[Categoría:Personas vivas]]"
end
-- categorizar por país: primera prioridad la tienen
if argus['país'] ~= nil and argus['país'] ~='' then
categorias=categorias.."[[Categoría:Autores "..frame:preprocess("{{gentilicio|"..argus['país'].."|mp}}").."]]"
else
argus['país'] = propiedad('P27',{['conjunción']=',',['enlace']='no'})
if argus['país'] ~= nil and argus['país'] ~='' then
for _,v in ipairs(mw.text.split(argus['país'], '[,]')) do --el módulo Wikidata entrega la información en palabras separadas por coma y por "y". Esto convierte esa información en una tabla y itera en sus ítems (para autores con más de una nacionalidad)
--categoría Autores por país: usa plantilla {{gentilicio}}
categorias=categorias.."[[Categoría:Autores "..frame:preprocess("{{gentilicio|"..v.."|mp}}").."]]"
end
else
categorias=categorias.."[[Categoría:Wikisource:Artículos de autores sin país]]"
end
end
for k,v in pairs(argus) do
if params[k] then
if params[k] == 0 then
categorias = categorias..'[[Categoría:Wikisource:Artículos que usan parámetros obsoletos en la plantilla Biocitas]]' --añade categoría de seguimiento a parámetros obsoletos (declarados arriba)
end
else
html:wikitext(errorMessage('Error: parámetro '..k..' no reconocido'))
categorias=categorias..'[[Categoría:Wikisource:Artículos que usan parámetros no reconocidos en la plantilla Biocitas]]'
end
end
if mw.title.getCurrentTitle().namespace ~= 106 then --solo categorías en el espacio principal
categorias = ''
end
html:wikitext(categorias)
return tostring(html) .. '\n__NOTOC__'
end
-- Función que devuelve la lista de los valores de una propiedad en Wikidata formateados
function propiedad(idPropiedad,opciones)
if Entidad and Entidad.claims then --and Entidad.claims[idPropiedad] then
if not opciones then
opciones = {}
end
idPropiedad = string.upper(idPropiedad)
opciones['propiedad'] = idPropiedad
valorPropiedad = Wikidata.getPropiedad(opciones,Entidad.claims[idPropiedad])
if not valorPropiedad or valorPropiedad == '' then
return ''
end
return valorPropiedad
else return ''
end
end
return p