Jump to content

Module:Sports table/Rugby

From Calamity Wiki
Revision as of 23:42, 9 October 2023 by imported>Frietjes (optional grand slam points for 2019 Six Nations Championship and others)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

This style for Lua-based Module:Sports table is meant to build group and league tables for rugby competitions with the following optional columns

  1. Played / Wins / Draws / Losses
  2. Match points for / Match points against / Match points difference
  3. Tries for / Tries against
  4. Try bonus competition points
  5. Loss bonus competition points
  6. Total competition points

The input syntax for this module is similar to the WDL module, but specialized for Rugby competitions.

Usage

Basic usage

In its simplest form only several parameters need to be used to build a table

What you type
{{#invoke:sports table|main|style=Rugby

<!-- Add team codes and names here -->
| team1 = AAA | name_AAA = Team AAA
| team2 = BBB | name_BBB = Team BBB
| team3 = CCC | name_CCC = Team CCC
| team4 = DDD | name_DDD = Team DDD
| team5 = EEE | name_EEE = Team EEE
| team6 = FFF | name_FFF = Team FFF
| team7 = GGG | name_GGG = Team GGG
| team8 = HHH | name_HHH = Team HHH

<!-- Update results here and then (if needed) positions below. Don't forget to update the date below (update parameter) -->
| win_AAA=0 | draw_AAA=0 | loss_AAA=0 | pf_AAA=0 | pa_AAA=0 | tf_AAA=0 | ta_AAA=0 | tb_AAA=0 | lb_AAA=0 | status_AAA=CQ
| win_BBB=0 | draw_BBB=0 | loss_BBB=0 | pf_BBB=0 | pa_BBB=0 | tf_BBB=0 | ta_BBB=0 | tb_BBB=0 | lb_BBB=0 | status_BBB=Q
| win_CCC=0 | draw_CCC=0 | loss_CCC=0 | pf_CCC=0 | pa_CCC=0 | tf_CCC=0 | ta_CCC=0 | tb_CCC=0 | lb_CCC=0 | status_CCC=A
| win_DDD=0 | draw_DDD=0 | loss_DDD=0 | pf_DDD=0 | pa_DDD=0 | tf_DDD=0 | ta_DDD=0 | tb_DDD=0 | lb_DDD=0 | status_DDD=T
| win_EEE=0 | draw_EEE=0 | loss_EEE=0 | pf_EEE=0 | pa_EEE=0 | tf_EEE=0 | ta_EEE=0 | tb_EEE=0 | lb_EEE=0 | status_EEE=
| win_FFF=0 | draw_FFF=0 | loss_FFF=0 | pf_FFF=0 | pa_FFF=0 | tf_FFF=0 | ta_FFF=0 | tb_FFF=0 | lb_FFF=0 | status_FFF=
| win_GGG=0 | draw_GGG=0 | loss_GGG=0 | pf_GGG=0 | pa_GGG=0 | tf_GGG=0 | ta_GGG=0 | tb_GGG=0 | lb_GGG=0 | status_GGG=R
| win_HHH=0 | draw_HHH=0 | loss_HHH=0 | pf_HHH=0 | pa_HHH=0 | tf_HHH=0 | ta_HHH=0 | tb_HHH=0 | lb_HHH=0 | status_HHH=R

<!-- Update team positions here -->
| team_order = AAA, BBB, CCC, DDD, EEE, FFF, GGG, HHH

<!--Update team qualifications here (defined below)-->
| result1=C | result2=C | result3=C | result4=C | result7=R | result8=R

<!-- Add promotion, qualification and/or relegation row colours and column definitions. Use green for top tournament, then blue followed by yellow; red is elimination. Different levels of same competitions should have different shades in color like green1, green2 and so on. -->
| res_col_header = QR <!-- All of these may not be needed, Promotion (P), Qualification (Q) and Relegation (R) -->
| col_C = green2 | text_C = Continental Championship
| col_R = red2   | text_R = Division 2

| start_date  = Unknown <!-- Add start date. When tournament starts, remove start_date -->
| update      = future <!-- When tournament starts, update the with date of latest update --> 
| source      = Unknown <!-- Add source for table here with single bracket, e.g. [URL info] -->
| class_rules = 1) competition points; 2) match points difference; 3) match points for <!-- Add classification rules here -->
}}
What it looks like
Pos Team Pld W D L PF PA PD TF TA TB LB Pts Qualification or relegation
1 Team AAA (C, Q) 0 0 0 0 0 0 0 0 0 0 0 0 Continental Championship
2 Team BBB (Q) 0 0 0 0 0 0 0 0 0 0 0 0
3 Team CCC (A) 0 0 0 0 0 0 0 0 0 0 0 0
4 Team DDD (T) 0 0 0 0 0 0 0 0 0 0 0 0
5 Team EEE 0 0 0 0 0 0 0 0 0 0 0 0
6 Team FFF 0 0 0 0 0 0 0 0 0 0 0 0
7 Team GGG (R) 0 0 0 0 0 0 0 0 0 0 0 0 Division 2
8 Team HHH (R) 0 0 0 0 0 0 0 0 0 0 0 0
First match(es) will be played: Unknown. Source: example.com
Rules for classification: 1) competition points; 2) match points difference; 3) match points for
(A) Advances to a further round; (C) Champion; (Q) Qualified for the phase indicated; (R) Relegated; (T) Qualified, but not yet for the particular phase indicated

