Difference between revisions of "Module:Sports results/sandbox"

From blackwiki
Jump to navigation Jump to search
blackwiki>Frietjes
blackwiki>Frietjes
Line 1: Line 1:
 
-- Module to build results cross-tables for standings in Sports
 
-- Module to build results cross-tables for standings in Sports
 
-- See documentation for details
 
-- See documentation for details
+
 
 
require('Module:No globals')
 
require('Module:No globals')
  
 
local p = {}
 
local p = {}
+
 
 
-- Main function
 
-- Main function
 
function p.main(frame)
 
function p.main(frame)
 +
-- Get the args, stripping out blank values
 +
local getArgs = require('Module:Arguments').getArgs
 +
local Args = getArgs(frame, {frameOnly=true})
 +
local Pargs = getArgs(frame, {parentOnly=true})
 +
 +
-- Exit early if we are using section transclusion for a different section
 +
if( Pargs['transcludesection'] and Args['section'] ) then
 +
if( Pargs['transcludesection'] ~= Args['section'] ) then
 +
return ''
 +
end
 +
end
 +
 
-- Declare locals
 
-- Declare locals
local Args = frame.args
 
local N_teams = 0
 
 
local t = {}
 
local t = {}
 
local t_footer = {}
 
local t_footer = {}
Line 22: Line 32:
 
local legs = tonumber(Args['legs']) or 1
 
local legs = tonumber(Args['legs']) or 1
 
-- Edit links if requested
 
-- Edit links if requested
local template_name = Args['template_name']  
+
local template_name = Args['template_name']
 
or (mw.title.getCurrentTitle().text ~= frame:getParent():getTitle() and (':' .. frame:getParent():getTitle()))
 
or (mw.title.getCurrentTitle().text ~= frame:getParent():getTitle() and (':' .. frame:getParent():getTitle()))
 
or ''
 
or ''
local edit_links = template_name == '' and ''  
+
local edit_links = template_name == '' and ''
or frame:expandTemplate{ title = 'navbar',  
+
or frame:expandTemplate{ title = 'navbar',
 
args = { mini=1, style='float:right', template_name} }
 
args = { mini=1, style='float:right', template_name} }
+
 +
-- Get the custom start point for the table (most will start by default at 1)
 +
local top_pos = tonumber(Pargs['highest_pos'] or Args['highest_pos']) or 1
 +
-- Get the custom end point for the table (unrestricted if bottom_pos is < top_pos)
 +
local bottom_pos = tonumber(Pargs['highest_pos'] or Args['highest_pos']) or 0
 +
local N_teams = top_pos - 1 -- Default to 0 at start, but higher number needed to skip certain entries
 +
 
 
-- Load some other modules
 
-- Load some other modules
 
local p_sub = require('Module:Sports table/sub')
 
local p_sub = require('Module:Sports table/sub')
+
 
 
-- Read in number of consecutive teams (ignore entries after skipping a spot)
 
-- Read in number of consecutive teams (ignore entries after skipping a spot)
ii_start = 0
+
ii_start = N_teams
while Args['team'..N_teams+1] ~= nil do
+
while Args['team'..N_teams+1] ~= nil and (bottom_pos < top_pos or N_teams < bottom_pos) do
 
N_teams = N_teams+1
 
N_teams = N_teams+1
 
-- Sneakily add it twice to the team_list parameter, once for the actual
 
-- Sneakily add it twice to the team_list parameter, once for the actual
Line 45: Line 61:
 
-- Get team to show
 
-- Get team to show
 
local ii_show = team_list[Args['showteam']] -- nil if non-existant
 
local ii_show = team_list[Args['showteam']] -- nil if non-existant
+
 
 
-- Set the font size
 
-- Set the font size
 
local font_size=Args['font_size'] or '100%'
 
local font_size=Args['font_size'] or '100%'
+
 
 
-- Create header
 
-- Create header
 
-- Open table
 
-- Open table
table.insert(t,'{|class="wikitable plainrowheaders" style="text-align:center;font-size:'..font_size..';"\n')  
+
table.insert(t,'{|class="wikitable plainrowheaders" style="text-align:center;font-size:'..font_size..';"\n')
 
-- Table title
 
-- Table title
 
if Args['title'] then
 
