Module:PHL sports overall tally explained

require('strict')

local p =

local div =

local evt =

local colors =

local function isnotempty(s) return s and s:match('^%s*(.-)%s*$') ~= end

local function stripwhitespace(text) return text:match("^%s*(.-)%s*$")end

local function findchamp(teams, t, r) local found = (teams[t].res[r].rank

1 or teams[t].res[r].raw

'T1') if found or (t

1) then return found else return findchamp(teams, t - 1, r) endend

local function countties(teams, r) local tie = for kt, vt in pairs(teams) do local raw = vt.res[r].raw or if (raw):match(p.TIE_REGEX) then tie[raw] = (tie[raw] or 0) + 1 end end return tieend

local function getevtdisp(teams, division) local r = 1 local evt_disp = for ke, ve in pairs(evt) do for kd, vd in pairs(div[division]) do local showevt = findchamp(teams, #teams, r) local ties = countties(teams, r) table.insert(evt_disp,) r = r + 1 end end return evt_dispend

local function getevtindex(value) for k, v in pairs(evt) do if v[1]

value then return tonumber(k) end end return tonumber(99)end

local function getvte(frame, args) local baselink = frame:getParent:getTitle if mw.title.getCurrentTitle.text

baselink then baselink = end local vtetemplate = args['tname'] or (baselink ~= and (':' .. baselink)) or

if vtetemplate ~= then return frame:expandTemplate end return nilend

local function getbg(rank, raw) rank = tonumber(tostring(raw):match(p.TIE_REGEX) or rank) or 0 if rank > 0 and rank <= 3 then return colors[rank][1] elseif raw

'WD' then return colors.WD[1] else return nil endend

local function comptiepts(ptsbyrank, trank, teamsize, ctie) local count = ctie['T'..trank] if count

0 then return ptsbyrank[trank] end local limit, total = trank + count - 1, 0 if limit > teamsize then error('Invalid number of teams tied on #'..trank) end for i=trank, limit do total = ptsbyrank[i] + total end return total / countend

local function getpts(rank, raw, ptsbyrank, tsize, ctie) local trank = tonumber(tostring(raw):match(p.TIE_REGEX)) or 0 if trank > 0 then return comptiepts(ptsbyrank,trank,tsize,ctie) or ptsbyrank.NT elseif string.match(raw,'([?|WD])') then return raw else return ptsbyrank[rank] or ptsbyrank.NT endend

local function prefillvalues(args,teams,division,ptsbyrank,ovptsonly) local tally = for kt, vt in pairs(teams) do local res, subtotal, overall, gold, silver, bronze =,, 0, 0, 0, 0 local evt_disp = getevtdisp(teams,division,ptsbyrank) for kr, vr in pairs(vt.res) do local evtprop = evt_disp[kr] if evtprop.show then local rank = tonumber(tostring(vr.raw):match(p.TIE_REGEX)) or vr.rank vr.pts = tonumber(getpts(rank,vr.raw,ptsbyrank,#teams,evtprop.ties)) or 0 subtotal[vr.div] = (tonumber(subtotal[vr.div]) or 0) + vr.pts if rank

1 then gold = gold + 1 elseif rank

2 then silver = silver + 1 elseif rank

3 then bronze = bronze + 1 end table.insert(res, vr) end end for kd, vd in pairs(div[division]) do overall = overall + tonumber(subtotal[vd] or 0) end

if ovptsonly then overall = tonumber(args['pts_'..vt.code]) or overall end table.insert(tally,) end table.sort(tally, function (a, b) return a.overall > b.overall or (a.overall

b.overall and a.rank < b.rank) end) return tallyend

local function medaltable(frame,args,tally,division,isfinal) local mMedals = require('Module:Medals table') local leadingLbl = 'Leads the '..(args['overall'] or 'general')..' championship tally' local legendL = isfinal and 'General champions' or leadingLbl args['team'] = 'Team' args['event'] = 'inst' args['legend_position'] = 'b' args['flag_template'] = args['team_template'] or 'UAAPteam' args['host_note'] = string.format('; %s %s', frame:expandTemplate, legendL) args['notes'] = isfinal and 'Results are final.' or 'Season in progress. Results are not yet final.' for kt, vt in pairs(tally) do local name = args['name_'..vt.code] if kt

1 and vt.overall ~= 0 then args['leading_'..vt.code] = 'yes' end if division

'junior' and isnotempty(args['j_short_'..vt.code]) then args['name_'..vt.code] = frame:expandTemplate elseif division

'senior' and isnotempty(args['short_'..vt.code]) then args['name_'..vt.code] = frame:expandTemplate elseif not isnotempty(name) or name

nil then args['name_'..vt.code] = vt.name end if stripwhitespace(args['status_'..vt.code] or )

'H' then args['host_'..vt.code] = 'yes' args['host'] = 'Season host' end args['gold_'..vt.code] = vt.medals[1] args['silver_'..vt.code] = vt.medals[2] args['bronze_'..vt.code] = vt.medals[3] end return mMedals.createTable(frame, args)end

local function buildtable(frame,args,teams,division,ptsbyrank,showmedals,ovptsonly,sumsonly,isfinal) local tally = prefillvalues(args,teams,division,ptsbyrank,ovptsonly) if showmedals then return medaltable(frame,args,tally,division,isfinal) end local root = mw.html.create local footer = mw.html.create local abbr = mw.html.create('abbr') root = root:tag('table') :addClass('wikitable') :addClass('plainrowheaders') :css('font-size', (ovptsonly or sumsonly) and '100%' or '95%') :css('text-align', 'center') -- header row (1) local evts = tally[1].res local divs = div[division] local row = root:tag('tr') local celltype = not ovptsonly and 'th' or 'td' local showwg, showc, showhost, hidedivs = false, false, false, true if not ovptsonly then row:tag('th') :attr('scope', 'col') :attr('colspan', '2') :wikitext(getvte(frame,args)) abbr:attr('title', 'Mixed or co-ed'):wikitext(divs[3]) -- column spanning by event local prevspan, prevcell, prevevt = 0, nil, nil for ke, ve in pairs(evts) do local evtname = evt[getevtindex(ve.evt)][2] if ve.div

divs[2] then showwg = true elseif ve.div

divs[3] then showc = true end if not sumsonly then if (prevevt

ve.evt) then prevspan = prevspan + 1 prevcell :attr('colspan', prevspan) else prevspan = 1 prevcell = row:tag('th') :attr('scope', 'col') :wikitext(string.format('', evtname, evtname)) prevevt = ve.evt end end end hidedivs = not showwg and not showc row:tag('th') :attr('scope', 'col') :attr('colspan', hidedivs and 1 or (((not showwg and showc) or (showwg and not showc)) and 4 or 5)) :css('border-left-width', '3px') :wikitext('Total') end -- header row (2) row = root:tag('tr') row:tag('th') :attr('scope', 'col') :attr('width', '50px') :wikitext('Rank') :tag('th') :attr('scope', 'col') :attr('width', '90px') :wikitext('Team') if not (ovptsonly or sumsonly) then for ke, ve in pairs(evts) do row:tag('th') :attr('scope', 'col') :attr('width', '22px') :wikitext(ve.div

divs[3] and tostring(abbr) or ve.div) end end if not ovptsonly then for kd, vd in pairs(divs) do if (hidedivs or (not showwg and vd

divs[2]) or (not showc and vd

divs[3])) then break else row:tag('th') :attr('scope', 'col') :attr('width', '22px') :css('border-left-width', (kd

1) and '3px' or nil) :wikitext(vd

divs[3] and tostring(abbr) or vd) end end end row:tag('th') :attr('scope', 'col') :css('border-left-width', hidedivs and '3px' or nil) :wikitext(ovptsonly and 'Points' or 'Overall') -- row spanning by points local prevpts, prevspan, prevrankcell, prevtotalcell = -1, 0, nil, nil -- team row for ka, va in pairs(tally) do local teamtext = va.team

if stripwhitespace(args['status_'..va.code] or )

'H' then showhost = true teamtext = va.team..' (H)' end row = root:tag('tr') if (prevpts

va.overall) then prevspan = prevspan + 1 prevrankcell :attr('rowspan', prevspan) else prevspan = 1 prevrankcell = row:tag(celltype) :attr('scope', 'row') :css('text-align', 'center') :wikitext(ka) end row:tag('td') :attr('scope', 'row') :css('white-space', 'nowrap') :css('text-align', 'left') :wikitext(teamtext) if not ovptsonly then if not sumsonly then for kr, vr in pairs(va.res) do row:tag('td') :css('background-color', getbg(vr.rank,vr.raw)) :wikitext(vr.pts ~= 0 and vr.pts or ptsbyrank.NT) end end for kd, vd in pairs(divs) do if (hidedivs or (not showwg and vd

divs[2]) or (not showc and vd

divs[3])) then break else row:tag('td') :css('border-left-width', (kd

1) and '3px' or nil) :wikitext(va.subtotal[vd] or 0) end end end if (prevpts

va.overall) then prevtotalcell :attr('rowspan', prevspan) else prevspan = 1 prevtotalcell = row:tag(celltype) :attr('scope', 'row') :css('font-weight', 'bold') :css('text-align', 'center') :css('border-left-width', hidedivs and '3px' or nil) :wikitext(va.overall) prevpts = va.overall end end local source, legend = args['source'], footer:tag('div'):cssText('font-size: 90%; margin-bottom: 0.5em;') if source then legend:tag():wikitext('Source: '.. source ..'
') end if showhost then legend:tag('span') :css('font-weight', 'bold') :wikitext('(H)') :done :wikitext(' Season host') if ovptsonly or sumsonly then legend:wikitext('.') end end if not (ovptsonly or sumsonly) then local firsttag = not showhost for kp, vp in pairs(ptsbyrank) do if not string.match(kp,p.TIE_REGEX) and (tonumber(kp) or 0) < 4 then if firsttag

false then legend:wikitext('; ') end legend:tag('span') :css('margin', '0') :css('white-space', 'nowrap') :tag('span') :addClass('legend-text') :css('border', 'none') :css('padding', '1px .3em') :css('background-color', getbg(kp)) :css('font-size', '95%') :css('border', '1px solid #BBB') :css('line-height', '1.25') :css('text-align', 'center') :wikitext(type(vp)

'number' and ' ' or vp) :done :wikitext(' = ' .. (colors[kp] or colors.NT)[2]) firsttag = false end end legend:wikitext('.') end legend:wikitext('
Notes: ' .. (isfinal and 'Results are final.' or 'Season in progress. Results are not yet final.'))

return tostring(root)..tostring(footer)end

function p.main(frame) local getArgs = require('Module:Arguments').getArgs local args = getArgs(frame,) local yesno = require('Module:Yesno') local showmedals = yesno(args['show_medals'] or 'n') local ovptsonly = yesno(args['overall_pts_only'] or 'n') local sumsonly = yesno(args['subtotals_only'] or 'n') local isfinal = yesno(args['final'] or 'y') local division = (args['division'] or 'senior'):lower local template = args['team_template'] or 'UAAPteam' local team_list, defaultpts =, local ptsbyrank = for ka, va in pairs(args) do -- Process team args local i = tostring(ka):match('^team([%d]+)%s*$') or '0' if (tonumber(i) > 0 and isnotempty(va)) then local res, t =, args['team' .. i] local sname = args['short_' .. t] if division

'junior' and isnotempty(args['j_short_' .. t]) then sname = args['j_short_' .. t] end local tname = args['name_' .. t] or (isnotempty(sname) and frame:expandTemplate or frame:expandTemplate ) for ke, ve in pairs(evt) do for kd, vd in pairs(div[division]) do local cvd = vd if (kd

3) then cvd = division:sub(1,1) end local evt_rank = stripwhitespace(args[cvd:lower..'_'..ve[1]..'_'..t] or ) table.insert(res,) end end table.insert(team_list,) end end if #team_list

0 then error ('At least one team required') end for r=1,#team_list do ptsbyrank[r] = tonumber(stripwhitespace(args['pts_'..require('Module:Ordinal')._ordinal(r)] or )) or defaultpts[r] or 0 end return buildtable(frame,args,team_list,division,ptsbyrank,showmedals,ovptsonly,sumsonly,isfinal)end

return p