Ir al contenido

Módulo:Wikidata

De Wikipedia, la enciclopedia libre

Uso

Este m�dulo es un proyecto de declaraci�n para la herramienta de formato Wikidata

Tiene las funciones Wikidata, getDeclaraciones, getPropiedad y setFrame.

Funci�n Wikidata

Permite instrucci�n de formato(s) para una propiedad espec�fica del tema relacionado con la p�gina actual (no podemos acceder a los otros �tems).

Par�metros

Par�metro Descripci�n
propiedad Propiedad de Wikidata a obtener
valor Si se da el valor anula el valor de Wikidata.
prioridad Si se indica |prioridad=s� entonces el valor de Wikidata (de existir) tendr� precedencia por sobre el valor local.
debeExistir Si se informa con "s�" no se recuperan las entidades de Wikidata sin un enlace a un art�culo de Wikipedia.
enlace Puede tomar los valores enlace = s� o enlace = no.
  • Si se da enlace = no aparecer� solamente la etiqueta del valor sin enlace interno.
  • Si se utiliza enlace = s� se mostrar� un enlace a la correspondiente p�gina de la Wikipedia definida en Wikidata si existe, si no se enlazar� a la p�gina con nombre igual a la etiqueta de Wikidata (si no existe un art�culo con ese nombre) y si no se mostrar� un enlace al elemento de Wikidata.
formatoTexto Si se da formatoTexto = may�scula o cursiva o may�scula cursiva (da igual el orden)
  • Con el valor may�scula:

la primera letra de la propiedad se pondr� en may�sculas. Cuando no se da el valor al par�metro separador y por consiguiente los valores aparecen separados por una coma a excepci�n de �ltimo que se separa por una conjunci�n por defecto y, solo se pondra en may�scula la inicial del primer valor. En caso de que se d� valor al par�metro enlace todos los valores apareceran con la inicial en may�scula.

  • Con el valor cursiva:

el texto de la propiedad se pondr� en cursivas.

formatoFecha Los valores posibles son:
  • =a�o: Se devuelve la fecha como una a�o. Por ejemplo 2014 o 1 a. C.
