Módulo:Biocitas

De Wikisource, la biblioteca libre.
Ir a la navegación Ir a la búsqueda
Template-info.svg Documentación del módulo


Uso

Utilizado por la plantilla {{Biocitas}}.
Esta documentación está transcluida desde Módulo:Biocitas/doc.
Los editores pueden experimentar en la zona de pruebas de este módulo.
Por favor, añade las categorías e interwikis a la subpágina de documentación. Subpáginas de este módulo.

local p = {}
local Wikidata = require('Módulo:Wikidata')
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,['añomuerte']=1,['siglomuerte']=1,['añonacimiento']=1,['siglonacimiento']=1,['ordenar']=1,['inicial']=1,['añosmuerte']=0,['vivo']=1,['país']=1}
local categorias = ''

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

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, fieldUpper)
	-- 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' .. 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("¡El calendario gregoriano no tiene año 0!")
			return struct
		end
		struct.century = computeCenturyFromYear(struct.year)
		struct.precision = 9
	elseif args['siglo' .. fieldUpper] ~= nil then
		struct.century = tonumber(args['siglo' .. 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['texto' .. fieldUpper] ~= nil then
		struct.precision = 0 --we don't know anything
		struct.text = args['Texto' .. fieldUpper] .. ' ' .. struct.text
	end
	if args['incierto' .. fieldUpper] ~= nil and struct.text ~= nil then
		struct.precision = 0 --we don't know anything
		struct.text = args['Incierto' .. fieldUpper] .. ' ' .. struct.text
	end

	return struct
end

function crearelemento(frame,argus,lista,nombre,imagen,texto1,texto2) --funcion que agrega enlaces de acuerdo a si existen, o están declarados
	local sep = "<span style='display:inline-block; width:2em;'>&nbsp;</span>" --separador de la imagen y el texto
	local sitios ={ --esta variable contiene los sitios reconocidos con posibles enlaces, y su nombre técnico
		['wikipedia']= 'eswiki',
		['wikiquote']='eswikiquote',
		['wikinoticias']='eswikinews',
		['commons']='commonswiki',
		['wikispecies']='specieswiki'
	}

	local sitio = ''
	local creado = false
	if sitios[nombre] then
		sitio = sitios[nombre]
	end
	if argus[nombre] ~='none' then
		elemento = mw.html.create('div'):addClass('bc-enlace')
		if argus[nombre] ~= '' and argus[nombre] ~= nil then
			elemento
				:wikitext('[[Archivo:'..imagen..'|28px|'..nombre..' logo]]'..sep..texto1..argus[nombre]..texto2)
			creado = true
		elseif sitio~='' and Entidad ~= '' then
			 if Entidad:getSitelink(sitio) ~= nil and Entidad:getSitelink(sitio) ~= '' then
				elemento
					:wikitext('[[Archivo:'..imagen..'|28px|'..nombre..' logo]]'..sep..texto1..Entidad:getSitelink(sitio)..texto2)
				creado = true
			elseif sitio =='commonswiki' and propiedad('p373') ~= '' then --categoría en commons
				elemento
					:wikitext('[[Archivo:'..imagen..'|28px|'..nombre..' logo]]'..sep..texto1..'category:'..propiedad('p373')..texto2)
				creado = true
			end
		end
		if creado then
			agregarelemento(lista,elemento)
		end
	end
	--chequear datos locales o por agregar a wikidata
  	if sitio~='' and Entidad ~= '' then
  	if sitio~='' and Entidad:getSitelink(sitio) ~= nil and Entidad:getSitelink(sitio) ~= ''  and argus[nombre] and argus[nombre] ~= '' then
	 		categorias = categorias..'[[Categoría:Wikisource:Artículos con datos locales]]'
	elseif sitio~='' and (Entidad:getSitelink(sitio) == nil or Entidad:getSitelink(sitio) == '')  and argus[nombre] ~= '' and argus[nombre] ~= nil then
	 		categorias = categorias..'[[Categoría:Wikisource:Artículos con datos por trasladar a Wikidata]]'
	end
	end
end

function agregarelemento(lista, elemento)
	if elemento ~= nil then
		lista:node(tostring(elemento))
	end
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
			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 snak.snaktype == 'somevalue' then
		if statement.qualifiers ~= nil and statement.qualifiers.P1480 ~= nil then
			for _,qualifier in pairs(statement.qualifiers.P1480) do
				if qualifier.datavalue.value['numeric-id'] == 5727902 then
					prefix = 'circa '
					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 = 'a partir 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
			end
		end
	else
		struct = parseWbTime(snak.datavalue.value)
	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 p.biocitas( frame ) -- función principal para llamar desde {{biocitas}}
    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 divgrande = html:tag('div'):addClass('divgrande')  -- div principal que contiene al resto 
    
	
	-- esqueleto y CSS de los divs internos 
	local divtitulo = divgrande:tag('div'):addClass('bc-titulo')
	local foto = divgrande:tag('div'):addClass('bc-foto')
	local medio = divgrande:tag('div'):addClass('bc-medio')
	local enlaces = divgrande:tag('div'):addClass('bc-enlaces')
	local derechos = divgrande:tag('div'):addClass('bc-derechos')
	
	--variables locales
	local sep = "<span style='display:inline-block; width:2em;'>&nbsp;</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

	-- Foto --
		if argus['foto'] ~= '' and argus['foto'] ~= nil  then
		foto:wikitext("[[File:"..argus['foto'].."|frameless|upright]]")
		
		elseif propiedad('p18') ~= '' then
			foto:wikitext("[[File:"..propiedad('p18',{['uno']='sí'}).."|frameless|upright]]")
		else
			foto:wikitext("[[File:Falta foto.jpg|frameless|upright]]")
		end
	
	-- Texto de al medio
	if argus['texto'] ~= '' and argus['texto'] ~= nil  then
		medio:wikitext(argus['texto'])
	else
		medio:wikitext("Con el parámetro '''''Texto=''''' Puedes incluir la linea de información relativa a sus fechas de nacimiento y defunción así como su lugar. También puedes incluir algún breve apunte.")
	end
	-- Firma
	if propiedad ('p109') ~= '' then
		medio:wikitext("<br><br> [[File:"..propiedad('p109',{['uno']='sí'}).."|frameless|upright]]")
	end
	
	-- Lista de enlaces
	veasetambien = enlaces:tag('div')
	veasetambien
		:addClass('bc-titulo2')
		:wikitext("Véase también...")
	
	---- Enlaces uno por uno ---
	if  argus['obras'] ~= 'none' then  --Obras (aparece siempre por defecto a menos que se defina como none)
		obrasWS = mw.html.create('div'):addClass('bc-enlace')
		if argus['obras'] ~= '' and argus['obras'] ~= nil  then
			obrasWS
				:wikitext("[[Archivo:Wikisource-logo.svg|28px|Wikisource logo]]"..sep.."[[:Categoría:Obras literarias de "..argus['obras'].."|Sus obras literarias]]")
		else
			obrasWS
				:wikitext("[[Archivo:Wikisource-logo.svg|28px|Wikisource logo]]"..sep.."[[:Categoría:Obras literarias de ".. nombre .."|Sus obras literarias]]")
		end		
		agregarelemento(enlaces,obrasWS)
	end
	
	-- crea elementos para el resto de los enlaces
	crearelemento(frame,argus,enlaces,'documentos','Wikisource-logo.svg','[[:Categoría:Documentos de ','|Sus documentos]]')
	crearelemento(frame,argus,enlaces,'wikipedia','Wikipedia-logo.svg','[[w:es:','|Biografía]]')
	crearelemento(frame,argus,enlaces,'wikiquote','Wikiquote-logo.svg','[[q:es:','|Citas]]')
	crearelemento(frame,argus,enlaces,'wikinoticias','Wikinews-logo.svg','[[n:es:','|Noticias]]')
	crearelemento(frame,argus,enlaces,'commons','Commons-logo.svg','[[commons:','|Multimedia]]')
	crearelemento(frame,argus,enlaces,'wikispecies','Wikispecies-logo.svg','[[wikispecies:','|Especies descritas]]')
	
	--- Índice de autores ---
	indice = enlaces:tag('div')
	indice
		:addClass('bc-titulo2')
		:wikitext("[[:Categoría:Autores|<span style='color:#FAFAFA;'>Índice de autores</span>]]")

	-- WIKIDATA! --
	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 [[d:Special:NewItem|crea un nuevo elemento en Wikidata]]</small>'))
	end
	---- variables para manejar fechas de muerte y nacimiento	
	local nacimiento = getDateFromArgs(argus, 'nacimiento', 'nacimiento')
	local muerte = getDateFromArgs(argus, 'muerte', 'muerte')
	local sexo = propiedad('p21')  
	local nacimientoWikidata = nil
	local muerteWikidata = nil
	
	if Entidad ~= nil and Entidad ~= '' then --si existe la entidad en Wikidata, obtiene las fechas desde ahí.
		nacimientoWikidata = getDateFromTimeStatements(Entidad:getBestStatements('P569'), 'nacimiento',html)
		muerteWikidata = getDateFromTimeStatements(Entidad:getBestStatements('P570'), 'muerte',html)
	end

	if nacimiento.text == nil and nacimientoWikidata ~= nil then
		nacimiento = nacimientoWikidata
	elseif nacimiento.text ~= nil then
		categorias = categorias..'[[Categoría:Wikisource:Artículos con datos locales]]'
		if nacimientoWikidata and nacimientoWikidata.text == nil then
			categorias = categorias..'[[Categoría:Wikisource:Artículos con datos por trasladar a Wikidata]]'
		end
	end
	if muerte.text == nil and muerteWikidata ~= nil then
		muerte = muerteWikidata
	elseif muerte.text ~= nil then
		categorias = categorias..'[[Categoría:Wikisource:Artículos con datos locales]]'
		if muerteWikidata and muerteWikidata.text == nil then
			categorias = categorias..'[[Categoría:Wikisource:Artículos con datos por trasladar a Wikidata]]'
		end
	end
	
	if nacimiento.precision >= 9 and nacimiento.year > 1400 then
		categorias=categorias..'[[Categoría:N' .. nacimiento.year .. ']]'
	
	end
	if muerte.precision >= 9 and muerte.year > 1400 then
		categorias=categorias..'[[Categoría:F' .. muerte.year .. ']]'
	end
	local withoutEpoque = true

	if nacimiento.century ~= nil and (nacimiento.year == nil or nacimiento.year <= nacimiento.century * 100 - 20 or nacimiento.precision <=8 ) then
		if 15 <= nacimiento.century then
			categorias=categorias..'[[Categoría:Autores del ' .. getTextForCentury(nacimiento.century, false) .. ']]'
		elseif 6 <= nacimiento.century and nacimiento.century <= 14 then
			categorias=categorias..'[[Categoría:Autores de la Edad Media]]'
		else
			categorias=categorias..'[[Categoría:Autores de la Antigüedad]]'
		end
		withoutEpoque = false
	end
	if muerte.century ~= nil and (muerte.year == nil or (muerte.century - 1) * 100 + 5 <= muerte.year or muerte.precision <=8 ) then
		if 15 <= muerte.century then
			categorias=categorias..'[[Categoría:Autores del ' .. getTextForCentury(muerte.century, false) .. ']]'
		elseif 6 <= muerte.century and muerte.century <= 14 then
			categorias=categorias..'[[Categoría:Autores de la Edad Media]]'
		else
			categorias=categorias..'[[Categoría:Autores de la Antigüedad]]'
		end
		withoutEpoque = false
	end
	if withoutEpoque then
		categorias=categorias..'[[Categoría:Época desconocida]]'
	end

	--año de la muerte, para las plantillas
	local anomuerte 
	if muerte.year then
		anomuerte = getTextForYear(muerte.year)
	end
	local anosmuerte = argus['añosmuerte']
	if 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
	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
	
	--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}}
			mw.log(v)
			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

	-- Ordenar e Iniciales--
	if argus['ordenar'] ~= nil then
		if argus['inicial'] == nil then
			argus['inicial'] = string.upper(string.sub(argus['ordenar'], 1, 1)) --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 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
    	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