Módulo:Ficha de película

Categorías


local z = {}

local argumentos	-- Tabla de argumentos con los que se llama a la función 
local argumento={}	-- Argumentos eliminando los argumentos sin datos
local Entidad		-- Tabla con los datos en Wikidata de la película.
local Entidades={}	-- Tabla con los datos en Wikidata de las películas que forman la serie.
local algunaPropiedadEnlazaWikidata -- Para alguna propiedad no existe la etiqueta ni el enlace mostrándose algo de la forma d:...

-- Características especiales para la ficha
local esSerieCinematografica = false  -- Para distinguir series cinematográficas de películas
local esPeliculaMuda = false

-- Módulos y funciones externas
local ModuloFicha				= require('Módulo:Ficha')
local ModuloPaginas				= require('Módulo:Páginas')	
local ModuloWikidataFormatos	= require('Módulo:Wikidata/Formatos')
local ModuloWikidata			= require('Módulo:Wikidata')
local 	getPropiedadWikidata	= ModuloWikidata.getPropiedad
local   tieneValorPropiedad     = ModuloWikidata.tieneValorPropiedad
local ModuloCategorizar			= require('Módulo:Categorizar')
local 	categoriza				= ModuloCategorizar.categoriza
local elementoTabla				= require('Módulo:Tablas').elemento
local listaHtml                 = require('Módulo:Listas').listahtml

local generosCinematograficos = {
	['Q188473']			= 'acción',
	['Q15637293']       = 'acción', -- Anime y manga de acción
	['Q104537013']      = 'acción', -- Anime de acción
	['Q202866']			= 'animación',
	['Q28968258']		= 'animación',
	['Q1033891']		= 'artes marciales',
	['Q319221']			= 'aventuras',
	['Q15712918']       = 'aventuras', -- Anime y manga de aventuras
	['Q104536870']      = 'aventuras', -- Anime de aventuras
	['Q471839']			= 'ciencia ficción',
	['Q5366020']        = 'ciencia ficción', -- Anime y manga de ciencia ficción
	['Q103925569']      = 'ciencia ficción', -- Anime de ciencia ficción
	['Q157443']			= 'comedia',
	['Q15286013']       = 'comedia', -- Anime y manga de comedia
	['Q11298147']       = 'comedia', -- Anime de comedia
	['Q959790']			= 'crímenes',
	['Q93204']			= 'documental',
	['Q130232']			= 'drama',
	['Q15637299']       = 'drama', -- Anime y manga dramático
	['Q104536994']      = 'drama', -- Anime dramático
	['Q1361932']		= 'familiar',
	['Q157394']			= 'fantasía',
	['Q2973181']		= 'fantasía',
	['Q15637301']       = 'fantasía', -- Anime y manga de fantasía
	['Q104536896']      = 'fantasía', -- Anime de fantasía
	['Q1200678']		= 'misterio',
	['Q104623091']      = 'misterio', -- Anime de misterio
	['Q842256']			= 'musical',
	['Q1054574']		= 'romance',
	['Q15637310']       = 'romance', -- Anime y manga romántico
	['Q104536771']      = 'romance', -- Anime romántico
	['Q182015']			= 'suspenso',
	['Q2484376']		= 'suspenso',
	['Q104623069']      = 'suspenso', -- Anime de suspenso
	['Q200092']			= 'terror',
	['Q172980']			= 'wéstern',
	
	-- Géneros para no mostrar en ficha
	['Q1257444']		= '',	-- Adaptación cinematográfica
	['Q21401869']		= '',	-- Flashback en el cine
	['Q52207399']       = '',   -- Película basada en una novela
	['Q52207310']		= '',	-- Película basada en un libro
	['Q52162262']       = '',   -- Película basada en una obra literaria
	['Q226730']         = '',   -- Cine mudo
}

-- Si el identificador está en la tabla de géneros cinematográficos cambiará
-- el nombre por el que aparece en la tabla y, en caso contrario, mantendrá
-- el nombre que aparezca en Wikidata para ese género
function formatoGenero(valor, opciones, frame, calificativos)
	local enlace, etiqueta, idEntidad = ModuloWikidataFormatos.obtenerDatos(valor)
	
	if generosCinematograficos[idEntidad] then
		etiqueta = generosCinematograficos[idEntidad]
	end
	
	if etiqueta ~= '' then
		return ModuloWikidataFormatos.enlazar(enlace, etiqueta, idEntidad, opciones)
	else
		return nil
	end
end

-- Constantes
local enMayusculas			= {['formatoTexto'] = 'mayúscula'}
local enMayusculasO			= {['formatoTexto'] = 'mayúscula', ['conjunción']=' o '}
local listaNoOrdenada		= {['lista'] = 'no ordenada', ['formatoTexto'] = 'mayúscula'}
local soloUno				= {['rangoMayor'] = 'sí', ['uno'] = 'sí' }
local rangoMayor			= {['rangoMayor'] = 'sí' }
local estreno				= {['rangoMayor'] = 'sí', ['formatoFecha'] = 'año', ['uno'] = 'sí', ['enlace'] = 'no' }
local obraAutor				= {['valor-función'] = ModuloWikidataFormatos.formatoObraAutor }
local listaPeliculas		= {['lista'] = 'no ordenada', ['valor-función'] = ModuloWikidataFormatos.formatoObraAnyo, ['ordenar'] = 'sí' }
local generoCinematografico	= {['formatoTexto'] = 'mayúscula', ['valor-función'] = formatoGenero }
local formatoCategorizar	= {['separador'] = '<br />', ['conjunción'] = '<br />', ['enlace'] = 'no'}
local formatoDuracion       = {['rangoMayor'] = 'sí', ['formatoUnidad'] = 'minutos'}

