Module:College color
Jump to navigation
Jump to search
This Lua module is used on approximately 119,000 pages. To avoid major disruption and server load, any changes should be tested in the module's /sandbox or /testcases subpages, or in your own module sandbox. The tested changes can be added to this page in a single edit. Consider discussing changes on the talk page before implementing them. |
This module is rated as beta, and is ready for widespread use. It is still new and should be used with some caution to ensure the results are as expected. |
This module depends on the following other modules: |
This module implements the colors for college athletic programs and is used by
- {{GotCollegeColorsFor}} - to check if colors are known for the given team.
- {{CollegePrimaryHex}}, {{CollegePrimaryStyle}}, {{CollegePrimaryColorLink}}, {{CollegePrimaryHeader}}
- {{CollegeSecondaryHex}}, {{CollegeSecondaryStyle}}, {{CollegeSecondaryColorLink}}, {{CollegeSecondaryHeader}}
- {{NCAA color}}, {{NCAA color cell}}, {{NCAA secondary color cell}}
- {{Infobox baseball biography/style}}
- {{Infobox basketball biography/style}}
- {{CBB roster/Header}}
- {{College color list}}, {{College color boxes}}
Usage
{{#invoke:College color|color}}
in the NCAA color template{{#invoke:College color|color1}}
in the primary color template{{#invoke:College color|color32}}
in the secondary color template{{#invoke:College color|style1}}
in the primary style template{{#invoke:College color|style2}}
in the secondary style template{{#invoke:College color|header1}}
in the primary header style of an infobox{{#invoke:College color|header2}}
in the secondary header style of an infobox{{#invoke:College color|tablehead1}}
in the primary header style of a wikitable{{#invoke:College color|tablehead2}}
in the secondary header style of a wikitable{{#invoke:College color|stripe1}}
in the primary header style of an infobox{{#invoke:College color|list}}
in the|colors=
field of an infobox{{#invoke:College color|boxes}}
in the|colors=
field of an infobox{{#invoke:College color|check}}
to check to see if a team has defined colors
Updating team colors
See Module:college color/data.
Test table
The time allocated for running scripts has expired.
Template:Sports color templates
--
-- This module implements {{CollegePrimaryHex}}, {{CollegePrimaryStyle}},
-- {{CollegePrimaryColorLink}}, {{CollegeSecondaryHex}},
-- {{CollegeSecondaryStyle}}, {{CollegeSecondaryColorLink}}, and {{NCAA color}}
--
local p = {}
local data_module = "Module:College color/data"
local function stripwhitespace(text)
return text:match("^%s*(.-)%s*$")
end
local function ucfirst(s)
local first = s:sub(1, 1)
local others = s:sub(2, -1)
return first:upper() .. others
end
local function bordercss(c, w)
local s = 'inset ' .. w .. 'px ' .. w .. 'px 0 ' .. c
.. ', inset -' .. w .. 'px -' .. w .. 'px 0 ' .. c
return 'box-shadow: ' .. s .. ';'
end
local function sRGB ( v )
if (v <= 0.03928) then
v = v / 12.92
else
v = math.pow((v+0.055)/1.055, 2.4)
end
return v
end
local function color2lum( origc )
local c = stripwhitespace(origc or ''):lower()
-- remove leading # (if there is one)
c = mw.ustring.match(c, '^[#]*([a-f0-9]*)$')
-- split into rgb
local cs = mw.text.split(c or '', '')
if( #cs == 6 ) then
local R = sRGB( (16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[2]))/255 )
local G = sRGB( (16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[4]))/255 )
local B = sRGB( (16*tonumber('0x' .. cs[5]) + tonumber('0x' .. cs[6]))/255 )
return 0.2126 * R + 0.7152 * G + 0.0722 * B
elseif ( #cs == 3 ) then
local R = sRGB( (16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[1]))/255 )
local G = sRGB( (16*tonumber('0x' .. cs[2]) + tonumber('0x' .. cs[2]))/255 )
local B = sRGB( (16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[3]))/255 )
return 0.2126 * R + 0.7152 * G + 0.0722 * B
end
-- failure
error('Invalid hex color ' .. origc, 2)
end
local function remove_sport(team)
team = mw.ustring.gsub(team, "%s*<[Bb][Rr][^<>]*>%s*", ' ');
team = mw.ustring.gsub(team, " [Tt]eam$", '')
team = mw.ustring.gsub(team, " [Bb]asketball$", '')
team = mw.ustring.gsub(team, " [Bb]aseball$", '')
team = mw.ustring.gsub(team, " [Cc]ross [Cc]ountry$", '')
team = mw.ustring.gsub(team, " [Ff]ield [Hh]ockey$", '')
team = mw.ustring.gsub(team, " [Ff]ootball$", '')
team = mw.ustring.gsub(team, " [Gg]olf$", '')
team = mw.ustring.gsub(team, " [Gg]ymnastics$", '')
team = mw.ustring.gsub(team, " [Ii]ce [Hh]ockey$", '')
team = mw.ustring.gsub(team, " [Ll]acrosse$", '')
team = mw.ustring.gsub(team, " [Rr]owing$", '')
team = mw.ustring.gsub(team, " [Ss]ki$", '')
team = mw.ustring.gsub(team, " [Ss]occer$", '')
team = mw.ustring.gsub(team, " [Ss]oftball$", '')
team = mw.ustring.gsub(team, " [Ss]wim$", '')
team = mw.ustring.gsub(team, " [Tt]ennis$", '')
team = mw.ustring.gsub(team, " [Tt]rack [Aa]nd [Ff]ield$", '')
team = mw.ustring.gsub(team, " [Vv]olleyball$", '')
team = mw.ustring.gsub(team, " [Ww]restling$", '')
team = mw.ustring.gsub(team, " [Ww]omen's$", '')
team = mw.ustring.gsub(team, " [Mm]en's$", '')
return team
end
local function get_colors(team, unknown)
team = stripwhitespace(team or '')
unknown = unknown or {"DCDCDC", "000000"}
local use_default = {
[""] = 1,
["retired"] = 1,
["free agent"] = 1,
}
local colors = nil
if ( team and use_default[team:lower()] ) then
colors = {"DCDCDC", "000000"}
else
local all_colors = mw.loadData(data_module)
colors = all_colors[team]
if ( colors and type(colors) == 'string' ) then
colors = all_colors[colors]
end
end
return colors or unknown
end
local function team_color(team, num, num2)
local colors = get_colors(team, nil)
num = tonumber(num:match('[1-3]') or '0')
num2 = tonumber(num2:match('[1-3]') or '0')
if ( num ) then
return colors[num] or colors[num2] or ''
else
return ''
end
end
local function team_style1(team, borderwidth, fontcolor)
local colors = get_colors(team, nil)
local color = '#' .. (colors[3] or colors[2] or '')
if fontcolor and fontcolor == 'auto' then
-- compute the luminosity of the background
local lum = color2lum(colors[1] or '')
-- compute the contrast with white and black
local wcontrast = (1 + 0.05)/(lum + 0.05)
local bcontrast = (lum + 0.05)/(0 + 0.05)
-- select the text color with the best contrast
if( bcontrast > wcontrast + 1.25 ) then
fontcolor = '#000000'
else
fontcolor = '#FFFFFF'
end
end
local style = 'background-color:#' .. (colors[1] or '') .. ';color:' .. (fontcolor or color) .. ';'
-- remove the border if it's nearly white
if ((1 + 0.05)/(color2lum(color) + 0.05) < 1.25) then
borderwidth = '0'
end
borderwidth = tonumber(borderwidth or '2') or 0
if (borderwidth > 0 and color ~= '#FFFFFF') then
style = style .. bordercss(color, borderwidth)
end
return style
end
local function team_style2(team, borderwidth, fontcolor)
local colors = get_colors(team, nil)
local color = '#' .. (colors[1] or '')
if fontcolor and fontcolor == 'auto' then
-- compute the luminosity of the background
local lum = color2lum(colors[3] or colors[2] or '')
-- compute the contrast with white and black
local wcontrast = (1 + 0.05)/(lum + 0.05)
local bcontrast = (lum + 0.05)/(0 + 0.05)
-- select the text color with the best contrast
if( bcontrast > wcontrast + 1.25 ) then
fontcolor = '#000000'
else
fontcolor = '#FFFFFF'
end
end
local style = 'background-color:#' .. (colors[3] or colors[2] or '') .. ';color:' .. (fontcolor or color) .. ';'
-- remove the border if it's nearly white
if ((1 + 0.05)/(color2lum(color) + 0.05) < 1.25) then
borderwidth = '0'
end
borderwidth = tonumber(borderwidth or '2') or 0
if (borderwidth > 0 and color ~= '#FFFFFF') then
style = style .. bordercss(color, borderwidth)
end
return style
end
local function team_header1(team, borderwidth)
local colors = get_colors(team, nil)
-- set the default background
local background = (colors[1] or 'FFFFFF'):upper()
-- set background to white if it's nearly white
if ((1 + 0.05)/(color2lum(background) + 0.05) < 1.25) then
background = 'FFFFFF'
end
-- now pick a font color
local fontcolor = '000000'
-- compute the luminosity of the background
local lum = color2lum(background)
-- compute the contrast with white and black
local wcontrast = (1 + 0.05)/(lum + 0.05)
local bcontrast = (lum + 0.05)/(0 + 0.05)
-- select the text color with the best contrast
if( bcontrast > wcontrast + 1.25 ) then
fontcolor = '000000'
else
fontcolor = 'FFFFFF'
end
local style
if( background == 'FFFFFF' ) then
style = 'background-color:none;color:#' .. fontcolor .. ';'
else
style = 'background-color:#' .. background .. ';color:#' .. fontcolor .. ';'
end
if borderwidth then
borderwidth = tonumber(borderwidth or '2') or 0
local bordercolor = (colors[3] or colors[2] or 'FFFFFF'):upper()
if (borderwidth > 0 and bordercolor ~= 'FFFFFF') then
-- do not add a border if it's nearly white
if ((1 + 0.05)/(color2lum(bordercolor) + 0.05) >= 1.25) then
style = style .. bordercss('#' .. bordercolor, borderwidth)
end
end
end
return style
end
local function team_header2(team)
local colors = get_colors(team, nil)
-- set the default background
local background = (colors[3] or colors[2] or 'FFFFFF'):upper()
-- set background to white if it's nearly white
if ((1 + 0.05)/(color2lum(background) + 0.05) < 1.25) then
background = 'FFFFFF'
end
-- if the background is white, then use the primary background instead
if( background == 'FFFFFF' ) then
background = (colors[1] or 'FFFFFF'):upper()
end
-- now pick a font color
local fontcolor = '000000'
-- compute the luminosity of the background
local lum = color2lum(background)
-- compute the contrast with white and black
local wcontrast = (1 + 0.05)/(lum + 0.05)
local bcontrast = (lum + 0.05)/(0 + 0.05)
-- select the text color with the best contrast
if( bcontrast > wcontrast + 1.25 ) then
fontcolor = '000000'
else
fontcolor = 'FFFFFF'
end
if( background == 'FFFFFF' ) then
return 'background-color:none;color:#' .. fontcolor .. ';'
else
return 'background-color:#' .. background .. ';color:#' .. fontcolor .. ';'
end
end
local function team_table_head(args, team, ctype)
local colors = get_colors(team, nil)
local borderwidth = tonumber(args['border']) or 0
-- set the default background
local background = (ctype == 'p') and
(colors[1] or 'FFFFFF'):upper() or
(colors[3] or colors[2] or 'FFFFFF'):upper()
-- now pick a font color
local fontcolor = ''
-- compute the luminosity of the background
local lum = color2lum(background)
-- compute the contrast with white and black
local wcontrast = (1 + 0.05)/(lum + 0.05)
local bcontrast = (lum + 0.05)/(0 + 0.05)
-- select the text color with the best contrast
if( bcontrast > wcontrast + 1.25 ) then
fontcolor = '#000000'
else
fontcolor = '#FFFFFF'
end
local s = 'background-color:#' .. background .. ';color:' .. (args['color'] or fontcolor) .. ';'
if borderwidth > 0 then
local bc = (ctype == 'p') and
(colors[3] or colors[2] or '') or (colors[1] or '')
if bc ~= 'FFFFFF' then
s = s .. bordercss('#' .. bc, borderwidth)
end
end
local res = '|-\n'
for i=1,50 do
if( args[i] ~= nil ) then
local cstyle = 'scope="col" style="' .. s .. '"'
if args['col' .. i .. 'span'] ~= nil then
cstyle = cstyle .. ' colspan=' .. args['col' .. i .. 'span']
end
if args['class' .. i ] ~= nil then
cstyle = cstyle .. ' class="' .. args['class' .. i] .. '"'
end
res = res .. '! ' .. cstyle .. ' |' .. args[i] .. '\n'
else
return res .. '|-\n'
end
end
return res .. '<span class="error">Error!</span>\n|-\n'
end
local function team_stripe1(team, borderwidth)
local colors = get_colors(team, nil)
-- set the default scheme
local background = colors[1] or ''
local fontcolor = colors[2] or ''
local bordercolor = (colors[3] or colors[2] or ''):upper()
borderwidth = tonumber(borderwidth or '3') or 0
-- if there is no tertiary color, then pick a font color
if (colors[3] == nil) then
-- compute the luminosity of the background
local lum = color2lum(colors[1])
-- compute the contrast with white and black
local wcontrast = (1 + 0.05)/(lum + 0.05)
local bcontrast = (lum + 0.05)/(0 + 0.05)
-- select the text color with the best contrast
if( bcontrast > wcontrast + 1.25 ) then
fontcolor = '000000'
else
fontcolor = 'FFFFFF'
end
end
-- finally build the style string
local style = ''
if (borderwidth > 0) then
-- use the primary as the border if the border is white or close to white
local bordercontrast = (1 + 0.05)/(color2lum(bordercolor) + 0.05)
if (bordercontrast < 1.25) then
bordercolor = background
local fontcontrast = (1 + 0.05)/(color2lum(colors[2] or 'FFFFFF') + 0.05)
if (fontcontrast < 1.25) then
fontcolor = colors[2] or 'FFFFFF'
end
end
style = style .. ' border:' .. borderwidth .. 'px solid #' .. bordercolor .. ';'
style = style .. ' border-left: none; border-right: none;'
style = style .. ' box-shadow: inset 0 2px 0 #FEFEFE, inset 0 -2px 0 #FEFEFE;'
end
style = 'background-color:#' .. background .. ';color:#' .. fontcolor .. ';' .. style
return style
end
local function team_boxes(frame, team, order, sep)
local function colorbox( h )
local r = mw.html.create('')
r:tag('span')
:addClass('legend-color')
:css('background-color', '#' .. (h or ''))
:wikitext(' ')
return tostring(r)
end
local colors = get_colors(team, 'unknown')
if type(colors) ~= 'table' then
return ''
end
local colorboxes = {}
local colororder = {'1','2','3','4','5'}
local namecheck = 0
if order == '' then
order = colors['order'] or ''
namecheck = 1
end
if order ~= '' then
colororder = mw.text.split(order, '')
end
for k,v in pairs(colororder) do
local i = tonumber(v) or 0
if( namecheck == 0 or colors['name' .. i]) then
if colors[i] then
table.insert(colorboxes,colorbox(colors[i]))
end
end
end
if (#colorboxes > 0) then
return frame:extensionTag{ name = 'templatestyles', args = { src = 'Legend/styles.css'} } .. table.concat(colorboxes, sep)
end
return ''
end
local function team_list(frame, team, num1, num2, num3, num4, num5, sep)
local function colorbox( h )
local r = mw.html.create('')
r:tag('span')
:addClass('legend-color')
:css('background-color', '#' .. (h or ''))
:wikitext(' ')
return tostring(r)
end
local colors = get_colors(team, 'unknown')
if type(colors) ~= 'table' then
return ''
end
local nums = {
tonumber(num1:match('[1-5]') or '0') or 0,
tonumber(num2:match('[1-5]') or '0') or 0,
tonumber(num3:match('[1-5]') or '0') or 0,
tonumber(num4:match('[1-5]') or '0') or 0,
tonumber(num5:match('[1-5]') or '0') or 0}
local colorboxes = {}
local colornames = {}
local colororder = {'1','2','3','4','5'}
local order = colors['order'] or ''
if(order ~= '') then
colororder = mw.text.split(order, '')
end
for k,v in pairs(colororder) do
local i = tonumber(v) or 0
if ( nums[i] > 0 ) then
if( colors['name' .. nums[i]]) then
table.insert(colornames,colors['name' .. nums[i]])
table.insert(colorboxes,colorbox(colors[nums[i]] or ''))
end
end
end
local res = ''
if (#colornames > 0) then
colornames[1] = ucfirst(colornames[1])
end
res = mw.text.listToText(
colornames,
', ',
#colornames == 2 and ' and ' or ', and '
)
if (colors['cite']) then
res = res .. frame:preprocess('<ref>' .. colors['cite'] .. '</ref>')
end
if (colors['ref']) then
res = res .. '[' .. colors['ref'] .. ']'
end
if (colors['ref2']) then
res = res .. '[' .. colors['ref2'] .. ']'
end
if (#colornames > 0) then
res = res .. sep
end
if (#colorboxes > 0) then
res = res .. frame:extensionTag{ name = 'templatestyles', args = { src = 'Legend/styles.css'} }
res = res .. table.concat(colorboxes, ' ')
end
return res
end
local function team_check(team, unknown)
local colors = get_colors(team, unknown)
if type(colors) == 'table' then
return 'known'
else
return unknown
end
end
function p.color(frame)
local args = (frame.args[1] ~= nil) and frame.args or frame:getParent().args
return team_color(remove_sport(args[1] or ''), args[2] or '', args[3] or '')
end
function p.color1(frame)
local args = (frame.args[1] ~= nil) and frame.args or frame:getParent().args
return team_color(remove_sport(args[1] or ''), '1', '')
end
function p.color32(frame)
local args = (frame.args[1] ~= nil) and frame.args or frame:getParent().args
return team_color(remove_sport(args[1] or ''), '3', '2')
end
function p.style1(frame)
local args = (frame.args[1] ~= nil) and frame.args or frame:getParent().args
return team_style1(remove_sport(args[1] or ''), args['border'], args['color'])
end
function p.style2(frame)
local args = (frame.args[1] ~= nil) and frame.args or frame:getParent().args
return team_style2(remove_sport(args[1] or ''), args['border'], args['color'])
end
function p.header1(frame)
local args = (frame.args[1] ~= nil) and frame.args or frame:getParent().args
return team_header1(remove_sport(args[1] or ''), args['border'])
end
function p.header2(frame)
local args = (frame.args[1] ~= nil) and frame.args or frame:getParent().args
return team_header2(remove_sport(args[1] or ''))
end
function p.tablehead1(frame)
local args = (frame.args[1] ~= nil) and frame.args or frame:getParent().args
return team_table_head(args, remove_sport(args['team'] or ''), 'p')
end
function p.tablehead2(frame)
local args = (frame.args[1] ~= nil) and frame.args or frame:getParent().args
return team_table_head(args, remove_sport(args['team'] or ''), 's')
end
function p.stripe1(frame)
local args = (frame.args[1] ~= nil) and frame.args or frame:getParent().args
return team_stripe1(remove_sport(args[1] or ''), args['border'])
end
function p.boxes(frame)
local args = (frame.args[1] ~= nil) and frame.args or frame:getParent().args
return team_boxes(frame, remove_sport(args[1] or ''),
args['order'] or '', args['sep'] or ' ')
end
function p.list(frame)
local args = (frame.args[1] ~= nil) and frame.args or frame:getParent().args
return team_list(frame, remove_sport(args[1] or ''),
args[2] or '1', args[3] or '2', args[4] or '3', args[5] or '4', args[6] or '5', args['sep'] or '')
end
function p.check(frame)
local args = (frame.args[1] ~= nil) and frame.args or frame:getParent().args
return team_check(remove_sport(args[1] or ''), args[2] or '')
end
function p.check_data()
-- In a sandbox, preview {{#invoke:college color|check_data}}
local results = {'Problems in [[Module:College color/data]]:'}
local function problems(msg)
if msg then
table.insert(results, msg)
elseif results[2] then
return table.concat(results, '\n*')
else
return 'No problems detected.'
end
end
local data = require(data_module)
local keys = {}
for k, _ in pairs(data) do
table.insert(keys, k)
end
table.sort(keys)
for _, key in ipairs(keys) do
local val = data[key]
if not (type(key) == 'string' and (type(val) == 'table' or type(val) == 'string')) then
problems('Invalid type for "' .. tostring(key) .. '"')
end
if type(val) == 'table' then
if not (2 <= #val and #val <= 4) then
problems('Invalid number of numbered parameters for "' .. tostring(key) .. '"')
end
for i, v in ipairs(val) do
if not tostring(v):match('^%x%x%x%x%x%x$') then
problems('Parameter [' .. i .. '] should be a 6-hex-digit color but is "' .. tostring(v) .. '" for "' .. tostring(key) .. '"')
end
end
for k, v in pairs(val) do
if type(k) == 'number' then
if not (1 <= k and k <= 4) then
problems('Invalid numbered parameter for "' .. tostring(key) .. '"')
end
elseif type(k) == 'string' then
if not (
k:match('^name[1-4]$') or
k:match('^cite2?$') or
k:match('^order$')
) then
problems('Unexpected key in table for "' .. tostring(key) .. '"')
end
else
problems('Invalid key type in table for "' .. tostring(key) .. '"')
end
end
elseif data[val] == nil then
problems('Undefined alias for "' .. tostring(key) .. '"')
elseif type(data[val]) ~= 'table' then
problems('Alias is not a table for "' .. tostring(key) .. '"')
end
end
return problems()
end
function p.testtable(frame)
local contrasttable_mod = require("Module:College color/contrast")
return contrasttable_mod._testtable(frame.args)
end
return p