if Args['title'] then
Line 59: Line 75:
 
t_return.count = 0 -- Dummy parameter, using subfunction call seems best at this point because both module are intertwined
 
t_return.count = 0 -- Dummy parameter, using subfunction call seems best at this point because both module are intertwined
 
t_return.tab_text = t -- Actual text
 
t_return.tab_text = t -- Actual text
t_return = p_sub.colhead(t_return,'auto', edit_links .. ' ' .. team_header)
+
t_return = p_sub.colhead(t_return,'auto', edit_links .. ' ' .. team_header)
 
-- Other columns passed to subfunction
 
-- Other columns passed to subfunction
 
t_return = p.header(t_return,Args,p_sub,N_teams,team_list,legs)
 
t_return = p.header(t_return,Args,p_sub,N_teams,team_list,legs)
 
t = t_return.tab_text
 
t = t_return.tab_text
+
 
 
-- Random value used for uniqueness
 
-- Random value used for uniqueness
 
math.randomseed( os.clock() * 10^8 )
 
math.randomseed( os.clock() * 10^8 )
 
local rand_val = math.random()
 
local rand_val = math.random()
+
 
 
local note_string, note_id
 
local note_string, note_id
 
local note_id_list = {}
 
local note_id_list = {}
+
 
 
-- Now create individual rows
 
-- Now create individual rows
 
for ii=1,N_teams do
 
for ii=1,N_teams do
Line 76: Line 92:
 
team_code_ii = team_list[ii]
 
team_code_ii = team_list[ii]
 
team_name = Args['name_'..team_code_ii] or team_code_ii
 
team_name = Args['name_'..team_code_ii] or team_code_ii
local ii_style = 'text-align:right;'  
+
local ii_style = 'text-align:right;'
 
.. (ii and ii == ii_show and 'font-weight:bold;' or '')
 
.. (ii and ii == ii_show and 'font-weight:bold;' or '')
  
 
-- Team names
 
-- Team names
table.insert(t,'|- \n') -- New row
+
table.insert(t,'|- \n') -- New row
table.insert(t,'! scope="row" style="'  
+
table.insert(t,'! scope="row" style="'
.. ii_style ..'"| '..team_name..'\n') -- Position number
+
.. ii_style ..'"| '..team_name..'\n') -- Position number
  
-- Now include note to match results if needed  
+
-- Now include note to match results if needed
 
for jj=1,N_teams do
 
for jj=1,N_teams do
 
local team_code_jj = team_list[jj]
 
local team_code_jj = team_list[jj]
Line 102: Line 118:
 
note_id = '"table_note_'..team_code_ii..'_'..team_code_jj..rand_val..'"'
 
note_id = '"table_note_'..team_code_ii..'_'..team_code_jj..rand_val..'"'
 
note_id_list[team_code_ii..'_'..team_code_jj] = note_id
 
note_id_list[team_code_ii..'_'..team_code_jj] = note_id
note_string = frame:expandTemplate{ title = 'efn',  
+
note_string = frame:expandTemplate{ title = 'efn',
 
args = { group='Table_notes', name=note_id,  match_note} }
 
args = { group='Table_notes', name=note_id,  match_note} }
else  
+
else
 
-- Check for existence elsewhere
 
-- Check for existence elsewhere
 
local note_local_num = team_list[match_note] or ii_end + 1
 
local note_local_num = team_list[match_note] or ii_end + 1
Line 110: Line 126:
 
-- It exists
 
-- It exists
 
note_id = '"table_note_'..match_note..rand_val..'"' -- Identifier
 
note_id = '"table_note_'..match_note..rand_val..'"' -- Identifier
note_string = frame:extensionTag{ name = 'ref',  
+
note_string = frame:extensionTag{ name = 'ref',
 
args = { group = 'lower-alpha', name = note_id} }
 
args = { group = 'lower-alpha', name = note_id} }
 
else
 
else
Line 118: Line 134:
 
note_id_list[match_note] = note_id
 
note_id_list[match_note] = note_id
 
-- Call refn template
 
-- Call refn template
note_string = frame:expandTemplate{ title = 'efn',  
+
note_string = frame:expandTemplate{ title = 'efn',
 
args = { group='Table_notes', name=note_id, Args['note_'..match_note]} }
 
args = { group='Table_notes', name=note_id, Args['note_'..match_note]} }
 
end
 
end
 
end
 
end
 
-- Now append this to the match result string
 
-- Now append this to the match result string
Args[m..team_code_ii..'_'..team_code_jj] = Args[m..team_code_ii..'_'..team_code_jj]..note_string
+
Args[m..team_code_ii..'_'..team_code_jj] = (Args[m..team_code_ii..'_'..team_code_jj] or '–')..note_string
 
end
 
end
 
end
 
end
Line 131: Line 147:
 
t = p.row(t,Args,N_teams,team_list,ii,ii_show,legs)
 
t = p.row(t,Args,N_teams,team_list,ii,ii_show,legs)
 
end
 
end
+
 
 
-- Close table
 
-- Close table
 
table.insert(t, '|}\n')
 
table.insert(t, '|}\n')
+
 
 
-- Get info for footer
 
-- Get info for footer
 
local update = Args['update']
 
local update = Args['update']
Line 141: Line 157:
 
or 'unknown'
 
or 'unknown'
 
local source = Args['source']
 
local source = Args['source']
or frame:expandTemplate{ title = 'citation needed',  
+
or frame:expandTemplate{ title = 'citation needed',
 
args = { reason='No source parameter defined', date=os.date('%B %Y') } }
 
args = { reason='No source parameter defined', date=os.date('%B %Y') } }
+
 
 
-- Create footer text
 
-- Create footer text
 
-- Date updating
 
-- Date updating
Line 159: Line 175:
 
table.insert(t_footer,'Source: '..source)
 
table.insert(t_footer,'Source: '..source)
 
if (Args['matches_style'] or '') == 'FBR' then
 
if (Args['matches_style'] or '') == 'FBR' then
table.insert(t_footer, Args['team_header']  
+
table.insert(t_footer, Args['team_header']
and '<br />Colours: Blue = left column team win; Yellow = draw; Red = top row team win.'  
+
and '<br />Colours: Blue = left column team win; Yellow = draw; Red = top row team win.'
 
or '<br />Colours: Blue = home team win; Yellow = draw; Red = away team win.')
 
or '<br />Colours: Blue = home team win; Yellow = draw; Red = away team win.')
 
elseif (Args['matches_style'] or '') == 'BSR' then
 
elseif (Args['matches_style'] or '') == 'BSR' then
table.insert(t_footer, Args['team_header']  
+
table.insert(t_footer, Args['team_header']
and '<br />Colours: Blue = left column team win; Red = top row team win.'  
+
and '<br />Colours: Blue = left column team win; Red = top row team win.'
 
or '<br />Colours: Blue = home team win; Red = away team win.')
 
or '<br />Colours: Blue = home team win; Red = away team win.')
 
end
 
end
Line 173: Line 189:
 
table.insert(t_footer, '<br />Matches with background in a lighter colour were decided after overtime.')
 
table.insert(t_footer, '<br />Matches with background in a lighter colour were decided after overtime.')
 
end
 
end
+
 
 
-- Add notes (if applicable)
 
-- Add notes (if applicable)
 
if notes_exist then
 
if notes_exist then
Line 184: Line 200:
 
t_footer = '<div class="reflist">'..table.concat(t_footer)..'</div>'
 
t_footer = '<div class="reflist">'..table.concat(t_footer)..'</div>'
 
end
 
end
+
 
 
-- Add footer to main text table
 
-- Add footer to main text table
 
table.insert(t,t_footer)
 
table.insert(t,t_footer)
Line 194: Line 210:
 
local function get_short_name(s, t, n)
 
local function get_short_name(s, t, n)
 
-- return short name if defined
 
-- return short name if defined
if s and s ~= '' then  
+
if s and s ~= '' then
return s  
+
return s
 
end
 
end
 
-- replace link text in name with team abbr if possible
 
-- replace link text in name with team abbr if possible
Line 221: Line 237:
 
end
 
end
  
-- delink if necessary
+
-- delink if necessary
 
if s:match('^%s*%[%[[^%[%]]*%|([^%[%]]*)%]%]') then
 
if s:match('^%s*%[%[[^%[%]]*%|([^%[%]]*)%]%]') then
 
s = s:match('^%s*%[%[[^%[%]]*%|([^%[%]]*)%]%]')
 
