Jump to content

Module:NBA team standings

Permanently protected module
From Wikipedia, the free encyclopedia

-- this module implements [[Template:NBA team standings]]
local p = {}

local math_module = require("Module:Math")

local headings = {
	["#"] = {"#", "#", "5"},
	["W"] = {"W", "Games won", "5"},
	["L"] = {"L", "Games lost", "5"},
	["PCT"] = {"PCT", "Winning percentage", "5"},
	["GB"] = {"GB", "Games behind", "7.5"},
	["Home"] = {"Home", "Home record", "7.5"},
	["Road"] = {"Road", "Road record", "7.5"},
	["Div"] = {"Div", "Division record", "7.5"},
	["GP"] = {"GP", "Games played", "7.5"}
}

local highlight = "#CCFFCC"
local splitcolor = "#CCCCCC"
local divleadermark = " *"

local function get_division(division)
	if division then
		division = division:sub(1,1):upper() .. division:sub(2,-1) -- ucfirst
		return '[[' .. division .. ' Division (NBA)|' .. division .. ' Division]]'
	else
		return nil
	end
end

local function get_conference(conference)
	if conference then
		conference = conference:sub(1,1):upper() .. conference:sub(2,-1) -- ucfirst
		return '[[' .. conference .. 'ern Conference (NBA)|' .. conference .. 'ern Conference]]'
	else
		return nil
	end
end

local function rnd(num, digits)
	-- This function implements {{rnd}}
	return math_module._precision_format(tostring(num), digits)
end

local function winpct(w, l)
	local pct = '–'
	if (w + l) > 0 then
		pct = rnd(w / (w + l), 3):gsub('^0', '')
	end
	return pct
end

local function gbformat(hw, hl, rw, rl, hw1, hl1, rw1, rl1)
	if (tonumber(hw1 or '0') == hw1 and tonumber(hl1 or '0') == hl1
		and tonumber(rw1 or '0') == rw1 or tonumber(rl1 or '0') == rl1) then
		local gb = ((hw1 - hl1 + rw1 - rl1) - (hw - hl + rw - rl))/2
		if gb == 0 then
			return '–'
		end
		return rnd(gb, 1)
	end
	return '–'
end

function p._division(args)
	-- division name
	local division = args['division']:lower()
	-- division leader record
	local dloffset = 8*((tonumber(args[division .. 'leader']) or 1) - 1)
	local dlhw = tonumber(args[dloffset + 3])
	local dlhl = tonumber(args[dloffset + 4])
	local dlrw = tonumber(args[dloffset + 5])
	local dlrl = tonumber(args[dloffset + 6])
	-- start the table
	local root = mw.html.create('table')
		:addClass('wikitable')
		:css('width', args['width'] or '500px')
		:css('font-size', args['font-size'] or '95%')
		:css('text-align', 'center')
	-- table headings
	local row = root:tag('tr')
	row:tag('th'):wikitext(get_division(args['division']))
	for k,v in ipairs({"W", "L", "PCT", "GB", "Home", "Road", "Div", "GP"}) do
		local abbr, text, width = v, v, 0
		if headings[v] then
			abbr = headings[v][1] or abbr
			text = headings[v][2] or abbr or text
			width = tonumber(headings[v][3]) or width
			if text ~= abbr then
				text = '<abbr title="' .. text .. '">' .. abbr .. '</abbr>'
			end
		end
		row:tag('th')
			:css('width', (width > 0) and width .. '%' or nil)
			:wikitext(text)
	end
	-- rows
	local pos = 1
	while args[(pos - 1)*8 + 1] or args[(pos - 1)*8 + 2] do
		local offset = (pos - 1)*8
		local team = args[offset + 1] or ''
		local abbr = args[offset + 2] or ''
		local hw = tonumber(args[offset + 3]) or 0
		local hl = tonumber(args[offset + 4]) or 0
		local rw = tonumber(args[offset + 5]) or 0
		local rl = tonumber(args[offset + 6]) or 0
		local wldiff = hw - hl + rw - rl
		local divrecord = args[offset + 7] or ''
		local divname = (args[offset + 8] or ''):lower()
		if divname == division then
			local rowcolor = nil
			if abbr == args['team'] then
				rowcolor = highlight
			end
			row = root:tag('tr'):css('background-color', rowcolor)
			-- team name
			row:tag('td'):css('text-align', 'left'):wikitext(team)
			-- wins
			row:tag('td'):wikitext(hw + rw)
			-- losses
			row:tag('td'):wikitext(hl + rl)
			-- percentage
			row:tag('td'):wikitext(winpct(hw + rw, hl + rl))
			-- gb
			row:tag('td'):wikitext(gbformat(hw, hl, rw, rl, dlhw, dlhl, dlrw, dlrl))
			-- home record
			row:tag('td'):wikitext(hw .. '&zwj;&ndash;&zwj;' .. hl)
			-- road record
			row:tag('td'):wikitext(rw .. '&zwj;&ndash;&zwj;' .. rl)
			-- div record
			row:tag('td'):wikitext(divrecord)
			-- played
			row:tag('td'):wikitext(hw + hl + rw + rl)
		end
		pos = pos + 1
	end
	return root