function z.Ficha(frame)
	ModuloWikidata:setFrame(frame)  -- No funciona si se pone ModuloWikidata.setFrame(marco)	
	-- Obtener una copia de los argumentos eliminando los argumentos sin valor
	-- y dejando en blanco (aunque no nil) aquellos que valen "no"
	local argumento = obtenerArgumentosConValor(frame)
	
	local color		= '#ABD2D0'
	local estilotitulo = 'background-color:'..color.. '; font-style:italic'
	local estiloseccion = 'background-color:'..color
	
	Entidad = mw.wikibase.getEntityObject(argumento['entidad']) or {}
	
	local esSerieCinematografica = tieneValorPropiedad(Entidad, 'P31', 'Q24856') or 
		tieneValorPropiedad(Entidad, 'P31', 'Q13593818') or
		tieneValorPropiedad(Entidad, 'P31', 'Q56884562')
	local esPeliculaMuda = tieneValorPropiedad(Entidad, 'P364', 'Q21686005') or 
		tieneValorPropiedad(Entidad, 'P31', 'Q226730') or
		tieneValorPropiedad(Entidad, 'P136', 'Q226730') or
		especificaNoTenerDialogo(Entidad)
	local esPeliculaEnBlancoYNegro = tieneValorPropiedad(Entidad, 'P462', 'Q838368')
	local esCortometraje = tieneValorPropiedad(Entidad, 'P31', 'Q24862') or
		tieneValorPropiedad(Entidad, 'P31', 'Q17517379')
	
	-- Cargar entidades enlazadas en la propiedad P527 (compuesto de)
	if esSerieCinematografica and Entidad and Entidad.claims and Entidad.claims['P527'] then
		for key,value in ipairs(Entidad.claims['P527']) do
			local ms = value.mainsnak
			if ms.snaktype == 'value' and ms.datavalue and ms.datavalue.value then
				local id = ms.datavalue.value.id
				Entidades[id] = mw.wikibase.getEntityObject(id) or {}
			end
		end
	end
	
	-- Imagen y pie de la imagen
	local imagen = argumento['imagen']  or argumento['Imagen'] or argumento['foto']
	local pieDeImagen
	
	if imagen then
		pieDeImagen = argumento['pie de imagen'] or argumento['pieimagen'] or
					  argumento['descripción'] or argumento['descripcion'] or
					  argumento['pie de foto'] or argumento['piedefoto'] or
					  argumento['textoimagen'] or argumento['TextoImagen'] or argumento['texto_imagen'] or
					  argumento['pie de foto']
	else
		imagen, pieDeImagen = obtenerImagenWikidata()
	end
	
	local tituloOriginal = argumento['título original'] or 
							argumento['título'] or
							propiedad('P1476', soloUno) or 
							obtenerEtiquetaWikidata() or 
							ModuloPaginas.nombrePagina({desambiguar='sí'})
	local tituloTraducido = nil
	
	if argumento['título'] ~= tituloOriginal then
		tituloTraducido = argumento['título']
	end
	
	local tituloES, tituloHA, tituloAR
	if not tituloTraducido then
		local valorES = obtenerValorCalificativo('P1552', 'P1476', 'Q27847754')
		local valorHA = obtenerValorCalificativo('P1552', 'P1476', 'Q27834579')
		local valorAR = obtenerValorCalificativo('P1552', 'P1476', 'Q106341285')
		tituloES = (valorES and valorES.text) or ''
		tituloHA = (valorHA and valorHA.text) or ''
		tituloAR = (valorAR and valorAR.text) or ''
		
		if tituloOriginal ~= tituloES and tituloES ~= '' then
			tituloTraducido = tituloES
		end
		
		if tituloOriginal ~= tituloHA and tituloHA ~= '' then
			if tituloTraducido ~= nil and tituloTraducido ~= tituloHA then
				tituloTraducido = ''
			elseif tituloTraducido == nil then
				tituloTraducido = tituloHA
			end
		end
		
		if tituloOriginal ~= tituloHA and tituloHA ~= '' then
			if tituloTraducido ~= nil and tituloTraducido ~= tituloHA then
				tituloTraducido = ''
			elseif tituloTraducido == nil then
				tituloTraducido = tituloHA
			end
		end
		
		if tituloOriginal ~= tituloAR and tituloAR ~= '' then
			if tituloTraducido ~= nil and tituloTraducido ~= tituloAR then
				tituloTraducido = ''
			elseif tituloTraducido == nil then
				tituloTraducido = tituloAR
			end
		end
		
		if tituloTraducido and tituloTraducido ~= '' then
			tituloTraducido = "''"..tituloTraducido.."''"
			tituloES = ''
			tituloHA = ''
			tituloAR = ''
		end
	end
	
	local directores
	
	if argumento['dirección'] or argumento['dirección2'] or argumento['dirección3'] or
		argumento['dirección4'] or argumento['dirección5'] or argumento['dirección6'] or
		argumento['dirección7'] or argumento['dirección8'] or argumento['dirección9'] then
			local enlazarDirector = 'sí'
			if (argumento['dir_enlace'] == 'no') then
				enlazarDirector = 'no'
			end
			
			directores = frame:preprocess('{{#Invoke:listas|listahtml'..
				'|enlazar='..enlazarDirector..
				'|'..(argumento['dirección'] or '').. 
				'|'..(argumento['dirección2'] or '').. 
				'|'..(argumento['dirección3'] or '').. 
				'|'..(argumento['dirección4'] or '').. 
				'|'..(argumento['dirección5'] or '').. 
				'|'..(argumento['dirección6'] or '').. 
				'|'..(argumento['dirección7'] or '')..
				'|'..(argumento['dirección8'] or '')..
				'|'..(argumento['dirección9'] or '')..'}}')
	else
		directores = propiedad('P57', listaNoOrdenada)
	end
	
	local serieCinematografica
	if esSerieCinematografica then
		serieCinematografica = propiedad('P527', listaPeliculas)	
	end

	local protagonistas = argumento['elenco'] or argumento['protagonistas'] or argumento['reparto']
	if not protagonistas then
		protagonistas = propiedad('P161', listaNoOrdenada)
		if protagonistas then
			local _, count = string.gsub(protagonistas, "<li>", "")
			 
			-- Si la lista es muy larga hacerla collapsible
			if count > 10 then
				protagonistas = '<div class="mw-collapsible mw-collapsed"><span class="noprint">'..count..' personas</span><div class="mw-collapsible-content">' .. protagonistas .. '</div></div>'
			end
		end
	end
	
	local actoresDeVoz = argumento['voces']
	if not actoresDeVoz and not (argumento['elenco'] or argumento['protagonistas'] or argumento['reparto']) then
		 actoresDeVoz = propiedad('P725', listaNoOrdenada)
		 if actoresDeVoz then
			local _, count = string.gsub(actoresDeVoz, "<li>", "")
			 
			-- Si la lista es muy larga hacerla collapsible
			if count > 10 then
				actoresDeVoz = '<div class="mw-collapsible mw-collapsed"><span class="noprint">'..count..' personas</span><div class="mw-collapsible-content">' .. actoresDeVoz .. '</div></div>'
			end
		 end
	end

	local imdbId, filmaffinityId, seccionEnlacesExternos
	if argumento['test'] == 'sí' then
		seccionEnlacesExternos = frame:preprocess('<small>{{#Invoke:listas|listahtml|clase=hlist'..
			'|'..((propiedad('P3593', soloUno) and '[http://www.afi.com/members/catalog/DetailView.aspx?s=&Movie='..propiedad('P3593', soloUno)..' AFI]') or '')..
			'|'..((propiedad('P1562', soloUno) and '[http://www.allmovie.com/movie/'..propiedad('P1562', soloUno)..' AllMovie]') or '')..
			'|'..((propiedad('P1237', soloUno) and '[http://www.boxofficemojo.com/movies/?id='..propiedad('P1237', soloUno)..' Box Office Mojo]') or '')..
			'|'..((propiedad('P480', soloUno) and '[https://www.filmaffinity.com/es/film'..propiedad('P480', soloUno)..'.html FilmAffinity]') or '')..
			'|'..((propiedad('P345', soloUno) and '[https://www.imdb.com/title/'..propiedad('P345', soloUno)..'/ IMDb]') or '')..
			'|'..((propiedad('P1712', soloUno) and '[http://www.metacritic.com/'..propiedad('P1712', soloUno)..' Metacritic]') or '')..
			'|'..((propiedad('P3302', soloUno) and '[https://www.omdb.org/movie/'..propiedad('P3302', soloUno)..' omdb]') or '')..
			'|'..((propiedad('P1258', soloUno) and '[https://www.rottentomatoes.com/'..propiedad('P1258', soloUno)..' Rotten Tomatoes]') or '')..
			'|'..((propiedad('P1265', soloUno) and '[http://www.sensacine.com/film/fichefilm_gen_cfilm='..propiedad('P1265', soloUno)..'.html SensaCine]') or '')..
			'|'..((propiedad('P2631', soloUno) and '[http://tcmdb.com/title/title.jsp?stid='..propiedad('P2631', soloUno)..' TCM]') or '')..
			'|'..((propiedad('P2638', soloUno) and '[http://www.tv.com/'..propiedad('P2638', soloUno)..' TV.com]') or '')..'}}</small>')
	else
		imdbId = propiedad('P345', soloUno)
		filmaffinityId = propiedad('P480', soloUno)
	end
	
	local enlaceImdb = imdbId and '[https://www.imdb.com/title/'..imdbId..'/ Ficha] en [[Internet Movie Database|IMDb]]'
	local enlaceFilmaffinity = filmaffinityId and '[https://www.filmaffinity.com/es/film'..filmaffinityId..'.html Ficha] en [[FilmAffinity]]'
	local identificadoresExternos
	
	if imdbId and filmaffinityId then
		identificadoresExternos = enlaceImdb..'<br />'..enlaceFilmaffinity
	elseif imdbId or filmaffinityId then 
		identificadoresExternos = enlaceImdb or enlaceFilmaffinity
	end
	
	local sucesion1, 
			sucesion2, 
			sucesionWikidata, 
			sucesionOscarMejorPelicula, 
			sucesionOscarMejorPeliculaAnimacion
	
	if argumento['criterio_sucesión'] or argumento['precedida_por'] or 
		argumento['sucedida_por'] then
		
		sucesion1 = {
			['tipo']			= 'sección',
			['título']			= argumento['criterio_sucesión'] or 'Sucesión de películas',
			['estilotitulo']	= estiloseccion,
			{
				['tipo']			= 'sucesión',
				['estilo fuente']	= 'italic',
				['anterior']		= argumento['precedida_por'],
				['actual']			= tituloOriginal,
				['siguiente']		= argumento['sucedida_por']
			}
		}
	end

	if argumento['criterio_sucesión2'] or argumento['precedida_por2'] or 
		argumento['sucedida_por2'] then
		
		sucesion2 = {
			['tipo']			= 'sección',
			['título']			= argumento['criterio_sucesión2'] or 'Sucesión de películas',
			['estilotitulo']	= estiloseccion,
			{
				['tipo']			= 'sucesión',
				['estilo fuente']	= 'italic',
				['anterior']		= argumento['precedida_por2'],
				['actual']			= tituloOriginal,
				['siguiente']		= argumento['sucedida_por2']
			}
		}
	end

	if argumento['oscar_anterior'] or argumento['oscar_siguiente'] then
		
		sucesionOscarMejorPelicula = {
			['tipo']			= 'sección',
			['título']			= '[[Anexo:Óscar a la mejor película|Óscar a la mejor película]]',
			['estilotitulo']	= estiloseccion,
			{
				['tipo']			= 'sucesión',
				['estilo fuente']	= 'italic',
				['anterior']		= argumento['oscar_anterior'],
				['actual']			= tituloOriginal,
				['siguiente']		= argumento['oscar_siguiente']
			}
		}
	end
	
	if argumento['oscar_animación_anterior'] or argumento['oscar_animación_siguiente'] then
		
		sucesionOscarMejorPeliculaAnimacion = {
			['tipo']			= 'sección',
			['título']			= '[[Anexo:Óscar a la mejor película de animación|Óscar a la mejor película de animación]]',
			['estilotitulo']	= estiloseccion,
			{
				['tipo']			= 'sucesión',
				['estilo fuente']	= 'italic',
				['anterior']		= argumento['oscar_animación_anterior'],
				['actual']			= tituloOriginal,
				['siguiente']		= argumento['oscar_animación_siguiente']
			}
		}
	end
	
	local Ficha = {
		entidad		= argumento['entidad'],
		clase		= 'plainlist plainlinks',

		-- Título
		tipocabecera		= 'cine',
		estilotitulo		= estilotitulo,
		titulo				= tituloOriginal,
		subtitulo1			= (esSerieCinematografica and 'Serie cinematográfica') or 
								(esCortometraje and 'Cortometraje') or '',
		
		--Imagen
		--De momento no se pone una raya como en la ficha de escritor tras la imagen
		imagen			= imagen,
		['tamañoimagen']= argumento['tamaño de imagen'] or argumento['tamaño'] or 
							argumento['tamaño imagen'] or argumento['tamañoimagen'] or argumento['tamañodelaimagen'] or
							argumento['tamaño de foto'] or 
							'220px', -- or '200px' en la ficha de escritor, 192 en la ficha de artista. Tomo por defecto 220, el tamaño de thumb
		pie				= pieDeImagen,
		
		{ tipo = 'sección',
			{ 'Título', tituloTraducido }
		},
	
		{ tipo = 'sección',
			['título'] = 'Títulos en español',
			estilotitulo = estiloseccion,
			{ 'Argentina', tituloAR, estilodatos='font-style:italic' },
			{ 'España', tituloES, estilodatos='font-style:italic' },
			{ 'Hispanoamérica', tituloHA, estilodatos='font-style:italic' }
		},
		
		{ tipo = 'sección',
			['título'] = 'Ficha técnica',
			estilotitulo = estiloseccion,
			{ '[[Director de cine|Dirección]]', directores },
			{ '[[Director de cine|Ayudante de dirección]]', argumento['ayudantedirección'] },
			{ 'Dirección artística', argumento['dirección artística'] },
			{ '[[Productor de cine|Producción]]', argumento['producción'] or propiedad('P162', listaNoOrdenada) },
			{ 'Diseño de producción', argumento['diseño producción'] },
			{ '[[Guionista|Guion]]', argumento['guión'] or argumento['guion'] or propiedad('P58', listaNoOrdenada) },
			{ 'Historia', argumento['historia'] },
			{ 'Basada en', argumento['basada en'] or propiedad('P144', obraAutor) },
			{ '[[Banda sonora|Música]]', argumento['música'] or propiedad('P86', listaNoOrdenada) },
			{ '[[Sonido]]', argumento['sonido'] },
			{ '[[Maquillaje]]', argumento['maquillaje'] },
			{ '[[Director de fotografía|Fotografía]]', argumento['fotografía'] or argumento['fotografia'] or propiedad('P344', listaNoOrdenada) },
			{ '[[Montaje]]', argumento['montaje'] or argumento['edición'] or argumento['edicion'] or propiedad('P1040', listaNoOrdenada) },
			{ '[[Escenografía]]', argumento['escenografía'] },
			{ '[[Vestuario]]', argumento['vestuario'] or propiedad('P2515', listaNoOrdenada) },
			{ '[[Efectos especiales]]', argumento['efectos'] },
			{ '[[Narrador]]', argumento['narrador'] or propiedad('P2438', listaNoOrdenada) },
			{ '[[Animador]]', argumento['animador'] },
			{ '[[Guion gráfico]]', argumento['storyboard'] or propiedad('P3275', listaNoOrdenada) },
			{ '[[Color]]', argumento['color'] },
			{ '[[Pintura]]', argumento['pintura'] },
			{ '[[Actuación|Protagonistas]]', protagonistas },
			{ '[[Actor de voz|Actores de voz]]', actoresDeVoz },
			{ '', imdbId and '[https://www.imdb.com/title/'..imdbId..'/fullcredits Ver todos los créditos] <span style="font-size:85%">([[Internet Movie Database|IMDb]])</span>' },
		},
		
		{tipo='sección',
			['título'] = 'Datos y cifras',
			estilotitulo = estiloseccion,
			{ '[[País]]', concatenarLista(argumento, {'país', 'país2', 'país3', 'país4', 'país5', 'país6'}, '<br />') or propiedad('P495', listaNoOrdenada)},
			{ '[[Año]]', argumento['año'] or argumento['estreno'] or propiedad('P577', estreno) or propiedad('P571', estreno)},
			{ 'Estreno', argumento['estreno1'] },
			{ '[[Género cinematográfico|Género]]', argumento['género'] or propiedad('P136', generoCinematografico) },
			{ 'Duración', argumento['duración'] or propiedad('P2047', formatoDuracion) },
			{ '[[Clasificación por edades (cine)|Clasificación]]', argumento['clasificación'] },
			{ '[[Idioma]](s)', concatenarLista(argumento, {'idioma', 'idioma2', 'idioma3', 'idioma4'}, '<br />') or propiedad('P364', listaNoOrdenada) },
			{ '[[Formato (arte)|Formato]]', argumento['formato'] or propiedad('P3803', rangoMayor) }
		},
		
		{tipo='sección',
			['título'] = 'Compañías',
			estilotitulo = estiloseccion,
			{ 'Productora', argumento['productora'] or propiedad('P272', listaNoOrdenada) },
			{ 'Distribución', argumento['distribución'] or argumento['distribucion'] or propiedad('P750', listaNoOrdenada) },
			{ 'Estudio', argumento['estudio'] },
			{ 'Presupuesto', argumento['presupuesto'] or propiedad('P2769', rangoMayor) },
			{ 'Recaudación', argumento['recaudación'] or argumento['recaudacion'] or propiedad('P2142', rangoMayor) }
		},
	
		{tipo='sección',
			['título'] = 'Películas que forman la serie',
			estilotitulo = estiloseccion,
			{'', serieCinematografica }
		},
	
		{tipo='sección',
			['título'] = 'Enlaces externos',
			estilotitulo = estiloseccion,
			{'', seccionEnlacesExternos }
		},
		
		sucesion1,
		sucesion2,
		sucesionWikidata,
		sucesionOscarMejorPelicula,
		sucesionOscarMejorPeliculaAnimacion,
		
		
		['estilopiedetabla'] = estiloseccion,
		['piedetabla'] = identificadoresExternos
	}
	-- Si no hay que categorizar automáticamente terminar aquí e ignorar la
	-- generación de categorías
	namespace = mw.title.getCurrentTitle().namespace
	if argumento['categorías'] == 'no' or not (namespace == 0 or namespace == 104) then
		return ModuloFicha.infobox(Ficha)
	end
	
	-- A partir de aquí se generan y definen las distintas categorías
	-- automáticas
	ModuloCategorizar.setFrame(frame)
	categorias = ''
	
	-- Convertir géneros e idiomas locales a minúsculas para la categorización
	if argumento['género'] then argumento['género'] = mw.ustring.lower(argumento['género']) end
	if argumento['idioma'] then argumento['idioma'] = mw.ustring.lower(argumento['idioma']) end
	if argumento['idioma2'] then argumento['idioma2'] = mw.ustring.lower(argumento['idioma2']) end
	if argumento['idioma3'] then argumento['idioma3'] = mw.ustring.lower(argumento['idioma3']) end
	if argumento['idioma4'] then argumento['idioma4'] = mw.ustring.lower(argumento['idioma4']) end
	
	-- Arreglar parámetros que la gente acostumbra a introducir mal en la plantilla para que no rompan la categorización
	if argumento['idioma'] then argumento['idioma'] = string.gsub(argumento['idioma'], '<br>', '<br />') end
	if argumento['idioma'] then argumento['idioma'] = string.gsub(argumento['idioma'], '<br/>', '<br />') end
	if argumento['idioma'] then argumento['idioma'] = string.gsub(argumento['idioma'], ',%s', '<br />') end
	if argumento['idioma'] then argumento['idioma'] = string.gsub(argumento['idioma'], '%s/%s', '<br />') end
	if argumento['idioma'] then argumento['idioma'] = string.gsub(argumento['idioma'], '%se%s', '<br />') end
	if argumento['idioma'] then argumento['idioma'] = string.gsub(argumento['idioma'], '%sy%s', '<br />') end
	if argumento['género'] then argumento['género'] = string.gsub(argumento['género'], 'drama %(cine y televisión%)', 'drama') end
	if argumento['género'] then argumento['género'] = string.gsub(argumento['género'], '<br>', '<br />') end
	if argumento['género'] then argumento['género'] = string.gsub(argumento['género'], '<br/>', '<br />') end
	if argumento['género'] then argumento['género'] = string.gsub(argumento['género'], ',%s', '<br />') end
	if argumento['género'] then argumento['género'] = string.gsub(argumento['género'], '%s/%s', '<br />') end
	if argumento['género'] then argumento['género'] = string.gsub(argumento['género'], '%sy%s', '<br />') end
	if argumento['género'] then argumento['género'] = string.gsub(argumento['género'], '%se%s', '<br />') end
	
	if argumento['género'] then argumento['género'] = string.gsub(argumento['género'], '%[%[[^%|%]]*|drama histórico%]%]', 'drama<br />histórico') end
	if argumento['género'] then argumento['género'] = string.gsub(argumento['género'], 'drama histórico', 'drama<br />histórico') end
	if argumento['género'] then argumento['género'] = string.gsub(argumento['género'], '%[%[[^%|%]]*|drama romántico%]%]', 'drama<br />romance') end
	if argumento['género'] then argumento['género'] = string.gsub(argumento['género'], '%[%[[^%|%]]*|drama%]%] %[%[[^%|%]]*|romántico%]%]', 'drama<br />romance') end
	if argumento['género'] then argumento['género'] = string.gsub(argumento['género'], 'drama romántico', 'drama<br />romance') end
	if argumento['género'] then argumento['género'] = string.gsub(argumento['género'], '%[%[comedia%]%] %[%[musical%]%]', 'comedia<br />musical') end
	if argumento['género'] then argumento['género'] = string.gsub(argumento['género'], 'comedia musical', 'comedia<br />musical') end
	
	function listaidiomas(str)
		-- Minúscula inicial para cada elemento de la lista de idiomas, no solo el primero
		local tab = mw.text.split(str, '<br />', true)
		for k,v in pairs(tab) do
			tab[k] = mw.getContentLanguage():lcfirst(v)
		end
		return mw.text.listToText(tab, '<br />', '<br />')
	end
	-- Categorización por idioma
	if not esPeliculaMuda then
		categorias = categorias .. categoriza('Películas en $1', '<br />', {[1] = concatenarLista(argumento, {'idioma', 'idioma2', 'idioma3', 'idioma4'}, '<br />') or listaidiomas(propiedad('P364', formatoCategorizar) or '' )}, {['arreglar'] = 'nombre idioma', ['filtrar'] = false })
	end
	
	-- Categorización por país
	if esCortometraje then
		categorias = categorias .. categoriza('Cortometrajes de $1', '<br />', {[1] = concatenarLista(argumento, {'país', 'país2', 'país3', 'país4', 'país5', 'país6'}, '<br />') or propiedad('P495', formatoCategorizar)}, {['arreglar'] = 'nombre país', ['filtrar'] = false })
	elseif esPeliculaMuda and esPeliculaEnBlancoYNegro then
		categorias = categorias .. categoriza('Películas mudas de $1', '<br />', {[1] = concatenarLista(argumento, {'país', 'país2', 'país3', 'país4', 'país5', 'país6'}, '<br />') or propiedad('P495', formatoCategorizar)}, {['arreglar'] = 'nombre país', ['filtrar'] = false })
		categorias = categorias .. categoriza('Películas en blanco y negro de $1', '<br />', {[1] = concatenarLista(argumento, {'país', 'país2', 'país3', 'país4', 'país5', 'país6'}, '<br />') or propiedad('P495', formatoCategorizar)}, {['arreglar'] = 'nombre país', ['filtrar'] = false })
	elseif esPeliculaMuda then
		categorias = categorias .. categoriza('Películas mudas de $1', '<br />', {[1] = concatenarLista(argumento, {'país', 'país2', 'país3', 'país4', 'país5', 'país6'}, '<br />') or propiedad('P495', formatoCategorizar)}, {['arreglar'] = 'nombre país', ['filtrar'] = false })
	elseif esPeliculaEnBlancoYNegro then
		categorias = categorias .. categoriza('Películas en blanco y negro de $1', '<br />', {[1] = concatenarLista(argumento, {'país', 'país2', 'país3', 'país4', 'país5', 'país6'}, '<br />') or propiedad('P495', formatoCategorizar)}, {['arreglar'] = 'nombre país', ['filtrar'] = false })
	else
		categorias = categorias .. categoriza('Películas de $1', '<br />', {[1] = concatenarLista(argumento, {'país', 'país2', 'país3', 'país4', 'país5', 'país6'}, '<br />') or propiedad('P495', formatoCategorizar)}, {['arreglar'] = 'nombre país', ['filtrar'] = false })
	end
	
	-- Categorización por año
	if esCortometraje then
		categorias = categorias .. categoriza('Cortometrajes de $1', '<br />', {[1] = argumento['año'] or argumento['estreno'] or propiedad('P577', {['rangoMayor'] = 'sí', ['formatoFecha'] = 'año', ['enlace'] = 'no', ['uno'] = 'sí'}) or propiedad('P571', {['rangoMayor'] = 'sí', ['formatoFecha'] = 'año', ['enlace'] = 'no', ['uno'] = 'sí'})}, {['filtrar'] = true})
	else
		categorias = categorias .. categoriza('Películas de $1', '<br />', {[1] = argumento['año'] or argumento['estreno'] or propiedad('P577', {['rangoMayor'] = 'sí', ['formatoFecha'] = 'año', ['enlace'] = 'no', ['uno'] = 'sí'}) or propiedad('P571', {['rangoMayor'] = 'sí', ['formatoFecha'] = 'año', ['enlace'] = 'no', ['uno'] = 'sí'})}, {['filtrar'] = true})
	end
	
	categorias = categorias .. categoriza('Películas de $1', '<br />', {[1] = argumento['productora'] or propiedad('P272', formatoCategorizar)}, {['filtrar'] = true, ['arreglar'] = 'nombre productora'})
	categorias = categorias .. categoriza('Películas de $1', '<br />', {[1] = argumento['género'] or propiedad('P136', formatoCategorizar)}, {['arreglar'] = 'géneros película', ['filtrar'] = true})
	categorias = categorias .. categoriza('Películas dirigidas por $1', '<br />', {[1] = concatenarLista(argumento, {'dirección', 'dirección2', 'dirección3', 'dirección4', 'dirección5', 'dirección6', 'dirección7', 'dirección8', 'dirección9'}, '<br />') or propiedad('P57', formatoCategorizar)}, {['filtrar'] = true})
	
	if argumento['oscar_anterior'] or argumento['oscar_siguiente'] then
		categorias = categorias .. '[[Categoría:Películas ganadoras del premio Óscar a la mejor película]]'
	end
	
	if argumento['oscar_animación_anterior'] or argumento['oscar_animación_siguiente'] then
		categorias = categorias .. '[[Categoría:Películas ganadoras del premio Óscar a la mejor película de animación]]'
	end
	
	-- Añadir '0' delante del parámetro imdb en caso de que exista hasta que 
	-- tenga al menos 7 caracteres para asegurarse que cumpla con el formato
	-- establecido en Wikidata
	if argumento['imdb'] then
		while #argumento['imdb'] < 7 do
			argumento['imdb'] = '0'..argumento['imdb']
		end
	end

	if (argumento['imdb'] and 'tt'..argumento['imdb'] ~= imdbId) or (argumento['filmaffinity'] and argumento['filmaffinity'] ~= filmaffinityId) then
		categorias = categorias .. '[[Categoría:Wikipedia:Artículos con identificadores diferentes en Wikidata]]'
	end

	if (not argumento['dirección'] and not propiedad('P57')) or
		(not argumento['país'] and not propiedad('P495')) or
		(not esSerieCinematografica and not argumento['año'] and not argumento['estreno'] and not propiedad('P577') and not propiedad('P571')) or
		(not argumento['género'] and not propiedad('P136')) or
		(not esPeliculaMuda and not argumento['idioma'] and not propiedad('P364')) then
			categorias = categorias .. '[[Categoría:Wikipedia:Películas con ficha incompleta]]'
	end
	
	if esSerieCinematografica then
		categorias = categorias .. '[[Categoría:Series de películas]]'
	end
	
	if tieneValorPropiedad(Entidad, 'P136', 'Q52207399') then
		categorias = categorias .. '[[Categoría:Películas basadas en novelas]]'
	elseif tieneValorPropiedad(Entidad, 'P136', 'Q52207310') then
		categorias = categorias .. '[[Categoría:Películas basadas en libros]]'
	end
	
	return ModuloFicha.infobox(Ficha) .. categorias
