Jump to content

Module:College color/sandbox

From Wikipedia, the free encyclopedia
--
-- 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 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()
    c = mw.ustring.match(c, '^[#]*([a-f0-9]*)$')
    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
    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
        local lum = color2lum(colors[1] or '')
        local wcontrast = (1 + 0.05)/(lum + 0.05)
        local bcontrast = (lum + 0.05)/(0 + 0.05)
        if( bcontrast > wcontrast + 1.25 ) then
            fontcolor = '#000000'
        else
            fontcolor = '#FFFFFF'
        end
    end
    local style = 'background-color:#' .. (colors[1] or '') .. ' !important;color:' .. (fontcolor or color) .. ' !important;'
    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 .. 'box-shadow: ' .. bordercss(color, borderwidth) .. ' !important;'
    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
        local lum = color2lum(colors[3] or colors[2] or '')
        local wcontrast = (1 + 0.05)/(lum + 0.05)
        local bcontrast = (lum + 0.05)/(0 + 0.05)
        if( bcontrast > wcontrast + 1.25 ) then
            fontcolor = '#000000'
        else
            fontcolor = '#FFFFFF'
        end
    end
    local style = 'background-color:#' .. (colors[3] or colors[2] or '') .. ' !important;color:' .. (fontcolor or color) .. ' !important;'
    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 .. 'box-shadow: ' .. bordercss(color, borderwidth) .. ' !important;'
    end
    return style
end

local function team_header1(team, borderwidth)
    local colors = get_colors(team, nil)
    local background = (colors[1] or 'FFFFFF'):upper()
    if ((1 + 0.05)/(color2lum(background) + 0.05) < 1.25) then
        background = 'FFFFFF'
    end
    local fontcolor = '000000'
    local lum = color2lum(background)
    local wcontrast = (1 + 0.05)/(lum + 0.05)
    local bcontrast = (lum + 0.05)/(0 + 0.05)
    if( bcontrast > wcontrast + 1.25 ) then
        fontcolor = '000000'
    else
        fontcolor = 'FFFFFF'
    end
    local style
    if( background == 'FFFFFF' ) then
        style = 'background-color:none !important;color:#' .. fontcolor .. ' !important;'
    else
        style = 'background-color:#' .. background .. ' !important;color:#' .. fontcolor .. ' !important;'
    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
            if ((1 + 0.05)/(color2lum(bordercolor) + 0.05) >= 1.25) then
                style = style .. 'box-shadow: ' .. bordercss('#' .. bordercolor, borderwidth) .. ' !important;'
            end
        end
    end
    return style
end

local function team_header2(team)
    local colors = get_colors(team, nil)
    local background = (colors[3] or colors[2] or 'FFFFFF'):upper()
    if ((1 + 0.05)/(color2lum(background) + 0.05) < 1.25) then
        background = 'FFFFFF'
    end
    if( background == 'FFFFFF' ) then
        background = (colors[1] or 'FFFFFF'):upper()
    end
    local fontcolor = '000000'
    local lum = color2lum(background)
    local wcontrast = (1 + 0.05)/(lum + 0.05)
    local bcontrast = (lum + 0.05)/(0 + 0.05)
    if( bcontrast > wcontrast + 1.25 ) then
        fontcolor = '000000'
    else
        fontcolor = 'FFFFFF'
    end
    if( background == 'FFFFFF' ) then
        return 'background-color:none !important;color:#' .. fontcolor .. ' !important;'
    else
        return 'background-color:#' .. background .. ' !important;color:#' .. fontcolor .. ' !important;'
    end
end

local function team_table_head(args, team, ctype)
    local colors = get_colors(team, nil)
    local borderwidth = tonumber(args['border']) or 0
    local background = (ctype == 'p') and
        (colors[1] or 'FFFFFF'):upper() or
        (colors[3] or colors[2] or 'FFFFFF'):upper()
    local fontcolor = ''
    local lum = color2lum(background)
    local wcontrast = (1 + 0.05)/(lum + 0.05)
    local bcontrast = (lum + 0.05)/(0 + 0.05)
    if( bcontrast > wcontrast + 1.25 ) then
        fontcolor = '#000000'
    else
        fontcolor = '#FFFFFF'
    end
    local s = 'background-color:#' .. background .. ' !important;color:' .. (args['color'] or fontcolor) .. ' !important;'
    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 .. 'box-shadow: ' .. bordercss('#' .. bc, borderwidth) .. ' !important;'
        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)
    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 (colors[3] == nil) then
        local lum = color2lum(colors[1])
        local wcontrast = (1 + 0.05)/(lum + 0.05)
        local bcontrast = (lum + 0.05)/(0 + 0.05)
        if( bcontrast > wcontrast + 1.25 ) then
            fontcolor = '000000'
        else
            fontcolor = 'FFFFFF'
        end
    end
    local style = ''
    if (borderwidth > 0) then
        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 .. ' !important;'
        style = style .. ' border-left: none !important; border-right: none !important;'
        style = style .. ' box-shadow: inset 0 2px 0 #FEFEFE, inset 0 -2px 0 #FEFEFE !important;'
    end
    style = 'background-color:#' .. background .. ' !important;color:#' .. fontcolor .. ' !important;' .. 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

return p