Additional parameters

  1. To merge the "bonus competition points" columns into one, use |bonus_total= with any additional bonus points specified using |b_XYZ=
  2. To hide the "bonus competition points" columns, use |show_bonus=no
  3. To hide the "draws" column, use |show_draw=no
  4. To hide the "tries for" column, use |show_tries_for=no
  5. To hide the "tries against" column, use |show_tries_against=no
  6. To show the "tries difference" column, use |show_tries_difference=yes
  7. To hide the "points for" column, use |show_points_for=no
  8. To hide the "points against" column, use |show_points_against=no
  9. To hide the "points difference" column, use |show_points_difference=no
  10. To add "competition points carried forward" to the next round, use |show_cf=yes
  11. To add "grand slam points" column, use |show_grand_slam=yes, with grand slam points specified using |gs_XYZ=
  12. To override the default number of "win points", use |winpoints=
  13. To override the default number of "draw points", use |drawpoints=
  14. To override the default number of "loss points", use |losspoints=

-- Style for rugby union tables
local pp = {}
 
function pp.header(t,Args,p_sub,pos_label,group_col,VTE_text,full_table,results_header_txt)
	-- Load relevant modules
	local yesno = require('Module:Yesno')
	
	-- Create table header
	-- Pre stuff
	local team_width = Args['teamwidth'] or '170'
	local sort_text = yesno(Args['sortable_table'] or 'no') and 'sortable' or ''
	local show_played = not yesno(Args['hide_played'] or 'no')
	local show_draw = yesno(Args['show_draw'] or 'yes')
	local show_points_for = yesno(Args['show_points_for'] or 'yes')
	local show_points_against = yesno(Args['show_points_against'] or 'yes')
	local show_points_difference = yesno(Args['show_points_difference'] or 'yes')
	local show_tries_for = yesno(Args['show_tries_for'] or 'yes')
	local show_tries_against = yesno(Args['show_tries_against'] or 'yes')
	local show_tries_difference = yesno(Args['show_tries_difference'] or 'no')
	local show_bonus = yesno(Args['show_bonus'] or 'yes')
	local bonus_total = yesno(Args['bonus_total'] or 'no')
	local show_cf = yesno(Args['show_cf'] or 'no')
	local ranking_style = string.lower(Args['ranking_style'] or 'pts')
	local show_adjust_points = yesno(Args['show_adjust_points'] or 'no')
	local grand_slam = yesno(Args['show_grand_slam'] or 'no')
	local show_points = true
	local show_ppg = false
	
	if ranking_style=='w' or ranking_style=='win' or ranking_style=='wins' or ranking_style=='none' then
		show_points = false
	elseif ranking_style=='ppg' then
		show_points = false
		show_ppg = true
	end

	-- Custom header
	local group_head_text = Args['group_header'] or '<abbr title="Group">Grp</abbr>'
	local adjust_head_text = Args['adjust_header'] or '<abbr title="Bonus points">B</abbr>'
	
	table.insert(t,'{|class="wikitable '..sort_text..'" style="text-align:center;"\n')            			-- Open table
	-- Table title
	if Args['title'] or Args['table_header'] then
		table.insert(t,'|+ ' .. (Args['title'] or Args['table_header']) .. '\n')
	end

	-- Initialize
	local tt = {}
	tt.count = 0 		-- Up by one after every call
	tt.tab_text = t		-- Actual text
	-- Actual headers
	if pos_label ~= nil then
		tt = p_sub.colhead(tt,28,pos_label)									-- Position col
	end
	-- Add group header
	if full_table and group_col then
		tt = p_sub.colhead(tt,28,group_head_text)							-- Group col
	end
	tt = p_sub.colhead(tt,team_width,'Team'..VTE_text)						-- Team col
	if show_played then
		tt = p_sub.colhead(tt,28,'<abbr title="Matches played">Pld</abbr>')			-- Matches played col
	end
	
	if full_table then
		tt = p_sub.colhead(tt,28,'<abbr title="Matches won">W</abbr>')				-- Win col
		if show_draw then
			tt = p_sub.colhead(tt,28,'<abbr title="Matches drawn">D</abbr>')		-- Draw col
		end
		tt = p_sub.colhead(tt,28,'<abbr title="Matches lost">L</abbr>')				-- Loss col
		if show_points_for then
			tt = p_sub.colhead(tt,28,'<abbr title="Match points for">PF</abbr>')		-- For col
		end
		if show_points_against then
			tt = p_sub.colhead(tt,28,'<abbr title="Match points against">PA</abbr>')	-- Against col
		end
		if show_points_difference then
			tt = p_sub.colhead(tt,28,'<abbr title="Match points difference">PD</abbr>')	-- Difference col
		end
		if show_tries_against then
			if show_tries_for then
				tt = p_sub.colhead(tt,28,'<abbr title="Tries for">TF</abbr>')	    -- Tries for col
			end
			tt = p_sub.colhead(tt,28,'<abbr title="Tries against">TA</abbr>')	-- Tries against col
		elseif show_tries_for then
			tt = p_sub.colhead(tt,28,'<abbr title="Tries scored">T</abbr>')	    -- Tries for col
		end
		if show_tries_difference then
			tt = p_sub.colhead(tt,28,'<abbr title="Tries difference">TD</abbr>')	-- Tries difference col
		end
		if show_bonus then
			if bonus_total then
				tt = p_sub.colhead(tt,28,'<abbr title="Bonus competition points">B</abbr>')		-- bonus col
			else
				if grand_slam then
					tt = p_sub.colhead(tt,28,'<abbr title="Grand slam competition points">GS</abbr>')		-- Grand slam bonus col
				end
				tt = p_sub.colhead(tt,28,'<abbr title="Try bonus competition points">TB</abbr>')		-- Try bonus col
				tt = p_sub.colhead(tt,28,'<abbr title="Losing bonus competition points">LB</abbr>')	-- Losing bonus col
			end
		end
		if show_adjust_points then
			tt = p_sub.colhead(tt,28,adjust_head_text)			-- Adjust points col
		end
		if show_ppg then
			tt = p_sub.colhead(tt,32,'<abbr title="Match points per game">PPG</abbr>') -- PPG col
		end
		if show_points then
			tt = p_sub.colhead(tt,32,'<abbr title="Total competition points">Pts</abbr>') -- Points col
		end
		if show_cf then
			tt = p_sub.colhead(tt,28,'<abbr title="Competition points carried forward to next phase">CF</abbr>') -- CF col
		end
		tt.count = tt.count+1
		table.insert(tt.tab_text,results_header_txt)
	end
 
	return tt
