Edge Rewrite
// HTMLRewriter · presentation

This page was redesigned at the edge.

Cloudflare fetched the original article and streamed it through HTMLRewriter to apply an entirely new visual system without rebuilding the source page.

Jump to content

Module:Sports table/Chess

From Wikipedia, the free encyclopedia

-- Style for chess tables
local pp = {}

function pp.preprocess(Args,N_teams,prefix,drawfractions)
	local legs = 1
	for ii=1,N_teams do
		local ti = Args['team' .. ii]
		Args[prefix..'win_'..ti] = 0
		Args[prefix..'draw_'..ti] = 0
		Args[prefix..'loss_'..ti] = 0
		local matchrow_str = Args[prefix..'matchrow_' .. ti] or ''
		for jj=1,N_teams do
			local tj = Args['team' .. jj] 
			if ii ~= jj then
				if matchrow_str ~= '' then
					Args[prefix..'match_' .. ti .. '_' .. tj] = mw.ustring.match(matchrow_str, '^([^,]*),?')
				end
				local match_str = Args[prefix..'match_' .. ti .. '_' .. tj] or ''
				local game_count = 1
				while match_str ~= '' do
					local gii = mw.ustring.match(match_str, '^([^%+]*)%+?')
					gii = mw.ustring.gsub(gii or '','^%s*','')						-- Trim starting whitespace
					gii = mw.ustring.gsub(gii or '','%s*$','')						-- Trim ending whitespace
					if gii == '1' then
						Args[prefix..'win_'..ti] = Args[prefix..'win_'..ti] + 1
					elseif gii == '½' then
						Args[prefix..'draw_'..ti] = Args[prefix..'draw_'..ti] + 1
						if drawfractions then
							gii = mw.getCurrentFrame():extensionTag{
								name = 'templatestyles', args = { src = 'Screen reader-only/styles.css' }
							} .. '<span class="sr-only">&nbsp;</span><sup>1</sup>&frasl;<sub>2</sub>'
						end
					elseif gii == '0' then
						Args[prefix..'loss_'..ti] = Args[prefix..'loss_'..ti] + 1
					end
					Args[prefix..'match' .. game_count .. '_' .. ti .. '_' .. tj] = gii
					match_str = mw.ustring.gsub(match_str, '^([^%+]*)', '') or ''	-- Remove gii from the match_str
					if match_str ~= '' then											-- If there is still a plus sign
						game_count = game_count + 1									-- Then there is another game in the match
						match_str = mw.ustring.gsub(match_str, '^%+?', '') or ''	-- So remove the plus sign
					end																-- And continue
				end
				if game_count > legs then											-- If there are more games than expected
					legs = game_count												-- Change the number of games
				end
			end
			matchrow_str = mw.ustring.gsub(matchrow_str, '^([^,]*),?', '') or ''
		end
	end
	Args[prefix..'legs'] = legs														-- And finally change the Arg at the end