end

-- Función que devuelve una lista de parámetros concatenados por un separador
function concatenarLista(arg, params, separador)
	local ret
	for key,param in pairs(params) do
		if ret and arg[param] then 
			ret = ret .. separador .. arg[param]
		elseif arg[param] then
			ret = arg[param]
		end
	end

	return ret
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 and Entidad.claims[idPropiedad] then
		if not opciones then
			opciones = {['linkback']='sí'}
		end
		
		opciones.entityId = Entidad.id
		--if idPropiedad =='P1477' then return require('Módulo:Tablas').tostring(Entidad) end -- FALTA
		opciones.propiedad = idPropiedad

		valorPropiedad = getPropiedadWikidata(opciones,Entidad.claims[idPropiedad])
		
		if not valorPropiedad then
			return
		end

		if valorPropiedad:match('%[%[:d:') then
		  algunaPropiedadEnlazaWikidata = true
		end
		
	   	return valorPropiedad
	end
	
	-- Si la entidad correspondiente no tiene esa propiedad y se trata de una serie
	-- cinematográfica buscar en los elementos que forman parte de la serie
	-- TODO: Hacer que combine los valores iguales especificando a qué películas pertenece
	if esSerieCinematografica and false then

		local propiedadesCombinadas = {}
		for k,v in pairs(Entidades) do
			if v and v.claims and v.claims[idPropiedad] then
				for kp,vp in pairs(v.claims[idPropiedad]) do
					table.insert(propiedadesCombinadas, vp)
				end
			end
		end
	
		if not opciones then
			opciones = {['linkback']='sí'}
		end
		
		--opciones.entityId = Entidad.id
		--if idPropiedad =='P1477' then return require('Módulo:Tablas').tostring(Entidad) end -- FALTA
		opciones.propiedad = idPropiedad
	
		valorPropiedad = getPropiedadWikidata(opciones,propiedadesCombinadas)
		
		if not valorPropiedad then
			return
		end

		if valorPropiedad:match('%[%[:d:') then
		  algunaPropiedadEnlazaWikidata = true
		end
		
	   	return valorPropiedad
	end