end

-- Numeric alignment
local function num_align(num, digits)
	if tonumber(digits) and tonumber(num) then
		local n = tonumber(num)
		digits = tonumber(digits)
		if digits == 1 then
			if n >= 0 and n < 10 then
				return '<span style="visibility:hidden;color:transparent;">0</span>' .. num
			end
		elseif digits == 2 then
			if n >= 0 and n < 10 then
				return '<span style="visibility:hidden;color:transparent;">00</span>' .. num
			elseif n >= 10 and n < 100 then
				return '<span style="visibility:hidden;color:transparent;">0</span>' .. num
			end
		end
	end
	return num
end

function pp.row(frame,t,Args,p_sub,notes_exist,hth_id_list,full_table,rand_val,team_list,team_code_ii,ii_start,ii_end,ii_fw,bg_col,N_teams,ii,ii_show)
	-- Build the inner parts of individual rows
	
	-- Sub-module usage
	local mm = require('Module:Math')
	local yesno = require('Module:Yesno')
	
	-- Get some input
	local show_played = not yesno(Args['hide_played'] or 'no')
	local show_draw = yesno(Args['show_draw'] or 'yes')
	local show_points_for = yesno(Args['show_points_for'] or 'yes')
	local show_points_against = yesno(Args['show_points_against'] or 'yes')
	local show_points_difference = yesno(Args['show_points_difference'] or 'yes')
	local show_tries_for = yesno(Args['show_tries_for'] or 'yes')
	local show_tries_against = yesno(Args['show_tries_against'] or 'yes')
	local show_tries_difference = yesno(Args['show_tries_difference'] or 'no')
	local show_bonus = yesno(Args['show_bonus'] or 'yes')
	local bonus_total = yesno(Args['bonus_total'] or 'no')
	local grand_slam = yesno(Args['show_grand_slam'] or 'no')
	local show_cf = yesno(Args['show_cf'] or 'no')
	local win_points = tonumber(Args['winpoints'])				or 4
	local draw_points = tonumber(Args['drawpoints'])			or 2
	local loss_points = tonumber(Args['losspoints'])			or 0
	local ranking_style = string.lower(Args['ranking_style'] or 'pts')
	local show_points = true
	local show_ppg = false
	local show_adjust_points = yesno(Args['show_adjust_points'] or 'no')
	local wins = tonumber(Args['win_'..team_code_ii])		or 0
	local draws = tonumber(Args['draw_'..team_code_ii])		or 0
	local losses = tonumber(Args['loss_'..team_code_ii])	or 0
	local pfor = tonumber(Args['pf_'..team_code_ii])			or 0
	local paig = tonumber(Args['pa_'..team_code_ii])			or 0
	local tf = tonumber(Args['tf_'..team_code_ii])			or 0
	local ta = tonumber(Args['ta_'..team_code_ii])			or 0
	local tb = tonumber(Args['tb_'..team_code_ii])			or 0
	local lb = tonumber(Args['lb_'..team_code_ii])			or 0
	local gs = tonumber(Args['gs_'..team_code_ii])			or 0
	local b = tonumber(Args['b_'..team_code_ii])			or 0
	local cf = tonumber(Args['cf_'..team_code_ii])			or 0
	local s_pts = (tonumber(Args['adjust_points_'..team_code_ii]) or 0) + (tonumber(Args['startpoints_'..team_code_ii]) or 0)
	local hth_local = Args['hth_'..team_code_ii]				or nil
	local digits = Args['digitpad']

	-- Then calculate some values
	b = b + lb + tb + gs
	local matches = wins + draws + losses
	local points = win_points*wins + draw_points*draws + loss_points*losses + b + s_pts
	local pcomp = 0
	
	if (pfor == '?') or (paig == '?') then
		pcomp = '&mdash;'
	else
		pcomp = pfor - paig
		-- Formatting with signs
		if pcomp>0 then
			pcomp='+'..num_align(pcomp,digits)
		elseif pcomp < 0 then
			pcomp='&minus;'..-num_align(pcomp,digits)
		end
	end
	
	local tcomp = 0
	if (tf == '?') or (ta == '?') then
		tcomp = '&mdash;'
	else
		tcomp = tf - ta
		-- Formatting with signs
		if tcomp>0 then
			tcomp='+'..num_align(tcomp,digits)
		elseif tcomp < 0 then
			tcomp='&minus;'..-num_align(tcomp,digits)
		end
	end
	
	-- Some local vars	
	local hth_string
	local tt_return = p_sub.hth(frame,Args,full_table,hth_id_list,hth_local,notes_exist,team_list,team_code_ii,ii_start,ii_end,rand_val)
	hth_string = tt_return.str
	hth_id_list = tt_return.list
	notes_exist = tt_return.notes_exist
 
 	-- What to rank the teams by
	local win_fw, win_string, pts_fw, pts_string, ppg_fw, ppg_string
	if ranking_style=='w' or ranking_style=='win' or ranking_style=='wins' then
		-- Based on wins
		win_fw = 'font-weight: bold;'
		win_string = hth_string
		pts_fw=ii_fw
		pts_string = ''
		show_points = false
	elseif ranking_style=='ppg' then
		win_fw=ii_fw
		win_string = ''
		ppg_fw = 'font-weight: bold;'
		ppg_string = hth_string
		pts_fw=ii_fw
		pts_string=''
		show_ppg = true
		show_points = false
	elseif ranking_style=='none' then
		win_fw=ii_fw
		win_string = ''
		pts_fw=ii_fw
		pts_string = ''
		show_points = false
	else
		win_fw=ii_fw
		win_string = ''
		pts_fw= 'font-weight:bold;'
		pts_string = ''
		show_points = true
	end
	
	-- Now that we are done calculating, show actual input values
	if tonumber(Args['win_'..team_code_ii] or 0) == nil then
		wins = '&mdash;'
	end
	if tonumber(Args['loss_'..team_code_ii] or 0) == nil then
		losses = '&mdash;'
	end
	local ppg = '&mdash;'
	if tonumber(matches) ~= nil and matches ~= 0 then 
		ppg = mm._precision_format(points / matches, 2)
	end

	local function numorval(s)
		return s and ((s == '' and 0) or tonumber(s) or s) or 0
	end

	-- Row building
	if show_played then
		table.insert(t,'| style="'..ii_fw..bg_col..'" |'..matches..'\n') 		-- Played
	end
	if full_table then
		table.insert(t,'| style="'..win_fw..bg_col..'" |'..wins..win_string..'\n') 	-- Won
		if show_draw then
			table.insert(t,'| style="'..ii_fw..bg_col..'" |'..draws..'\n') 	-- Drawn
		end
		if show_points or show_points_difference then
			table.insert(t,'| style="'..ii_fw..bg_col..'" |'..losses..'\n') 		    -- Lost
		else
			table.insert(t,'| style="'..ii_fw..bg_col..'" |'..losses..hth_string..'\n') 		    -- Lost
		end
		if show_points_for then
			table.insert(t,'| style="'..ii_fw..bg_col..'" |'..pfor..'\n') 	-- PF
		end
		if show_points_against then
			table.insert(t,'| style="'..ii_fw..bg_col..'" |'..paig..'\n') 	-- PA
		end
		if show_points_difference then
			if show_points then
				table.insert(t,'| style="'..ii_fw..bg_col..'" |'..pcomp..'\n')  -- PD
			else
				table.insert(t,'| style="'..ii_fw..bg_col..'" |'..pcomp..hth_string..'\n')  -- PD
			end
		end
		if show_tries_for then
			table.insert(t,'| style="'..ii_fw..bg_col..'" |'..tf..'\n') 	-- TF
		end
		if show_tries_against then
			table.insert(t,'| style="'..ii_fw..bg_col..'" |'..ta..'\n') 	-- TA
		end
		if show_tries_difference then
			table.insert(t,'| style="'..ii_fw..bg_col..'" |'..tcomp..'\n') 	-- TD
		end
		if show_bonus then
			if bonus_total then
				table.insert(t,'| style="'..ii_fw..bg_col..'" |'..b..'\n') 	-- B
			else
				if grand_slam then
					table.insert(t,'| style="'..ii_fw..bg_col..'" |'..gs..'\n') 	-- GS
				end
				table.insert(t,'| style="'..ii_fw..bg_col..'" |'..tb..'\n') 	-- TB
				table.insert(t,'| style="'..ii_fw..bg_col..'" |'..lb..'\n') 	-- LB
			end
		end
		if show_adjust_points then
			if s_pts < 0 then
				table.insert(t,'| style="'..bg_col..'" | &minus;'..num_align(-s_pts,digits)..'\n')
			else
				table.insert(t,'| style="'..bg_col..'" | '..num_align(s_pts,digits)..'\n')
			end
		end
		if show_ppg then
			table.insert(t,'| style="'..ppg_fw..bg_col..'" |'..ppg..ppg_string..'\n') 	-- ppg
		end
		if show_points then
			-- Add &minus; for negative point totals
			if points<0 then
				table.insert(t,'| style="'..pts_fw..bg_col..'" | &minus;'..num_align(-points,digits)..hth_string..'\n')
			else
				table.insert(t,'| style="'..pts_fw..bg_col..'" | '..num_align(points,digits)..hth_string..'\n')
			end
		end
		if show_cf then
			table.insert(t,'| style="'..ii_fw..bg_col..'" |'..cf..'\n') 	-- CF
		end
	end
	return {t=t, notes_exist=notes_exist, hth_id_list=hth_id_list}
