-- 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
-- Get the args, stripping out blank values
local getArgs = require('Module:Arguments').getArgs
local Args = getArgs(, {parentFirst = true})  
-- Exit early if we are using section transclusion for a different section
if (Args['transcludesection'] and Args['section'])
and Args['transcludesection'] ~= Args['section'] then
return ''
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 = :getParent:getTitle
if mw.title.getCurrentTitle.text == baselink then baselink = '' end
local template_name = Args['template_name']
or (baselink ~= '' and (':' .. baselink))
or ''
local edit_links = template_name == * and *
or :expandTemplate{ title = 'navbar',
args = { mini=1,, template_name} }  
-- 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 = :expandTemplate{ title = 'efn',
args = { group='lower-alpha', Args['team_header_note']} }
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')
-- 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,multirowlegs)
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
ii_start = tonumber(Args['highest_row']) and (tonumber(Args['highest_row']) > top_pos) and tonumber(Args['highest_row']) or top_pos
ii_end = tonumber(Args['lowest_row']) and (tonumber(Args['lowest_row']) < N_teams) and tonumber(Args['lowest_row']) or N_teams
for ii=ii_start,ii_end do
-- Get team info
team_code_ii = team_list[ii]
team_name = Args['name_'..team_code_ii] or team_code_ii
local ii_ .. (Args['team_align'] or '') .. ';'
.. (ii and ii == ii_show and 'font-weight:bold;' or '')
.. (Args['team_nowrap'] and 'white-space:nowrap;' or '')
local team_note = Args['note_'..team_code_ii]
if team_note then
notes_exist = true
-- Only when it exist
-- First check for existence of reference for note
if not Args['note_'..team_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..rand_val..'"'
note_id_list[team_code_ii] = note_id
note_string = :expandTemplate{ title = 'efn',
args = { group='lower-alpha', name=note_id, team_note} }
else
-- Check for existence elsewhere
local note_local_num = team_list[team_note] or ii_end + 1
if note_id_list[team_note] or ((note_local_num >= ii_start) and (note_local_num <= ii_end)) then
-- It exists
note_id = '"table_note_'..team_note..rand_val..'"' -- Identifier
note_string = :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_'..team_note..rand_val..'"'
note_id_list[team_note] = note_id
-- Call refn template
note_string = :expandTemplate{ title = 'efn',
args = { group='lower-alpha', name=note_id, Args['note_'..team_note]} }
end
end
-- Now append this to the team_name string
team_name = team_name..note_string
end
-- Team names
table.insert(t,'|- \n') -- New row
table.insert(t,'! scope="row"'.. (multirowlegs and '')
.. '| '..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 = (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 = :expandTemplate{ title = 'efn',
args = { group='lower-alpha', 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 = :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 = :expandTemplate{ title = 'efn',
args = { group='lower-alpha', 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,multirowlegs)
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 :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..'. ')