s = s:match('^%s*%[%[[^%[%]]*%|([^%[%]]*)%]%]')
Line 230: Line 246:
  
 
-- get the scores
 
-- get the scores
s1 = tonumber(mw.ustring.gsub( s or '',  
+
s1 = tonumber(mw.ustring.gsub( s or '',
 
'^%s*([%d][%d]*)%s*–%s*([%d][%d]*).*', '%1' ) or '') or ''
 
'^%s*([%d][%d]*)%s*–%s*([%d][%d]*).*', '%1' ) or '') or ''
s2 = tonumber(mw.ustring.gsub( s or '',  
+
s2 = tonumber(mw.ustring.gsub( s or '',
 
'^%s*([%d][%d]*)%s*–%s*([%d][%d]*).*', '%2' ) or '') or ''
 
'^%s*([%d][%d]*)%s*–%s*([%d][%d]*).*', '%2' ) or '') or ''
+
 
 
-- return colouring if possible
 
-- return colouring if possible
 
if s1 ~= '' and s2 ~= '' then
 
if s1 ~= '' and s2 ~= '' then
 
return (s1 > s2) and wc or ((s2 > s1) and lc or tc)
 
return (s1 > s2) and wc or ((s2 > s1) and lc or tc)
 
else
 
else
return s
+
return 'transparent'
 
end
 
end
 
end
 
end
Line 247: Line 263:
 
s = mw.ustring.gsub(s, '^%s*([%d]+)%s*&[MmNn][Dd][Aa][Ss][Hh];%s*([%d]+)', '%1–%2')
 
s = mw.ustring.gsub(s, '^%s*([%d]+)%s*&[MmNn][Dd][Aa][Ss][Hh];%s*([%d]+)', '%1–%2')
 
s = mw.ustring.gsub(s, '^%s*(%[%[[^%[%]]*%|[%d]+)%s*%-%s*([%d]+)', '%1–%2')
 
s = mw.ustring.gsub(s, '^%s*(%[%[[^%[%]]*%|[%d]+)%s*%-%s*([%d]+)', '%1–%2')
 +
s = mw.ustring.gsub(s, '^%s*(%[[^%[%]%s]*%s+[%d]+)%s*%-%s*([%d]+)', '%1–%2')
 
s = mw.ustring.gsub(s, '^%s*(%[%[[^%[%]]*%|[%d]+)%s*&[MmNn][Dd][Aa][Ss][Hh];%s*([%d]+)', '%1–%2')
 
s = mw.ustring.gsub(s, '^%s*(%[%[[^%[%]]*%|[%d]+)%s*&[MmNn][Dd][Aa][Ss][Hh];%s*([%d]+)', '%1–%2')
 +
s = mw.ustring.gsub(s, '^%s*(%[[^%[%]%s]*%s+[%d]+)%s*&[MmNn][Dd][Aa][Ss][Hh];%s*([%d]+)', '%1–%2')
 
return s
 
return s
 
end
 
end
Line 254: Line 272:
 
local ii, team_code_ii, short_name
 
local ii, team_code_ii, short_name
 
legs = legs or 1
 
legs = legs or 1
+
 
 
-- Set match column width
 
-- Set match column width
 
local col_width = Args['match_col_width'] or '28'
 
local col_width = Args['match_col_width'] or '28'
+
 
 
-- Get some default values in case it doesn't start at 1
 
-- Get some default values in case it doesn't start at 1
 
local top_pos = tonumber(Args['highest_pos']) or 1
 
local top_pos = tonumber(Args['highest_pos']) or 1
+
 
 
for l=1,legs do
 
for l=1,legs do
 
for ii=top_pos,N_teams do
 
for ii=top_pos,N_teams do
 
team_code_ii = team_list[ii]
 
team_code_ii = team_list[ii]
short_name = get_short_name(Args['short_'..team_code_ii],  
+
short_name = get_short_name(Args['short_'..team_code_ii],
 
team_code_ii, Args['name_'..team_code_ii])
 
team_code_ii, Args['name_'..team_code_ii])
 
local bl = legs > 1 and ii == top_pos and ' style="border-left:2px solid #aaa;"' or ''
 
local bl = legs > 1 and ii == top_pos and ' style="border-left:2px solid #aaa;"' or ''
Line 277: Line 295:
 
