-- Module to build results cross-tables for standings in Sports-- See documentation for details
require('strict')
local p =
-- Main functionfunction p.main(frame) -- Get the args, stripping out blank values local getArgs = require('Module:Arguments').getArgs local Args = getArgs(frame,)
-- Exit early if we are using section transclusion for a different section local tsection = frame:getParent.args['transcludesection'] or frame:getParent.args['section'] or local bsection = frame.args['section'] or if(tsection ~= and bsection ~= ) then if(tsection ~= bsection) 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 local multirowlegs = (Args['multirowlegs'] or 'no') ~= 'no'
-- Edit links if requested local baselink = frame:getParent:getTitle if mw.title.getCurrentTitle.text
and or require('Module:Navbar')._navbar
-- Get the custom start point for the table (most will start by default at 1) local top_pos = tonumber(Args['highest_pos']) or 1 -- Get the custom end point for the table (unrestricted if bottom_pos is < top_pos) local bottom_pos = tonumber(Args['lowest_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')
-- Alternative syntax for team list if Args['team_order'] and Args['team_order'] ~= then local tlist = mw.text.split(Args['team_order'], '%s*[;,]%s*') for k, tname in ipairs(tlist) do if tname ~= then Args['team' .. k] = tname end end end
if Args['team_header_note'] then notes_exist=true local note_string = frame:expandTemplate team_header = team_header .. note_string end
-- 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,'
- \n') -- New row table.insert(t,'! scope="row"'.. (multirowlegs and ' rowspan=' .. legs or ) .. 'style="'.. ii_style ..'" | '..team_name..'\n') -- Position number -- Now include note to match results if needed for jj=top_pos,N_teams do local team_code_jj = team_list[jj] if ii jj then -- Nothing else for l=1,legs do local m = (legs1) 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_'..l.."_"..team_code_ii..'_'..team_code_jj..rand_val..'"' note_id_list[team_code_ii..'_'..team_code_jj] = note_id note_string = frame:expandTemplate else -- Check for existence elsewhere local note_local_num = team_list[match_note] or ii_end + 1 if note_id_list[match_note] then -- Referencing an existing note note_id = note_id_list[match_note] -- Borrow the existing identifier note_string = frame:extensionTag elseif (note_local_num >= ii_start) and (note_local_num <= ii_end) then -- Referencing a player note from a match note. In this case, we remove the leg part note_id = '"table_note_'..match_note..rand_val..'"' note_string = frame:extensionTag else -- Referencing a different match note before its defined with its content note_id = '"table_note_'..l.."_"..match_note..rand_val..'"' note_id_list[match_note] = note_id note_string = frame:expandTemplate 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,multirowlegs) end -- Close table table.insert(t, ' |
-- 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
-- Create footer text -- Date updating if string.lower(update)
then -- Empty parameter table.insert(t_footer,'Updated to match(es) played on unknown. ') elseif string.lower(update)
'FBR' then table.insert(t_footer, Args['team_header'] and '
Legend: Blue = left column team win; Yellow = draw; Red = top row team win.' or '
Legend: Blue = home team win; Yellow = draw; Red = away team win.') elseif (Args['matches_style'] or )
local templatestyles = frame:extensionTag
-- Add notes (if applicable) if notes_exist then table.insert(t_footer,'
Notes:') t_footer = templatestyles .. '
'..table.concat(t_footer)..'
' t_footer = t_footer..frame:expandTemplate else t_footer = templatestyles .. '
'..table.concat(t_footer)..'
' end
-- Add footer to main text table table.insert(t,t_footer)
-- Rewrite anchor links for k=1,#t do if t[k]:match('%[%[#[^%[%]]*%|') then t[k] = mw.ustring.gsub(t[k], '(%[%[)(#[^%[%]]*%|)', '%1' .. baselink .. '%2') end end
return '
' .. '
\n' .. table.concat(t) .. '
'end
-- Other functionslocal function get_short_name(s, t, n, ss) -- return short name if defined if s and s ~= then return s end -- deflag if necessary if ss and n then if ss
'flag' then n = mw.ustring.gsub(n, '(
%s*%[%[[Ff][Ii][Ll][Ee]:[^%[%]]*link=)[^%|%[%]]*(%]%][^<>]*)%s*%[%[([^%[%]%|]*)%|[^%[%]]*%]%]', '%1%3%2') n = mw.ustring.gsub(n, '(%[%[[Ff][Ii][Ll][Ee]:[^%[%]]*link=)[^%|%[%]]*(%]%])%s* %s*%[%[([^%[%]%|]*)%|[^%[%]]*%]%]', '%1%3%2') n = mw.ustring.gsub(n, '(%[%[[Ff][Ii][Ll][Ee]:[^%[%]]*link=)[^%|%[%]]*(%]%])%s*%[%[([^%[%]%|]*)%|[^%[%]]*%]%]', '%1%3%2') n = mw.ustring.gsub(n, '.*(%s*%[%[[Ff][Ii][Ll][Ee]:[^%[%]]*%]%][^<>]*).*', '%1') n = mw.ustring.gsub(n, '.*(%[%[[Ff][Ii][Ll][Ee]:[^%[%]]*%]%]).*', '%1') n = mw.ustring.gsub(n, ' ()', '%1') end 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') n = mw.ustring.gsub(n, '(%[%[[^%|%]]*%|)([A-Z][A-Z][A-Z])(%]%])
]*>%([A-Z][A-Z][A-Z]%)', '%1%2%3') return n end -- nothing worked, so just return the unlinked team abbr return t or endlocal function get_score_background(s, c) local s1, s2 -- Define the colouring local wc, lc, tc if c
'level3' then wc, lc, tc = '#DDFCFF', '#FDD', '#FFD' -- blue3, red3, yellow3 elseif c
-- check for override if s:match('^%s*
]*).-$') then local c = mw.ustring.gsub(s,'^%s*]*).-$', '%1') return c 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 if s:match('
]*>(.-)') then s = s:match(']*>(.-)') end-- get the scores s1 = tonumber(mw.ustring.gsub(s or , '^%s*([%d%.]+)%s*–%s*([%d%.]+).*', '%1') or ) or s2 = tonumber(mw.ustring.gsub(s or , '^%s*([%d%.]+)%s*–%s*([%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 endend
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 send
function p.header(tt,Args,p_sub,N_teams,team_list,legs,multirowlegs) 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 if multirowlegs and l > 1 then break end 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], Args['short_style'] or ) local bl = legs > 1 and ii
function p.row(tt,Args,N_teams,team_list,ii,ii_show,legs,multirowlegs) -- 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 if multirowlegs and l > 1 then table.insert(tt,'|- \n') -- New row end for jj=top_pos,N_teams do team_code_jj = team_list[jj] local m = (legs
top_pos and 'border-left:2px solid #aaa;' or
if ii
'null' then -- Solid cell fw = 'font-weight:' .. (ii
-- Grey background color for solid cell if Args['solid_cell']
ii_show or jj
-- Reformat dashes if result ~= then result = format_score(result) end -- Background coloring if enabled if matches_style
'OT' then bg = get_score_background(result,'level2') elseif result_extra
'BSR' and result ~= then if result_extra
'OTL' then bg = get_score_background('0–1','level3') elseif result_extra
'L' then bg = get_score_background('0–1',) elseif result_extra
return ttend
return p