Module:CFB schedule explained

local p = local horizontal = require('Module:List').horizontal

local dagger = ''

local haslocgamename = falselocal hasoppgamename = falselocal haslocrivalry = falselocal hasopprivalry = falselocal hasrank = falselocal hasstrangescore = falselocal hasnowrap = 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 endend

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

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 >= 1962 then return 'NCAA University Division' elseif y >= 1958 then return 'major college' 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 '' .. 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]') then hasnowrap = true end if 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, gnend

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

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 else game_name = mw.ustring.gsub(game_name, '^%s*', ) if isnotempty(game_name) then game_name = ' (' .. game_name .. ')' end return stadium .. location .. game_name endend

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

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, bgend 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][%d]*)%s*[%‐‒–—―]%s*', '%1–') s = mw.ustring.gsub(s, '^%s*(%[%[%s*[^|]*|%s*[%d][%d]*)%s*[%‐‒–—―]%s*', '%1–') s = mw.ustring.gsub(s, '^%s*(%%[%]%s*%s+[%d][%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]*)[%D]%s*([%d][%d]*)(.-)$' if mw.ustring.match(s, pat) then return parse4(pat, s) end

pat = '^([%a])%s*(%[%[%s*[^|]*|%s*[%d][%d]*)[%D]%s*([%d][%d]*%]%])(.-)$' if mw.ustring.match(s, pat) then return parse4(pat, s) end pat = '^([%a])%s*(%%[%]%s*%s+[%d][%d]*)[%D]%s*([%d][%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 endend

local function make_outer_table(args) 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('%s*[^%s<]') then showdate = true end end if showtime

false then if args[k]:find('%s*[^%s<]') then showtime = true end end if showrank

false then if args[k]:find('%s*[^%s<]') then showrank = true end end if showtv

false then if args[k]:find('%s*[^%s<]') then showtv = true end end if showattend

false then if args[k]:find('%s*[^%s<]') then showattend = true end end if showsource

false then if args[k]:find('%s*[^%s<]') then showsource = true end end if ncg

false then if args[k]:find('

false then if args[k]:find('

false then if showrank

true or args[k]:find('No%. %d') or args[k]:find('No%. T[%-–%s]*%d') then hasrank = true end end k = k + 1 end if k

1 then return '' 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

k = 1 while args[k] ~= nil do row = args[k] or if showdate then row = mw.ustring.gsub(row, '', '') else row = mw.ustring.gsub(row, '%s*%s*', ) end if showtime then row = mw.ustring.gsub(row, '', '') else row = mw.ustring.gsub(row, '%s*%s*', ) end if showrank then row = mw.ustring.gsub(row, '', '') else row = mw.ustring.gsub(row, '%s*%s*', ) end if showtv then row = mw.ustring.gsub(row, '', '') else row = mw.ustring.gsub(row, '%s*%s*', ) end if showattend then row = mw.ustring.gsub(row, '', '') else row = mw.ustring.gsub(row, '%s*%s*', ) end if showsource then row = mw.ustring.gsub(row, '', '') else row = mw.ustring.gsub(row, '%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) local wl = s = mw.ustring.gsub(s or , '&[MmNn][Dd][Aa][Ss][Hh];', '–') s = mw.ustring.gsub(s, '^%s*(.-)%s*$', '%1') local r = if mw.ustring.match(s, '^[%a]%s*[%d][%d]*[%D]%s*[%d][%d]*%s*.*$') then local t = for k = 1,4 do t[k] = mw.ustring.gsub(s,'^([%a])%s*([%d][%d]*)[%D]%s*([%d][%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 resend

local function make_table(args) local hasgamename = true

-- switch headers on and off local headers = 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%') -- 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 k = 1 local stopflag = (args[k]

nil) and true or false if stopflag then return '' end while stopflag

false 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 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'], 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 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 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 '' 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 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') :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 args.tv and (args.tv):lower ~= 'no' then cell :wikitext(args.tv or ) 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 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] and frame.args or frame:getParent.args if (args[1] or ):find('

function p.table(frame) local args = frame.args[1] and frame.args or frame:getParent.args if (args[1] or ):find('

return p