local jj, fw, bg, result, result_extra, team_code_ii, team_code_jj
 
local jj, fw, bg, result, result_extra, team_code_ii, team_code_jj
 
legs = legs or 1
 
legs = legs or 1
+
 
 
-- Set score cell style
 
-- Set score cell style
 
local matches_style = Args['matches_style'] or ''
 
local matches_style = Args['matches_style'] or ''
+
 
 
team_code_ii = team_list[ii]
 
team_code_ii = team_list[ii]
+
 
 
-- Get some default values in case it doesn't start at 1
 
-- Get some default values in case it doesn't start at 1
 
local top_pos = tonumber(Args['highest_pos']) or 1
 
local top_pos = tonumber(Args['highest_pos']) or 1
Line 292: Line 310:
 
result_extra = Args['result_'..team_code_ii..'_'..team_code_jj] or ''
 
result_extra = Args['result_'..team_code_ii..'_'..team_code_jj] or ''
 
local bl = legs > 1 and jj == top_pos and 'border-left:2px solid #aaa;' or ''
 
local bl = legs > 1 and jj == top_pos and 'border-left:2px solid #aaa;' or ''
+
 
 
if ii == jj or result == 'null' then
 
if ii == jj or result == 'null' then
 
-- Solid cell
 
-- Solid cell
 
fw = 'font-weight:' .. (ii==ii_show and 'bold' or 'normal') .. ';'
 
fw = 'font-weight:' .. (ii==ii_show and 'bold' or 'normal') .. ';'
 
bg = 'background:transparent;'
 
bg = 'background:transparent;'
+
 
 
-- Grey background color for solid cell
 
-- Grey background color for solid cell
 
if Args['solid_cell'] == 'grey' then
 
if Args['solid_cell'] == 'grey' then

Revision as of 15:00, 16 May 2019

Documentation for this module may be created at Module:Sports results/sandbox/doc

-- Module to build results cross-tables for standings in Sports
-- See documentation for details

require('Module:No globals')

local p = {}