end

function obtenerEtiquetaWikidata()
	if Entidad and Entidad.labels and Entidad.labels.es then
		return Entidad.labels.es.value
	end
end

function obtenerValorCalificativo(Propiedad, Calificativo, ValorPropiedad)
	-- Obtener el valor del primer calificativo de la propiedad con el valor recibido 
	if not Entidad or not Entidad.claims or not Entidad.claims[Propiedad] then
		return
	end
	
	for k,v in pairs(Entidad.claims[Propiedad]) do
		if	 v.mainsnak
		   and v.mainsnak.datavalue
		   and v.mainsnak.datavalue.value
		   and v.mainsnak.datavalue.value['id'] == ValorPropiedad
		   and v.qualifiers
		   and v.qualifiers[Calificativo]
		   and v.qualifiers[Calificativo][1]
		   and v.qualifiers[Calificativo][1].datavalue then 
			return v.qualifiers[Calificativo][1].datavalue.value
		end
	end		
end

function obtenerArgumentosConValor(frame)
	local original
	
	if frame == mw.getCurrentFrame() then
		original = frame:getParent().args
	else
		original = frame.args or frame
	end
	
	local copia= {}
	
	for k,v in pairs(original) do
		if v == 'no' then
			--Si vale "no" dejar en blanco el argumento para no obtener el valor
			--de Wikidata
			copia[k] = ''
		elseif v~='' then
			--Si está en blanco dejarlo a nil para obtener en su caso el valor de 
			-- Wikidata si no hay otro argumento con un nombre similar
			copia[k] = original[k]
		end
	end	
	
	return copia
