Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100755 278 lines (231 sloc) 7.86 kb
e01bb08 Chris Kempson Initial commit
authored
1 #!/usr/bin/env ruby
2 # Base16 Builder (https://github.com/chriskempson/base16-builder)
3
d9925da Chris Kempson Changed rgb_float hash key to srgb
authored
4 require "securerandom"
e01bb08 Chris Kempson Initial commit
authored
5 require "yaml"
cc85348 Dirk Breuer Allow schemes to be read from an URL
railsbros-dirk authored
6 require "open-uri"
e01bb08 Chris Kempson Initial commit
authored
7 require "erb"
1016886 Petr Hosek Support for Terminal.app
petrhosek authored
8 require "base64"
e01bb08 Chris Kempson Initial commit
authored
9
10 class Theme
9efc2e8 José Otávio Rizzatti Ferreira Allow running base16 from anywhere in the PATH
rizzatti authored
11 BASE_PATH = File.dirname(__FILE__)
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
12
4d1b843 Chris Kempson Output now sits in directories
authored
13 attr_accessor :template
e01bb08 Chris Kempson Initial commit
authored
14
15 def initialize
9efc2e8 José Otávio Rizzatti Ferreira Allow running base16 from anywhere in the PATH
rizzatti authored
16 @scheme_dir = File.join(BASE_PATH, "schemes")
17 @template_dir = File.join(BASE_PATH, "templates")
18 @output_dir = File.join(BASE_PATH, "output")
e01bb08 Chris Kempson Initial commit
authored
19 end
20
123b9ba Alejandro Baez Modified how CLI runs for more specific options.
abaez authored
21 def build(scheme_file, template_dir)
22 if template_dir then
23 build_single_template(template_dir)
24 end
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
25 if scheme_file then
e01bb08 Chris Kempson Initial commit
authored
26 build_single_scheme(scheme_file)
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
27 else
e01bb08 Chris Kempson Initial commit
authored
28 build_all_schemes
29 end
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
30
e01bb08 Chris Kempson Initial commit
authored
31 end
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
32
e01bb08 Chris Kempson Initial commit
authored
33 def build_all_schemes
34 scheme_files = read_scheme_dir
35
36 scheme_files.each do |scheme_file|
37 build_single_scheme(scheme_file)
38 end
39 end
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
40
e01bb08 Chris Kempson Initial commit
authored
41 def build_single_scheme(scheme_file)
42 puts scheme_file
43 scheme_data = read_scheme_file(scheme_file)
142ade7 Chris Kempson Broken apart main parsing method
authored
44 populate_template_variables(scheme_data)
45 create_output_files
e01bb08 Chris Kempson Initial commit
authored
46 end
47
48 def read_scheme_file(scheme_file)
cc85348 Dirk Breuer Allow schemes to be read from an URL
railsbros-dirk authored
49 YAML.load open(scheme_file)
9efc2e8 José Otávio Rizzatti Ferreira Allow running base16 from anywhere in the PATH
rizzatti authored
50 rescue StandardError
51 abort(read_error_message(scheme_file))
e01bb08 Chris Kempson Initial commit
authored
52 end
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
53
e01bb08 Chris Kempson Initial commit
authored
54 def read_scheme_dir
9efc2e8 José Otávio Rizzatti Ferreira Allow running base16 from anywhere in the PATH
rizzatti authored
55 Dir.glob(File.join(@scheme_dir, '**', '*.yml'))
56 rescue StandardError
57 abort(read_error_message(scheme_dir))
e01bb08 Chris Kempson Initial commit
authored
58 end
59
123b9ba Alejandro Baez Modified how CLI runs for more specific options.
abaez authored
60 def build_single_template(template_dir)
61 @template_dir = File.join(BASE_PATH, "templates", template_dir)
62 rescue StandardError
63 abort(read_error_message(@template_dir))
64 end
65
e01bb08 Chris Kempson Initial commit
authored
66 def read_template_dir
9efc2e8 José Otávio Rizzatti Ferreira Allow running base16 from anywhere in the PATH
rizzatti authored
67 Dir.glob(File.join(@template_dir, '**', '*.erb'))
68 rescue StandardError
69 abort(read_error_message(@template_dir))
e01bb08 Chris Kempson Initial commit
authored
70 end
71
72 def read_template_file(template_file)
9efc2e8 José Otávio Rizzatti Ferreira Allow running base16 from anywhere in the PATH
rizzatti authored
73 File.read(template_file)
74 rescue StandardError
75 abort(read_error_message(template_file))
e01bb08 Chris Kempson Initial commit
authored
76 end
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
77
142ade7 Chris Kempson Broken apart main parsing method
authored
78 def populate_template_variables(scheme_data)
737d26a Chris Kempson Changes color referencing
authored
79 # Define ERB vars
142ade7 Chris Kempson Broken apart main parsing method
authored
80 @scheme = scheme_data["scheme"]
81 @author = scheme_data["author"]
82 @slug = slug(scheme_data["scheme"])
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
83
142ade7 Chris Kempson Broken apart main parsing method
authored
84 # Define ERB color vars
85 @base = {}
737d26a Chris Kempson Changes color referencing
authored
86 [
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
87 "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B",
737d26a Chris Kempson Changes color referencing
authored
88 "0C", "0D", "0E", "0F"
89 ].each do |key|
90 hex = scheme_data["base" + key];
142ade7 Chris Kempson Broken apart main parsing method
authored
91 @base[key] = {
737d26a Chris Kempson Changes color referencing
authored
92 "hex" => hex,
17f74b6 Jessica Stokes Add "hexbgr" scheme method. Add Windows Command Prompt template.
grapegravity authored
93 "hexbgr" => to_hex_bgr(hex),
7a787cf Chris Kempson Double hex fix
authored
94 "dhex" => to_dhex(hex),
737d26a Chris Kempson Changes color referencing
authored
95 "rgb" => to_rgb(hex),
d9925da Chris Kempson Changed rgb_float hash key to srgb
authored
96 "srgb" => to_srgb(hex)
737d26a Chris Kempson Changes color referencing
authored
97 }
98 end
142ade7 Chris Kempson Broken apart main parsing method
authored
99 end
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
100
142ade7 Chris Kempson Broken apart main parsing method
authored
101 def create_output_files
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
102 # Read each
737d26a Chris Kempson Changes color referencing
authored
103 read_template_dir.each do |template_file|
142ade7 Chris Kempson Broken apart main parsing method
authored
104 puts " - " + template_file # Show which file we are parsing
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
105
142ade7 Chris Kempson Broken apart main parsing method
authored
106 # Grab the results of the parsed ERB file
107 contents = parse_template_file(template_file)
4d1b843 Chris Kempson Output now sits in directories
authored
108
142ade7 Chris Kempson Broken apart main parsing method
authored
109 write_output_file(template_file, contents)
e01bb08 Chris Kempson Initial commit
authored
110 end
142ade7 Chris Kempson Broken apart main parsing method
authored
111 end
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
112
142ade7 Chris Kempson Broken apart main parsing method
authored
113 def parse_template_file(template_file)
114 # Define ERB vars
115 @uuid = SecureRandom.uuid
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
116
142ade7 Chris Kempson Broken apart main parsing method
authored
117 template_contents = read_template_file(template_file)
118 parsed = ERB.new(template_contents)
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
119
142ade7 Chris Kempson Broken apart main parsing method
authored
120 return parsed.result(binding)
121 end
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
122
142ade7 Chris Kempson Broken apart main parsing method
authored
123 def write_output_file(template_file, contents)
9efc2e8 José Otávio Rizzatti Ferreira Allow running base16 from anywhere in the PATH
rizzatti authored
124 dir_name = File.basename(File.dirname(template_file))
125 file_name = File.basename(template_file, ".erb")
142ade7 Chris Kempson Broken apart main parsing method
authored
126 scheme_name = slug(@scheme)
127
9efc2e8 José Otávio Rizzatti Ferreira Allow running base16 from anywhere in the PATH
rizzatti authored
128 output_dir = File.join(@output_dir, dir_name)
129 make_dir(output_dir)
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
130
142ade7 Chris Kempson Broken apart main parsing method
authored
131 # If the filename starts with a dash, we use the dash to separate
132 delimiter = file_name.starts_with?("-") ? "" : "."
e01bb08 Chris Kempson Initial commit
authored
133
9efc2e8 José Otávio Rizzatti Ferreira Allow running base16 from anywhere in the PATH
rizzatti authored
134 output_filename = File.join(output_dir,
135 "base16-#{scheme_name}#{delimiter}#{file_name}")
136 output_file = File.open(output_filename, "w")
142ade7 Chris Kempson Broken apart main parsing method
authored
137 output_file.write(contents)
9efc2e8 José Otávio Rizzatti Ferreira Allow running base16 from anywhere in the PATH
rizzatti authored
138 output_file.close
e01bb08 Chris Kempson Initial commit
authored
139 end
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
140
4d1b843 Chris Kempson Output now sits in directories
authored
141 def make_dir(name)
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
142 if FileTest::directory?(name)
4d1b843 Chris Kempson Output now sits in directories
authored
143 return
144 end
145 Dir::mkdir(name)
146 end
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
147
4d1b843 Chris Kempson Output now sits in directories
authored
148 def slug(string)
149 string.downcase.strip.gsub(' ', '.').gsub(/[^\w-]/, '')
150 end
17f74b6 Jessica Stokes Add "hexbgr" scheme method. Add Windows Command Prompt template.
grapegravity authored
151
152 def to_hex_bgr(hex)
153 hex.scan(/../).reverse.join
154 end
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
155
7a787cf Chris Kempson Double hex fix
authored
156 def to_dhex(hex)
b2262a3 djmason Fix "dhex" for xfce4-terminal
djmason authored
157 hex.scan(/../).map {|color| color + color}.join
7a787cf Chris Kempson Double hex fix
authored
158 end
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
159
737d26a Chris Kempson Changes color referencing
authored
160 def to_rgb(hex)
161 hex.scan(/../).map {|color| color.to_i(16)}
162 end
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
163
d9925da Chris Kempson Changed rgb_float hash key to srgb
authored
164 def to_srgb(hex)
737d26a Chris Kempson Changes color referencing
authored
165 hex.scan(/../).map {|color| color.to_i(16).to_f / 255 }
166 end
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
167
142ade7 Chris Kempson Broken apart main parsing method
authored
168 def split_by_slash(hex)
169 hex.scan(/.{1,2}/).join('/')
170 end
e179fa6 Seth Wright fix whitespace in base16 builder script
asethwright authored
171
e01bb08 Chris Kempson Initial commit
authored
172 def read_error_message(file)
173 "Error reading #{file}"
174 end
175
cebbebf No GUI Add mix, shade & tint functions
evaryont authored
176 # Mix two given colors. The code is borrowed from
177 # [SASS](https://github.com/nex3/sass/blob/6f09f90cbb4f130f7bd20f18c63c6f62c6857b98/lib/sass/script/functions.rb#L1001).
178 #
179 # The original algorithm has been modified somewhat, removing all
180 # consideration of an alpha channel (as Base16 does not support it.)
181 #
182 # @param color_1 [Array] A RGB triplet (e.g. [24,24,178]) of the original color
183 # @param color_2 [Array] A RGB triplet (e.g. [0,0,0]) of the mixer color
184 # @param weight [Fixnum] Relative weight of each color, 0-100. Closer to 0
185 # gives more weight to color_1, while closer to 100 gives more weight to
186 # color_2. Defaults to 50, which is an even balance.
187 def mix(color_1, color_2, weight = 50)
188 # This algorithm factors in both the user-provided weight (w) and the
189 # difference between the alpha values of the two colors (a) to decide how
190 # to perform the weighted average of the two RGB values.
191 #
192 # It works by first normalizing both parameters to be within [-1, 1],
193 # where 1 indicates "only use color_1", -1 indicates "only use color_2", and
194 # all values in between indicated a proportionately weighted average.
195 #
196 # Once we have the normalized variables w and a, we apply the formula
197 # (w + a)/(1 + w*a) to get the combined weight (in [-1, 1]) of color_1.
198 # This formula has two especially nice properties:
199 #
200 # * When either w or a are -1 or 1, the combined weight is also that number
201 # (cases where w * a == -1 are undefined, and handled as a special case).
202 #
203 # * When a is 0, the combined weight is w, and vice versa.
204 #
205 # Finally, the weight of color_1 is renormalized to be within [0, 1]
206 # and the weight of color_2 is given by 1 minus the weight of color_1.
207 p = (weight/100.0).to_f
208 w = p*2 - 1
209 a = 0
210
211 w1 = (((w == -1) ? w : (w)/(1 + w)) + 1)/2.0
212 w2 = 1 - w1
213
68b7156 No GUI Ensure the results of mix() are integers
evaryont authored
214 rgb = color_1.zip(color_2).map {|v1, v2| (v1*w1 + v2*w2).to_i}
cebbebf No GUI Add mix, shade & tint functions
evaryont authored
215 rgb
216 end
217
218 # Add a bit of 'white' to a color. White is defined by color 7, the end of the
219 # gray scale in a color scheme. (This is usually #FFFFFF, or close.)
220 #
221 # @param color [Array] The RGB triplet of the color to be modified.
222 # @param weight [Fixnum] The color weight. See #mix for more information.
223 def tint(color, weight = 50)
5a24790 No GUI Reverse the order of the parameters passed to mix
evaryont authored
224 mix(@base['07']['rgb'], color, weight)
cebbebf No GUI Add mix, shade & tint functions
evaryont authored
225 end
226
227 # Add a bit of 'black' to a color. White is defined by color 0, the end of the
228 # gray scale in a color scheme. (This is usually #000000, or close.)
229 #
230 # @param color [Array] The RGB triplet of the color to be modified.
231 # @param weight [Fixnum] The color weight. See #mix for more information.
232 def shade(color, weight = 50)
5a24790 No GUI Reverse the order of the parameters passed to mix
evaryont authored
233 mix(@base['00']['rgb'], color, weight)
cebbebf No GUI Add mix, shade & tint functions
evaryont authored
234 end
e01bb08 Chris Kempson Initial commit
authored
235 end
236
142ade7 Chris Kempson Broken apart main parsing method
authored
237 # Provide starts_with? method borrowed from Rails
238 class String
239 def starts_with?(prefix)
240 prefix = prefix.to_s
241 self[0, prefix.length] == prefix
242 end
243 end
244
e01bb08 Chris Kempson Initial commit
authored
245 help_message = <<-EOF
246 Base16 Builder v0.1
247 https://github.com/chriskempson/base16-builder
248
123b9ba Alejandro Baez Modified how CLI runs for more specific options.
abaez authored
249 usage: base16 build all schemes and templates
250 or: base16 [-s <scheme>] [-t <template>]
251
252 -h, --help opens this help prompt
253 -s, --scheme build specified scheme
254 -t, --template build specified template
e01bb08 Chris Kempson Initial commit
authored
255 EOF
256
123b9ba Alejandro Baez Modified how CLI runs for more specific options.
abaez authored
257 if ARGV[0] != nil then
258 tmp_template = false
259 tmp_scheme = false
260
261 ARGV.length.times do |i|
262 case ARGV[i]
263 when "-h", "--help"
264 puts help_message
265 when "-s", "--scheme"
266 tmp_scheme = ARGV[i+1]
7106a82 Alejandro Baez change texteditor to template
abaez authored
267 when "-t", "--template"
123b9ba Alejandro Baez Modified how CLI runs for more specific options.
abaez authored
268 tmp_template = ARGV[i+1]
269 end
270 end
271
272 if tmp_template or tmp_scheme then
273 Theme.new.build(tmp_scheme, tmp_template)
274 end
275 else
276 Theme.new.build(false,false)
00e31bd Neil B emacs24 requires '-theme' to be appended to theme files. included code t...
neil477 authored
277 end
Something went wrong with that request. Please try again.