Jump to content

Module:CFB schedule/sandbox

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Frietjes (talk | contribs) at 18:00, 4 September 2018 (Created page with '-- This module implements {{CFB schedule}} local p = {} local dagger = '<sup class="CFB-schedule-hcgame">alt=dagger|link=</sup>' l...'). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
(diff) ← Previous revision | Latest revision (diff) | Newer revision → (diff)
-- This module implements {{CFB schedule}}
local p = {}

local dagger = '<sup class="CFB-schedule-hcgame">[[File:Dagger-14-plain.png|alt=dagger|link=]]</sup>'

local haslocgamename = false
local hasoppgamename = false
local haslocrivalry = false
local hasopprivalry = false

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

local function yesno(s, d)
	s = (s or ''):lower()
	if (s == 'no' or s == 'n') then
		return false
	elseif (s == 'yes' or s == 'y') then
		return true
	else
		return d
	end
end

local function ifexist(page)
    if not page then return false end
    if mw.title.new(page).exists then return true end
    return false
end

local function getdivision(y)
	if y >= 2006 then
		return 'NCAA Division I FBS'
	elseif y >= 1978 then
		return 'NCAA Division I-A'
	elseif y >= 1973 then
		return 'NCAA Division I'
	elseif y >= 1956 then
		return 'NCAA University Division'
	elseif y >= 1910 then
		return 'NCAA'
	elseif y >= 1906 then
		return 'Intercollegiate Athletic Association of the United States'
	else
		return 'college'
	end

	return ''
end

local function getpolltext(y, d, p)
	-- default poll is the Coaches poll
	if (p or '') == '' then
		p = 'Coaches\''
	end
	
	-- if p is linked then just return p
	if (p or ''):find('[%[%]]') then
		return p
	end

	-- else if y is a number
	if isnotempty(y) and tonumber(y) then
		if (d or '') == '' then
			d = getdivision(tonumber(y))
		end

		return '[[' .. y .. ' ' .. d .. ' football rankings'
					.. '#' .. p .. ' Poll|' .. p .. ' Poll]]'
					.. ' released prior to the game'
	end
	
	-- else if d is not empty
	if isnotempty(d) then
		d = d .. ' '
		
		if ifexist(d .. p .. ' Poll') then
			return '[[' .. d .. p .. ' Poll|' .. p .. ' Poll]]'
				.. ' released prior to the game'
		end
	end

	-- else if p Poll is an article
	if ifexist(p .. ' Poll') then
		return (d or '') .. '[[' .. p .. ' Poll]]'
			.. ' released prior to the game'
	end
	
	return (d or '') .. p .. ' poll released prior to the game'	
end

local function getopp(s, atvs)
	s = mw.ustring.gsub(s, '<[Nn][Cc][Gg]>', '<span class="CFB-schedule-ncgame">*</span>')
	s = mw.ustring.gsub(s, '<[Hh][Cc]>', dagger)
	atvs = mw.ustring.gsub(atvs or '', '^%s*@%s*', 'at')
	atvs = mw.ustring.gsub(atvs or '', '^%s*[Vv][Ss]?[%.%s]*', 'vs.')
	s = mw.ustring.gsub(s, '^([A-Za-z%.%s]*)[Nn][Oo][%.%s]*([0-9])', '%1 No.&nbsp;%2' )
	s = mw.ustring.gsub(s, '^([A-Za-z%.%s]*)#([0-9])', '%1 No.&nbsp;%2')
	if mw.ustring.match(s, '%s%(%[%[') then 
		if mw.ustring.match(s, '%s%(%[%[[^%]]*%|%s*[Rr]ivalry') then 
			hasopprivalry = true
		else
			hasoppgamename = true
		end
	end
	if atvs ~= '' then
		return atvs .. ' ' .. s
	end
	return atvs .. s
end

local function getrank(s)
	s = mw.ustring.gsub(s, '^%s*([%d][%d]*)', 'No.&nbsp;%1')
	return s
end

local function getsite(s,l,gn)
	if s ~= '' and l ~= '' then
		local r = mw.html.create('div')
		local u = r:addClass('hlist'):tag('ul')
		if gn ~= '' then gn = ' (' .. gn .. ')' end
		u:tag('li'):wikitext(s)
		u:tag('li'):wikitext(l .. gn)
		if mw.ustring.match(l, '%s%(%[%[') then 
			if mw.ustring.match(l, '%s%(%[%[[^%]]*%|%s*[Rr]ivalry') then 
				haslocrivalry = true
			else
				haslocgamename = true
			end
		end
		return tostring(r)
	else
		return s .. l
	end
end

local function getresult(s)
	local bg = 'inherit'
	s = mw.ustring.gsub(s or '', '&[MmNn][Dd][Aa][Ss][Hh];', '–')
	local r = ''
	if mw.ustring.match(s, '^%s*[%a]%s*[%d][%d]*[%D]%s*[%d][%d]*%s*.*%s*$') then
		local t = {'', '', '', ''}
		for k = 1,4 do
			t[k] = mw.ustring.gsub(s,'^%s*([%a])%s*([%d][%d]*)[%D]%s*([%d][%d]*)%s*(.*)%s*$', '%' .. k)
		end
		local wl, s1, s2, n = t[1], t[2], t[3], t[4]
		wl = wl:upper()
		if wl == 'W' then
			bg = '#DDFFDD'
		elseif wl == 'L' then
			bg = '#FFDDDD'
		elseif wl == 'T' then
			bg = '#FFFFE6'
		elseif wl == 'V' then
			bg = '#F0E8E8'
			wl = 'W'
			n = n .. ' (vacated)'
		end
		r = '<span style="display:inline-block; font-weight:bold; width:1em">' .. wl .. '</span> ' .. s1 .. '–' .. s2 .. n
	else
		r = s
	end
	return r, bg
end

local function getfootnotes(ncg, hc, oe, rank, opprank, poll, tz)
	-- footnotes
	local fn = {}
	if ncg then
		table.insert(fn,'*Non-conference game')
	end
	if hc then
		table.insert(fn, dagger .. 'Homecoming')
	end
	if isnotempty(oe)  then
		table.insert(fn,args['other-event'])
	end
	if (rank == true) or (opprank == true) then
		table.insert(fn, '<sup>#</sup>Rankings from ' .. poll)
	end
	if isnotempty(tz) then
		table.insert(fn,'All times are in [[' .. tz .. ' Time Zone|' .. tz .. ' time]]')
	end
	
	if (#fn > 0) then
		local res = mw.html.create('div')
				:addClass('hlist')
				:tag('ul')
					:wikitext('<li>' .. table.concat(fn,'</li><li>') .. '</li>')
					:done()
		return tostring(res)
	else
		return nil
	end
end

local function make_outer_table(args)
	local ranknote   = yesno(args['rank'], true) and '<sup>#</sup>' or ''
	local showdate   = yesno(args['date'], false)
	local showtime   = yesno(args['time'], false)
	local showrank   = yesno(args['rank'], false)
	local showtv     = yesno(args['tv'], false)
	local showattend = yesno(args['attend'], false)
	local showsource = yesno(args['source'], false)
	local ncg, hc = false, false
	local row 
	
	-- Step 1: Inspect the rows to determine which headers are active
	local k = 1
	while args[k] ~= nil do
		if showdate == false then
			if args[k]:find('<td[^>]*CFB%-schedule%-date[^>]*>%s*[^%s<]') then
				showdate = true
			end
		end
		if showtime == false then
			if args[k]:find('<td[^>]*CFB%-schedule%-time[^>]*>%s*[^%s<]') then
				showtime = true
			end
		end
		if showrank == false then
			if args[k]:find('<td[^>]*CFB%-schedule%-rank[^>]*>%s*[^%s<]') then
				showrank = true
			end
		end
		if showtv == false then
			if args[k]:find('<td[^>]*CFB%-schedule%-tv[^>]*>%s*[^%s<]') then
				showtv = true
			end
		end
		if showattend == false then
			if args[k]:find('<td[^>]*CFB%-schedule%-attend[^>]*>%s*[^%s<]') then
				showattend = true
			end
		end
		if showsource == false then
			if args[k]:find('<td[^>]*CFB%-schedule%-source[^>]*>%s*[^%s<]') then
				showsource = true
			end
		end
		if ncg == false then
			if args[k]:find('<s[pu][ap][^>]*CFB%-schedule%-ncgame') then
				ncg = true
			end
		end
		if hc == false then
			if args[k]:find('<s[pu][ap][^>]*CFB%-schedule%-hcgame') then
				hc = true
			end
		end
		k = k + 1
	end
	
	-- Step 2: Build the table
	local root = mw.html.create('table')
	root:addClass('wikitable')
		:css('font-size', '95%')

	-- add the headers
	local cols = 3
	row = root:tag('tr')
	if showdate then
		row:tag('th'):wikitext('Date')
		cols = cols + 1
	end
	if showtime then
		row:tag('th'):wikitext('Time')
		cols = cols + 1
	end
	row:tag('th'):wikitext('Opponent')
	if showrank then
		row:tag('th'):wikitext('Rank' .. ranknote)
		cols = cols + 1
	end
	row:tag('th'):wikitext('Site')
	if showtv then
		row:tag('th'):wikitext('TV')
		cols = cols + 1
	end
	row:tag('th'):wikitext('Result')
	if showattend then
		row:tag('th'):wikitext('Attendance')
		cols = cols + 1
	end
	if showsource then
		row:tag('th'):wikitext('Source')
		cols = cols + 1
	end
	
	k = 1
	while args[k] ~= nil do
		row = args[k] or ''
		if showdate then
			row = mw.ustring.gsub(row, '<td[^>]*CFB%-schedule%-date[^>]*>', '<td>')
		else
			row = mw.ustring.gsub(row, '<td[^>]*CFB%-schedule%-date[^>]*>%s*</td>%s*', '')
		end
		if showtime then
			row = mw.ustring.gsub(row, '<td[^>]*CFB%-schedule%-time[^>]*>', '<td>')
		else
			row = mw.ustring.gsub(row, '<td[^>]*CFB%-schedule%-time[^>]*>%s*</td>%s*', '')
		end
		if showrank then
			row = mw.ustring.gsub(row, '<td[^>]*CFB%-schedule%-rank[^>]*>', '<td>')
		else
			row = mw.ustring.gsub(row, '<td[^>]*CFB%-schedule%-rank[^>]*>%s*</td>%s*', '')
		end
		if showtv then
			row = mw.ustring.gsub(row, '<td[^>]*CFB%-schedule%-tv[^>]*>', '<td>')
		else
			row = mw.ustring.gsub(row, '<td[^>]*CFB%-schedule%-tv[^>]*>%s*</td>%s*', '')
		end
		if showattend then
			row = mw.ustring.gsub(row, '<td[^>]*CFB%-schedule%-attend[^>]*>', '<td style="text-align:center">')
		else
			row = mw.ustring.gsub(row, '<td[^>]*CFB%-schedule%-attend[^>]*>%s*</td>%s*', '')
		end
		if showsource then
			row = mw.ustring.gsub(row, '<td[^>]*CFB%-schedule%-source[^>]*>', '<td style="text-align:center">')
		else
			row = mw.ustring.gsub(row, '<td[^>]*CFB%-schedule%-source[^>]*>%s*</td>%s*', '')
		end
		root:wikitext(row)
		k = k + 1
	end
	
	-- footnotes
	local fnotes = getfootnotes(
		ncg, hc, args['other-event'] or args['other_event'] or args['otherevent'], 
		showrank, 
		yesno(args['opprank'], false), 
		getpolltext(args['rank_year'] or args['rankyear'], args['rank_division'] or args['rankdivision'], args['poll']), 
		args['timezone'])
	
	if fnotes ~= nil then
		root:tag('tr')
				:tag('td')
				:attr('colspan',cols)
				:css('font-size', '85%')
				:wikitext(fnotes)
	end
	return tostring(root)
end

local function convert_table(args)
	local function splitresult(s)
		local wl = ''
		s = mw.ustring.gsub(s or '', '&[MmNn][Dd][Aa][Ss][Hh];', '–')
		local r = ''
		if mw.ustring.match(s, '^%s*[%a]%s*[%d][%d]*[%D]%s*[%d][%d]*%s*.*%s*$') then
			local t = {'', '', '', ''}
			for k = 1,4 do
				t[k] = mw.ustring.gsub(s,'^%s*([%a])%s*([%d][%d]*)[%D]%s*([%d][%d]*)%s*(.*)%s*$', '%' .. k)
			end
			local wl, s1, s2, n = t[1], t[2], t[3], t[4]
			wl = wl:lower()
			return wl, s1 .. '–' .. s2 .. n
		end
		return '', s
	end
	res = '{{CFB schedule\n'
	res = res .. (yesno(args['opprank'], false) == false and '' or '| opprank = y\n')
	res = res .. (isnotempty(args['other-event']) 
			and '| other-event = ' .. args['other-event'] .. '\n' or '')
	res = res .. (isnotempty(args['rankyear']) 
			and '| rankyear = ' .. args['rankyear'] .. '\n' or '')
	res = res .. (isnotempty(args['rankdivision']) 
			and '| rankdivision = ' .. args['rankdivision'] .. '\n' or '')
	res = res .. (isnotempty(args['poll']) 
		and '| poll = ' .. args['poll'] .. '\n' or '')
	res = res .. (isnotempty(args['timezone']) 
		and '| timezone = ' .. args['timezone'] .. '\n' or '')
	
	-- switch headers on and off
	local headers = {'Date', 'Time', 'At/Vs', 'Opponent', 'Rank', 'Site', 'Location', 'TV', 'Result', 'Attendance', 'Source'}
	local resultoffset = 8

	for k = #headers,1,-1 do
		if headers[k] == 'Time' and (yesno(args['time'], false) == false) then
			table.remove(headers,k)
			resultoffset = resultoffset - 1
		elseif headers[k] == 'At/Vs' and (yesno(args['atvs'], true) == false) then
			table.remove(headers,k)
			resultoffset = resultoffset - 1
		elseif headers[k] == 'Rank' and (yesno(args['rank'], false) == false) then
			table.remove(headers,k)
			resultoffset = resultoffset - 1
		elseif headers[k] == 'TV' and (yesno(args['tv'], false) == false) then
			table.remove(headers,k)
			resultoffset = resultoffset - 1
		elseif headers[k] == 'Attendance' and (yesno(args['attend'], false) == false) then
			table.remove(headers,k)
		elseif headers[k] == 'Source' and (yesno(args['source'], false) == false) then
			table.remove(headers,k)
		end
	end
	
	-- parse the table
	local k = 1
	local stopflag = (args[k] == nil) and true or false
	while stopflag == false do
		res = res .. '|{{CFB schedule entry\n'
		for j = 1,#headers do
			if headers[j] == 'Date' then
				res = res .. '| date = ' .. mw.ustring.gsub(args[k] or '', '^%s*(.-)%s*$', '%1') .. '\n'
			elseif headers[j] == 'Time' then
				res = res .. '| time = ' .. mw.ustring.gsub(args[k] or '', '^%s*(.-)%s*$', '%1') .. '\n'
			elseif headers[j] == 'At/Vs' then
				local atvs = mw.ustring.gsub(args[k] or '', '^%s*(.-)%s*$', '%1')
				atvs = mw.ustring.gsub(atvs, '^@', 'at')
				atvs = mw.ustring.gsub(atvs, '^[Vv][Ss]?[%.%s]*', 'vs.')
				if mw.ustring.find(atvs, '^at') then
					res = res .. '| away = y\n'
				elseif mw.ustring.find(atvs, '^vs') then
					res = res .. '| neutral = y\n'
				elseif atvs ~= '' then 
					res = res .. '| atvs = ~' .. atvs .. '~\n'
				end
			elseif headers[j] == 'Opponent' then
				local opp = mw.ustring.gsub(args[k] or '', '^%s*(.-)%s*$', '%1')
				if mw.ustring.find(opp, '%s*<[Nn][Cc][Gg]>%s*') then
					opp = mw.ustring.gsub(opp, '%s*<[Nn][Cc][Gg]>%s*', ' ')
					res = res .. '| nonconf = y\n'
				end
				if mw.ustring.find(opp, '%s*<[Hh][Cc]>%s*') then
					opp = mw.ustring.gsub(opp, '%s*<[Hh][Cc]>%s*', ' ')
					res = res .. '| homecoming = y\n'
				end
				opp = mw.ustring.gsub(opp, '^%s*(.-)%s*$', '%1')
				opp = mw.ustring.gsub(opp, '^[Nn][Oo][%.%s]*([0-9])', '#%1' )
				if mw.ustring.find(opp, '^#([0-9]+)%s*') then
					local orank = mw.ustring.gsub(opp, '^#([0-9]+)%s*(.-)$', '%1' )
					opp = mw.ustring.gsub(opp, '^#([0-9]+)%s*(.-)$', '%2' )
					res = res .. '| opprank = ' .. orank .. '\n'
				end
				if mw.ustring.find(opp, '^(.-)%s*%((%[%[[^%[%]]*%]%])%)%s*$') then
					local rgame = mw.ustring.gsub(opp, '^(.-)%s*%((%[%[[^%[%]]*%]%])%)%s*$', '%2')
					opp = mw.ustring.gsub(opp, '^(.-)%s*%((%[%[[^%[%]]*%]%])%)%s*$', '%1')
					res = res .. '| gamename = ' .. rgame .. '\n'
				end
				res = res .. '| opponent = ' .. opp .. '\n'
			elseif headers[j] == 'Rank' then
				res = res .. '| rank = ' .. mw.ustring.gsub(args[k] or '', '^%s*(.-)%s*$', '%1') .. '\n'
			elseif headers[j] == 'Site' then
				res = res .. '| stadium = ' .. mw.ustring.gsub(args[k] or '', '^%s*(.-)%s*$', '%1') .. '\n'
			elseif headers[j] == 'Location' then
				local loc = mw.ustring.gsub(args[k] or '', '^%s*(.-)%s*$', '%1')
				if mw.ustring.find(loc, '^(.-)%s*%((%[%[[^%[%]]*%]%])%)%s*$') then
					local rgame = mw.ustring.gsub(loc, '^(.-)%s*%((%[%[[^%[%]]*%]%])%)%s*$', '%2')
					loc = mw.ustring.gsub(loc, '^(.-)%s*%((%[%[[^%[%]]*%]%])%)%s*$', '%1')
					res = res .. '| gamename = ' .. rgame .. '\n'
				end
				res = res .. '| cityst = ' .. loc .. '\n'
			elseif headers[j] == 'TV' then
				res = res .. '| tv = ' .. mw.ustring.gsub(args[k] or '', '^%s*(.-)%s*$', '%1') .. '\n'
			elseif headers[j] == 'Result' then
				local wl, score = splitresult(args[k] or '')
				res = res .. '| w/l = ' .. wl .. '\n'
				res = res .. '| score = ' .. score .. '\n'
			elseif headers[j] == 'Attendance' then
				res = res .. '| attend = ' .. mw.ustring.gsub(args[k] or '', '^%s*(.-)%s*$', '%1') .. '\n'
			elseif headers[j] == 'Source' then
				res = res .. '| source = ' .. mw.ustring.gsub(args[k] or '', '^%s*(.-)%s*$', '%1') .. '\n'
			else
				res = res .. '| ?? = ' .. mw.ustring.gsub(args[k] or '', '^%s*(.-)%s*$', '%1') .. '\n'
			end
			k = k + 1
			stopflag = (args[k] == nil) and true or false
		end
		res = res .. '}}\n'
	end
	res = res .. '}}'
	
	return res
end

local function make_table(args)
	local ranknote = yesno(args['rank'], false) and '<sup>#</sup>' or ''
	local oppranknote = yesno(args['opprank'], false) and '<sup>#</sup>' or ''
	local hasgamename = true
	
	-- switch headers on and off
	local headers = {'Date', 'Time', 'At/Vs', 'Opponent', 'Rank', 'Site', 'Location', 'Game name', 'TV', 'Result', 'Attendance', 'Source'}
	local resultoffset = 9
	
	local ncg, hc = false, false

	for k = #headers,1,-1 do
		if headers[k] == 'Time' and (yesno(args['time'], false) == false) then
			table.remove(headers,k)
			resultoffset = resultoffset - 1
		elseif headers[k] == 'At/Vs' and (yesno(args['atvs'], true) == false) then
			table.remove(headers,k)
			resultoffset = resultoffset - 1
		elseif headers[k] == 'Rank' and (yesno(args['rank'], false) == false) then
			table.remove(headers,k)
			resultoffset = resultoffset - 1
		elseif headers[k] == 'Game name' and (yesno(args['gamename'], false) == false) then
			table.remove(headers,k)
			resultoffset = resultoffset - 1
			hasgamename = false
		elseif headers[k] == 'TV' and (yesno(args['tv'], false) == false) then
			table.remove(headers,k)
			resultoffset = resultoffset - 1
		elseif headers[k] == 'Attendance' and (yesno(args['attend'], false) == false) then
			table.remove(headers,k)
		elseif headers[k] == 'Source' and (yesno(args['source'], false) == false) then
			table.remove(headers,k)
		end
	end

	-- create the root table
	local root = mw.html.create('table')
	root:addClass('wikitable')
		:css('font-size', '95%')

	-- add the headers
	local row = root:tag('tr')
	for k=1,#headers do
		if headers[k] == 'Rank' then
			local cell = row:tag('th')
			cell:wikitext('Rank' .. ranknote)
		elseif headers[k] == 'Location' then
		elseif headers[k] == 'At/Vs' then
		elseif headers[k] == 'Opponent' then
			local cell = row:tag('th')
			cell:wikitext('Opponent' .. oppranknote)
		else
			local cell = row:tag('th')
			cell:wikitext(headers[k])
		end
	end
	
	-- build the table
	local k = 1
	local stopflag = (args[k] == nil) and true or false
	while stopflag == false do
		local res, bg = getresult(args[k+resultoffset] or '')
		row = root:tag('tr'):css('background-color', bg)
		for j = 1,#headers do
			if headers[j] == 'Result' then
				row:tag('td'):css('white-space', 'nowrap'):wikitext(res)
			elseif headers[j] == 'At/Vs' then
			elseif headers[j] == 'Opponent' then
				if mw.ustring.find(args[k] or '', '<[Nn][Cc][Gg]>') then
					ncg = true
				end
				if mw.ustring.find(args[k] or '', '<[Hh][Cc]>') then
					hc = true
				end
				if (yesno(args['atvs'], true) == true) then
					row:tag('td'):wikitext(getopp(args[k], args[k-1] or ''))
				else
					row:tag('td'):wikitext(getopp(args[k], ''))
				end
			elseif headers[j] == 'Rank' then
				row:tag('td'):wikitext(getrank(args[k]))
			elseif headers[j] == 'Site' then
				row:tag('td'):wikitext(getsite(args[k] or '', args[k+1] or '', hasgamename and (args[k+2] or '') or ''))
			elseif headers[j] == 'Location' then
			elseif headers[j] == 'Game name' then
			elseif headers[j] == 'Attendance' then
				row:tag('td'):css('text-align', 'center'):wikitext(args[k])
			else
				row:tag('td'):wikitext(args[k])
			end
			k = k + 1
			stopflag = (args[k] == nil) and true or false
		end
	end
	
	-- footnotes
	local fnotes = getfootnotes(
		ncg, hc, args['other-event'] or args['other_event'] or args['otherevent'], 
		yesno(args['rank'], false), 
		yesno(args['opprank'], false), 
		getpolltext(args['rank_year'] or args['rankyear'], args['rank_division'] or args['rankdivision'], args['poll']), 
		args['timezone'])
	
	if fnotes ~= nil then
		row = root:tag('tr')
		row:tag('td')
			:attr('colspan',#headers)
			:css('font-size', '85%')
			:wikitext(fnotes)
	end
	
	-- return the root table
	return tostring(root) .. 
		(haslocgamename and '[[Category:Pages using CFB schedule with gamename after location]]' or '') ..
		(hasoppgamename and '[[Category:Pages using CFB schedule with gamename after opponent]]' or '') ..
		(haslocrivalry and '[[Category:Pages using CFB schedule with rivalry after location]]' or '') ..
		(hasopprivalry and '[[Category:Pages using CFB schedule with rivalry after opponent]]' or '')
end

function p.entry(frame)
	local args = (frame.args.opponent ~= nil) and frame.args or frame:getParent().args
	local cell
	
	if args['overtime'] then 
		args['overtime'] = '&nbsp;<sup>' .. args['overtime'] .. '</sup>'
	end
	
	local res, bg = getresult(
		(args['w/l'] or '') .. ' ' ..
		(args['score'] or '') .. 
		(args['overtime'] or '')
		)
		
	local root = mw.html.create('tr')
		:addClass('CFB-schedule-row')
		:css('background-color', bg)
	
	-- Date
	cell = root:tag('td'):addClass('CFB-schedule-date')
	if args.date and (args.date):lower() ~= 'no' then
		cell
			:css('white-space:nowrap')
			:wikitext(args.date or '')
	else
		cell:css('display','none')
	end
	
	-- Time
	cell = root:tag('td'):addClass('CFB-schedule-time')
	if args.time and (args.time):lower() ~= 'no' then
		cell
			:css('white-space:nowrap')
			:wikitext(args.time or '')
	else
		cell:css('display','none')
	end
	
	-- Opponent
	root:tag('td')
		:wikitext(getopp(
		(isnotempty(args.opprank) and 'No.&nbsp;' .. args.opprank .. ' ' or '') ..
		(args.opponent or '') ..
		((yesno(args.nonconf,false) == true) and '<ncg>' or '') ..
		((yesno(args.homecoming,false) == true) and '<hc>' or '') ..
		(args.ref or ''),
		(isnotempty(args.away) and 'at' or '') ..
		(isnotempty(args.neutral) and 'vs.' or '')
		) )

	-- Rank
	cell = root:tag('td'):addClass('CFB-schedule-rank')
	if args.rank and (args.rank):lower() ~= 'no' then
		local rank = args.rank or ''
		if rank ~= '' then
			rank = 'No. ' .. rank
		end
		cell
			:css('text-align:center')
			:wikitext(rank)
	else
		cell:css('display','none')
	end

	-- Gamename
	local gamename = args.gamename or ''

	-- Site
	root:tag('td')
		:wikitext(getsite(args.stadium or args.site_stadium or '', (args.cityst or args.site_cityst or ''), gamename))

	-- TV
	cell = root:tag('td'):addClass('CFB-schedule-tv')
	if args.tv and (args.tv):lower() ~= 'no' then
		cell
			:css('white-space:nowrap')
			:wikitext(args.tv or '')
	else
		cell:css('display','none')
	end
	
	-- Result
	root:tag('td')
		:wikitext(res)
		
	-- Attendance
	cell = root:tag('td'):addClass('CFB-schedule-attend')
	if args.attend and (args.attend):lower() ~= 'no' then
		cell
			:css('text-align:center')
			:wikitext(args.attend or '')
	else
		cell:css('display','none')
	end
	
	-- Source
	cell = root:tag('td'):addClass('CFB-schedule-source')
	if args.source and (args.source):lower() ~= 'no' then
		cell
			:css('text-align:center')
			:wikitext(args.source or '')
	else
		cell:css('display','none')
	end
	
	return tostring(root)
end

function p.subst(frame)
	local args = (frame.args[1] ~= nil) and frame.args or frame:getParent().args
	if (args[1] or ''):find('<tr[^>]*CFB%-schedule%-row') then
		return make_outer_table(args)
	else
		return convert_table(args)
	end
end

function p.table(frame)
	local args = (frame.args[1] ~= nil) and frame.args or frame:getParent().args
	if (args[1] or ''):find('<tr[^>]*CFB%-schedule%-row') then
		return make_outer_table(args) .. '[[Category:Pages using CFB schedule with named parameters]]'
	else
		return make_table(args) .. '[[Category:Pages using CFB schedule with unnamed parameters]]'
	end
end

return p