Created
April 7, 2015 07:24
-
-
Save phluid61/e51f8a390a3a218005df to your computer and use it in GitHub Desktop.
colour analysis of CSS files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/env ruby | |
if ARGV.length == 0 | |
puts "Usage: #$0 *.css" | |
exit 1 | |
end | |
$dict = {} | |
ARGV.each do |f| | |
in_comment = false | |
line = 0 | |
File.open(f) do |fh| | |
fh.each_line do |l| | |
line += 1 | |
if in_comment | |
c = l.index '*/' | |
if c | |
l[0..c+1] = '' | |
else | |
next | |
end | |
end | |
l.sub! %r(//.*$), '' | |
l.sub! %r(/\*.*\*/), '' | |
c = l.index '/*' | |
if c | |
in_comment = true | |
l[c..-1] = '' | |
end | |
l.gsub! /\s+/, ' ' | |
l.strip! | |
# fixme: multiple instances per line? | |
r_hex = /[0-9a-f]/i | |
r_s = /\s*/ | |
r_c = /\s*,\s*/ | |
colour = nil | |
lit = nil | |
if /#([0-9a-f])([0-9a-f])([0-9a-f])\b/i =~ l | |
colour = "#$1#$1#$2#$2#$3#$3".to_i(16) | |
lit = $& | |
elsif /#([0-9a-f]{6})\b/i =~ l | |
colour = $1.to_i(16) | |
lit = $& | |
elsif /rgb\(#{r_s}(\d+)#{r_c}(\d+)#{r_c}(\d+)#{r_s}\)/i =~ l | |
colour = ($1.to_i << 16) | ($2.to_i << 8) | ($3.to_i) | |
lit = $& | |
elsif /rgba\(#{r_s}(\d+)#{r_c}(\d+)#{r_c}(\d+)#{r_c}(\d*\.\d*)#{r_s}\)/i =~ l | |
colour = [($1.to_i << 16) | ($2.to_i << 8) | ($3.to_i), $4.to_f] | |
lit = $& | |
elsif /\bcolor\s*:\s*(\w+)\b/ =~ l | |
colour = $1.downcase | |
lit = $1 | |
if /\b(transparent|inherit)\b/ =~ colour | |
colour = nil | |
end | |
end | |
if colour | |
$dict[colour] ||= [] | |
$dict[colour] << [f, line, l, lit] | |
end | |
end | |
end | |
end | |
def c2rgb c | |
r = (c & 0xFF0000) >> 16 | |
g = (c & 0x00FF00) >> 8 | |
b = (c & 0x0000FF) | |
[r, g, b] | |
end | |
def c2hsv c | |
rgb2hsv *c2rgb(c) | |
end | |
def rgb2hsv r, g, b | |
r = r.to_f / 255 | |
g = g.to_f / 255 | |
b = b.to_f / 255 | |
max = [r,g,b].max | |
min = [r,g,b].min | |
delta = max - min | |
v = max * 100 | |
if max != 0.0 | |
s = delta / max * 100 | |
else | |
s = 0.0 | |
end | |
if s == 0.0 | |
h = 0.0 | |
else | |
if r == max | |
h = (g - b) / delta | |
elsif g == max | |
h = 2 + (b - r) / delta | |
elsif b == max | |
h = 4 + (r - g) / delta | |
end | |
h *= 60 | |
if h < 0 | |
h += 360 | |
end | |
end | |
[h, s, v] | |
end | |
cmp_hsv = proc {|a,b| | |
a = c2hsv a | |
b = c2hsv b | |
if a[0] == b[0] | |
if a[1]==b[1] | |
a[2] <=> b[2] | |
else | |
a[1] <=> b[1] | |
end | |
else | |
a[0] <=> b[0] | |
end | |
} | |
cmp_hsva = proc{|a,b| | |
r = cmp_hsv[a[0],b[0]] | |
if r == 0 | |
r = a[1] <=> b[1] | |
end | |
r | |
} | |
def usage key | |
x = $dict[key] | |
usage = '<div class="action">' | |
usage << x.length.to_s | |
usage << '<div class="popup">' | |
x.each do |f, l, t| | |
usage << "<span class=\"f\">#{f}</span>:<span class=\"l\">#{l}</span>: <span class=\"c\">#{t}</span>\n" | |
end | |
usage << '</div>' | |
usage << '</div>' | |
usage | |
end | |
alphas = [] | |
greys = [] | |
colours = [] | |
words = [] | |
puts <<HTML | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Colour Analysis</title> | |
<style type="text/css"> | |
body{color:#000;background:#fff} | |
.box{display:inline-block;width:1em;height:1em;border:1px solid #000} | |
.alpha{display:inline-block;background-image:url(data:image/gif;base64,R0lGODlhEAAQAPcAAAAAAAEBAQICAgMDAwQEBAUFBQYGBgcHBwgICAkJCQoKCgsLCwwMDA0NDQ4ODg8PDxAQEBERERISEhMTExQUFBUVFRYWFhcXFxgYGBkZGRoaGhsbGxwcHB0dHR4eHh8fHyAgICEhISIiIiMjIyQkJCUlJSYmJicnJygoKCkpKSoqKisrKywsLC0tLS4uLi8vLzAwMDExMTIyMjMzMzQ0NDU1NTY2Njc3Nzg4ODk5OTo6Ojs7Ozw8PD09PT4+Pj8/P0BAQEFBQUJCQkNDQ0REREVFRUZGRkdHR0hISElJSUpKSktLS0xMTE1NTU5OTk9PT1BQUFFRUVJSUlNTU1RUVFVVVVZWVldXV1hYWFlZWVpaWltbW1xcXF1dXV5eXl9fX2BgYGFhYWJiYmNjY2RkZGVlZWZmZmdnZ2hoaGlpaWpqamtra2xsbG1tbW5ubm9vb3BwcHFxcXJycnNzc3R0dHV1dXZ2dnd3d3h4eHl5eXp6ent7e3x8fH19fX5+fn9/f4CAgIGBgYKCgoODg4SEhIWFhYaGhoeHh4iIiImJiYqKiouLi4yMjI2NjY6Ojo+Pj5CQkJGRkZKSkpOTk5SUlJWVlZaWlpeXl5iYmJmZmZqampubm5ycnJ2dnZ6enp+fn6CgoKGhoaKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq6ysrK2tra6urq+vr7CwsLGxsbKysrOzs7S0tLW1tba2tre3t7i4uLm5ubq6uru7u7y8vL29vb6+vr+/v8DAwMHBwcLCwsPDw8TExMXFxcbGxsfHx8jIyMnJycrKysvLy8zMzM3Nzc7Ozs/Pz9DQ0NHR0dLS0tPT09TU1NXV1dbW1tfX19jY2NnZ2dra2tvb29zc3N3d3d7e3t/f3+Dg4OHh4eLi4uPj4+Tk5OXl5ebm5ufn5+jo6Onp6erq6uvr6+zs7O3t7e7u7u/v7/Dw8PHx8fLy8vPz8/T09PX19fb29vf39/j4+Pn5+fr6+vv7+/z8/P39/f7+/v///ywAAAAAEAAQAAAINgD/CRwo8JfBgwYJEkSIUOFAhgcdFoT4S+I/ihUlYrS4USNGihxBeoQYkuRIhiVRnmy4MqLEgAA7)} | |
.action{display:inline-block;position:relative;cursor:pointer} | |
.action .popup{display:none} | |
.action:hover .popup{display:block} | |
.popup{position:absolute;z-index:2; padding:0.25em;border:1px solid #000;background-color:#f0f8ff} | |
.popup .f{color:#00d} | |
.popup .l{color:#0c0} | |
</style> | |
</head> | |
<body><pre> | |
<b>Colours</b> | |
HTML | |
puts "Total: #{$dict.length}" | |
$dict.each_pair do |c,x| | |
if c.is_a? Array | |
alphas << c | |
elsif c.is_a? String | |
words << c | |
else | |
r, g, b = c2rgb c | |
if r == g && g == b | |
greys << c | |
else | |
colours << c | |
end | |
end | |
end | |
puts '', "Alpha colours: #{alphas.length}" | |
alphas.sort(&cmp_hsva).each do |c,a| | |
r,g,b = c2rgb c | |
css = 'rgba(%d,%d,%d,%f)' % [r, g, b, a] | |
puts ' <div class="box" style="background-color:#%06x"> </div><div class="alpha"><div class="box" style="background-color:%s"> </div></div> #%06x %f : %s' % [c, css, c, a, usage([c,a])] | |
end | |
puts '', "Grey: #{greys.length}" | |
greys.sort.each do |c| | |
puts ' <div class="box" style="background-color:#%06x"> </div> #%06x : %s' % [c, c, usage(c)] | |
end | |
puts '', "Colours: #{colours.length}" | |
colours.sort(&cmp_hsv).each do |c| | |
puts ' <div class="box" style="background-color:#%06x"> </div> #%06x : %s' % [c, c, usage(c)] | |
end | |
puts '', "Words: #{words.length}" | |
words.sort.each do |c| | |
puts " <div class=\"box\" style=\"background-color:#{c}\"> </div> #{c} : #{usage c}" | |
end | |
puts <<HTML | |
</pre></body> | |
</html> | |
HTML |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment