Difference between revisions of "Module:College color/sandbox"
Jump to navigation
Jump to search
blackwiki>Jackmcbarn (add error checking to color2lum) |
blackwiki>Corkythehornetfan (match main module) |
||
Line 1: | Line 1: | ||
-- | -- | ||
− | -- This module implements {{CollegePrimaryHex}}, {{CollegePrimaryStyle}}, | + | -- This module implements {{CollegePrimaryHex}}, {{CollegePrimaryStyle}}, |
− | -- {{CollegePrimaryColorLink}}, {{CollegeSecondaryHex}}, | + | -- {{CollegePrimaryColorLink}}, {{CollegeSecondaryHex}}, |
-- {{CollegeSecondaryStyle}}, {{CollegeSecondaryColorLink}}, and {{NCAA color}} | -- {{CollegeSecondaryStyle}}, {{CollegeSecondaryColorLink}}, and {{NCAA color}} | ||
-- | -- | ||
Line 8: | Line 8: | ||
local data_module = "Module:College color/data" | local data_module = "Module:College color/data" | ||
− | local function sRGB ( v ) | + | local function stripwhitespace(text) |
− | if (v <= 0.03928) then | + | return text:match("^%s*(.-)%s*$") |
− | + | end | |
+ | local function bordercss(c, w) | ||
+ | local s = 'inset ' .. w .. 'px ' .. w .. 'px 0 ' .. c | ||
+ | .. ', inset -' .. w .. 'px -' .. w .. 'px 0 ' .. c | ||
+ | return '-moz-box-shadow: ' .. s .. '; -webkit-box-shadow: ' .. s .. '; box-shadow: ' .. s .. ';' | ||
+ | end | ||
+ | local function sRGB ( v ) | ||
+ | if (v <= 0.03928) then | ||
+ | v = v / 12.92 | ||
else | else | ||
− | + | v = math.pow((v+0.055)/1.055, 2.4) | |
− | + | end | |
+ | return v | ||
end | end | ||
local function color2lum( origc ) | local function color2lum( origc ) | ||
− | local c = origc:match('^ | + | 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 | end | ||
− | + | ||
− | + | -- failure | |
− | + | error('Invalid hex color ' .. origc, 2) | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
local function remove_sport(team) | 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, " [Tt]eam$", '') | ||
− | |||
team = mw.ustring.gsub(team, " [Bb]asketball$", '') | team = mw.ustring.gsub(team, " [Bb]asketball$", '') | ||
team = mw.ustring.gsub(team, " [Bb]aseball$", '') | 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]oftball$", '') | ||
− | team = mw.ustring.gsub(team, " [Vv] | + | 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, " [Ww]omen's$", '') | ||
team = mw.ustring.gsub(team, " [Mm]en's$", '') | team = mw.ustring.gsub(team, " [Mm]en's$", '') | ||
Line 49: | Line 77: | ||
end | end | ||
local function get_colors(team, unknown) | local function get_colors(team, unknown) | ||
− | team = | + | team = stripwhitespace(team or '') |
unknown = unknown or {"DCDCDC", "000000"} | unknown = unknown or {"DCDCDC", "000000"} | ||
− | + | ||
local use_default = { | local use_default = { | ||
[""] = 1, | [""] = 1, | ||
Line 57: | Line 85: | ||
["free agent"] = 1, | ["free agent"] = 1, | ||
} | } | ||
− | + | ||
local colors = nil | local colors = nil | ||
− | + | ||
if ( team and use_default[team:lower()] ) then | if ( team and use_default[team:lower()] ) then | ||
colors = {"DCDCDC", "000000"} | colors = {"DCDCDC", "000000"} | ||
Line 87: | Line 115: | ||
local function team_style1(team, borderwidth, fontcolor) | local function team_style1(team, borderwidth, fontcolor) | ||
local colors = get_colors(team, nil) | local colors = get_colors(team, nil) | ||
− | + | ||
local color = '#' .. (colors[3] or colors[2] or '') | local color = '#' .. (colors[3] or colors[2] or '') | ||
local style = 'background-color:#' .. (colors[1] or '') .. ';color:' .. (fontcolor or color) .. ';' | local style = 'background-color:#' .. (colors[1] or '') .. ';color:' .. (fontcolor or color) .. ';' | ||
Line 96: | Line 124: | ||
borderwidth = tonumber(borderwidth or '2') or 0 | borderwidth = tonumber(borderwidth or '2') or 0 | ||
if (borderwidth > 0 and color ~= '#FFFFFF') then | if (borderwidth > 0 and color ~= '#FFFFFF') then | ||
− | style = style .. | + | style = style .. bordercss(color, borderwidth) |
end | end | ||
− | + | ||
return style | return style | ||
end | end | ||
Line 104: | Line 132: | ||
local function team_style2(team, borderwidth, fontcolor) | local function team_style2(team, borderwidth, fontcolor) | ||
local colors = get_colors(team, nil) | local colors = get_colors(team, nil) | ||
− | + | ||
local color = '#' .. (colors[1] or '') | local color = '#' .. (colors[1] or '') | ||
local style = 'background-color:#' .. (colors[3] or colors[2] or '') .. ';color:' .. (fontcolor or color) .. ';' | local style = 'background-color:#' .. (colors[3] or colors[2] or '') .. ';color:' .. (fontcolor or color) .. ';' | ||
Line 113: | Line 141: | ||
borderwidth = tonumber(borderwidth or '2') or 0 | borderwidth = tonumber(borderwidth or '2') or 0 | ||
if (borderwidth > 0 and color ~= '#FFFFFF') then | if (borderwidth > 0 and color ~= '#FFFFFF') then | ||
− | style = style .. | + | style = style .. bordercss(color, borderwidth) |
end | end | ||
− | + | ||
return style | return style | ||
end | end | ||
Line 154: | Line 182: | ||
-- do not add a border if it's nearly white | -- do not add a border if it's nearly white | ||
if ((1 + 0.05)/(color2lum(bordercolor) + 0.05) >= 1.25) then | if ((1 + 0.05)/(color2lum(bordercolor) + 0.05) >= 1.25) then | ||
− | style = style .. ' | + | style = style .. bordercss('#' .. bordercolor, borderwidth) |
end | end | ||
end | end | ||
Line 191: | Line 219: | ||
return 'background-color:#' .. background .. ';color:#' .. fontcolor .. ';' | return 'background-color:#' .. background .. ';color:#' .. fontcolor .. ';' | ||
end | end | ||
+ | end | ||
+ | |||
+ | local function team_table_head(args, team, ctype) | ||
+ | local colors = get_colors(team, nil) | ||
+ | -- 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 = '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 s = 'background-color:#' .. background .. ';color:#' .. fontcolor .. ';' | ||
+ | |||
+ | 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 | ||
+ | res = res .. '! ' .. cstyle .. ' |' .. args[i] .. '\n' | ||
+ | else | ||
+ | return res .. '|-\n' | ||
+ | end | ||
+ | end | ||
+ | return res .. '<span class="error">Error!</span>\n|-\n' | ||
+ | |||
end | end | ||
local function team_stripe1(team, borderwidth) | local function team_stripe1(team, borderwidth) | ||
local colors = get_colors(team, nil) | local colors = get_colors(team, nil) | ||
− | + | ||
-- set the default scheme | -- set the default scheme | ||
local background = colors[1] or '' | local background = colors[1] or '' | ||
Line 201: | Line 266: | ||
local bordercolor = (colors[3] or colors[2] or ''):upper() | local bordercolor = (colors[3] or colors[2] or ''):upper() | ||
borderwidth = tonumber(borderwidth or '3') or 0 | borderwidth = tonumber(borderwidth or '3') or 0 | ||
− | + | ||
-- if there is no tertiary color, then pick a font color | -- if there is no tertiary color, then pick a font color | ||
if (colors[3] == nil) then | if (colors[3] == nil) then | ||
Line 234: | Line 299: | ||
end | end | ||
style = 'background-color:#' .. background .. ';color:#' .. fontcolor .. ';' .. style | style = 'background-color:#' .. background .. ';color:#' .. fontcolor .. ';' .. style | ||
− | + | ||
return style | return style | ||
+ | end | ||
+ | |||
+ | local function team_boxes(frame, team, order, sep) | ||
+ | local function colorbox( h ) | ||
+ | local r = mw.html.create('') | ||
+ | r:tag('span') | ||
+ | :css('background-color', '#' .. (h or '')) | ||
+ | :css('border', '1px solid #000') | ||
+ | :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 table.concat(colorboxes, sep) | ||
+ | end | ||
+ | |||
+ | return '' | ||
end | end | ||
Line 253: | Line 360: | ||
return '' | return '' | ||
end | end | ||
− | + | ||
− | local nums = { | + | local nums = { |
tonumber(num1:match('[1-5]') or '0') or 0, | 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 colorboxes = {} | ||
local colornames = {} | 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 ( nums[i] > 0 ) then | ||
if( colors['name' .. nums[i]]) then | if( colors['name' .. nums[i]]) then | ||
Line 274: | Line 387: | ||
local res = '' | local res = '' | ||
if (#colornames == 1) then | if (#colornames == 1) then | ||
− | res = colornames[1] | + | res = colornames[1] |
elseif (#colornames == 2) then | elseif (#colornames == 2) then | ||
res = colornames[1] .. ' and ' .. colornames[2] | res = colornames[1] .. ' and ' .. colornames[2] | ||
− | + | elseif (#colornames > 2) then | |
res = colornames[1] | res = colornames[1] | ||
for i=2,#colornames do | for i=2,#colornames do | ||
Line 287: | Line 400: | ||
end | end | ||
end | end | ||
− | + | ||
if (colors['cite']) then | if (colors['cite']) then | ||
res = res .. frame:preprocess('<ref>' .. colors['cite'] .. '</ref>') | res = res .. frame:preprocess('<ref>' .. colors['cite'] .. '</ref>') | ||
Line 297: | Line 410: | ||
res = res .. '[' .. colors['ref2'] .. ']' | res = res .. '[' .. colors['ref2'] .. ']' | ||
end | end | ||
− | + | ||
if (#colornames > 0) then | if (#colornames > 0) then | ||
res = res .. sep | res = res .. sep | ||
end | end | ||
− | + | ||
if (#colorboxes > 0) then | if (#colorboxes > 0) then | ||
res = res .. table.concat(colorboxes, ' ') | res = res .. table.concat(colorboxes, ' ') | ||
end | end | ||
− | + | ||
return res | return res | ||
end | end | ||
Line 351: | Line 464: | ||
local args = (frame.args[1] ~= nil) and frame.args or frame:getParent().args | local args = (frame.args[1] ~= nil) and frame.args or frame:getParent().args | ||
return team_header2(remove_sport(args[1] or '')) | 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 | end | ||
Line 356: | Line 479: | ||
local args = (frame.args[1] ~= nil) and frame.args or frame:getParent().args | local args = (frame.args[1] ~= nil) and frame.args or frame:getParent().args | ||
return team_stripe1(remove_sport(args[1] or ''), args['border']) | 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 | end | ||
function p.list(frame) | function p.list(frame) | ||
local args = (frame.args[1] ~= nil) and frame.args or frame:getParent().args | local args = (frame.args[1] ~= nil) and frame.args or frame:getParent().args | ||
− | return team_list(frame, remove_sport(args[1] or ''), | + | 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 '') | args[2] or '1', args[3] or '2', args[4] or '3', args[5] or '4', args[6] or '5', args['sep'] or '') | ||
end | end | ||
Line 367: | Line 496: | ||
local args = (frame.args[1] ~= nil) and frame.args or frame:getParent().args | local args = (frame.args[1] ~= nil) and frame.args or frame:getParent().args | ||
return team_check(remove_sport(args[1] or ''), args[2] or '') | 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 | end | ||
Revision as of 23:46, 14 January 2018
Documentation for this module may be created at Module:College color/sandbox/doc
--
-- 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 bordercss(c, w)
local s = 'inset ' .. w .. 'px ' .. w .. 'px 0 ' .. c
.. ', inset -' .. w .. 'px -' .. w .. 'px 0 ' .. c
return '-moz-box-shadow: ' .. s .. '; -webkit-box-shadow: ' .. s .. '; 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 '')
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 '')
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)
-- 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 = '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 s = 'background-color:#' .. background .. ';color:#' .. fontcolor .. ';'
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
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')
:css('background-color', '#' .. (h or ''))
:css('border', '1px solid #000')
: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 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')
:css('background-color', '#' .. (h or ''))
:css('border', '1px solid #000')
: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 == 1) then
res = colornames[1]
elseif (#colornames == 2) then
res = colornames[1] .. ' and ' .. colornames[2]
elseif (#colornames > 2) then
res = colornames[1]
for i=2,#colornames do
if( i < #colornames ) then
res = res .. ', ' .. colornames[i]
else
res = res .. ', and ' .. colornames[i]
end
end
end
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 .. 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