end
 
function pp.status(Args)
	-- Declare status options
	-- ------------------------------------------------------------
	-- NOTE: If you add to status_code, also add to status_called and status_letters!!
	-- Or functionality will be compromised
	-- ------------------------------------------------------------
	local status_code, status_called = {}, {}
	status_code = {	A='Advances to a further round', C='Champion', D='Disqualified', 
		E='Eliminated', H='Host', O='Play-off winner', P='Promoted', Q='Qualified for the phase indicated',
		R='Relegated', T='Qualified, but not yet for the particular phase indicated'}
	local status_letters = (Args['status_order'] or '') .. 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
	
	-- Status position (before or after read and default)
	local stat_pos_val = string.lower(Args['status_pos'] or '')
	local status_position = 'after' 	-- Default location
	if stat_pos_val=='before' then
		status_position = 'before'
	elseif stat_pos_val=='after' then
		status_position = 'after'
	end
	-- Read in custom status options
	for l in mw.text.gsplit(status_letters, '') do
		status_called[l] = false
		status_code[l] = status_code[l] or '?'
		status_letters = mw.ustring.gsub(status_letters, '(' .. l ..'.-)' .. l, '%1')

		if Args['status_text_' .. l] then
			status_code[l] = Args['status_text_' .. l]
		end
	 end
	
	return {code=status_code, called=status_called, letters=status_letters, position=status_position}
end

return pp