Skip to content

Instantly share code, notes, and snippets.

@jyfeather
Last active December 18, 2015 18:59
Show Gist options
  • Save jyfeather/5829837 to your computer and use it in GitHub Desktop.
Save jyfeather/5829837 to your computer and use it in GitHub Desktop.
Read and Comment Color-Palette from https://github.com/alyssa/color-palette
require 'open-uri'
require 'nokogiri' # Nokogiri 是 Ruby 上的一個 HTML, XML, SAX 的 parser
class ColorPalette
@@site_name # 类变量
def initialize(url) # 构造函数
url = check_url(url)
@@site_name = URI.parse(url).host # 从url中取得网址
@color_map = Hash.new # 类实例变量,哈希表用来保存出现的颜色
urls = get_stylesheet_urls(url) # 取得相应的样式表,因为里面记录了颜色文件
build_color_palette(urls) # 生成颜色列表
sort_palette # 进行排序
end
def check_url(url)
url = "http://" + url if !url.start_with?("http", "https", "ftp")
url = url.chomp('/') if url.end_with? '/'
return url
end
def get_stylesheet_urls(url)
urls = Array.new # 用来保存可能获取颜色信息的网页位置
begin
page = Nokogiri::HTML(open(url))
rescue # rescue 块用来处理异常
abort("Not a valid link. Try another one.")
end
page.css('head').css('link[rel=stylesheet]').each {|stylesheet|
if !stylesheet['href'].start_with? '/'
css_url = stylesheet['href']
else
css_url = url + stylesheet['href'] # local files, must add to url for uri parsing
end
urls << css_url # 数组这样也可以追加元素
}
urls
end
def build_color_palette(urls)
urls.each{ |css_url|
# puts css_url
begin
page_source = Nokogiri::HTML(open(css_url)).text
rescue
puts "Did not pull any colors from badly formed url:\n"+css_url
next
end
page_source = Nokogiri::HTML(open(css_url)).text
# |color| 5个元素的数组 (5个正则模式去匹配)
# 种类 1: hex
# 种类 2,3,4: rgb respectively notes: handles rgba but ignores opacity
# 种类 5: 颜色名
color_array = page_source.scan(/color\s*:\s*(#[0-9A-Fa-f]{3,6}+)\s*|rgba?\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*|color\s*:\s*(white|aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple)/)
color_array.each{|color|
#puts color.inspect
if color[0] != nil
color = color[0].downcase
color = expand_hex(color) if color.length == 4 # usually length 3 but including '#' so use length 4
elsif color[1] != nil
color = "#" + color[1].to_i.to_s(16) + color[2].to_i.to_s(16) + color[3].to_i.to_s(16)
# below is the case that you have r: 0 g: 0 b: 0 => #000 .... need to expand
color = expand_hex(color) if color.length == 4 # usually length 3 but including '#' so use length 4
else
color = color[4].downcase
hex_color = get_hex(color)
color = hex_color if hex_color != nil # try to assign a hex value, if not, will remain as is.
end
# 颜色哈希表中,对应颜色的频率加1
if @color_map[color] == nil
@color_map[color] = 1
else
@color_map[color] += 1
end
}
}
end
# 有些颜色使用名称指定的,那么需要转化为rgb码
def get_hex(color) # 注意 case 语句的返回值
hex = case color
when "white" then "#ffffff"
when "black" then "#000000"
when "blue" then "#0000ff"
when "fuchsia" then "#ff00ff"
when "gray" then "#808080"
when "green" then "#008000"
when "lime" then "#00ff00"
when "maroon" then "#800000"
when "olive" then "#808000"
when "orange" then "#ffA500"
when "purple" then "#800080"
end
end
# 类似于 #765 这种rgb码,需要转化
def expand_hex(color)
new_hex = color[0]
for i in 1..3
new_hex += color[i]+color[i]
end
new_hex
end
# 对哈希表排序,返回仅含颜色名的数组
def sort_palette
@color_palette = Array.new
@color_map = @color_map.sort_by {|k,v| v}.reverse
@color_map.each{|key, value|
@color_palette << key
}
return @color_palette
end
def print_palette_html
file = File.new("#{@@site_name}.html", "w+") # File puts 直接写入文件中
file.puts "<html>"
file.puts "<title>#{@@site_name} Color Page</title>"
file.puts "<body>"
file.puts "<table>"
file.puts "<tr>"
file.puts "<th> Color </th>"
file.puts "<th> Hex </th>"
file.puts "<th> Frequency </th>"
file.puts "</tr>"
@color_map.each{|key, value|
file.puts "<tr>"
file.puts "<td style='width:50px; height:50px; background-color: #{key}'></td>"
file.puts "<td> #{key} </td>"
file.puts "<td> #{value} </td>"
file.puts "</tr>"
}
file.puts "</body>"
file.puts "</html>"
end
def print_color_palette
@color_palette.each{|c| puts c}
end
def print_palette_with_freq
puts "number of unique colors: " + @color_map.size.to_s
printf("--------|-----------\n")
printf("%.8s\t|%s\n", "Color", "Frequency")
printf("--------|-----------\n")
@color_map.each{|key, value|
printf("%.8s |%d\n", key, value)
}
end
end
if ARGV.length == 0
abort("must provide a url") # 终止程序,并输出提示信息
elsif ARGV.length > 1
abort("Too much info, buddy. I just need one url.")
elsif ARGV.length == 1
param_url = ARGV[0] # ARGV是一个参数数组变量
end
cp = ColorPalette.new("#{param_url}") # Perl只需要 $param_url ,这里略显复杂
puts "Palette for " + param_url
cp.print_palette_with_freq # 控制台,输出对应网页使用颜色的频率列表
cp.print_palette_html # 记录颜色列表信息,并生成相应网页
Palette for http://www.cityu.edu.hk/
number of unique colors: 27
--------|-----------
Color |Frequency
--------|-----------
#ffffff |31
#555555 |10
#666666 |7
#333333 |5
#398600 |5
#000000 |4
#444444 |3
#dddddd |2
#f3f3ed |2
#cccccc |2
#323232 |2
#0072aa |2
#222222 |2
#888888 |1
#acd5ea |1
#025d8c |1
#323f41 |1
#ff0000 |1
#367e00 |1
#dd0000 |1
#667172 |1
#2094c3 |1
#d7e1e1 |1
#9ec990 |1
#0074a3 |1
#999999 |1
#767775 |1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment