Skip to content

Instantly share code, notes, and snippets.

@phluid61
Created April 7, 2015 07:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save phluid61/e51f8a390a3a218005df to your computer and use it in GitHub Desktop.
Save phluid61/e51f8a390a3a218005df to your computer and use it in GitHub Desktop.
colour analysis of CSS files
#!/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