Module:CFB schedule/sandbox

local p = {} local horizontal = require('Module:List').horizontal local yesno = require("Module:Yesno") local dagger = ' '

local haslocgamename = false local hasoppgamename = false local haslocrivalry = false local hasopprivalry = false local hasrank = false local hasstrangescore = false local hasnowrap = false

local function isnotempty(s) return s and s:match( '^%s*(.-)%s*$' ) ~= '' 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 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 '' .. 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 '' .. 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, movegn) s = mw.ustring.gsub(s, '<[%s/]*[Nn][Cc][Gg][%s/]*>', ' * ') s = mw.ustring.gsub(s, '<[%s/]*[Hh][Cc][%s/]*>', 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. %2' ) s = mw.ustring.gsub(s, '^([A-Za-z%.%s]*)#([0-9])', '%1 No. %2') if mw.ustring.match(s, 'No%. %d') then hasrank = true end local gn, r = ,  if mw.ustring.match(s, '[Nn][Oo][Ww][Rr][Aa][Pp]') or mw.ustring.match(s, '[Nn][Bb][Ss][Pp]') then hasnowrap = true end if mw.ustring.match(s, '^.*%s*%(%s*%[%^%[%*%]%]%s*%)%s*.*$') then if mw.ustring.match(s, '%(%[%^%[%*%|%s*[Rr]ivalry') then			hasopprivalry = true		else			hasoppgamename = true		end		if movegn == true then			s, gn, r = mw.ustring.match(s, '^(.*)%s*%(%s*(%[%^%[%*%]%])%s*%)(%s*.*)$')		end	end	if atvs ~= '' then atvs = atvs .. ' ' end	return atvs .. s .. r, gn end

local function getrank(s) s = mw.ustring.gsub(s, '^%s*(%d+)', 'No. %1') s = mw.ustring.gsub(s, '^%s*(T)[%-–%s]*(%d+)', 'No. %1–%2') return s end

local function getsite(stadium, location, game_name) if isnotempty(stadium) and isnotempty(location) then game_name = mw.ustring.gsub(game_name, '^%s*', '') if isnotempty(game_name) then game_name = mw.ustring.gsub(game_name, '^([Rr][Ii][Vv][Aa][Ll][Rr][Yy])$', '%1') game_name = mw.ustring.gsub(game_name, '^([^%[%]]*)$', '%1') game_name = ' (' .. game_name .. ')' end if mw.ustring.match(location, '%s%(%[%[') then			if mw.ustring.match(location, '%s%(%[%^%*%|%s*[Rr]ivalry') then haslocrivalry = true else haslocgamename = true end end return horizontal({stadium, location .. game_name}) else game_name = mw.ustring.gsub(game_name, '^%s*', '') if isnotempty(game_name) then game_name = ' (' .. game_name .. ')' end return stadium .. location .. game_name end end

local function setbg(WL,N) local BG = 'inherit' WL = mw.ustring.match(WL, '^%s*(.-)%s*$') 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 return BG, WL, N end

local function parse4(p, s)	local t = {} for k = 1,4 do t[k] = mw.ustring.gsub(s, p, '%' .. k)	end local wl, sc, n, bg = t[1], t[2] .. '–' .. t[3], t[4], 'inherit' bg, wl, n = setbg(wl, n) return ' ' .. wl .. ' ' .. sc .. n, bg end local function getresult(wl, s, n)	local bg = 'inherit'

local loopnum = 0 while (mw.ustring.match(s, '&[Nn][Bb][Ss][Pp];') and loopnum < 5) do		hasstrangescore = true s = mw.ustring.gsub(s, '&[Nn][Bb][Ss][Pp];', ' ') s = mw.ustring.gsub(s, '<%s*[Ss][Pp][Aa][Nn][^<>]*>%s*', ' ') loopnum = loopnum + 1 end s = mw.ustring.gsub(s, '&[Nn][Bb][Ss][Pp];%s*(<[%s/]*[0-9]*OT[%s/]*>)', ' %1') s = mw.ustring.gsub(s, '%s*<([0-9]*)[Oo][Tt]>', ' %1OT') s = mw.ustring.gsub(s, '&[MmNn][Dd][Aa][Ss][Hh];', '–') s = mw.ustring.gsub(s, ' (.-) ', '%1') s = mw.ustring.gsub(s, '^%s*(.-)%s*$', '%1')

if wl ~= '' then s = mw.ustring.gsub(s, '^%s*(%d+)%s*[%‐‒–—―]%s*', '%1–') s = mw.ustring.gsub(s, '^%s*(%[%[%s*[^|]*|%s*%d+)%s*[%‐‒–—―]%s*', '%1–') s = mw.ustring.gsub(s, '^%s*(%[[^|%[%]%s]*%s+%d+)%s*[%‐‒–—―]%s*', '%1–')		local r		if mw.ustring.match(wl, '^%s*[%a]?%s*$') then			bg, wl, n = setbg(wl, n)			r = ' ' 				.. wl .. ' ' .. s .. n		else			hasstrangescore = true			r = wl .. s .. n		end		return r,bg	end	if s == 'Cancelled' or s == '' or s == '?' then		return wl .. s .. n, 'inherit'	end	if mw.ustring.match(s, '^[%a]%s+[^%d]') then		wl = mw.ustring.gsub(s, '^(%a)%s+(.-)$', '%1')		s = mw.ustring.gsub(s, '^(%a)%s+(.-)$', '%2')		bg, wl, n = setbg(wl, n)		local r = ' '			.. wl .. ' ' .. s .. n		return r, bg	end	if mw.ustring.match(s, '^[%a]$') then		bg, wl, n = setbg(s, n)		local r = ' '			.. wl .. ' ' .. n		return r, bg	end

local pat pat = '^(%a)%s*(%d+)[%D]%s*(%d+)(.-)$' if mw.ustring.match(s, pat) then return parse4(pat, s)	end

pat = '^(%a)%s*(%[%[%s*[^|]*|%s*%d+)[%D]%s*(%d+%]%])(.-)$' if mw.ustring.match(s, pat) then return parse4(pat, s)	end pat = '^([%a])%s*(%[[^|%[%]%s]*%s+%d+)[%D]%s*(%d+%s*%])(.-)$'	if mw.ustring.match(s, pat) then		return parse4(pat, s)	end	hasstrangescore = true

return wl .. s .. n, 'inherit' end

local function getfootnotes(ncg, hc, oe, rank, opprank, poll, tz, src) -- 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, oe) end if (rank == true) or (opprank == true) then table.insert(fn, 'Rankings from ' .. poll) end if isnotempty(tz) then table.insert(fn,'All times are in ' .. tz .. ' time') end if isnotempty(src) then table.insert(fn, 'Source: ' .. src) end