end

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 player_width = Args['playerwidth'] or '190'
	local sort_text = ''
	local sort_table_val = Args['sortable_table'] 	or 'no'
	if yesno(sort_table_val) then sort_text = ' sortable' end
	-- Open table
	table.insert(t,'{|class="wikitable'..sort_text..'" style="text-align:center;"\n')
	-- Table title
	if Args['title'] or Args['table_header'] then
		table.insert(t,'|+ ' .. (Args['title'] or Args['table_header']) .. '\n')
	end
	-- Preprocess match data
	local top_pos = tonumber(Args['highest_pos']) or 1
	local N_teams = top_pos - 1 -- Default to 0 at start, but higher number needed to skip certain entries
	while Args['team'..N_teams+1] ~= nil do N_teams = N_teams+1 end
	pp.preprocess(Args,N_teams,'',yesno(Args['crosstable_fractions'] or 'no'))
	local tb_numplayers = tonumber(Args['tb_numplayers']) or 0
	if tb_numplayers > N_teams then
		tb_numplayers = N_teams
		Args['tb_numplayers'] = N_teams
	end
	if tb_numplayers >= 2 then
		pp.preprocess(Args,tb_numplayers,'tb',yesno(Args['crosstable_fractions'] or 'no'))
	end
	-- Which columns to show
	local show_rating = yesno(Args['show_rating'] or 'no')
	local show_played = not yesno(Args['hide_played'] or 'no')
	local hth_first = yesno(Args['hth_before_w'] or 'yes')
	local show_hth = yesno(Args['show_hth'] or 'yes')
	local show_win = yesno(Args['show_win'] or 'yes')
	local show_draw = yesno(Args['show_draw'] or 'no')
	local show_loss = yesno(Args['show_loss'] or 'no')
	local sb_first = yesno(Args['sb_before_w'] or 'no')
	local show_sb = yesno(Args['show_sb'] or 'no')
	local extra_cols = tonumber(Args['extra_cols']) or 0
	-- Custom header options
	local group_head_text = Args['group_header'] or '<abbr title="Group">Grp</abbr>'
	local player_head_text = Args['player_header'] or 'Player'

	-- 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,player_width,player_head_text..VTE_text)				-- Player col
	if full_table and show_rating then
		local rate_date = Args['rate_date'] or ''
		tt = p_sub.colhead(tt,28, '[[FIDE world rankings|Rating]]<br/><small><span style="white-space:nowrap">'..rate_date..'</span></small>')
	end
	if show_played then
		tt = p_sub.colhead(tt,28, '<abbr title="Games Played">Pld</abbr>')		-- Games played col
	end
	tt = p_sub.colhead(tt,28, 'Score')											-- Score col
	if full_table then
		if show_hth and hth_first then
			tt = p_sub.colhead(tt,28, '<abbr title="Head-to-head">H2H</abbr>')	-- Head-to-head col
		end
		if show_sb and sb_first then
			tt = p_sub.colhead(tt,28, '<abbr title="Sonneborn–Berger score">[[Sonneborn–Berger score|SB]]</abbr>')
		end
		if show_win then
			tt = p_sub.colhead(tt,28, 'Wins')									-- Wins col
		end
		if show_draw then
			tt = p_sub.colhead(tt,28, 'Draws')									-- Draws col
		end
		if show_loss then
			tt = p_sub.colhead(tt,28, 'Losses')									-- Losses col
		end
		if show_hth and not hth_first then
			tt = p_sub.colhead(tt,28, '<abbr title="Head-to-head">H2H</abbr>')	-- Head-to-head col if not first tiebreak
		end
		if show_sb and not sb_first then
			tt = p_sub.colhead(tt,28, '<abbr title="Sonneborn–Berger score">[[Sonneborn–Berger score|SB]]</abbr>')
		end
		for ecol=1,extra_cols do
			local extra_head_text = Args['extra_header'..ecol] or ('Extra' .. ecol)
			tt = p_sub.colhead(tt,28,extra_head_text)
		end
		tt.count = tt.count+1
		table.insert(tt.tab_text,results_header_txt)
	end
	
	return tt
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 custom/default options for in table
	local win_points = tonumber(Args['winpoints'])				or 1
	local draw_points = tonumber(Args['drawpoints'])			or 0.5
	local loss_points = tonumber(Args['losspoints'])			or 0
	
	-- Get some input
	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 hth_local = Args['hth_'..team_code_ii]				or ''
	local show_rating = yesno(Args['show_rating'] or 'no')
	local show_played = not yesno(Args['hide_played'] or 'no')
	local score_over_played = yesno(Args['score_over_played'] or 'no')
	local hth_first = yesno(Args['hth_before_w'] or 'yes')
	local show_hth = yesno(Args['show_hth'] or 'yes')
	local show_win = yesno(Args['show_win'] or 'yes')
	local show_draw = yesno(Args['show_draw'] or 'no')
	local show_loss = yesno(Args['show_loss'] or 'no')
	local wdl_iff_hth = yesno(Args['wdl_iff_hth'] or 'no')
	local sb_first = yesno(Args['sb_before_w'] or 'no')
	local show_sb = yesno(Args['show_sb'] or 'no')
	local nosb = yesno(Args['nosb_'..team_code_ii] or 'no')
	local sb_iff_hth = yesno(Args['sb_iff_hth'] or 'no')
	local extra_cols = tonumber(Args['extra_cols']) or 0
	local disp_fractions = yesno(Args['disp_fractions'] or 'yes')
	-- Then calculate some values
	local matches = wins + draws + losses
	local points = win_points*wins + draw_points*draws + loss_points*losses
	local sb_score = 0
	
	local templatestyles = mw.getCurrentFrame():extensionTag{
		name = 'templatestyles', args = { src = 'Screen reader-only/styles.css' }
	}
	hth_local = mw.ustring.gsub(hth_local, '%s*½', '.5')
	if hth_local == '' then
		hth_local = '&mdash;'
	elseif disp_fractions then
		hth_local = tonumber(hth_local) or 0
		if math.floor(hth_local) ~= hth_local then
			if math.floor(hth_local) > 0 then
				hth_local = math.floor(hth_local) .. templatestyles .. '<span class="sr-only">&nbsp;</span><sup>1</sup>&frasl;<sub>2</sub>'
			else
				hth_local = templatestyles .. '<span class="sr-only">&nbsp;</span><sup>1</sup>&frasl;<sub>2</sub>'
			end
		end
	end

	if score_over_played then
		points = '<span style="white-space:nowrap">' .. points .. ' / ' .. matches .. '</span>'
	elseif disp_fractions then
		if math.floor(points) ~= points then
			if math.floor(points) > 0 then
				points = math.floor(points) .. templatestyles .. '<span class="sr-only">&nbsp;</span><sup>1</sup>&frasl;<sub>2</sub>'
			else
				points = templatestyles .. '<span class="sr-only">&nbsp;</span><sup>1</sup>&frasl;<sub>2</sub>'
			end
		end
	end

	-- Sonneborn–Berger score
	if show_sb then
		if (sb_iff_hth and hth_local == '&mdash;') or nosb then
			sb_score = '&mdash;'
		end
		if sb_score == 0 then
			local legs = tonumber(Args['legs']) or 1
			for jj=1,N_teams do
				local tj = Args['team' .. jj]
				local tjpoints = win_points*Args['win_'..tj] + draw_points*Args['draw_'..tj] + loss_points*Args['loss_'..tj]
				if ii ~= jj then
					local match_str = Args['match_' .. team_code_ii .. '_' .. tj] or ''
					for l=1,legs do
						local gii = mw.ustring.match(match_str, '^%s*([^%+%s]*)%s*%+?')
						if gii == '1' then
							sb_score = sb_score + win_points*tjpoints
						elseif gii == '½' then
							sb_score = sb_score + draw_points*tjpoints
						elseif gii == '0' then
							sb_score = sb_score + loss_points*tjpoints
						end
						match_str = mw.ustring.gsub(match_str, '^%s*([^%+%s]*)%s*%+?', '') or ''
					end
				end
			end
		end
	end
	
	-- Some local vars	
	local hth_string
	local tt_return = p_sub.hth(frame,Args,full_table,hth_id_list,nil,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
	
	-- Row building
	if full_table and show_rating then
		local rateii = Args['rating_'..team_code_ii] or ''
		table.insert(t,'| style="'..ii_fw..bg_col..'" |'..rateii..'\n')					-- Rating
	end
	if show_played then
		table.insert(t,'| style="'..ii_fw..bg_col..'" |'..matches..'\n')				-- Played
	end
	table.insert(t,'| style="font-weight: bold;'..bg_col..'" | '..points..'\n')			-- Points
	if full_table then
		if show_hth and hth_first then
			table.insert(t,'| style="'..ii_fw..bg_col..'" |'..(hth_local or '')..'\n')	-- Head-to-head
		end
		if show_sb and sb_first then
			table.insert(t,'| style="'..ii_fw..bg_col..'" |'..sb_score..'\n')			-- Sonneborn–Berger
		end
		if show_win then
			if wdl_iff_hth and hth_local == '&mdash;' then
				wins = '&mdash;'
			end
			table.insert(t,'| style="'..ii_fw..bg_col..'" |'..wins..'\n')				-- Won
		end
		if show_draw then
			if wdl_iff_hth and hth_local == '&mdash;' then
				draws = '&mdash;'
			end
			table.insert(t,'| style="'..ii_fw..bg_col..'" |'..draws..'\n')				-- Drew
		end
		if show_loss then
			if wdl_iff_hth and hth_local == '&mdash;' then
				losses = '&mdash;'
			end
			table.insert(t,'| style="'..ii_fw..bg_col..'" |'..losses..'\n')				-- Lost
		end
		if show_hth and not hth_first then
			table.insert(t,'| style="'..ii_fw..bg_col..'" |'..(hth_local or '')..'\n')	-- Head-to-head if not first tiebreak
		end
		if show_sb and not sb_first then
			table.insert(t,'| style="'..ii_fw..bg_col..'" |'..sb_score..'\n')			-- Sonneborn–Berger
		end
		for ecol=1,extra_cols do
			local extraii = Args['extra'..ecol..'_'..team_code_ii] or ''
			table.insert(t,'| style="'..ii_fw..bg_col..'" |'..extraii..'\n')			-- Extra
		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='Advance to a further round', C='Champion', D='Disqualified', 
		E='Eliminated', G='Guest', H='Host', O='Play-off winner', P='Promoted', Q='Qualified to the phase indicated',
		R='Relegated', T='Qualified, but not yet to the particular phase indicated',
		X='?', Y='?', Z='?'}
	status_called = {	A=false, C=false, D=false, E=false, G=false, H=false, O=false, P=false,
		Q=false, R=false, T=false, X=false, Y=false, Z=false}
	local status_letters = 'ACDEGHOPQRTXYZ'
	
	-- Status position (before or after read and default)
	local stat_pos_val = Args['status_pos'] or ''
	local status_position = 'after' 	-- Default location
	stat_pos_val = string.lower(stat_pos_val)
	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
		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