end


function obtenerImagenWikidata()
	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','P18',1)
		or elementoTabla(Entidad, 'claims','P154',1)
	
	if not imagen then
		return
	end
	
	-- Obtener el nombre de la imagen
	valorImagen =  elementoTabla(imagen, 'mainsnak','datavalue','value') -- Por ejemplo, imagen.jpg
	
	-- Obtener los pies de la imagen, uno por idioma
	piesDeImagen =  elementoTabla(imagen, 'qualifiers','P2096')
	
	-- Encontrar el pie en español (aquel con datavalue.value.language = "es")
	if piesDeImagen then
		for k,pieDeImagen in pairs(piesDeImagen) do
			if pieDeImagen.datavalue.value.language=='es' then
				-- devolver la imagen y el texto del pie de la imagen en español
				return valorImagen, pieDeImagen.datavalue.value.text
			end
		end
	end
	
	-- Sin pie de imagen en español
	return valorImagen
end

function especificaNoTenerDialogo(entidad)
	
	if entidad and entidad.claims and entidad.claims['P364'] then
		
		local mainsnak
		
		for key,value in ipairs(entidad.claims['P364']) do
			if value and value.mainsnak then
				mainsnak = value.mainsnak
				if mainsnak.datatype == 'wikibase-item' and
						mainsnak.snaktype == 'novalue' and
						value.qualifiers then
					for qKey,qValue in ipairs(value.qualifiers['P518']) do
						if qValue.datatype == 'wikibase-item' and
								qValue.snaktype == 'value' and
								qValue.datavalue.value.id == 'Q131395' then
							return true
						end
					end
				end
			end
		end
	end
	
	return false
end

return z