-- Main function
function p.main(frame)
	-- Get the args, stripping out blank values
	local getArgs = require('Module:Arguments').getArgs
	local Args = getArgs(frame, {frameOnly=true})
	local Pargs = getArgs(frame, {parentOnly=true})

	-- Exit early if we are using section transclusion for a different section
	if( Pargs['transcludesection'] and Args['section'] ) then
		if( Pargs['transcludesection'] ~= Args['section'] ) then
			return ''
		end
	end

	-- Declare locals
	local t = {}
	local t_footer = {}
	local t_return = {}
	local team_list = {}
	local notes_exist = false
	local ii, ii_fw, bg_col, team_name, team_code_ii, ii_start, ii_end
	-- Optional custom team header
	local team_header = Args['team_header'] or 'Home \\ Away'
	-- Number of legs
	local legs = tonumber(Args['legs']) or 1
	-- Edit links if requested
	local template_name = Args['template_name']
		or (mw.title.getCurrentTitle().text ~= frame:getParent():getTitle() and (':' .. frame:getParent():getTitle()))
		or ''
	local edit_links = template_name == '' and ''
		or frame:expandTemplate{ title = 'navbar',
			args = { mini=1, style='float:right', template_name} }
		
	-- Get the custom start point for the table (most will start by default at 1)
	local top_pos = tonumber(Pargs['highest_pos'] or Args['highest_pos']) or 1
	-- Get the custom end point for the table (unrestricted if bottom_pos is < top_pos)
	local bottom_pos = tonumber(Pargs['highest_pos'] or Args['highest_pos']) or 0
	local N_teams = top_pos - 1 -- Default to 0 at start, but higher number needed to skip certain entries

	-- Load some other modules
	local p_sub = require('Module:Sports table/sub')

	-- Read in number of consecutive teams (ignore entries after skipping a spot)
	ii_start = N_teams
	while Args['team'..N_teams+1] ~= nil and (bottom_pos < top_pos or N_teams < bottom_pos) do
		N_teams = N_teams+1
		-- Sneakily add it twice to the team_list parameter, once for the actual
		-- ranking, the second for position lookup in sub-tables
		-- This is possible because Lua allows both numbers and strings as indices.
		team_list[N_teams] = Args['team'..N_teams] -- i^th entry is team X
		team_list[Args['team'..N_teams]] = N_teams -- team X entry is position i
	end
	ii_end = N_teams
	-- Get team to show
	local ii_show = team_list[Args['showteam']] -- nil if non-existant

	-- Set the font size
	local font_size=Args['font_size'] or '100%'

	-- Create header
	-- Open table
	table.insert(t,'{|class="wikitable plainrowheaders" style="text-align:center;font-size:'..font_size..';"\n')
	-- Table title
	if Args['title'] then
		table.insert(t,'|+ ' .. Args['title'] .. '\n')
	end
	-- First column
	t_return.count = 0 			-- Dummy parameter, using subfunction call seems best at this point because both module are intertwined
	t_return.tab_text = t		-- Actual text
	t_return = p_sub.colhead(t_return,'auto', edit_links .. ' ' .. team_header)
	-- Other columns passed to subfunction
	t_return = p.header(t_return,Args,p_sub,N_teams,team_list,legs)
	t = t_return.tab_text

	-- Random value used for uniqueness
	math.randomseed( os.clock() * 10^8 )
	local rand_val = math.random()

	local note_string, note_id
	local note_id_list = {}

	-- Now create individual rows
	for ii=1,N_teams do
		-- Get team info
		team_code_ii = team_list[ii]
		team_name = Args['name_'..team_code_ii] or team_code_ii
		local ii_style = 'text-align:right;'
			.. (ii and ii == ii_show and 'font-weight:bold;' or '')

		-- Team names
		table.insert(t,'|- \n')  -- New row
		table.insert(t,'! scope="row" style="'
			.. ii_style ..'"| '..team_name..'\n')  -- Position number

		-- Now include note to match results if needed
		for jj=1,N_teams do
			local team_code_jj = team_list[jj]
			if ii == jj then
				-- Nothing
			else
				for l=1,legs do
					local m = (legs == 1) and 'match_' or 'match' .. l .. '_'
					local match_note = Args[m ..team_code_ii..'_'..team_code_jj..'_note']
					if match_note then
						notes_exist = true
						-- Only when it exist
						-- First check for existence of reference for note
						if not (Args['note_'..match_note] or Args[m ..match_note..'_note']) then
							-- It's the entry
							-- Add random end for unique ID if more tables are present on article (which might otherwise share an ID)
							note_id = '"table_note_'..team_code_ii..'_'..team_code_jj..rand_val..'"'
							note_id_list[team_code_ii..'_'..team_code_jj] = note_id
							note_string = frame:expandTemplate{ title = 'efn',
								args = { group='Table_notes', name=note_id,  match_note} }
						else
							-- Check for existence elsewhere
							local note_local_num = team_list[match_note] or ii_end + 1
							if note_id_list[match_note] or ((note_local_num >= ii_start) and (note_local_num <= ii_end)) then
								-- It exists
								note_id = '"table_note_'..match_note..rand_val..'"' -- Identifier
								note_string = frame:extensionTag{ name = 'ref',
									args = { group = 'lower-alpha', name = note_id} }
							else
								-- Now define the identifier for this
								-- Add random end for unique ID
								note_id = '"table_note_'..match_note..rand_val..'"'
								note_id_list[match_note] = note_id
								-- Call refn template
								note_string = frame:expandTemplate{ title = 'efn',
									args = { group='Table_notes', name=note_id, Args['note_'..match_note]} }
							end
						end
						-- Now append this to the match result string
						Args[m..team_code_ii..'_'..team_code_jj] = (Args[m..team_code_ii..'_'..team_code_jj] or '–')..note_string
					end
				end
			end
		end
		-- Then individual results
		t = p.row(t,Args,N_teams,team_list,ii,ii_show,legs)
	end

	-- Close table
	table.insert(t, '|}\n')

	-- Get info for footer
	local update = Args['update']
		or 'unknown'
	local start_date = Args['start_date']
		or 'unknown'
	local source = Args['source']
		or frame:expandTemplate{ title = 'citation needed',
			args = { reason='No source parameter defined', date=os.date('%B %Y') } }

	-- Create footer text
	-- Date updating
	if string.lower(update)=='complete' then
		-- Do nothing
	elseif update=='' then
		-- Empty parameter
		table.insert(t_footer,'Updated to match(es) played on unknown. ')
	elseif string.lower(update)=='future' then
		-- Future start date
		table.insert(t_footer,'First match(es) will be played on '..start_date..'. ')
	else
		table.insert(t_footer,'Updated to match(es) played on '..update..'. ')
	end
	table.insert(t_footer,'Source: '..source)
	if (Args['matches_style'] or '') == 'FBR' then
		table.insert(t_footer, Args['team_header']
			and '<br />Colours: Blue = left column team win; Yellow = draw; Red = top row team win.'
			or '<br />Colours: Blue = home team win; Yellow = draw; Red = away team win.')
	elseif (Args['matches_style'] or '') == 'BSR' then
		table.insert(t_footer, Args['team_header']
			and '<br />Colours: Blue = left column team win; Red = top row team win.'
			or '<br />Colours: Blue = home team win; Red = away team win.')
	end
	if (Args['a_note'] or '') ~= '' then
		table.insert(t_footer, '<br />For upcoming matches, an "a" indicates there is an article about the match.')
	end
	if (Args['ot_note'] or '') ~= '' then
		table.insert(t_footer, '<br />Matches with background in a lighter colour were decided after overtime.')
	end

	-- Add notes (if applicable)
	if notes_exist then
		table.insert(t_footer,'<br>Notes:')
		-- As reflist size text
		t_footer = '<div class="reflist">'..table.concat(t_footer)..'</div>'
		t_footer = t_footer..frame:expandTemplate{ title = 'notelist', args = { group='Table_notes'} }
	else
		-- As reflist size text
		t_footer = '<div class="reflist">'..table.concat(t_footer)..'</div>'
	end

	-- Add footer to main text table
	table.insert(t,t_footer)

	return table.concat(t)
end

-- Other functions
local function get_short_name(s, t, n)
	-- return short name if defined
	if s and s ~= '' then
		return s
	end
	-- replace link text in name with team abbr if possible
	if n and t and n:match('(%[%[[^%[%]]*%]%])') then
		n = mw.ustring.gsub(n, '(%[%[[^%|%]]*%|)[^%|%]]*(%]%])', '%1' .. t .. '%2')
		n = mw.ustring.gsub(n, '(%[%[[^%|%]]*)(%]%])', '%1|' .. t .. '%2')
		return n
	end
	-- nothing worked, so just return the unlinked team abbr
	return t or ''
end

local function get_score_background(s, c)
	local s1, s2
	-- Define the colouring
	local wc, lc, tc
	if c == 'level2' then
	wc, lc, tc = '#CCF9FF', '#FCC', '#FFC' -- blue2, red2, yellow2
	elseif c == 'level3' then
	wc, lc, tc = '#DDFCFF', '#FDD', '#FFD' -- blue3, red3, yellow3
	elseif c == 'level4' then
	wc, lc, tc = '#EEFFFF', '#FEE', '#FFE' -- blue4, red4, yellow4
	else
	wc, lc, tc = '#BBF3FF', '#FBB', '#FFB' -- blue1, red1, yellow1
	end

	-- delink if necessary
	if s:match('^%s*%[%[[^%[%]]*%|([^%[%]]*)%]%]') then
		s = s:match('^%s*%[%[[^%[%]]*%|([^%[%]]*)%]%]')
	end
	if s:match('^%s*%[[^%[%]%s]*%s([^%[%]]*)%]') then
		s = s:match('^%s*%[[^%[%]%s]*%s([^%[%]]*)%]')
	end

	-- get the scores
	s1 = tonumber(mw.ustring.gsub( s or '',
		'^%s*([%d][%d]*)%s*–%s*([%d][%d]*).*', '%1' ) or '') or ''
	s2 = tonumber(mw.ustring.gsub( s or '',
		'^%s*([%d][%d]*)%s*–%s*([%d][%d]*).*', '%2' ) or '') or ''

	-- return colouring if possible
	if s1 ~= '' and s2 ~= '' then
		return (s1 > s2) and wc or ((s2 > s1) and lc or tc)
	else
		return 'transparent'
	end
end

local function format_score(s)
	s = mw.ustring.gsub(s or '', '^%s*([%d]+)%s*[–−—%-]%s*([%d]+)', '%1–%2')
	s = mw.ustring.gsub(s, '^%s*([%d]+)%s*&[MmNn][Dd][Aa][Ss][Hh];%s*([%d]+)', '%1–%2')
	s = mw.ustring.gsub(s, '^%s*(%[%[[^%[%]]*%|[%d]+)%s*%-%s*([%d]+)', '%1–%2')
	s = mw.ustring.gsub(s, '^%s*(%[[^%[%]%s]*%s+[%d]+)%s*%-%s*([%d]+)', '%1–%2')
	s = mw.ustring.gsub(s, '^%s*(%[%[[^%[%]]*%|[%d]+)%s*&[MmNn][Dd][Aa][Ss][Hh];%s*([%d]+)', '%1–%2')
	s = mw.ustring.gsub(s, '^%s*(%[[^%[%]%s]*%s+[%d]+)%s*&[MmNn][Dd][Aa][Ss][Hh];%s*([%d]+)', '%1–%2')
	return s
end

function p.header(tt,Args,p_sub,N_teams,team_list,legs)
	local ii, team_code_ii, short_name
	legs = legs or 1

	-- Set match column width
	local col_width = Args['match_col_width'] or '28'

	-- Get some default values in case it doesn't start at 1
	local top_pos = tonumber(Args['highest_pos']) or 1

	for l=1,legs do
		for ii=top_pos,N_teams do
			team_code_ii = team_list[ii]
			short_name = get_short_name(Args['short_'..team_code_ii],
				team_code_ii, Args['name_'..team_code_ii])
			local bl = legs > 1 and ii == top_pos and ' style="border-left:2px solid #aaa;"' or ''
			tt = p_sub.colhead(tt,col_width .. bl,short_name)
		end
	end
	return tt
end

function p.row(tt,Args,N_teams,team_list,ii,ii_show,legs)
	-- Note ii is the row number being shown
	local jj, fw, bg, result, result_extra, team_code_ii, team_code_jj
	legs = legs or 1

	-- Set score cell style
	local matches_style = Args['matches_style'] or ''

	team_code_ii = team_list[ii]

	-- Get some default values in case it doesn't start at 1
	local top_pos = tonumber(Args['highest_pos']) or 1
	for l=1,legs do
		for jj=top_pos,N_teams do
			team_code_jj = team_list[jj]
			local m = (legs == 1) and 'match_' or 'match' .. l .. '_'
			result = Args[m..team_code_ii..'_'..team_code_jj] or ''
			result_extra = Args['result_'..team_code_ii..'_'..team_code_jj] or ''
			local bl = legs > 1 and jj == top_pos and 'border-left:2px solid #aaa;' or ''

			if ii == jj or result == 'null' then
				-- Solid cell
				fw = 'font-weight:' .. (ii==ii_show and 'bold' or 'normal') .. ';'
				bg = 'background:transparent;'

				-- Grey background color for solid cell
				if Args['solid_cell'] == 'grey' then
					table.insert(tt,'| style="'..fw..bl..'background:#bbb;" |\n')
				else
					table.insert(tt,'| style="'..fw..bl..bg..'" | &mdash;\n')
				end
			else
				-- Content cell
				-- Set bolding and background
				fw = 'font-weight:' .. ((ii==ii_show or jj == ii_show) and 'bold' or 'normal') .. ';'
				bg = 'background:transparent;'

				-- Reformat dashes
				if result ~= '' then
					result = format_score(result)
				end
				-- Background coloring if enabled
				if matches_style == 'FBR' and result ~= '' then
					if result_extra == 'OT' then
						bg = 'background:' .. get_score_background(result,'level2') .. ';'
					elseif result_extra == 'PK' then
						bg = 'background:' .. get_score_background(result,'level3') .. ';'
					else
						bg = 'background:' .. get_score_background(result,'') .. ';'
					end
				elseif matches_style == 'BSR' and result ~= '' then
					if result_extra == 'OT' then
						bg = 'background:' .. get_score_background(result,'level3') .. ';'
					else
						bg = 'background:' .. get_score_background(result,'') .. ';'
					end
				end
				table.insert(tt,'| style="white-space:nowrap;'..fw..bl..bg..'" |'..result..'\n')
			end
		end
	end

	return tt
end

return p