Listas
lista no (por implementar): Solo se devuelve el primer elemento de Wikidata. De momento puede utilizarse el par�metro uno=s� . Por ejemplo, en el art�culo de Espa�a, si se escribe {{#invoke:Wikidata|Wikidata|propiedad=p37|uno=s�}} se generar�a "espa�ol".
  • =ordenada: Se devuelve una lista ordenada o numerada. Por ejemplo, en el art�culo de Espa�a, si se escribe {{#invoke:Wikidata|Wikidata|propiedad=p37|lista=ordenada}} se generar�a:
  1. espa�ol
  2. gallego
  3. euskera
  4. catal�n
  5. occitano
ordenada Se devuelve una lista ordenada o numerada. Por ejemplo, en el art�culo de Espa�a, si se escribe {{#invoke:Wikidata|Wikidata|propiedad=p37|lista=ordenada}} se generar�a:
  1. espa�ol
  2. gallego
  3. euskera
  4. catal�n
  5. occitano
no ordenada Se devuelve una lista no ordenada o con vi�etas. Por ejemplo, en el art�culo de Espa�a, si se escribe {{#invoke:Wikidata|Wikidata|propiedad=p37|lista=no ordenada}} se generar�a:
  • Si no se informa el tipo de lista se devuelve una lista de los elementos separados por coma. Por ejemplo, si se escribe{{#invoke:Wikidata|Wikidata|propiedad=p37}} se generar�a "espa�ol, gallego, euskera, catal�n y occitano"
En este �ltimo caso se pueden utilizar los par�metros separador y conjunci�n que permiten separar los primeros valores y el �ltimo valor de una propiedad. Si no se especifica se toma por defecto como separador una coma y como conjunci�n "y" respectivamente. Por ejemplo, en el art�culo de Espa�a, si se escribe {{#invoke:Wikidata|Wikidata|propiedad=p37|separador=/|conjunci�n=/}} se mostrar�a "espa�ol/gallego/euskera/catal�n/occitano".
Formatos
valor-funci�n Nombre de la funci�n Lua que se llama para dar formato al valor. La funci�n acepta como argumentos las siguientes tablas Lua:
  • valor: datos obtenidos de Wikidata para la propiedad. El �nico argumento obligatorio al llamar a la funci�n
  • opciones: argumentos con los que se accede a la plantilla {{propiedad}} o en el tipo de dato espec�fico
  • marco o frame:
  • calificativos: calificativos de la propiedad en Wikidata
valor-m�dulo Nombre del m�dulo donde est� definida la funci�n. Si no se especifica el m�dulo se intentar� buscar la funci�n en el m�dulo:Wikidata/Formatos y si no se buscar� en el m�dulo definido en la tabla modulosTipos del m�dulo Wikidata. Algunas de las funciones existentes se muestran en la siguiente secci�n.

M�dulos y funciones espec�ficas para formatos

tipo de dato / valor-funci�n M�dulo de Wikidata en el que se encuentra definido Descripci�n Usado en Ejemplos de propiedades de Wikidata
altura Ver magnitud
�rea Ver magnitud
bandera Formatos pa�s Se muestra la bandera y el nombre del pa�s. {{Ficha de biblioteca}}, {{Ficha de templo}} pa�s (P17)
formatoCargo Formatos Ficha de persona cargo ocupado (P39)
educado en Formatos educaci�n Se muestra el lugar donde se ha educado y en su caso entre par�ntesis el grado acad�mico, especialidad y periodo. Ficha de persona educado en (P69)
formatoGenero Ficha de pel�cula Ficha de pel�cula g�nero (P136)
formatoId Formatos {{Infobox animanga principal}} instancia de (P31)
imagen Formato imagen {{Ficha de programa de televisi�n}}, {{Ficha de entidad subnacional}}, {{Ficha de artista musical}} imagen (P18), logotipo (P154)
lugar Formato lugar Formato para lugares de la forma ciudad (unidad administrativa, pa�s) Ficha de persona, {{Ficha de organizaci�n}}, {{Ficha de competici�n deportiva}}, {{Ficha de aeropuerto}} lugar de nacimiento (P19), lugar de fallecimiento (P20), ubicaci�n de la sede (P159), ubicaci�n (P276), situado en la entidad territorial administrativa (P131)
magnitud Formato magnitud Se muestra la magnitud junto a sus unidades y en su caso entre par�ntesis el valor en el sistema internacional. Ficha de lugar ficticio, {{Ficha de entidad subnacional}}, {{Ficha de cuerpo de agua}}, {{Ficha de espacio natural}}{{Ficha de localidad de Espa�a}}, {{Ficha de faro}} altura (P2048)

masa (P2067)

superficie (P2046), superficie de cuenca hidrogr�fica (P2053)

alcance del faro (P2929)

movimiento Formato movimiento Formato para movimientos Ficha de persona movimiento (P135)
formatoNumero Formatos {{Ficha de epidemia}} n�mero de casos (P1603)
nacionalidad Formatos pa�s Ficha de persona pa�s de nacionalidad (P27)
formatoObraAnyo Formatos Ficha de pel�cula

Ficha de libro

compuesto por (P527)
formatoObraAutor Formatos Ficha de pel�cula basado en (P144)
formatoOcupacionFemenino

formatoOcupacionMasculino

Ficha de persona Formato para ocupaciones de personas Ficha de persona ocupaci�n (P106)
periodicidad Formato magnitud Se muestra la periodicidad (anual, mensual, quincenal, semanal, etc). {{Ficha de peri�dico}}, {{Ficha de revista}} periodicidad (P2896)
premio Formato premio Formato para premios de obras eliminando los literales de la forma " a ...", " a la ..." o " en la categor�a ...". Ficha de libro premio recibido (P166)
formatoURL

url

Formatos Ficha de persona, {{Ficha de videojuego}} p�gina web oficial (P856)

Valores devueltos

Devuelve la declaraci�n formateada de acuerdo a las opciones.

Funci�n getDeclaraciones

Para ser usado en otro m�dulos.

Valores devueltos

Devuelve una tabla con todas las declaraciones del elemento

Funci�n getPropiedad

Para ser usado en otros m�dulos.

Par�metros

declaraciones

Una tabla de declaraciones

opciones

Una tabla con las opciones. los elementos de la tabla son los par�metros de la funci�n Wikidata.

Valores devueltos

Devuelve la declaraci�n formateada de acuerdo a las opciones.

Funci�n setFrame

Para pasar el frame desde otro m�dulo. Es necesario poner esta funci�n cuando se usa la anterior en casos en que haya que expandir wikitexto como por ejemplo con las coordenadas o los formatos de banderas.

Par�metros

frame

Una tabla/objeto que se pasa desde la invocaci�n del m�dulo.

Valores devueltos

Ninguno.

Funci�n addLinkback(texto, identificador de la entidad, identificador de la propiedad)

La funci�n a�ade al texto recibido la imagen de un l�piz que enlaza a la propiedad de la entidad en Wikidata.

Valores devueltos


--[[*********************************************************************************
	* Nombre: M�dulo:Wikidata
	*
	* Descripci�n: Este m�dulo devuelve el valor o valores con o sin formato
	* espec�fico a una propiedad de Wikidata.
	*
	* Fecha �ltima revisi�n: 30 de junio de 2021.
	*
	* Estado: En uso.
	*
	*********************************************************************************`-- ]]
local p = {}
local datequalifiers = {'P585', 'P571', 'P580', 'P582'}
local es = mw.language.new('es')
local primera = true
--local marco Ojo. marco no debe definirse como local pues si se hace as� puede fallar.
 --[[ =========================================================================
			Mensajes de error
	  ========================================================================= `-- ]]

local avisos = mw.loadData('M�dulo:Wikidata/mensajes')

-- M�dulos y funciones utilizadas
local elementoTabla = require('M�dulo:Tablas').elemento
--
-- M�dulos en los que est�n definidos los tipos de datos m�s habituales si son
-- diferentes de Wikidata/Formatos
--
local modulosTipos	=  mw.loadData('M�dulo:Wikidata/modulosTipos')

local modulosTiposComplejos	=  {
	['nacionalidad']		= 'M�dulo:Wikidata/Formatos pa�s',	
}

 --[[ =========================================================================
	  Funci�n para pasar el frame cuando se usa en otros m�dulos.	 
	 ========================================================================= `-- ]]
function p:setFrame(frame)
	marco = frame
end
 --[[ =========================================================================
	  Funci�n para identificar el �tem correspondiente a la p�gina o otro dado.
			  Esto �ltimo a�n no funciona.	 
	 ========================================================================= `-- ]]

function SelecionEntidadPorId( id )

		if id and id ~= ''  then
			return mw.wikibase.getEntityObject( id )
		else
			return mw.wikibase.getEntityObject()
		end
end

 --[[ =========================================================================
	  Funci�n que identifica si el valor devuelto es un �tem o una propiedad
	  y en funci�n de eso a�ade el prefijo correspondiente	
	 ========================================================================= `-- ]]

function SelecionEntidadPorValor( valor )
	local prefijo = ''
	if valor['entity-type'] == 'item' then
		prefijo = 'q' -- Prefijo de �tem
	elseif valor['entity-type'] == 'property' then
		prefijo = 'p' -- Prefijo de propiedad
	else
		return formatoError( 'unknown-entity-type' )
	end
	return prefijo .. valor['numeric-id'] -- Se concatena el prefijo y el c�digo num�rico
end

 --[[ =========================================================================
	  Funci�n auxiliar para dar formato a los mensajes de error	 
	 ========================================================================= `-- ]]

function formatoError( clave )
	return '<span class="error">' .. avisos.errores[clave] .. '</span>'
end
 --[[ =========================================================================
	  Funci�n para determinar el rango	
	 ========================================================================= `-- ]]
function getRango(tablaDeclaraciones)

	local rank = 'deprecated'

	for indice, declaracion in pairs(tablaDeclaraciones) do
		if declaracion.rank == 'preferred' then
			return 'preferred'
		elseif declaracion.rank == 'normal' then
			rank = 'normal'
		end
	end

	return rank
end

 --[[ =========================================================================
	  Funci�n para determinar la declaracion o declaraciones de mayor rango	
	 ========================================================================= `-- ]]
function p.filtrarDeclaracionPorRango(tablaDeclaraciones)
	local rango = getRango(tablaDeclaraciones)
	local tablaAuxiliar = tablaDeclaraciones
	tablaDeclaraciones = {}
	
	if rango == 'deprecated' then
		return {}
	end

	for indice, declaracion in pairs(tablaAuxiliar) do
		if declaracion.rank == rango then
			table.insert(tablaDeclaraciones, declaracion)
		end
	end
	return tablaDeclaraciones
end

 --[[ =========================================================================
	  Funci�n para seleccionar el tipo de declaraci�n: Referencia, valor principal
	  o calificador	 
	 ========================================================================= `-- ]]

function seleccionDeclaracion(declaracion, opciones)
	local fuente = {}
	local propiedadFuente = {}
	local calificador = opciones.formatoCalificador ~= '()' and opciones.calificador

	if calificador ~= '' and calificador  and declaracion['qualifiers'] then
		if declaracion['qualifiers'][mw.ustring.upper(calificador)] then
			return declaracion.qualifiers[mw.ustring.upper(calificador)][1] -- devuelve el calificador (solo devolver� el primer valor)
		else
			return "" --Para que no lance excepci�n si no existe el calificador
		end
	elseif opciones.dato == 'fuente' and declaracion['references'] then
		fuente = declaracion.references[1]['snaks']
		for k,v in pairs(fuente) do
			propiedadFuente = k
		end
		return declaracion.references[1]['snaks'][propiedadFuente][1]  -- devuelve la fuente (queda que se itinere la tabla)
	elseif (calificador == '' or not calificador) and (opciones.dato ~= 'fuente') then
		return declaracion.mainsnak -- devuelve el valor principal
	else
		return ''	
	end
end

 --[[ =========================================================================
	  Funci�n para recopilar las declaraciones	 
	 ========================================================================= `-- ]]

function p.getDeclaraciones(entityId)

	-- == Comprobamos que existe un �tem enlazado a la p�gina en Wikidata ==
	if not pcall (SelecionEntidadPorId, entityId ) then
		return false
	end
	local entidad  = SelecionEntidadPorId(entityId)
	if not entidad then
		return  '' -- Si la p�gina no est� enlazada a un �tem no devuelve nada
	end

	-- == Comprobamos que el �tem tiene declaraciones (claims) ==

	if not entidad.claims then
		return '' -- Si el �tem no tiene declaraciones no devuelve nada
	end
	-- == Declaraci�n de formato y concatenado limpio ==
	return entidad.claims
end

 --[[ =========================================================================
	  Funci�n para  crear la cadena que devolver� la declaraci�n	
	 ========================================================================= `-- ]]
	
local function valinQualif(claim, qualifs)
	local claimqualifs = claim.qualifiers
	local i,qualif
	local vals, vals1, datavalue, value, datatype
	
	if not claimqualifs then
		return nil
	end
	for i, qualif in pairs(qualifs) do
		vals = claimqualifs[qualif]
		if vals then
			vals1 = vals[1]
			if vals1 then
				datavalue=vals1.datavalue
				
				if datavalue then
					datatype = datavalue.type
					value = datavalue.value
					
					if datatype == 'time' and value then
						return value.time
					elseif datatype == 'string' and value then
						return value
					end
				end
			end
		end
	end
end	

function p.getPropiedad(opciones, declaracion)
	local propiedad	 = {}

	-- Resolver alias de propiedad
	if opciones.propiedad == 'precisi�n' or opciones.propiedad == 'latitud' or opciones.propiedad == 'longitud'  then --latitud, longitud o precisi�n
		propiedad = 'P625'
	else
		propiedad = opciones.propiedad -- En el resto de casos se lee lo dado
    end

	if not propiedad then -- Comprobamos si existe la propiedad dada y en caso contrario se devuelve un error
		return formatoError( 'property-param-not-provided' )
	end
	local tablaOrdenada
	if declaracion then
		tablaOrdenada = declaracion
	elseif mw.wikibase.isValidEntityId(tostring(opciones.entityId)) and mw.wikibase.isValidEntityId(tostring(propiedad)) then
			tablaOrdenada = mw.wikibase.getAllStatements( opciones.entityId, mw.ustring.upper(propiedad) )
			if not tablaOrdenada[1] then return '' end
	else
		return ''
	end
	
	-- Funci�n que separa la cadena de texto 'inputstr' utilizando un separador 'sep' 
	function split(inputstr, sep) 
		sep=sep or '%s' 
		local t={}
		for field,s in string.gmatch(inputstr, "([^"..sep.."]*)("..sep.."?)") do 
			table.insert(t,field)  
			if s=="" then 
				return t 
			end 
		end 
	end
	
	tablaOrdenada = p.filtroDesconocidos(tablaOrdenada)
	
	-- Aplicar filtro de calificador
	if (opciones.filtroCalificador ~= nil and opciones.filtroCalificador ~= '') then
		local opts = split(opciones.filtroCalificador, ';')
		local negative = false
		if (#opts > 2) then
			if (opts[3]=='n') then
				negative = true
			elseif (opts[3]=='p') then
				negative = false
			end
		end
	
		tablaOrdenada = p.filtroCalificadores(tablaOrdenada, opts[1], split(opts[2], ','), negative)
	end
	
	-- Aplicar filtro de valor
	if (opciones.filtroValor ~= nil and opciones.filtroValor ~= '') then
		local opts = split(opciones.filtroValor, ';')
		local negative = false
		if (#opts > 1) then
			if (opts[2]=='n') then
				negative = true
			elseif (opts[2]=='p') then
				negative = false
			end
		end
		
		tablaOrdenada = p.filtroValores(tablaOrdenada, split(opts[1], ','), negative)
	end
	
	-- Aplicar funci�n de formato
	local modulo, funcion
	funcion = opciones['valor-funci�n'] or opciones['value-function'] or opciones['funcion']
	if funcion then 
		modulo = modulosTiposComplejos[funcion]
	
		if modulo then
			return require(modulo)[funcion](tablaOrdenada, opciones)
		end
	end	

	-- Evitar que pete cuando se haga el find en opciones['formatoTexto'] si vale nil
	if not opciones['formatoTexto'] then
		opciones['formatoTexto'] = ''
	end

	-- Aplicar filtro de mayor rango
	if (opciones.rangoMayor == 's�') then
		tablaOrdenada = p.filtrarDeclaracionPorRango(tablaOrdenada)
	end

	-- Ordenarseg�n el calificador "orden dentro de la serie"
	if opciones.ordenar == 's�' then
		require('M�dulo:Tablas').ordenar(tablaOrdenada,
			function(elemento1,elemento2)
				local orden1 = valinQualif(elemento1, { 'P1545' }) or '' -- elemento1.qualifiers.P1545[1].datavalue.value or ''
				local orden2 = valinQualif(elemento2, { 'P1545' }) or '' -- elemento2.qualifiers.P1545[1].datavalue.value or ''
				
				return orden1 < orden2
			end
		 )
	end

	--Ordenar seg�n la fecha. [V�ase la funci�n chronosort de :fr:Module:Wikidata/R�cup]
	if opciones.ordenar == 'por fecha' then
		require('M�dulo:Tablas').ordenar(tablaOrdenada,
			function(elemento1,elemento2)
				local fecha1 = valinQualif(elemento1, datequalifiers) or '' -- elemento1.qualifiers.P580[1].datavalue.value.time or ''
				local fecha2 = valinQualif(elemento2, datequalifiers) or '' -- elemento2.qualifiers.P580[1].datavalue.value.time or ''
				
				return fecha1 < fecha2
			end
		 )
	end
	
	-- Si despu�s de todo no queda nada en la tabla retornar
	if not tablaOrdenada[1] then
		return
	end

	-- == Si solo se desea que devuelva un valor ==
	-- Pendiente eliminar el par�metro y sustituirlo por un nuevo valor del par�metro lista=no que har�a lo mismo que opciones.uno = s�
	if opciones.uno == 's�' then -- Para que devuelva el valor de �ndice 1
		tablaOrdenada = {tablaOrdenada[1]}
	elseif opciones.uno == '�ltimo' then -- Para que devuelva la �ltima entrada de la tabla
		tablaOrdenada = {tablaOrdenada[#tablaOrdenada]}
	end

-- == Creamos una tabla con los valores que devolver� ==

	local formatoDeclaraciones = {}
	local hayDeclaraciones
	
	for indice, declaracion in pairs(tablaOrdenada) do
   		declaracionFormateada = p.formatoDeclaracion(declaracion, opciones)
   		if declaracionFormateada and declaracionFormateada ~= '' then
		   	table.insert(formatoDeclaraciones, declaracionFormateada)
		   	hayDeclaraciones = true
	   	end	
   	end
   	
	primera = true
	
	if not hayDeclaraciones then
		return
	end

	-- Aplicar el formato a la lista de valores seg�n el tipo de lista de las
	-- opciones
	
	return p.formatoLista(formatoDeclaraciones, opciones)
end

-- Funci�n que sirve para comprobar si una entidad tiene una propiedad con un
-- valor espec�fico
-- Par�metros:
--   � entidad: tabla de la entidad de Wikidata
--   � propiedad: identificador de Wikidata para la propiedad
--   � valor: valor de la propiedad en Wikidata
function p.tieneValorPropiedad(entidad, propiedad, valor)
	
	if entidad and entidad.claims and entidad.claims[propiedad] then
		
		local mainsnak
		
		for key,value in ipairs(entidad.claims[propiedad]) do
			if value and value.mainsnak then
				mainsnak = value.mainsnak
				if mainsnak.datatype == 'wikibase-item' and
						mainsnak.snaktype == 'value' and
						mainsnak.datavalue.value.id == valor then
					return true
				end
			end
		end
	end
	
	return false
end

-- Funci�n que sirve para devolver la leyenda (P2096) de una imagen (P18) en Wikidata en un determinado idioma
-- La funci�n se llama as�: {{#invoke:Wikidata |getLeyendaImagen | <PAR�METRO> | lang=<ISO-639code> |id=<QID>}}
-- Devuelve PAR�METRO, a menos que sea igual a "FETCH_WIKIDATA", del objeto QID (llamada que consume recursos)
-- Si se omite QID o est� vacio, se utiliza el art�culo actual (llamada que NO consume recursos)
-- Si se omite lang se utiliza por defecto el idioma local de la wiki, en caso contrario el idioma del c�digo ISO-639
-- ISO-639 est� documentado aqu�: https://docs.oracle.com/cd/E13214_01/wli/docs92/xref/xqisocodes.html#wp1252447
-- El ranking es: 'preferred' > 'normal' y devuelve la etiqueta de la primera im�gen con ranking 'preferred'
-- O la etiqueta de la primera imagen with ranking 'normal' si no hay ning�n 'preferred'
-- Ranks: https://www.mediawiki.org/wiki/Extension:Wikibase_Client/Lua

p.getLeyendaImagen = function(frame)
	-- busca un un elemento concreto en Wikidata (QID), en caso contrario que sea nil
	local id = frame.args.id

	if id and (#id == 0) then
		id = nil
	end

	-- busca el par�metro del idioma que deber�a contender un c�digo ISO-639 de dos d�gitos
	-- si no se declara, toma por defecto el idioma local de la wiki (es)
	local lang = frame.args.lang
	if (not lang) or (#lang < 2) then
		lang = mw.language.getContentLanguage().code
	end

	-- el primer par�metro sin nombrar es el par�metro local, si se declara
	local input_parm = mw.text.trim(frame.args[1] or "")
	if input_parm == "FETCH_WIKIDATA" or input_parm == "" or input_parm == nil then
		local ent = mw.wikibase.getEntityObject(id)
		local imgs
		if ent and ent.claims then
			imgs = ent.claims.P18
		end
		local imglbl
		if imgs then
			-- busca una imagen con ranking 'preferred'
			for k1, v1 in pairs(imgs) do
				if v1.rank == "preferred" and v1.qualifiers and v1.qualifiers.P2096 then
					local imglbls = v1.qualifiers.P2096
					for k2, v2 in pairs(imglbls) do
						if v2.datavalue.value.language == lang then
							imglbl = v2.datavalue.value.text
							break
						end
					end
				end
			end
			-- si no hay ninguna, busca una con ranking 'normal'
			if (not imglbl) then
				for k1, v1 in pairs(imgs) do
					if v1.rank == "normal" and v1.qualifiers and v1.qualifiers.P2096 then
						local imglbls = v1.qualifiers.P2096
						for k2, v2 in pairs(imglbls) do
							if v2.datavalue.value.language == lang then
								imglbl = v2.datavalue.value.text
								break
							end
						end
					end
				end
			end
		end
		return imglbl
	else
		return input_parm
	end
end

-- Funci�n que devuelve el valor de entidad.claims[idPropiedad][ocurrencia].mainsnak.datavalue.value.text
-- con entidad.claims[idPropiedad][ocurrencia].mainsnak.datavalue.value.language = 'es'

-- �til para obtener valores de propiedades de tipo monolingualtext

function p.getPropiedadEnEspanyol(idEntidad, idPropiedad)
	-- Ver cs:Modul:Wikidata/item	formatEntityWithGender
	
	--
	local entidad =  mw.wikibase.getEntityObject(idEntidad)
	
	if not entidad then
		return
	end
	
	local declaracion   = elementoTabla(entidad,'claims', idPropiedad)
	
	if not declaracion then
		return
	end
	
	local valor
	
	for k,v in pairs(declaracion) do
		valor = elementoTabla(v,'mainsnak', 'datavalue', 'value')
		
		if valor and valor.language == 'es' then
			return valor.text
		end
	end
end

-- devuelve el ID de la p�gina en Wikidata (Q...), o nada si la p�gina no est� conectada a Wikidata
function p.pageId(frame)
	local entity = mw.wikibase.getEntityObject()
	if not entity then return nil else return entity.id end
end

function p.categorizar(opciones, declaracion)
	-- Evitar que pete cuando se haga el find en opciones['formatoTexto'] si vale nil
	if not opciones['formatoTexto'] then
		opciones['formatoTexto'] = ''
	end	
	
	local categoriaOpciones=opciones['categor�a']	
	
	if not categoriaOpciones then
		return ''
	end

	opciones['enlace'] = 'no'

	-- Crear una tabla con los valores de la propiedad.	
	local valoresDeclaracion = {}

	if declaracion then
		valoresDeclaracion = declaracion
	elseif opciones.propiedad then
		local propiedad = {}
		if opciones.propiedad == 'precisi�n' or opciones.propiedad == 'latitud' or opciones.propiedad == 'longitud'  then
			propiedad = 'P625' -- Si damos el valor latitud, longitud o precisi�n equivaldr� a dar p625
		else
			propiedad = opciones.propiedad -- En el resto de casos se lee lo dado
		end
		
		if not p.getDeclaraciones(opciones.entityId) then
			return formatoError( 'other entity' )
		elseif p.getDeclaraciones(opciones.entityId)[mw.ustring.upper(propiedad)] then
			valoresDeclaracion = p.getDeclaraciones(opciones.entityId)[mw.ustring.upper(propiedad)]
		else
			return ''
		end		
	else
		return ''
	end

--  Creamos una tabla con cada categor�a a partir de cada valor de la declaraci�n
	local categorias	= {}
	local hayCategorias
	
	if type(categoriaOpciones) == 'string' then
		local ModuloPaginas = require('M�dulo:P�ginas')
	 
		for indice, valor in pairs(valoresDeclaracion) do
			valorFormateado = p.formatoDeclaracion(valor, opciones)
			if valorFormateado ~= '' then
				categoria = ModuloPaginas.existeCategoria(categoriaOpciones:gsub('$1',valorFormateado))
			
				if categoria then
					table.insert(categorias, categoria)
					hayCategorias = true
				end
			end	
		end
	elseif type(categoriaOpciones) == 'table' then
		for indice, valor in pairs(valoresDeclaracion) do
			categoria = categoriaOpciones[elementoTabla(valor, 'mainsnak', 'datavalue', 'value', 'numeric-id')]
			
			if categoria then
				table.insert(categorias, 'Categor�a:' .. categoria)
				hayCategorias = true
			end
		end
	end
	
	if hayCategorias then
		return '[[' .. mw.text.listToText( categorias, ']][[',']][[') .. ']]'
	end
	
	return ''
end

 --[[ =========================================================================
		Funci�n que filtra los valores de una propiedad y devuelve solo los que
		tengan el calificador "qualifier" indicado con uno de los valores "values"  
	 ========================================================================= `-- ]]
	 
function p.filtroCalificadores(t, qualifier, values, negativo)
	local f = {}  -- Tabla que se devolver� con el resultado del filtrado
	for k,v in pairs(t) do
		local counts = false
		if(v["qualifiers"] ~= nil and v["qualifiers"][qualifier] ~= nil) then
			for k2,v2 in pairs(v["qualifiers"][qualifier]) do
				-- Comprobar si el identificador del valor del cualificador est� en la lista
				for k3,v3 in pairs(values) do
					if (v2["datavalue"] ~= nil and v2["datavalue"]["value"] ~= nil and v2["datavalue"]["value"]["id"] ~= nil and v3 == v2["datavalue"]["value"]["id"])then  
						counts = true -- Si est� marcar como true
					end
				end
			end
		end
		if counts and not negativo then -- Si uno de los valores del cualificador dio true se inserta el elemento
			table.insert(f, v)
		elseif not counts and negativo then -- Si ninguno de los valores del cualificador dio true se inserta el elemento
			table.insert(f, v)
		end
	end
	return f
end

 --[[ =========================================================================
		Funci�n que filtra los valores de una propiedad y devuelve solo los que
		tengan uno de los valores "values"  
	 ========================================================================= `-- ]]
	 
function p.filtroValores(t, values, negativo)
	local f = {}  -- Tabla que se devolver� con el resultado del filtrado
	for k,v in pairs(t) do
		local counts = false
		if(v["mainsnak"]["datavalue"]["value"]["id"] ~= nil) then
			for k2,v2 in pairs(values) do
				if (v2 == v["mainsnak"]["datavalue"]["value"]["id"])then  
					counts = true -- Si est� marcar como true
				end
			end
		end
		if counts and not negativo then -- Si uno de los valores del cualificador dio true se inserta el elemento
			table.insert(f, v)
		elseif not counts and negativo then -- Si ninguno de los valores del cualificador dio true se inserta el elemento
			table.insert(f, v)
		end
	end
	return f
end

 --[[ =========================================================================
		Funci�n que filtra los valores de una propiedad y devuelve solo los que
		tengan formatos de valor, omitiendo los de formato desconocido o sin valor
	 ========================================================================= `-- ]]
function p.filtroDesconocidos(t)
	for k,v in pairs(t) do
		if(v["mainsnak"]["snaktype"] ~= "value") then
			t[k] = nil
		end
		local qual = v["qualifiers"]
		if(qual ~= nil) then
			for qualk,qualv in pairs(qual) do
				local prop = qualv
				for propk,propv in pairs(prop) do
					if(propv["snaktype"] ~= "value") then
						prop[propk] = nil
						-- same as: qual[prop] = nil
						-- same as: t["qualifiers"][prop] = nil
					end
				end
				if #prop == 0 then
					prop = nil
					qual[qualk] = nil
				end
			end
			if #qual == 0 then
				qual = nil
			end
		end
	end
	return t
end

 --[[ =========================================================================
		Funci�n que comprueba si la p�gina est� enlazada a  Wikidata
		en caso de estarlo pasa el valor como a argumento a la funci�n formatSnak()  
	 ========================================================================= `-- ]]

function p.formatoDeclaracion( declaracion, opciones)
	if not declaracion.type or declaracion.type ~= 'statement' then -- Se comprueba que tiene valor de tipo y que este sea statement (declaraci�n) lo cual pasa siempre que existe la propiedad
		return formatoError( 'unknown-claim-type' ) -- Si no se cumple devuelve error
	end
	
	-- En el caso de que haya calificador se devuelve a la derecha del valor de la
	-- declaraci�n entre par�ntesis.
	
	local calificativo = opciones.calificativo or opciones.calificador

	if calificativo and declaracion.qualifiers then
		-- De momento los calificativos, normalmente a�os, no se enlazan
	   local opcionesCalificativo = {['formatoTexto']='', enlace='no', ['formatoFecha']='a�o'} -- Pendiente
	  
	   local wValorCalificativo
	   local wValorCalificativoFormateado
	  
	   local funcionCalificativo, mensajeError = obtenerFuncion(calificativo, opciones['m�dulo calificativo'])
	  
		if mensajeError then
			return mensajeError
		elseif funcionCalificativo then
	   	  -- Utilizar la funci�n recibida sobre todos los calificativos
	   	  wValorCalificativo		   = declaracion.qualifiers
		  wValorCalificativoFormateado = funcionCalificativo(wValorCalificativo, opcionesCalificativo)
	   	elseif opciones.formatoCalificador and opciones.formatoCalificador == '()' then
			wValorCalificativo = declaracion.qualifiers[mw.ustring.upper(calificativo)]
			if wValorCalificativo and wValorCalificativo[1] then
				wValorCalificativoFormateado = p.formatoDato(wValorCalificativo[1], opcionesCalificativo)
			end
		elseif opciones.formatoCalificador and table.getn(mw.text.split(opciones.formatoCalificador, '%.')) == 2 then
			moduloFormatoCalificador = mw.text.split(opciones.formatoCalificador, '%.')
			formateado = require ('M�dulo:' .. moduloFormatoCalificador[1])
			if not formateado then
				return formatoError( 'value-module-not-found' )
			end
			fun = formateado[moduloFormatoCalificador[2]]
			if not fun then
				return formatoError( 'value-function-not-found' )
			end
			
			if mw.ustring.find(opciones['formatoTexto'],'may�scula', plain ) and
			   (primera or (opciones['separador'] and opciones['separador'] ~= 'null') or
			   	(opciones['lista'] and opciones['lista'] ~= '')) then
			  opciones['may�scula'] = 's�'
				  primera = false
			end
			
			if mw.ustring.find(opciones['formatoTexto'],'cursivas', plain ) then
				opcionesEntidad.cursivas = 's�'
			end
			
			wValorCalificativoFormateado = fun( declaracion.qualifiers, opciones, marco)
			--return require('M�dulo:Tablas').tostring(declaracion)
		else
	   	  -- Utilizar el primer valor del calificativo de la propiedad recibida
	   	  wValorCalificativo = declaracion.qualifiers[mw.ustring.upper(calificativo)]
	   	 
	   	  if wValorCalificativo and wValorCalificativo[1] then
			wValorCalificativoFormateado = p.formatoDato(wValorCalificativo[1], opcionesCalificativo)
		  end
		end
		if opciones.separadorcalificador then separador = opciones.separadorcalificador else separador = ' ' end
		if wValorCalificativoFormateado then
			datoFormateado = p.formatoDato(declaracion.mainsnak, opciones)
			
			-- Si el par�metro especificado era "|calificador="" no devolver propiedad y par�ntesis
			if(opciones.calificador ~= nil and opciones.calificador ~= '') then
				return wValorCalificativoFormateado
			end
			-- Si el par�metro especificado era "|calificativo="" devolver propiedad y calificativo entre par�ntesis
			return (datoFormateado and datoFormateado .. '&nbsp;<small>(' .. wValorCalificativoFormateado .. ')</small>') or nil
		end		
	end

	-- Si no hay calificativo.
	return p.formatoDato(seleccionDeclaracion(declaracion, opciones), opciones, declaracion.qualifiers)
end

 --[[ =========================================================================
		Funci�n que comprueba el tipo de dato (snaktype)
		si es value pasa el valor como argumento a la funci�n formatoValorDato()	
	 ========================================================================= `-- ]]

function p.formatoDato( dato, opciones, calificativos)
	
	if not dato or dato == '' then
		return ''
	end
	if dato.snaktype == 'somevalue' then
		-- Fecha m�s temprana
		if calificativos then
			if calificativos['P1319'] and calificativos['P1319'][1] and
			   calificativos['P1319'][1].datavalue and
			   calificativos['P1319'][1].datavalue.type=='time' then
			   	
				local opcionesFecha={['formatoFecha']=opciones['formatoFecha'],enlace=opciones.enlace}
		
				return 'post. ' .. require('M�dulo:Wikidata/Fecha').FormateaFechaHora(calificativos['P1319'][1].datavalue.value, opcionesFecha)
			end
		end
		
		-- Si no tiene un calificativo v�lido
		return avisos['somevalue'] -- Valor desconocido
	elseif dato.snaktype == 'novalue' then
		return avisos['novalue'] -- Sin valor
	elseif dato.snaktype == 'value' then
		return formatoValorDato( dato.datavalue, opciones, calificativos) -- Si tiene el tipo de dato se pasa el valor a la funci�n formatDatavalue()
	else
		return formatoError( 'unknown-snak-type' ) -- Tipo de dato desconocido
	end
end

 --[[ =========================================================================
	   Funci�n que establece el tipo de formato en funci�n del tipo de valor
	   (valorDato.type) y en caso de solicitarse un formato complemetario asocia
	   el m�dulo donde se establece el formato y la funci�n de este que lo establece	
	 ========================================================================= `-- ]]

function formatoValorDato( valorDato, opciones, calificativos)
	local funcion, mensajeError = obtenerFuncion(opciones['valor-funci�n'] or opciones['value-function'] or opciones['funcion'], opciones['valor-m�dulo'] or opciones['modulo'])
	
	if mensajeError then
		return mensajeError
	elseif funcion then
		local opcionesEntidad = {}
		
		for k, v in pairs(opciones) do
			opcionesEntidad[k] = v
		end
		
		if mw.ustring.find(opciones['formatoTexto'],'may�scula', plain ) and
		   (primera or (opciones['separador'] and opciones['separador'] ~= 'null') or
		   	(opciones['lista'] and opciones['lista'] ~= '')) then
		  opcionesEntidad['may�scula'] = 's�'
			  primera = false
		end	
		
		if mw.ustring.find(opciones['formatoTexto'],'cursivas', plain ) then
			opcionesEntidad.cursivas = 's�'
		end
		
		return funcion(valorDato.value, opcionesEntidad, marco, calificativos)		
	end

	-- == Formatos por defecto en funci�n del tipo de valor ==

--		   * Con el resto de valores en propiedad

	if valorDato.type == 'wikibase-entityid' then	-- Tipo: N�mero de entidad que puede ser un �tem o propiedad
		local opcionesEntidad = {}
		if mw.ustring.find(opciones['formatoTexto'],'may�scula', plain ) and
		   (primera or (opciones['separador'] and opciones['separador'] ~= 'null') or
		   	(opciones['lista'] and opciones['lista'] ~= '')) then
		  opcionesEntidad['may�scula'] = 's�'
			  primera = false
		end
		opcionesEntidad.enlace		 = opciones.enlace
		opcionesEntidad.etiqueta	   = opciones.etiqueta
		opcionesEntidad['debeExistir'] = opciones['debeExistir']
		
		if mw.ustring.find(opciones['formatoTexto'],'cursivas', plain ) then
			opcionesEntidad.cursivas = 's�'
		end
		return p.formatoIdEntidad( SelecionEntidadPorValor( valorDato.value ), opcionesEntidad)
	elseif valorDato.type == 'string' then			   -- Tipo: Cadena de texto (string)
		return valorDato.value
	elseif valorDato.type == 'url' then	 --Tipo URL (direcci�n web)
		return value.url
	elseif valorDato.type == 'time' then				 -- Tipo: Fecha/hora
		local opcionesFecha={['formatoFecha']=opciones['formatoFecha'],enlace=opciones.enlace}
	  
		if mw.ustring.find(opciones['formatoTexto'] or '','may�scula', plain ) and primera then
			opcionesFecha['may�scula']='s�'
		end
		
		return require('M�dulo:Wikidata/Fecha').FormateaFechaHora(valorDato.value, opcionesFecha, calificativos)
	elseif valorDato.type == 'monolingualtext' then	   -- Tipo: monoling�e
		if valorDato.value then
			if opciones.idioma then
				for k, v in pairs(valorDato) do
					if v.language == opciones.idioma then
						return v.text
					end
				end
			else
				return valorDato.value.text
			end
		else
			return ''
		end
	elseif valorDato.type ==  'quantity' then			-- Tipo: Cantidad
		return require('M�dulo:Wikidata/Formatos').formatoUnidad(valorDato, opciones)
	elseif  valorDato.value['latitude']  and valorDato.value['longitude'] then -- Tipo: Coordenadas



--		  * Para tipo coordenadas cuando se da como valor de propiedad: latitud, longitud o precisi�n
	if TIPOLLP == 'latitud' then
		return valorDato.value['latitude']
	elseif TIPOLLP == 'longitud' then
		return valorDato.value['longitude']
	elseif TIPOLLP == 'precisi�n' then
		return valorDato.value['precision']
    else
		local globo = require('M�dulo:Wikidata/Globos')[valorDato.value.globe]

--Concatenamos los valores de latitud y longitud dentro de la plantilla Coord

		if globo ~= 'earth' then
			return  marco:preprocess('{{coord|' .. valorDato.value['latitude'] .. '|' ..
				   valorDato.value['longitude'] .. '|globe:' .. globo .. '_type:' .. opciones.tipo .. '|display=' ..
				   opciones.display ..'|formato=' .. opciones.formato..'}}')
		else
			return  marco:preprocess('{{coord|' .. valorDato.value['latitude'] .. '|' ..
				   valorDato.value['longitude'] .. '|type:' .. opciones.tipo .. '|display=' ..
				   opciones.display ..'|formato=' .. opciones.formato..'}}')
		end
    end
	else
		return formatoError( 'unknown-datavalue-type' ) -- Si no es de ninguno de estos tipos devolver� error valor desconocido
	end
end

  --[[ =========================================================================
		  Damos formato a los enlaces internos	
	   ========================================================================= `-- ]]

-- Opciones:
--	 - enlace:		Valores posibles 's�' o 'no'
--	 - may�scula:		Valores posibles 's�' o 'no'
--	 - cursivas:		Valores posibles 's�' o 'no'

function p.formatoIdEntidad(idEntidad, opciones)
	local enlace   = mw.wikibase.sitelink(idEntidad)
	local etiqueta = mw.wikibase.label(idEntidad)
	return require('M�dulo:Wikidata/Formatos').enlazar(enlace, etiqueta, idEntidad, opciones)
end

 --[[ =========================================================================
		Funci�n principal	
	 ========================================================================= `-- ]]

function p.Wikidata( frame )

    TIPOLLP="" --Variable global para identificar los casos de latitud, longitud o precisi�n
    
	marco = frame
	local args = frame.args
	
	if args.valor == 'no' then
		return
	end

	local parentArgs = frame:getParent().args


	-- Copiar los argumentos
	local argumentos = {}
	
	for k, v in pairs(args) do
		argumentos[k] = v
	end
	
	for k, v in pairs(parentArgs) do
		if not argumentos[k] then
			argumentos[k] = v
		end
	end

    if argumentos[1]=='longitud' or argumentos[1]=='latitud' or argumentos[1]=='precisi�n' then
       TIPOLLP=argumentos[1]
       marco.args[argumentos[1]]='P625'
    end

	--if true then return require('M�dulo:Tablas').tostring(argumentos) end
	
	-- No generar el valor de Wikidata si se ha facilitado un valor local y
	-- el valor local es prioritario.
	local valorWikidata;
	if (args.prioridad ~= 's�' or (args.importar and args.importar == 'no')) and args.valor and args.valor ~= '' then
		valorWikidata = nil;
	else
		if not mw.wikibase.isValidEntityId(tostring(argumentos.entityId)) then
			argumentos.entityId = mw.wikibase.getEntityIdForCurrentPage() or nil
		end
		valorWikidata = p.getPropiedad(argumentos, nil);
	end
	
 	local categorias = '';
 	local namespace = frame:preprocess('{{NAMESPACENUMBER}}');
 	
 	if (namespace == '0' and (not args.categorias or args.categorias ~= 'no') and
 			args.propiedad and string.upper(args.propiedad) ~= 'P18' -- P18: imagen de Commons
 			and string.upper(args.propiedad) ~= 'P41' -- P41: imagen de la bandera
 			and string.upper(args.propiedad) ~= 'P94' -- P94: imagen del escudo de armas
 			and string.upper(args.propiedad) ~= 'P109' -- P109: firma de persona
 			and string.upper(args.propiedad) ~= 'P154') then -- P154: logotipo
	 	if valorWikidata and valorWikidata ~= '' and args.valor and args.valor ~= '' then
	 		categorias = '[[Categor�a:Wikipedia:Art�culos con datos locales]]'
	 	elseif valorWikidata and valorWikidata == '' and args.valor and args.valor ~= '' and
	 		(not args.calificador or args.calificador == '') and
	 		(not args.dato or args.dato == '' or args.dato ~= 'fuente') then
	 		categorias = '[[Categor�a:Wikipedia:Art�culos con datos por trasladar a Wikidata]]'
	 	end
	end

	if args.prioridad == 's�' and valorWikidata and valorWikidata ~= '' then -- Si se da el valor s� a prioridad tendr� preferencia el valor de Wikidata
		if args.importar and args.importar == 'no' and args.valor and args.valor ~= '' then
			return args.valor .. categorias
		elseif valorWikidata then
			return valorWikidata .. categorias -- valor que sustituye al valor de Wikidata par�metro 2
		else
			return categorias
		end
	elseif args.valor and args.valor ~= '' then
		 return args.valor .. categorias
	elseif args.importar and args.importar == 'no' then
		 return ''
	elseif valorWikidata then -- Si el valor es nil salta una excepcion al concatenar
		return valorWikidata .. categorias
	else
		return ''
  end 
end

function obtenerFuncion(funcion, nombreModulo)
	if not funcion then
		return
	elseif type(funcion) == 'function' then -- Uso desde LUA
		return funcion
	elseif funcion == '' or not nombreModulo or nombreModulo == '' then
		return
	else -- Uso desde una plantilla
		local modulo
		
		if not nombreModulo or nombreModulo == '' or nombreModulo == 'Wikidata/Formatos' then
			modulo = require(modulosTipos[funcion] or 'M�dulo:Wikidata/Formatos')
		else
			modulo = require ('M�dulo:' .. nombreModulo)
		end
		
	   	if not modulo then
		   	return nil, formatoError( 'value-module-not-found' )
		elseif not modulo[funcion] then
		   	return nil, formatoError( 'value-function-not-found' )
		else
		   	return modulo[funcion]
	   	end
	end
end

function p.addLinkback(valorPropiedad, idEntidad, idPropiedad)
	local lidEntidad
	
	if valorPropiedad and idPropiedad then
		lidEntidad= (idEntidad ~='' and idEntidad) or mw.wikibase.getEntityIdForCurrentPage()
	end

	if lidEntidad then
		return valorPropiedad .. '<span class=\"wikidata-link lapiz noprint\"> [[Archivo:Blue_pencil.svg|Ver y modificar los datos en Wikidata|10px|baseline|alt=Ver y modificar los datos en Wikidata|enlace=/proxy/https://www.wikidata.org/wiki/' .. lidEntidad .. '?uselang=es#' .. idPropiedad ..
		 ']]</span>'
	else
		return valorPropiedad
	end
end

function p.formatoLista(tabla, opciones)
	if not tabla or not tabla[1] then
		return
	end
	
	local tipo_lista = opciones.lista
	local lapiz
	
	if opciones.linkback == 's�' and opciones.entityId and opciones.propiedad then
		lapiz = '<span class=\"wikidata-link lapiz noprint\"> [[Archivo:Blue_pencil.svg|Ver y modificar los datos en Wikidata|10px|baseline|alt=Ver y modificar los datos en Wikidata|enlace=/proxy/https://www.wikidata.org/wiki/' .. opciones.entityId .. '?uselang=es#' .. opciones.propiedad ..
		 ']]</span>'
	else
		lapiz = ''
	end
	
	if not tabla[2] then
		-- Si la tabla solo tiene un elemento devolverlo
		return tabla[1] .. lapiz
	end
	
	if tipo_lista == 'no ordenada' or tipo_lista == 'ordenada' or tipo_lista == 'nobullet' then
		local lista = mw.text.listToText( tabla, '</li><li>', '</li><li>' )
		
		if tipo_lista == 'no ordenada' then
			return '<ul><li>' .. lista .. lapiz .. '</li></ul>'
		elseif tipo_lista == 'ordenada' then
			return '<ol><li>' .. lista .. lapiz .. '</li></ol>'			
		else
			return '<ul style="list-style-type:none;list-style-image:none;margin-left:0;padding-left:0"><li>' .. lista .. lapiz .. '</li></ul>'
		end
	else
		local separadores = {
			[''] = '',
			[','] = ', ',
			['null'] = ', ',
			['no'] = ''
		}
		local conjunciones = {
			[''] = '',
			['y'] = ' y ',
			['o'] = ' o ',			
			['null'] = ' y ',
			['no'] = ''
		}
		
		local separador = opciones.separador
		local conjuncion = opciones['conjunci�n']
		
		if not separador then
			separador = ', '
		else
			separador = separadores[separador] or separador
		end
		
		if not conjuncion then
			conjuncion = ' y '
		else
			conjuncion = conjunciones[conjuncion] or conjuncion
		end
		
		if conjuncion == ' y ' and marco and tabla[2] then
			conjuncion = ' ' .. marco:preprocess('{{y-e|{{Desvincular|' .. tabla[#tabla] .. '}}|sin texto}}') .. ' '
		end
		
		return mw.text.listToText( tabla, separador, conjuncion ) .. lapiz
	end
end

-- Funciones existentes en otros m�dulos
function p.obtenerEtiquetaWikidata(entidad, fallback)
	if not entidad then entidad = fallback end
	if entidad and entidad.labels and entidad.labels.es then
		return entidad.labels.es.value
	end
end

function p.obtenerImagenWikidata(entidad, propiedad)
	local imagen, valorImagen, piesDeImagen, k, pieDeImagen
	if not entidad then
		return
	end
	
	--  Obtener la primera imagen en Wikidata de la persona
	local imagen = elementoTabla(entidad, 'claims', propiedad, 1)
--[[	
	-- Obtener el objeto de imagen, ya sea la primera, la �ltima (WIP) o por fecha (WIP)
	local imagen = (function()
		local ImagenObj = elementoTabla(entidad, 'claims', idPropiedad)
		if opciones.ordenar == 'por fecha' then
			--
		end

		return elementoTabla(ImagenObj, 1)
	end)()
--]]
	if not imagen then
		return
	end
	valorImagen =  elementoTabla(imagen, 'mainsnak', 'datavalue', 'value')
	piesDeImagen =  elementoTabla(imagen, 'qualifiers', 'P2096')
	-- Encontrar el pie en espa�ol
	if piesDeImagen then
		for k,pieDeImagen in pairs(piesDeImagen) do
			if pieDeImagen.datavalue.value.language == 'es' then
				return valorImagen, pieDeImagen.datavalue.value.text
			end
		end
	end
	-- Si no hay pie de imagen en espa�ol comprueba si hay fecha especificada para la imagen
	piesDeImagen = elementoTabla(imagen, 'qualifiers', 'P585')
	if piesDeImagen and piesDeImagen[1] then
		return valorImagen, 'En ' .. require('M�dulo:Wikidata/Fecha').FormateaFechaHora(piesDeImagen[1].datavalue.value, {['formatoFecha']='a�o',['enlace']='no'})
	end
	-- Sin pie de imagen en espa�ol
	return valorImagen
end

function p.propiedad(entidad, idPropiedad, opciones)
	if entidad and entidad.claims and entidad.claims[idPropiedad] then
		if not opciones then
			opciones = {['linkback']='s�'}
		end
		--[[
		local ValorPosicional = (function()
			if opciones['valor_posicional'] == '�ltimo' then return -1 end
			if type(opciones['valor_posicional']) == 'number' then return opciones['valor_posicional'] end
			return 1
		end)()

		local ValorPosicionalCalif =(function()
			if opciones['valor_posicional_calif'] == '�ltimo' then return -1 end
			if type(opciones['valor_posicional_calif']) == 'number' then return opciones['valor_posicional_calif'] end
			return 1
		end)()
		
		local Calificador = opciones['calificador']

		local Obj = (function()
			local Obj = (function()
				local Obj = elementoTabla(entidad, 'claims', idPropiedad)
				if ValorPosicional == -1 then return elementoTabla(Obj, #Obj) end
				return elementoTabla(Obj, ValorPosicional)
			end)()

			if Calificador then
				Obj = (function()
					local Obj = elementoTabla(Obj, 'qualifiers', Calificador)
					if ValorPosicionalCalif == -1 then return elementoTabla(Obj, #Obj) end
					return elementoTabla(Obj, ValorPosicionalCalif)
				end)()
			end
			return Obj
		end)()
		
		Tipo	= elementoTabla(Obj, 'datavalue', 'type')
		
		-- Devolver el ID de la entidad, para propiedades de entidad
		if opciones['formato'] == 'entidadID' then
			return elementoTabla(Obj, 'datavalue', 'value', 'id')
		end
		
		-- Preparar para devolver el archivo m�s reciente en la propiedad. Buscar c�mo hacerlo con los calificadores
		if opciones['formato'] == 'archivo' then
			if Calificador then return elementoTabla(Obj, 'datavalue', 'value') end
			if not opciones['uno'] then opciones['uno'] = '�ltimo' end
			opciones['ordenar'] = 'por fecha'
		end

		-- Obtener la propiedad como cadena sin formato
		if opciones['formato'] == 'cadena' then
			opciones['linkback'] = 'no'
			if Tipo == 'string' then
				return elementoTabla(Obj, 'datavalue', 'value')
			end
		end

		-- Devolver una cadena num�rica correctamente formateada
		if opciones['formato'] == 'n�mero' then
			if Tipo == 'quantity' then
				return formatoNumero(elementoTabla(Obj, 'datavalue', 'value', 'amount'))
			end
		end

		-- Devolver una cadena num�rica con su unidad
		if opciones['formato'] == 'unidad' then
			if elementoTabla(entidad, 'claims', idPropiedad, 2, 'mainsnak', 'datavalue') then
				return formatoNumero(elementoTabla(entidad, 'claims', idPropiedad, 1, 'mainsnak', 'datavalue', 'value', 'amount')) .. '&nbsp;-&nbsp;' .. numeroUnidad(elementoTabla(entidad, 'claims', idPropiedad, 2, 'mainsnak', 'datavalue'), opciones)
			else
				return numeroUnidad(elementoTabla(entidad, 'claims', idPropiedad, 1, 'mainsnak', 'datavalue'), opciones)
			end
		end
		--]]
		
		opciones.entityId  = entidad.id
		opciones.propiedad = idPropiedad
		
		return p.getPropiedad(opciones, entidad.claims[idPropiedad])
	end
end

function p.esUnValor(entidad, idPropiedad, idaBuscar)
	if not entidad or not idPropiedad then
		return false
	end
	
	local declaracion = elementoTabla(entidad, 'claims', idPropiedad)
	local idBuscado
	if not declaracion then
		return false
	end

	for k,v in pairs(declaracion) do
		idBuscado = elementoTabla(v,'mainsnak','datavalue','value','id')
		if idBuscado == idaBuscar then
			return true
		end
	end
	return false
end

-- Obtener el objeto mw.language, para usar sus funciones en otros módulos
function p.language()
	return es
end

return p