Vés al contingut

Mòdul:Episode table

De Viki.cat

Ús

Creates one of three usages related to {{Episode table}} with the parameters defined in the documentation of the template:

A standard episode table with

A row for a parted season with

A white background for references used in the header row of episode tables with

Categories de seguiment

{{#lst:Plantilla:Episode table/ús|Tracking}}



-- This module implements {{Episode table}} and {{Episode table/part}}.

local HTMLcolor = mw.loadData( 'Module:Color contrast/colors' )

--------------------------------------------------------------------------------
-- EpisodeTable class
-- The main class.
--------------------------------------------------------------------------------

local contrast_ratio = require('Module:Color contrast')._ratio
local EpisodeTable = {}


--Traduccions català (codi copiat de la viquipèdia en hongarès, magyar)
local parameterAliases = {
	caption    = {'caption', 'encapçalament','Encapçalament'},
    background = {'background', 'colorfons','ColorFons',},
	overall    = {'overall', 'número total','Número Total','númerototal','NúmeroTotal','EpisodiNúmero','Episodi Número','episodinúmero','episodi número'},
	overallR    = {'overallR', 'número totalR','Número TotalR','númerototalR','NúmeroTotalR','EpisodiNúmeroR','Episodi NúmeroR','episodinúmeroR','episodi númeroR'},
	overallT    = {'overallT', 'número totalT','Número TotalT','númerototalT','NúmeroTotalT','EpisodiNúmeroT','Episodi NúmeroT','episodinúmeroT','episodi númeroT'},
    season = {'season', 'temporada','Temporada','EpisodiNúmero2','Episodi Número 2','episodinúmero2','episodi número 2'},
    seasonR = {'seasonR', 'temporadaR','TemporadaR','EpisodiNúmero2R','Episodi Número 2R','episodinúmero2R','episodi número 2R'},
    seasonT = {'seasonT', 'temporadaT','TemporadaT','EpisodiNúmero2T','Episodi Número 2T','episodinúmero2T','episodi número 2T'},
    series  = {'series', 'sèrie','Sèrie'},
    seriesR = {'seriesR', 'sèrieR','SèrieR'},
    seriesT = {'seriesT', 'sèrieT','SèrieT'},
    title = {'title', 'títol','Títol'},
    titleR = {'titleR', 'títolR','TítolR'},
    titleT = {'titleT', 'títolT','TítolT'},
    director = {'director', 'direcció','Direcció','Dirigitper'},
    directorR = {'directorR', 'direccióR','DireccióR'},
    directorT = {'directorT', 'direccióT','DireccióT'},
    writer = {'writer', 'guió','Guió'},
    writerR = {'writerR', 'guióR','GuióR'},
    writerT = {'writerT', 'guióT','GuióT'},
    airdate = {'airdate', 'data','Data'},
    airdateR = {'airdateR', 'dataR','DataR'},
    airdateT = {'airdateT', 'dataT','DataT'},
    altdate = {'alt date', 'data alt','Data Alt'},
    altdateR = {'alt dateR', 'data altR','Data AltR'},
    altdateT = {'alt dateT', 'data altT','Data AltT','DataAltT','dataaltT'},
    prodcode = {'prodcode', 'codiprod','CodiProd'},
    prodcodeR = {'prodcodeR', 'codiprodR','CodiProdR'},
    prodcodeT = {'prodcodeT', 'codiprodT','CodiProdT'},
    viewers = {'viewers', 'espectadors','Espectadors'},
    viewersR = {'viewersR', 'espectadorsR','EspectadorsR'},
    viewersT = {'viewersT', 'espectadorsT','EspectadorsT'},
    guests = {'musical guests','convidats','Convidats'},
    guestsR = {'musical guestsR','convidatsR','ConvidatsR'},
    guestsT = {'musical guestsT','convidatsT','ConvidatsT'},
    musicalguests = {'musical guests','convidats musicals','Convidats Musicals'},
    musicalguestsR = {'musical guestsR','convidats musicalsR','Convidats MusicalsR','convidatsmusicalsR','ConvidatsMusicalsR'},
    musicalguestsT = {'musical guestsT','convidats musicalsT','Convidats MusicalsT','convidatsmusicalsT','ConvidatsMusicalsT'},
    country = {'country', 'país','País'},
    episodes = {'episodes', 'episodis','Episodis'},
    act = {'act', 'acte','Acte'},
    chapter = {'chapter', 'capítol','Capítol'},
    volume = {'volume', 'volum','Volum'},
    week = {'week', 'setmana','Setmana'},
    subtitle = {'subtitle', 'subtítol','Subtítol'},
}


function EpisodeTable.cell(background, width, text, reference, textColor)
	local cell = mw.html.create('th')
	
	-- Width
	local cell_width
	if width == 'auto' then
		cell_width = 'auto'
	elseif tonumber(width) ~= nil then
		cell_width = width .. '%'
	else
		cell_width = nil
	end
	
	-- Cell
	cell:attr('scope','col')
		:css('background',background or '#CCCCFF')
		:css('width',cell_width)
		:css('color',textColor)
		:wikitext(text)
	
	-- Reference
	if reference and reference ~= '' then
		cell:wikitext(" " .. EpisodeTable.reference(reference, background))
	end
	
	return cell
end

function EpisodeTable.reference(reference, background)
	local link1_cr = contrast_ratio{'#0645AD', background or '#CCCCFF', ['error'] = 0}
	local link2_cr = contrast_ratio{'#0B0080', background or '#CCCCFF', ['error'] = 0}
	
	local refspan = mw.html.create('span')
		:wikitext(reference)
	
	if link1_cr < 7 or link2_cr < 7 then
		refspan
			:css('color','black')
			:css('background-color','white')
			:css('padding','1px')
			:css('display','inline-block')
			:css('line-height','50%')
	end
	
	return tostring(refspan)
end

function EpisodeTable.abbr(text,title)
	local abbr = mw.html.create('abbr')
		:attr('title',title)
		:wikitext(text)
	return tostring(abbr)
end

function EpisodeTable.part(_,args)
	local row = mw.html.create('tr')
	
	if (args.c == nil or args.c == '') then args.c = '#CCCCFF' end
	
	-- Add # to color if necessary
	if args.c ~= nil and HTMLcolor[args.c] == nil then
		args.c = '#'..(mw.ustring.match(args.c, '^[%s#]*([a-fA-F0-9]*)[%s]*$') or '')
	end
	
	local black_cr = contrast_ratio{args.c or '#CCCCFF', 'black', ['error'] = 0}
	local white_cr = contrast_ratio{'white', args.c or '#CCCCFF', ['error'] = 0}
	
	local partTypes = {
		{'act','Act'},
		{'chapter','Chapter'},
		{'part','Part'},
		{'volume','Volume'},
		{'week','Week'},
	}
	
	local displaytext = ''
	local isAnyPartSet = false
	
	for k,v in pairs(partTypes) do
		if args[v[1]] then
			isAnyPartSet = true
			displaytext = v[2] .. ' ' .. args[v[1]]
		end
	end
	if args.subtitle then
		displaytext = displaytext .. ((isAnyPartSet and ': ' or '') .. args.subtitle)
	end

	local plainText = require('Module:Plain text')._main
	local displayTextAnchor = plainText(displaytext)
	
	row:tag('td')
		:attr('colspan', 13)
		:attr('id', args.id or displayTextAnchor)
		:css('text-align', 'center')
		:css('background-color', args.c or '#CCCCFF')
		:css('color', black_cr > white_cr and 'black' or 'white')
		:wikitext((args.nobold and displaytext or "'''" .. displaytext .. "'''") .. (args.r and "&#8202;" .. EpisodeTable.reference(args.r, args.c) or ''))
	
	return tostring(row)
end

--El local function applyParameterAliases(args) no s'ha d'eliminar, és perquè els paràmetres es puguin posar en català

local function applyParameterAliases(args)
    for internal, aliases in pairs(parameterAliases) do
        for _, alias in ipairs(aliases) do
            if args[alias] ~= nil then
                if args[internal] ~= nil and args[internal] ~= args[alias] then
                    error('Parameter conflict: "' .. alias .. '" and "' .. internal .. '" cannot be used together.')
                end
                args[internal] = args[alias]
            end
        end
    end
end


function EpisodeTable.new(frame,args)
	args = args or {}
	local categories = ''
	local background = (args.background and args.background ~= '' and args.background ~= '#') and args.background or nil
	
	-- Add # to background if necessary
	if background ~= nil and HTMLcolor[background] == nil then
		background = '#'..(mw.ustring.match(background, '^[%s#]*([a-fA-F0-9]*)[%s]*$') or '')
	end
	
	-- Default widths noted by local consensus
	local defaultwidths = {};
	defaultwidths.overall = 5;
	defaultwidths.overall2 = 5;
	defaultwidths.season = 5;
	defaultwidths.series = 5;
	defaultwidths.prodcode = 7;
	defaultwidths.viewers = 10;
	
	-- Create episode table
	local root = mw.html.create('table')
	
	-- Table width
	local table_width = string.gsub(args.total_width or '','%%','')
	if args.total_width == 'auto' or args.total_width == '' then
		table_width = 'auto'
	elseif tonumber(table_width) ~= nil then
		table_width = table_width .. '%'
	else
		table_width = '100%'
	end
	
	root
		:addClass('wikitable')
		:addClass('plainrowheaders')
		:addClass('wikiepisodetable')
		:css('width', table_width)
	
	-- Caption
	if args.show_caption then
		-- Visible caption option, with a tracking category
		root:tag('caption'):wikitext(args.caption)
		categories = categories .. '[[Categoria:Articles que fan servir la Plantilla:Episode table amb una descripció visible]]'
	elseif args.caption then
		-- If a visible caption isn't defined, then default to the screenreader-only caption
		root:tag('caption'):wikitext(frame:expandTemplate{title='Screen reader-only',args={args.caption}})
	end
	
	-- Colour contrast; add to category only if it's in the mainspace
	local title = mw.title.getCurrentTitle()
	local black_cr = contrast_ratio{background, 'black', ['error'] = 0}
	local white_cr = contrast_ratio{'white', background, ['error'] = 0}
	
	if title.namespace == 0 and (args.background and args.background ~= '' and args.background ~= '#') and black_cr < 7 and white_cr < 7 then
		categories = categories .. '[[Categoria:Articles que fan servir la Plantilla:Episode table amb una combinació de colors incorrecta]]' 
	end
	
	-- Main row
	local textColor = background and (black_cr > white_cr and 'black' or 'white') or 'black'
	local mainRow = root:tag('tr')
	mainRow
		:css('color', textColor)
		:css('text-align', 'center')
	
	-- Cel·les # El primer i el segon paràmetre no s'han de traduir aquí. El tercer paràmetre sí, perquè és la traducció que es veurà a la taula, no el que escrius tu al codi
	do
		local used_column = false
		local used_season = false
		local country = args.country ~= '' and args.country ~= nil
		local viewers = 'Espectadors' .. ' ' ..  (country and args.country or '') .. 
			((not args.viewers_type or args.viewers_type ~= '') and '<br />(' .. (args.viewers_type or 'milions') .. ')' or '')
		
		local cellNames = {
			{'overall','EpisodeNumber',EpisodeTable.abbr('Núm.','Número') ..
				((args.season or args.series or args.EpisodeNumber2 or args.EpisodeNumber2Series or args.forceoverall) and '<br />'..(args.overall_type or 'total') or '')},
			{'overall2','*',''},
			{'season','EpisodeNumber2',EpisodeTable.abbr('Núm.','Número') .. ' de la<br />'..(args.season_type or 'temporada')},
			{'series','EpisodeNumber2Series',EpisodeTable.abbr('Núm.','Número') .. ' en la<br />'..(args.series_type or 'sèrie')},
			{'title','Title','Títol'},
			{'aux1','Aux1',''},
			{'director','DirectedBy','Direcció'},
			{'writer','WrittenBy','Guió'},
			{'aux2','Aux2',''},
			{'aux3','Aux3',''},
			{'airdate','OriginalAirDate','Data d\'estrena original'},
			{'altdate','AltDate'},
			{'guests','Guests','Convidat(s)'},
			{'musicalguests','MusicalGuests'},
			{'prodcode','ProdCode','Codi de<br />' .. EpisodeTable.abbr('prod.','producció')},
			{'viewers','Viewers',viewers},
			{'aux4','Aux4',''}
		}
	
		for k,v in pairs(cellNames) do
			local thisCell = args[v[1]] or args[v[2]]
			if thisCell and (v[1] ~= 'series' or (v[1] == 'series' and used_season == false)) then
				used_column = true
				if v[1] == 'season' then used_season = true end
				if (k <= 3 and thisCell == '') then thisCell = '5' end
				if (thisCell == '' and defaultwidths[v[1]]) then thisCell = defaultwidths[v[1]] end
				
								if v[1] == 'title' then
	
		
					local thisCellT = args[v[1] .. 'T'] or args[v[2] .. 'T']
		
					local thisCellR = args[v[1] .. 'R'] or args[v[2] .. 'R']
		
					thisCellT = (thisCellT or v[3]) .. (thisCellR and ("&#8202;" .. EpisodeTable.reference(thisCellR, background)) or '')
	
					
	
					local altTitle = {"alttitle", "AltTitle"}
	
					if args[altTitle[1] .. 'T'] or args[altTitle[2] .. 'T'] then
	
						local altCellT = args[altTitle[1] .. 'T'] or args[altTitle[2] .. 'T']
	
						local altCellR = args[altTitle[1] .. 'R'] or args[altTitle[2] .. 'R']
	
						thisCellT = thisCellT .. "<br /> " .. altCellT .. (altCellR and ("&#8202;" .. EpisodeTable.reference(altCellR, background)) or '')
	
					end
	
					
	
					mainRow:node(EpisodeTable.cell(background, thisCell, thisCellT, false, textColor))
	
				else
	
					local thisCellT = args[v[1] .. 'T'] or args[v[2] .. 'T']
	
					local thisCellR = args[v[1] .. 'R'] or args[v[2] .. 'R']
	
					mainRow:node(EpisodeTable.cell(background, thisCell, thisCellT or v[3], thisCellR, textColor))
	
				end
			end
		end

		if title.namespace == 0 and used_column == false then
			categories = categories .. '[[Categoria:Articles que fan servir Plantilla:Episode table sense paràmetres de columna]]'
		end

	
		-- Episodes
		if args.episodes then
			if args.anchor then 
				args.episodes = string.gsub(args.episodes, "(id=\")(ep%w+\")", "%1" .. args.anchor .. "%2")
			end
			
			root:node(args.episodes)
		end
	end
	


    local templateStyles = mw.getCurrentFrame():extensionTag{
		name = 'templatestyles', args = { src = 'Module:Episode table/styles.css' }
	}
	return (((args.dontclose or '') ~= '') and mw.ustring.gsub(tostring(root), "</table>", "") or tostring(root)) .. categories .. templateStyles
end

--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------

local p = {}

function p.main(frame)
	local args = require('Module:Arguments').getArgs(frame, {
		removeBlanks = false,
		wrappers = 'Template:Episode table'
	})

	applyParameterAliases(args) --no s'ha d'eliminar, és perquè els paràmetres es puguin posar en català

	local check = require('Module:Check for unknown parameters')._check
	local tracking = ''
	local title = mw.title.getCurrentTitle()
	if title.namespace == 0 then
		tracking = check({
			['unknown']='[[Categoria:Pàgines que fan servir episode table amb paràmetres desconeguts|_VALUE_'..title.text..']]',
			['preview']='Pàgina que fa servir [[Plantilla:Episode table]] amb el paràmetre desconegut "_VALUE_"',
			['showblankpositional']='y',
			['regexp1']='[%w_]+NULL',
			-- Paràmetres originals en anglès
			'airdate', 'airdateR', 'airdateT', 'altdate', 'AltDate', 'altdateR', 'AltDateR',
			'altdateT', 'AltDateT', 'alttitleT', 'alttitleR', 'AltTitleT', 'AltTitleR',
			'anchor', 'aux1', 'Aux1', 'aux1R', 'Aux1R', 'aux1T',
			'Aux1T', 'aux2', 'Aux2', 'aux2R', 'Aux2R', 'aux2T', 'Aux2T', 'aux3', 'Aux3',
			'aux3R', 'Aux3R', 'aux3T', 'Aux3T', 'aux4', 'Aux4', 'aux4R', 'Aux4R', 'aux4T',
			'Aux4T', 'b', 'background', 'c', 'caption', 'country', 'DirectedBy', 'DirectedByR',
			'DirectedByT', 'director', 'directorR', 'directorT', 'dontclose', 'EpisodeNumber',
			'EpisodeNumber2', 'EpisodeNumber2R', 'EpisodeNumber2Series', 'EpisodeNumber2SeriesR',
			'EpisodeNumber2SeriesT', 'EpisodeNumber2T', 'EpisodeNumberR', 'EpisodeNumberT',
			'episodes', 'forceoverall', 'guests', 'Guests', 'guestsR', 'GuestsR', 'guestsT',
			'GuestsT', 'id', 'musicalguests', 'MusicalGuests', 'musicalguestsR', 'MusicalGuestsR',
			'musicalguestsT', 'MusicalGuestsT', 'OriginalAirDate', 'OriginalAirDateR',
			'OriginalAirDateT', 'overall', 'overall_type', 'overall2', 'overall2R',
			'overall2T', 'overallR', 'overallT', 'prodcode', 'ProdCode', 'prodcodeR',
			'ProdCodeR', 'prodcodeT', 'ProdCodeT', 'r', 'season', 'season_type', 'seasonR',
			'seasonT', 'series', 'series_type', 'seriesR', 'seriesT', 'show_caption',
			'subtitle', 'title', 'Title', 'titleR', 'TitleR', 'titleT', 'TitleT', 'total_width',
			'viewers', 'Viewers', 'viewers_type', 'viewersR', 'ViewersR', 'viewersT',
			'ViewersT', 'writer', 'writerR', 'writerT', 'WrittenBy', 'WrittenByR', 'WrittenByT',
			-- Alias en català (extrets de parameterAliases)
			'encapçalament', 'Encapçalament',
			'colorfons', 'ColorFons',
			'número total', 'Número Total', 'númerototal', 'NúmeroTotal',
			'EpisodiNúmero', 'Episodi Número', 'episodinúmero', 'episodi número',
			'número totalR', 'Número TotalR', 'númerototalR', 'NúmeroTotalR',
			'EpisodiNúmeroR', 'Episodi NúmeroR', 'episodinúmeroR', 'episodi númeroR',
			'número totalT', 'Número TotalT', 'númerototalT', 'NúmeroTotalT',
			'EpisodiNúmeroT', 'Episodi NúmeroT', 'episodinúmeroT', 'episodi númeroT',
			'temporada', 'Temporada', 'EpisodiNúmero2', 'Episodi Número 2',
			'episodinúmero2', 'episodi número 2',
			'temporadaR', 'TemporadaR', 'EpisodiNúmero2R', 'Episodi Número 2R',
			'episodinúmero2R', 'episodi número 2R',
			'temporadaT', 'TemporadaT', 'EpisodiNúmero2T', 'Episodi Número 2T',
			'episodinúmero2T', 'episodi número 2T',
			'sèrie', 'Sèrie',
			'sèrieR', 'SèrieR',
			'sèrieT', 'SèrieT',
			'títol', 'Títol',
			'títolR', 'TítolR',
			'títolT', 'TítolT',
			'direcció', 'Direcció', 'Dirigitper',
			'direccióR', 'DireccióR',
			'direccióT', 'DireccióT',
			'guió', 'Guió',
			'guióR', 'GuióR',
			'guióT', 'GuióT',
			'data', 'Data',
			'dataR', 'DataR',
			'dataT', 'DataT',
			'alt date', 'data alt', 'Data Alt',
			'alt dateR', 'data altR', 'Data AltR',
			'alt dateT', 'data altT', 'Data AltT', 'DataAltT', 'dataaltT',
			'codiprod', 'CodiProd',
			'codiprodR', 'CodiProdR',
			'codiprodT', 'CodiProdT',
			'espectadors', 'Espectadors',
			'espectadorsR', 'EspectadorsR',
			'espectadorsT', 'EspectadorsT',
			'convidats', 'Convidats',
			'convidatsR', 'ConvidatsR',
			'convidatsT', 'ConvidatsT',
			'convidats musicals', 'Convidats Musicals', 'convidatsmusicals',
			'convidats musicalsR', 'Convidats MusicalsR', 'convidatsmusicalsR', 'ConvidatsMusicalsR',
			'convidats musicalsT', 'Convidats MusicalsT', 'convidatsmusicalsT', 'ConvidatsMusicalsT',
			'país',  'País',
			'episodis', 'Episodis',
			'acte', 'Acte',
			'capítol', 'Capítol',
			'volum', 'Volum',
			'setmana', 'Setmana',
			'subtítol', 'Subtítol',
			'musical guests', 'musical guestsR', 'musical guestsT'
		}, args)
	end

return EpisodeTable.new(frame,args) .. tracking
end

function p.part(frame)
	local args = require('Module:Arguments').getArgs(frame, {
		removeBlanks = false,
		wrappers = 'Template:Episode table/part'
	})
	return EpisodeTable.part(frame,args)
end

function p.ref(frame)
	local args = require('Module:Arguments').getArgs(frame, {
		removeBlanks = false,
	})
	return EpisodeTable.reference(args.r,args.b)
end

return p