coloryze 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README ADDED
File without changes
data/bin/coloryze ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ # exec ruby -w -x $0 ${1+"$@"} # -*- ruby -*-
3
+ #!ruby -w
4
+ # vim: set filetype=ruby : set sw=2
5
+
6
+ dir = File.dirname(File.dirname(File.expand_path(__FILE__)))
7
+
8
+ libpath = dir + "/lib"
9
+ $:.unshift libpath
10
+
11
+ require 'color/coloryze'
12
+
13
+ Log.output = $stderr
14
+
15
+ col = Coloryze.new(ARGV, $stdout)
16
+ exit(col.exit_status)
data/lib/color.rb ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ $:.unshift(File.dirname(__FILE__)) unless
5
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
6
+
7
+ module Color
8
+ VERSION = '0.0.1'
9
+ end
10
+
11
+ rbfiles = Dir[File.dirname(__FILE__) + "/color/**/*.rb"]
12
+
13
+ rbfiles.sort.each do |rbfile|
14
+ rootname = rbfile.match(%r{.*/(\w+)\.rb})[1]
15
+ require "color/" + rootname
16
+ end
@@ -0,0 +1,225 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'color/rgb'
5
+ require 'color/hsb'
6
+ require 'color/full_palette'
7
+ require 'color/sample_palette'
8
+ require 'color/scheme'
9
+
10
+ require 'rubygems'
11
+ require 'riel'
12
+
13
+ Log.level = Log::WARN
14
+
15
+ class SchemeOption
16
+
17
+ attr_accessor :stype, :desc, :cls, :option, :re, :args, :params
18
+
19
+ def initialize(stype, desc, cls, *params)
20
+ @stype = stype
21
+ @desc = desc
22
+ @cls = cls
23
+ @params = params
24
+ @option = '--' + stype + "=" + params.collect { |arg| arg.to_s.upcase }.join(',')
25
+ restr = '^' + '--' + stype + "=" + params.collect { |arg| arg == :hue ? '(\#?\w+)' : '(\d+)' }.join(',') + '$' # '$
26
+ @re = Regexp.new(restr)
27
+ @args = Array.new
28
+ end
29
+
30
+ def set_args(args)
31
+ (0 ... args.length).each do |idx|
32
+ if @params[idx] == :hue
33
+ @args << create_hue(args[idx])
34
+ else
35
+ @args << args[idx].to_i
36
+ end
37
+ end
38
+ end
39
+
40
+ def create_hue(val)
41
+ if Color::RGB.matches_rgb_string?(val)
42
+ Color::RGB.new(val).to_hsb.hue
43
+ elsif md = %r{^\d+$}.match(val)
44
+ val.to_i
45
+ else
46
+ raise RuntimeErro.new("invalid value for hue: #{val}")
47
+ end
48
+ end
49
+
50
+ def to_s
51
+ [ @stype, @desc, @cls, @re ].join(" ")
52
+ end
53
+ end
54
+
55
+ class Coloryze
56
+ include Loggable
57
+
58
+ VERSION = "2.0.0"
59
+
60
+ attr_reader :exit_status
61
+
62
+ def initialize(args, outio = $stdout, errio = $stderr)
63
+ info "args: #{args}"
64
+
65
+ @exit_status = 0
66
+ @scheme_options = Array.new
67
+
68
+ _add_option("monochromatic", "display one hue", Color::Monochromatic, :hue)
69
+ _add_option("split-complementary", "display hue and two complements near 180 degrees", Color::SplitComplementary, :hue, :deg)
70
+ _add_option("double-complementary", "display two hues and their two complements", Color::DoubleComplementary, :hue, :hue)
71
+ _add_option("complementary", "display hues at 180 degrees from each other", Color::Complementary, :hue)
72
+ _add_option("analogous", "display three hues near each other", Color::Analogous, :hue, :deg)
73
+ _add_option("triadic", "display three equidistant hues", Color::Triadic, :hue)
74
+ _add_option("hues", "display colors for the generated hues (no scheme applied)", Color::Hues, :start, :end, :int)
75
+
76
+ output_type = :html
77
+ sample = nil
78
+ total_sample = nil
79
+
80
+ @scheme_options.each do |sopt|
81
+ # info "sopt: #{sopt}"
82
+ end
83
+
84
+ sopt = nil
85
+ scheme_args = Array.new
86
+
87
+ params = {
88
+ :background => nil,
89
+ :saturation_start => nil,
90
+ :saturation_end => nil,
91
+ :saturation_step => nil,
92
+ :brightness_start => nil,
93
+ :brightness_end => nil,
94
+ :brightness_step => nil,
95
+ }
96
+
97
+ args.each do |arg|
98
+ info "arg: #{arg}"
99
+
100
+ case arg
101
+ when %r{--(saturation|brightness)=(\d+),(\d+),(\d+)}
102
+ md = Regexp.last_match
103
+ fieldname = md[1]
104
+ %w{ _start _end _step }.each_with_index do |fieldsuffix, idx|
105
+ field = (fieldname + fieldsuffix).intern
106
+ params[field] = md[idx + 2].to_i
107
+ end
108
+ # not supported
109
+ # when %r{--background}
110
+ # args[:background] = md[1]
111
+ when %r{--output=(\w+)}
112
+ md = Regexp.last_match
113
+ output_type = md[1].intern
114
+ when "--version"
115
+ show_version(outio)
116
+ @exit_status = 0
117
+ return
118
+ when "--verbose"
119
+ Log.level = Log::DEBUG
120
+ when %r{--sample=(\d+)}
121
+ md = Regexp.last_match
122
+ sample = md[1].to_i
123
+ when %r{--total-sample=(\d+)}
124
+ md = Regexp.last_match
125
+ total_sample = md[1].to_i
126
+ when "--help", "--usage"
127
+ show_usage(outio)
128
+ @exit_status = 0
129
+ return
130
+ else
131
+ md = nil
132
+ if sopt
133
+ $stderr.puts "error: invalid argument: #{arg}"
134
+ @sxit_status = 1
135
+ elsif sopt = @scheme_options.detect { |so| md = so.re.match(arg) }
136
+ sopt.set_args(md[1 .. -1])
137
+ scheme_args.concat(md[1 .. -1])
138
+
139
+ # add process for scheme without the right parameters
140
+ end
141
+ end
142
+ end
143
+
144
+ unless sopt
145
+ # check for invalid scheme parameters
146
+
147
+ args.each do |arg|
148
+ @scheme_options.each do |so|
149
+ if arg.index("--" + so.stype)
150
+ info "matched #{so}"
151
+ errio.puts "error: scheme '#{so.stype}' requires " + so.params.collect { |p| p.to_s }.join(",")
152
+ @exit_status = 1
153
+ return
154
+ end
155
+ end
156
+ end
157
+ end
158
+
159
+ unless sopt
160
+ show_usage(outio)
161
+ @exit_status = 1
162
+ return
163
+ end
164
+
165
+ info "sopt: #{sopt}"
166
+ info "scheme_args: #{scheme_args}"
167
+
168
+ hues = sopt.cls.new(*sopt.args).hues
169
+
170
+ info "hues: #{hues}"
171
+ info "params: #{params}"
172
+
173
+ info "sample: #{sample}"
174
+ info "total_sample: #{total_sample}"
175
+
176
+ palette_cls = if sample || total_sample
177
+ # yes, a mismatch between *sample and *samples ... legacy option.
178
+ params[:samples] = sample
179
+ params[:total_samples] = total_sample
180
+ Color::SamplePalette
181
+ else
182
+ Color::FullPalette
183
+ end
184
+
185
+ palette = palette_cls.new(hues, params)
186
+ info "palette: #{palette}"
187
+ if output_type == :html
188
+ palette.print_as_html(outio)
189
+ else
190
+ palette.print_as_text(outio)
191
+ end
192
+ end
193
+
194
+ def show_version(io)
195
+ io.puts "coloryze, version #{VERSION}"
196
+ io.puts "Written by Jeff Pace (jpace@incava.org)"
197
+ io.puts "Released under the GNU Public License."
198
+ end
199
+
200
+ def show_usage(io)
201
+ io.puts "usage: coloryze [options]"
202
+ io.puts "options:"
203
+ options = Array.new
204
+ options << [ "--help, --usage", "display this help message" ]
205
+ @scheme_options.each do |sopt|
206
+ options << [ sopt.option, sopt.desc ]
207
+ end
208
+ options << [ "--sample=NUM", "select only NUM colors per hue, chosen randomly" ]
209
+ options << [ "--total-sample=NUM", "select only NUM total colors, chosen randomly" ]
210
+ options << [ "--saturation=START,END,INT", "set the saturation start, end, and interval" ]
211
+ options << [ "--brightness=START,END,INT", "set the brightness start, end, and interval" ]
212
+ options << [ "--output=TYPE", "set the output type, \"text\" (the default) or \"html\"" ]
213
+ options << [ "--verbose", "produce debugging output" ]
214
+ options << [ "--version", "display the version and exit"]
215
+
216
+ options.each do |opt|
217
+ io.printf " %-30s %s\n", *opt
218
+ end
219
+ end
220
+
221
+ def _add_option(stype, desc, cls, *params)
222
+ @scheme_options << SchemeOption.new(stype, desc, cls, *params)
223
+ end
224
+
225
+ end
@@ -0,0 +1,158 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'color/hsb'
5
+ require 'color/rgb'
6
+ require 'color/util'
7
+ require 'color/palette'
8
+
9
+ # shows a set of colors, in text and html
10
+
11
+ module Color
12
+
13
+ class FullPalette < Palette
14
+
15
+ def initialize(hues, args = Hash.new)
16
+ super(args)
17
+
18
+ # hue => saturation => brightness => rgb
19
+ @colors = Array.new
20
+
21
+ hues.each do |hue|
22
+ (saturation_start .. saturation_end).step(saturation_step) do |sat|
23
+ (brightness_start .. brightness_end).step(brightness_step) do |brt|
24
+ hsb = HSB.new hue, sat / 100.0, brt / 100.0
25
+ @colors << hsb
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ def colors
32
+ @colors
33
+ end
34
+
35
+ def puts_indented(io, level, msg)
36
+ io.puts((' ' * (4 * level)) + msg)
37
+ end
38
+
39
+ def print_html_tables(io = $stdout)
40
+ n_columns = 1 + (@brightness_end - @brightness_start) / @brightness_step
41
+
42
+ # want the output to be:
43
+
44
+ # +-------------------------------------------------------+
45
+ # + hue[0] +
46
+ # + +-----------------------------------------------------+
47
+ # + + sat[0] +
48
+ # + +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
49
+ # + + r/b + + r/b + + r/b + + r/b + + r/b + + r/b + + r/b +
50
+ # + + + + + + + + + + + + + + +
51
+ # + +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
52
+ # + + sat[1] +
53
+ # + +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
54
+ # + + r/b + + r/b + + r/b + + r/b + + r/b + + r/b + + r/b +
55
+ # + + + + + + + + + + + + + + +
56
+ # + +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
57
+ # +-------------------------------------------------------+
58
+ # + hue[1] +
59
+ # + +-----------------------------------------------------+
60
+ # + + sat[0] +
61
+ # + +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
62
+ # + + r/b + + r/b + + r/b + + r/b + + r/b + + r/b + + r/b +
63
+ # + + + + + + + + + + + + + + +
64
+ # + +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
65
+ # + + sat[1] +
66
+ # + +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
67
+ # + + r/b + + r/b + + r/b + + r/b + + r/b + + r/b + + r/b +
68
+ # + + + + + + + + + + + + + + +
69
+ # + +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
70
+ # +-------------------------------------------------------+
71
+
72
+ cellwidth = 100 / n_columns
73
+
74
+ level = 1
75
+
76
+ colors_by_hue.sort.each do |hue, by_saturation|
77
+ puts_indented io, 1, '<table width="100%">'
78
+
79
+ puts_indented io, 2, '<tr>'
80
+
81
+ textcolor = @background.nil? || @background.index(%r{[A-Z]\w}) ? "000000" : "FFFFFF"
82
+ puts_indented io, 3, "<td style=\"color: \##{textcolor};\">hue #{hue} &deg;</td>"
83
+
84
+ puts_indented io, 2, '</tr>'
85
+
86
+ by_saturation.sort.each do |sat, by_brightness|
87
+ puts_indented io, 2, '<tr>'
88
+ puts_indented io, 3, '<td>'
89
+
90
+ puts_indented io, 4, '<table width="100%">'
91
+ puts_indented io, 5, '<tr>'
92
+ puts_indented io, 6, "<td colspan=#{n_columns}>"
93
+
94
+ puts_indented io, 7, "saturation: #{sat}"
95
+
96
+ puts_indented io, 6, '</td>'
97
+ puts_indented io, 5, '</tr>'
98
+
99
+ puts_indented io, 5, '<tr>'
100
+
101
+ by_brightness.sort.reverse.each do |brt, hsb|
102
+ rgbstr = sprintf("%06x", hsb.to_rgb)
103
+
104
+ puts_indented io, 6, "<td style=\"width: #{cellwidth}%; vertical-align: bottom; border:2px outset; border-collapse:collapse;\">"
105
+
106
+ puts_indented io, 7, "<table width=\"100%\" border=\"0\" border-width=\"4px\">"
107
+
108
+ stylestr = @background ? " style=\"color: \##{rgbstr};\"" : ""
109
+
110
+ text = sprintf "\#%s; b: %3.2f", rgbstr, brt
111
+
112
+ puts_indented io, 8, '<tr><td' + stylestr + '>' + text + '</td></tr'
113
+
114
+ puts_indented io, 8, "<tr><td style=\"background-color: \##{rgbstr}; vertical-align: bottom;\"><br>&nbsp;</td></tr>"
115
+
116
+ puts_indented io, 7, "</table>"
117
+ puts_indented io, 6, "</td>"
118
+ end
119
+
120
+ puts_indented io, 5, '</tr>'
121
+
122
+ puts_indented io, 4, '</table>'
123
+
124
+ puts_indented io, 3, '</td>'
125
+ puts_indented io, 2, '</tr>'
126
+
127
+ end
128
+
129
+ puts_indented io, 1, '</table>'
130
+ end
131
+
132
+ return nil if true
133
+
134
+
135
+ colors_by_hue.sort.each do |hue, by_saturation|
136
+ print_html_hue_line(io, hue, n_columns)
137
+
138
+ io.puts "<table width=\"100%\">"
139
+ io.puts " <tr>"
140
+
141
+ by_saturation.sort.each do |sat, by_brightness|
142
+ by_brightness.sort.reverse.each do |brt, hsb|
143
+ io.puts " <tr>"
144
+
145
+ # this is one color per row, for now
146
+ print_html_color(io, sat, brt, hsb.to_rgb, 100 / n_columns)
147
+
148
+ io.puts " </tr>"
149
+ end
150
+ end
151
+ io.puts "</table>"
152
+ io.puts "<br/>"
153
+ end
154
+ end
155
+
156
+ end
157
+
158
+ end
data/lib/color/hsb.rb ADDED
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'color/rgb'
5
+ require 'color/util'
6
+
7
+ module Color
8
+
9
+ class HSB
10
+ attr_accessor :hue, :saturation, :brightness
11
+
12
+ def initialize(hue, saturation, brightness)
13
+ Color::check_constraint(hue, "hue", 0, 360)
14
+ Color::check_constraint(saturation, "saturation", 0, 1)
15
+ Color::check_constraint(brightness, "brightness", 0, 1)
16
+
17
+ @hue = hue
18
+ @saturation = saturation
19
+ @brightness = brightness
20
+ end
21
+
22
+ def to_s
23
+ "hue: #{hue}; saturation: #{saturation}; brightness: #{brightness}"
24
+ end
25
+
26
+ def inspect
27
+ to_s
28
+ end
29
+
30
+ def equal?(other)
31
+ $stderr.puts "*******"
32
+
33
+ hue.equal?(other.hue) &&
34
+ if cmp == 0
35
+ cmp = saturation <=> other.saturation
36
+ if cmp == 0
37
+ cmp = brightness <=> other.brightness
38
+ end
39
+ end
40
+
41
+ puts "returning: #{cmp}"
42
+ cmp
43
+ end
44
+
45
+ def <=>(other)
46
+ cmp = hue <=> other.hue
47
+ if cmp == 0
48
+ cmp = saturation <=> other.saturation
49
+ if cmp == 0
50
+ cmp = brightness <=> other.brightness
51
+ end
52
+ end
53
+
54
+ cmp
55
+ end
56
+
57
+ def floats_equal?(a, b, threshold)
58
+ (a - b).abs < 0.0001
59
+ end
60
+
61
+ def ==(other)
62
+ threshold = 0.0001
63
+ floats_equal?(hue, other.hue, threshold) && floats_equal?(saturation, other.saturation, threshold) && floats_equal?(brightness, other.brightness, threshold)
64
+ end
65
+
66
+ # Converts HSB (HSV) to RGB. Hue is expected as 0-360; saturation
67
+ # and brightness (value) as 0.0-1.0. Returns an RGB object.
68
+ def to_rgb
69
+ red = green = blue = nil
70
+
71
+ if saturation == 0
72
+ red = green = blue = brightness * 255
73
+ else
74
+ hi = (hue / 60.0).to_i
75
+ f = (hue / 60.0) - hi
76
+ p = brightness * (1 - saturation)
77
+ q = brightness * (1 - saturation * f)
78
+ t = brightness * (1 - saturation * (1 - f))
79
+
80
+ red, green, blue = case hi
81
+ when 0
82
+ [ brightness, t, p ]
83
+ when 1
84
+ [ q, brightness, p ]
85
+ when 2
86
+ [ p, brightness, t ]
87
+ when 3
88
+ [ p, q, brightness ]
89
+ when 4
90
+ [ t, p, brightness ]
91
+ when 5
92
+ [ brightness, p, q ]
93
+ else
94
+ raise "error: hue: #{hue}; hi: #{hi}"
95
+ end
96
+
97
+ red *= 255
98
+ green *= 255
99
+ blue *= 255
100
+ end
101
+
102
+ RGB.new red, green, blue
103
+ end
104
+
105
+ end
106
+
107
+ end