Відкрити головне меню
{{i}} Документація модуля[створити]
-- 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)
	-- Declare locals
	local Args = frame.args
	local N_teams = 0
	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
	-- Optional custom team header
	local team_header = Args['team_header'] or 'Команда'
	-- Edit links if requested
	local template_name = Args['template_name'] or ''
	local edit_links = template_name == '' and '' 
		or frame:expandTemplate{ title = 'navbar', 
			args = { mini=1, style='float:right', template_name} }
	
	-- Load some other modules
	local p_sub = require('Module:Sports table/sub')
	
	-- Read in number of consecutive teams (ignore entries after skipping a spot)
	while Args['team'..N_teams+1] ~= nil 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
	
	-- 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') 
	-- 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)
	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;'
		if ii and ii == ii_show then
			ii_style = ii_style .. 'font-weight:bold;'
		end
		-- 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
				local match_note = Args['match_'..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['match_'..match_note..'_note']) then
						-- It's the entry
						note_id = '"table_note_'..team_code_ii..'_'..team_code_jj..rand_val..'"' -- Add random end for unique ID if more tables are present on article (which might otherwise share an ID)
						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
						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
							note_id = '"table_note_'..match_note..rand_val..'"' -- Add random end for unique ID
							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['match_'..team_code_ii..'_'..team_code_jj] = Args['match_'..team_code_ii..'_'..team_code_jj]..note_string
				end
			end
		end
		
		-- Then individual results
		t = p.row(t,Args,N_teams,team_list,ii,ii_show)
	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,'Перший матч зіграний '..start_date..'. ')
	else
		table.insert(t_footer,'Оновлено після матчів, зіграних '..update..'. ')
	end
	table.insert(t_footer,'Джерело: '..source)
	if (Args['matches_style'] or '') == 'FBR' then
		table.insert(t_footer, '<br>Колір: блакитний = перемога господарів; жовтий = нічія; рожевий = перемога гостей.')
	end
	
	-- Add notes (if applicable)
	if notes_exist then
		table.insert(t_footer,'<br>Примітки:')
		-- 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', '#FFCCCC', '#FFFFCC' -- blue2, red2, yellow2
	elseif c == 'level3' then
	wc, lc, tc = '#DDFCFF', '#FFDDDD', '#FFFFDD' -- blue3, red3, yellow3
	elseif c == 'level4' then
	wc, lc, tc = '#EEFFFF', '#FFEEEE', '#FFFFEE' -- blue4, red4, yellow4
	else
	wc, lc, tc = '#BBF3FF', '#FFBBBB', '#FFFFBB' -- blue1, red1, yellow1
	end

	-- delink if necessary	
	if s:match('^%s*%[%[[^%[%]]*%|([^%[%]]*)%]%]') then
		s = s:match('^%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*(%[%[[^%[%]]*%|[%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)
	local ii, team_code_ii, short_name
	
	-- 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 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])
		tt = p_sub.colhead(tt,col_width,short_name)
	end
	
	return tt
end

function p.row(tt,Args,N_teams,team_list,ii,ii_show)
	-- Note ii is the row number being shown
	local jj, fw, bg, result, result_extra, team_code_ii, team_code_jj
	local cell_bold = false
	
	-- 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 jj=top_pos,N_teams do
		
		team_code_jj = team_list[jj]
		result = Args['match_'..team_code_ii..'_'..team_code_jj] or ''
		result_extra = Args['result_'..team_code_ii..'_'..team_code_jj] or ''
	
		if ii == jj or result == 'null' then
			-- Solid cell
			if ii==ii_show then cell_bold = true else cell_bold = false end
			fw = cell_bold and 'font-weight: bold;' or 'font-weight: normal;'
			bg = 'background-color:transparent;'
			
			-- Grey background color for solid cell
			if Args['solid_cell'] == 'grey' then
			table.insert(tt,'| style="'..fw..'background-color:#BBBBBB;" |\n')
			else
			table.insert(tt,'| style="'..fw..bg..'" | &mdash;\n')
			end
		else
			-- Content cell
			-- Set bolding and background
			if ii==ii_show or jj == ii_show then cell_bold = true else cell_bold = false end
			fw = cell_bold and 'font-weight: bold;' or 'font-weight: normal;'
			bg = 'background-color: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-color:' .. get_score_background(result,'level2') .. ';'
				elseif result_extra == 'PK' then
					bg = 'background-color:' .. get_score_background(result,'level3') .. ';'
				else
					bg = 'background-color:' .. get_score_background(result,'') .. ';'
				end
			elseif matches_style == 'BSR' and result ~= '' then
				if result_extra == 'OT' then
					bg = 'background-color:' .. get_score_background(result,'level3') .. ';'
				else
					bg = 'background-color:' .. get_score_background(result,'') .. ';'
				end
			end
			table.insert(tt,'| style="white-space:nowrap;'..fw..bg..'" |'..result..'\n')
		end
	end
	
	return tt
end

return p