end

function p._conference(args)
	-- conference leader
	local cloffset = 0
	local clhw = tonumber(args[cloffset + 3])
	local clhl = tonumber(args[cloffset + 4])
	local clrw = tonumber(args[cloffset + 5])
	local clrl = tonumber(args[cloffset + 6])
	-- start the table
	local root = mw.html.create('table')
		:addClass('wikitable')
		:css('width', args['width'] or '400px')
		:css('font-size', args['font-size'] or '95%')
		:css('text-align', 'center')
	-- title
	root:tag('tr'):tag('th'):attr('colspan', 7):wikitext(get_conference(args['conference']))
	-- headings
	local row = root:tag('tr')
	for k,v in ipairs({"#", "Team", "W", "L", "PCT", "GB", "GP"}) do
		local abbr, text, width = v, v, 0
		if headings[v] then
			abbr = headings[v][1] or abbr
			text = headings[v][2] or abbr or text
			width = tonumber(headings[v][3]) or width
			if text ~= abbr then
				text = '<abbr title="' .. text .. '">' .. abbr .. '</abbr>'
			end
		end
		row:tag('th')
			:css('width', (width > 0) and width .. '%' or nil)
			:wikitext(text)
	end
	-- rows
	local pos = 1
	local div1leader = tonumber(args[(args['div1name'] or ''):lower() .. 'leader'])
	local div2leader = tonumber(args[(args['div2name'] or ''):lower() .. 'leader'])
	local div3leader = tonumber(args[(args['div3name'] or ''):lower() .. 'leader'])
	while args[(pos - 1)*8 + 1] or args[(pos - 1)*8 + 2] do
		local offset = (pos - 1)*8
		local team = args[offset + 1] or ''
		local abbr = args[offset + 2] or ''
		local hw = tonumber(args[offset + 3]) or 0
		local hl = tonumber(args[offset + 4]) or 0
		local rw = tonumber(args[offset + 5]) or 0
		local rl = tonumber(args[offset + 6]) or 0
		local wldiff = hw - hl + rw - rl
		local divrecord = args[offset + 7] or ''
		local divname = (args[offset + 8] or ''):lower()
		if (pos == div1leader or pos == div2leader or pos == div3leader) then
			team = team .. divleadermark
		end
		local rowcolor = nil
		if abbr == args['team'] then
			rowcolor = highlight
		end
		row = root:tag('tr'):css('background-color', rowcolor)
		-- position
		row:tag('th'):wikitext(pos)
		-- team name
		row:tag('td'):css('text-align', 'left'):wikitext(team)
		-- wins
		row:tag('td'):wikitext(hw + rw)
		-- losses
		row:tag('td'):wikitext(hl + rl)
		-- percentage
		row:tag('td'):wikitext(winpct(hw + rw, hl + rl))
		-- gb
		row:tag('td'):wikitext(gbformat(hw, hl, rw, rl, clhw, clhl, clrw, clrl))
		-- played
		row:tag('td'):wikitext(hw + hl + rw + rl)
		if args['split' .. pos] then
			root:tag('tr'):css('background-color', splitcolor):tag('td'):attr('colspan', 7)
		end
		pos = pos + 1
	end
	return root
end
	
function p.main(frame)
	local args = require('Module:Arguments').getArgs(frame)
	if args['division'] then
		return p._division(args)
	else
		return p._conference(args)
	end
end

return p