if (#fn > 0) then return horizontal(fn) else return nil end end

local function make_outer_table(args) if not args[1] then return '' end 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 for _, v in ipairs(args) do		if showdate == false then if v:find(']*CFB%-schedule%-date[^>]*>%s*[^%s<]') then showdate = true end end if showtime == false then if v:find(']*CFB%-schedule%-time[^>]*>%s*[^%s<]') then showtime = true end end if showrank == false then if v:find(']*CFB%-schedule%-rank[^>]*>%s*[^%s<]') then showrank = true end end if showtv == false then if v:find(']*CFB%-schedule%-tv[^>]*>%s*[^%s<]') then showtv = true end end if showattend == false then if v:find(']*CFB%-schedule%-attend[^>]*>%s*[^%s<]') then showattend = true end end if showsource == false then if v:find(']*CFB%-schedule%-source[^>]*>%s*[^%s<]') then showsource = true end end if ncg == false then if v:find(']*CFB%-schedule%-ncgame') then ncg = true end end if hc == false then if v:find(']*CFB%-schedule%-hcgame') then hc = true end end if hasrank == false then if showrank == true or v:find('No%. %d') or v:find('No%. T[%-–%s]*%d') then hasrank = true end end end -- Step 2: Build the table local root = mw.html.create('table') root:addClass('wikitable') :css('font-size', '95%')

-- optional caption if args['caption'] then root:tag('caption'):wikitext(args['caption']) end -- 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') 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

local k = 1 while args[k] ~= nil do		row = args[k] if showdate then row = mw.ustring.gsub(row, ']*CFB%-schedule%-date[^>]*>', '') else row = mw.ustring.gsub(row, ']*CFB%-schedule%-date[^>]*>%s* %s*', '') end if showtime then row = mw.ustring.gsub(row, ']*CFB%-schedule%-time[^>]*>', '') else row = mw.ustring.gsub(row, ']*CFB%-schedule%-time[^>]*>%s* %s*', '') end if showrank then row = mw.ustring.gsub(row, '<td[^>]*CFB%-schedule%-rank[^>]*>', '<td style="white-space:nowrap">') else row = mw.ustring.gsub(row, '<td[^>]*CFB%-schedule%-rank[^>]*>%s* %s*', '') end if showtv then row = mw.ustring.gsub(row, '<td[^>]*CFB%-schedule%-tv[^>]*>', ' ') else row = mw.ustring.gsub(row, '<td[^>]*CFB%-schedule%-tv[^>]*>%s* %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* %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* %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'], hasrank),		getpolltext( args['rank_year'] or args['rankyear'], args['rank_division'] or args['rankdivision'], args['poll'] ),		showtime and args['timezone'] or '',		args['seasonsource']	)

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) s = mw.ustring.gsub(s or '', '&[MmNn][Dd][Aa][Ss][Hh];', '–') s = mw.ustring.match(s, '^%s*(.-)%s*$') if mw.ustring.match(s, '^[%a]%s*%d+[%D]%s*%d+%s*.*$') then local t = {} for k = 1,4 do t[k] = mw.ustring.gsub(s,'^([%a])%s*(%d+)[%D]%s*(%d+)%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 local res = ''

return res end

local function make_table(args) if args[1] == nil then return '' end 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

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%') -- optional caption if args['caption'] then root:tag('caption'):wikitext(args['caption']) end

-- 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') elseif headers[k] == 'Location' then elseif headers[k] == 'At/Vs' then elseif headers[k] == 'Opponent' then local cell = row:tag('th') cell:wikitext('Opponent') else local cell = row:tag('th') cell:wikitext(headers[k]) end end

-- build the table local ncg, hc = false, false local k = 1 while args[k] ~= nil do		local res, bg = getresult(, args[k+resultoffset] or , '') row = root:tag('tr'):css('background-color', bg) local op, gn = ,  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 '', '<[%s/]*[Nn][Cc][Gg][%s/]*>') then ncg = true end if mw.ustring.find(args[k] or '', '<[%s/]*[Hh][Cc][%s/]*>') then hc = true end op, gn = getopp(args[k], (yesno(args['atvs'], true) == true) and (args[k-1] or ) or , true) row:tag('td'):wikitext(op) 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 ) .. (' ' .. gn))) 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 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'], hasrank),		getpolltext( args['rank_year'] or args['rankyear'], args['rank_division'] or args['rankdivision'], args['poll'] ),		(yesno(args['time'], false) == false) and '' or args['timezone'],		args['seasonsource']	)

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  or ) .. (hasoppgamename and  or ) .. (haslocrivalry and  or ) .. (hasopprivalry and  or ) .. (hasstrangescore and  or ) .. (hasnowrap and  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'] = ' ' .. args['overtime'] .. ''	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 yesno(args.date, true) then -- won't trigger if args.date is nil, since yesno always yields nil if its input is nil cell :css('white-space','nowrap') :wikitext(args.date) else cell:css('display','none') end

-- Time cell = root:tag('td'):addClass('CFB-schedule-time') if yesno(args.time, true) then cell :css('white-space','nowrap') :wikitext(args.time) else cell:css('display','none') end

-- Opponent local op, gn = getopp(		(isnotempty(args.opprank) and getrank(args.opprank) .. ' ' or ) ..		(args.opponent or ) ..		((yesno(args.nonconf,false) == true) and ' ' or ) ..		((yesno(args.homecoming,false) == true) and '<hc>' or ) ..		(args.ref or ),		(isnotempty(args.away) and 'at' or ) ..		(isnotempty(args.neutral) and 'vs.' or ''),		false		) root:tag('td') :css('white-space', 'nowrap') :wikitext(op)

-- Rank cell = root:tag('td'):addClass('CFB-schedule-rank') if yesno(args.rank, true) then -- won't trigger if args.rank is nil, since yesno always yields nil if its input is nil if rank ~= '' then rank = 'No. ' .. rank end cell :css('text-align','center') :css('white-space','nowrap') :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 yesno(args.tv, true) then -- won't trigger if args.tv is nil cell :wikitext(args.tv) else cell:css('display','none') end

-- Result root:tag('td') :css('white-space','nowrap') :wikitext(res)

-- Attendance cell = root:tag('td'):addClass('CFB-schedule-attend') if yesno(args.attend, true) then -- won't trigger if args.attend is nil cell :css('text-align','center') :wikitext(args.attend) else cell:css('display','none') end

-- Source cell = root:tag('td'):addClass('CFB-schedule-source') if yesno(args.source, true) then -- won't trigger if args.source is nil cell :css('text-align','center') :wikitext(args.source) else cell:css('display','none') end

return tostring(root) end

function p.subst(frame) local args = frame.args[1] 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] and frame.args or frame:getParent.args if (args[1] or ''):find('<tr[^>]*CFB%-schedule%-row') then return make_outer_table(args) .. ''	else return make_table(args) .. ''	end end

return p