vic 0.0.6 → 1.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/lib/vic.rb CHANGED
@@ -1,11 +1,12 @@
1
1
  module Vic
2
- VERSION = '0.0.6'
2
+ VERSION = '1.0.0'.freeze
3
3
  end
4
4
 
5
+ require 'ostruct'
6
+ require 'vic/color_scheme'
7
+ require 'vic/color_scheme_writer'
5
8
  require 'vic/color'
6
- require 'vic/color_error'
7
- require 'vic/colorscheme'
8
- require 'vic/colorscheme/highlight'
9
- require 'vic/colorscheme/highlight_set'
10
- require 'vic/colorscheme/highlight/argument'
11
- require 'vic/colorscheme/highlight/argument_set'
9
+ require 'vic/convert'
10
+ require 'vic/xterm_color'
11
+ require 'vic/highlight'
12
+ require 'vic/link'
data/lib/vic/color.rb CHANGED
@@ -1,87 +1,104 @@
1
1
  module Vic
2
- module Color extend self
3
- # System colors (0-15)
4
- SYSTEM_COLORS = [
5
- [0x00, 0x00, 0x00],
6
- [0x80, 0x00, 0x00],
7
- [0x00, 0x80, 0x00],
8
- [0x80, 0x80, 0x00],
9
- [0x00, 0x00, 0x80],
10
- [0x80, 0x00, 0x80],
11
- [0x00, 0x80, 0x80],
12
- [0xc0, 0xc0, 0xc0],
13
- [0x80, 0x80, 0x80],
14
- [0xff, 0x00, 0x00],
15
- [0x00, 0xff, 0x00],
16
- [0xff, 0xff, 0x00],
17
- [0x00, 0x00, 0xff],
18
- [0xff, 0x00, 0xff],
19
- [0x00, 0xff, 0xff],
20
- [0xff, 0xff, 0xff]
21
- ]
2
+ class Color
3
+ attr_accessor :value
22
4
 
23
- # RGB colors (16 - 231)
24
- RGB_COLORS = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff].repeated_permutation(3).to_a
25
-
26
- # Grayscale colors (232 - 255)
27
- GRAYSCALE_COLORS = (0x08..0xee).step(0x0a).to_a.map {|v| Array.new(3).fill(v) }
5
+ def initialize(value)
6
+ @value = value
7
+ end
28
8
 
29
- # All 256 colors of the rainbow. Organized from 0 to 255.
30
- COLORS_256 = SYSTEM_COLORS + RGB_COLORS + GRAYSCALE_COLORS
9
+ class ColorError < RuntimeError; end
31
10
 
32
- # Convert hexidecimal color to an Array of RGB values.
11
+ # Convert the color value to a hexadecimal color
12
+ #
13
+ # @return [Symbol,String]
14
+ # the color as either "NONE" or hexadecimal
33
15
  #
34
- # @param [String] hex the hexidecimal color
35
- # @return [Array] the RGB color conversion
36
- def hex_to_rgb(hex)
37
- hex.match(/#?(..)(..)(..)/)[1..4].to_a.map {|v| v.to_i(16) }
16
+ # @api public
17
+ def to_gui
18
+ return to_standard_hex if hexadecimal?
19
+ return Convert.xterm_to_hex(@value) if cterm?
20
+ return :NONE if none?
21
+
22
+ raise ColorError.new "can't convert \"#{ @value }\" to gui"
38
23
  end
39
24
 
40
- # Takes a hexidecimal color and returns is closest 256 color match.
25
+ # Convert the color value to a cterm compatible color
41
26
  #
42
- # Credit goes to Micheal Elliot for the algorithm which was originally written
43
- # in Python.
27
+ # @return [Fixnum]
28
+ # the color as either "NONE" or cterm color
44
29
  #
45
- # @see https://gist.github.com/719710
46
- # @param [String] hex the hexidecimal color
47
- # @return [FixNum] the closest 256 color match
48
- def hex_to_256(hex)
49
- parts = hex_to_rgb(hex)
30
+ # @api public
31
+ def to_cterm
32
+ return @value if cterm?
33
+ return Convert.hex_to_xterm(to_standard_hex) if hexadecimal?
34
+ return :NONE if none?
50
35
 
51
- # If the hex is a member of the 256 colors club, we'll just return it's 256
52
- # color value. No sense in doing extra work, right?
53
- return COLORS_256.index(parts) if COLORS_256.include?(parts)
36
+ raise ColorError.new "can't convert \"#{ @value }\" to cterm"
37
+ end
54
38
 
55
- increments = 0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff
39
+ # Returns true if the color value is cterm compatible color and false if
40
+ # it's not
41
+ #
42
+ # @return [TrueClass,FalseClass]
43
+ # whether or not the color value is cterm compatible
44
+ #
45
+ # @api public
46
+ def cterm?
47
+ @value.kind_of?(Fixnum) and @value.between?(0, 255)
48
+ end
56
49
 
57
- # For each part we need to check if it's between any two of the increments.
58
- # If it is we'll determine the closest match, change it's value, break,
59
- # and move on to the next part.
60
- parts.map! do |part|
61
- closest = nil
62
- for i in (0..(increments.length - 1))
63
- lower = increments[i]
64
- upper = increments[i + 1]
65
- next unless (lower <= part) && (part <= upper)
66
- distance_from_lower = (lower - part).abs
67
- distance_from_upper = (upper - part).abs
68
- closest = distance_from_lower < distance_from_upper ? lower : upper
69
- break
70
- end
71
- closest
72
- end
50
+ # Returns true if the color value is a gui compatible color and false if
51
+ # it's not
52
+ #
53
+ # @return [TrueClass,FalseClass]
54
+ # whether or not the color value is gui compatible
55
+ #
56
+ # @api public
57
+ def gui?
58
+ hexadecimal?
59
+ end
73
60
 
74
- # Return the index of the color
75
- COLORS_256.index(parts)
61
+ # Returns true if the color value is a hexadecimal color and false if it's not
62
+ #
63
+ # @return [TrueClass,FalseClass]
64
+ # whether or not the color value is hexadecimal
65
+ #
66
+ # @api public
67
+ def hexadecimal?
68
+ # Both standard and shorthand (CSS) style hexadecimal color value.
69
+ not cterm? and /\A#?(?:[0-9a-f]{3}|[0-9a-f]{6})\z/io.match(@value.to_s)
76
70
  end
77
71
 
78
- # Checks if the subjec is a valid hexidecimal color.
72
+ # Returns true if the color value is either empty or set to "NONE"
73
+ #
74
+ # @return [TrueClass,FalseClass]
75
+ # whether or not the color value is empty or "NONE"
79
76
  #
80
- # @param [String] subject the string in question
81
- # @return [Match
82
- def is_hexadecimal?(subject)
83
- return false unless subject.respond_to? :match
84
- subject.match(/#?[\da-f]{6}/i) ? true : false
77
+ # @api public
78
+ def none?
79
+ @value.to_s.empty? or /\Anone\z/io.match(@value.to_s)
80
+ end
81
+
82
+ private
83
+
84
+ # Convert the color value to a standard hexadecimal value
85
+ #
86
+ # @example
87
+ # Color.new('333').send(:to_standard_hex) # => '#333333'
88
+ #
89
+ # @return [String]
90
+ # the color in standard hexadecimal format
91
+ #
92
+ # @api private
93
+ def to_standard_hex
94
+ color = @value.dup
95
+ color.insert(0, '#') unless color.start_with? '#'
96
+
97
+ # Convert shorthand hex to standard hex.
98
+ if color.size == 4
99
+ color.slice!(1, 3).chars { |char| color << char * 2 }
100
+ end
101
+ color
85
102
  end
86
- end
87
- end
103
+ end # class Color
104
+ end # module Vic
@@ -0,0 +1,303 @@
1
+ module Vic
2
+ class ColorScheme
3
+ attr_accessor :title
4
+
5
+ def initialize(title, &block)
6
+ @title = title
7
+ @highlights = []
8
+ @links = []
9
+ @info = OpenStruct.new
10
+
11
+ if block_given?
12
+ block.arity.zero? ? instance_eval(&block) : yield(self)
13
+ end
14
+ end
15
+
16
+ # Return the colorscheme information
17
+ #
18
+ # @return [Hash]
19
+ # the colorscheme information
20
+ #
21
+ # @api public
22
+ def info
23
+ @info.marshal_dump
24
+ end
25
+
26
+ # Set the colorscheme information
27
+ #
28
+ # @param [Hash] data
29
+ # the data to use
30
+ #
31
+ # @return [Hash]
32
+ # the colorscheme information
33
+ #
34
+ # @api public
35
+ def info=(data = {})
36
+ @info.marshal_load(data)
37
+ end
38
+
39
+ # Updates the colorscheme information
40
+ #
41
+ # @param [Hash] data
42
+ # the data to use
43
+ #
44
+ # @return [Hash]
45
+ # the colorscheme information
46
+ #
47
+ # @api public
48
+ def add_info(data = {})
49
+ self.info = @info.marshal_dump.merge(data)
50
+ end
51
+
52
+ # Return the background setting
53
+ #
54
+ # @return [NilClass,String,Symbol]
55
+ # the background setting
56
+ def background
57
+ @background
58
+ end
59
+
60
+ # Sets the background
61
+ #
62
+ # @param [String,Symbol] setting
63
+ # a background setting of either "light" or "dark"
64
+ #
65
+ # @return [String,Symbol]
66
+ # the background setting
67
+ #
68
+ # @api public
69
+ def background=(setting)
70
+ unless /\A(light|dark)\z/o.match(setting)
71
+ raise ArgumentError.new("expected 'light' or 'dark'")
72
+ end
73
+ @background = setting
74
+ end
75
+
76
+ # Sets the background automatically
77
+ #
78
+ # By default this will return "dark". If a highlight with the `group`
79
+ # "Normal" and a `guibg` setting has been added to the colorscheme, it will
80
+ # determine the setting to use. If the `guibg` is strictly less than
81
+ # "#808080" the background will be set to "dark" otherwise it will be set
82
+ # to "light".
83
+ #
84
+ # @return [String]
85
+ # the background setting
86
+ #
87
+ # @api public
88
+ def background!
89
+ normal = find_highlight(:Normal)
90
+ return @background = 'dark' unless normal && normal.guibg
91
+ @background = normal.guibg[1..-1].to_i(16) < 8421504 ? 'dark' : 'light'
92
+ end
93
+
94
+ # Return the colorscheme's highlights
95
+ #
96
+ # @return [Array]
97
+ # the colorscheme's highlights
98
+ #
99
+ # @api public
100
+ def highlights
101
+ @highlights.dup
102
+ end
103
+
104
+ # Add or update a highlight
105
+ #
106
+ # @example
107
+ # scheme.highlight(:Normal, fg: 'eee', bg: '333')
108
+ #
109
+ # @param [String,Symbol] group
110
+ # the group to highlight
111
+ #
112
+ # @param [Hash] attributes
113
+ # the attributes to set or update
114
+ #
115
+ # @return [Vic::Highlight]
116
+ # the highlight
117
+ #
118
+ # @api public
119
+ def highlight(group, attributes={})
120
+ if hilight = find_highlight(group)
121
+ hilight.update_attributes!(attributes)
122
+ else
123
+ hilight = Highlight.new(:"#{ language }#{ group }", attributes)
124
+ @highlights << hilight
125
+ end
126
+
127
+ hilight
128
+ end
129
+ alias_method :hi, :highlight
130
+
131
+ # Add or update a forced highlight
132
+ #
133
+ # @example
134
+ # scheme.highlight!(:Normal, fg: 'eee', bg: '333').force? # => true
135
+ #
136
+ # @param [Hash] attributes
137
+ # the attributes to set or update
138
+ #
139
+ # @return [Vic::Highlight]
140
+ # the highlight
141
+ #
142
+ # @api public
143
+ def highlight!(group, attributes={})
144
+ highlight(group, attributes.dup.tap { |hash| hash[:force] = true })
145
+ end
146
+ alias_method :hi!, :highlight!
147
+
148
+ # Return the colorscheme's links
149
+ #
150
+ # @return [Array]
151
+ # the colorscheme's links
152
+ #
153
+ # @api public
154
+ def links
155
+ @links.dup
156
+ end
157
+
158
+ # Add highlight links to the colorscheme
159
+ #
160
+ # @example
161
+ # scheme.link(:rubyInstanceVariable, :rubyClassVariable)
162
+ #
163
+ # @param [String,Symbol] from_groups
164
+ # a list of groups to link from
165
+ #
166
+ # @param [String,Symbol] to_groups
167
+ # the group to link to
168
+ #
169
+ # @return [Array]
170
+ # the added links
171
+ #
172
+ # @api public
173
+ def link(*from_groups, to_group)
174
+ from_groups.flatten.map do |from_group|
175
+ # Don't add anything we don't already have.
176
+ next if find_link(from_group, to_group)
177
+ link = Link.new(from_group, to_group)
178
+ link.tap { |l| @links << l }
179
+ end.compact
180
+ end
181
+
182
+ # Add forced highlight links to the colorscheme
183
+ #
184
+ # @example
185
+ # scheme.link!(:rubyInstanceVariable, :rubyClassVariable)
186
+ # link = scheme.links.find do |l|
187
+ # l.from_group == :rubyInstanceVariable and l.to_group = :rubyClassVariable
188
+ # end
189
+ # link.force? # => true
190
+ #
191
+ # @param [String,Symbol] from_groups
192
+ # a list of groups to link from
193
+ #
194
+ # @param [String,Symbol] to_groups
195
+ # the group to link to
196
+ #
197
+ # @return [Array]
198
+ # the added/updated links
199
+ #
200
+ # @api public
201
+ def link!(*from_groups, to_group)
202
+ # Use the default method first.
203
+ self.link(from_groups, to_group)
204
+
205
+ # Then update the links.
206
+ from_groups.flatten.map do |from_group|
207
+ link = find_link(from_group, to_group)
208
+ link.tap(&:force!)
209
+ end
210
+ end
211
+
212
+ # Set a language to prepend new highlight group names with
213
+ #
214
+ # @example
215
+ # scheme.language = :ruby
216
+ # scheme.hi(:InstanceVariable).group == :rubyInstanceVariable # => true
217
+ #
218
+ # @param [String,Symbol] name
219
+ # the language name
220
+ #
221
+ # @return [String,Symbol]
222
+ # the language name
223
+ #
224
+ # @api public
225
+ def language=(name)
226
+ @language = name
227
+ end
228
+
229
+ # Return the language
230
+ #
231
+ # If a name and a block is passed the language will be temporarily set to
232
+ # name inside the block.
233
+ #
234
+ # @example
235
+ # scheme.language :ruby do |s|
236
+ # s.hi(:InstanceVariable)
237
+ # s.hi(:ClassVariable)
238
+ # end
239
+ # scheme.highlights.any? { |h| h.group == :rubyClassVarible } # => true
240
+ #
241
+ # @param [String,Symbol] name
242
+ # the language to temporarily set if a block is given
243
+ #
244
+ # @yieldparam [Vic::Colorscheme]
245
+ # the colorscheme
246
+ #
247
+ # @return [String,Symbol]
248
+ # the language setting
249
+ #
250
+ # @api public
251
+ def language(name = nil, &block)
252
+ return @language unless name and block_given?
253
+
254
+ previous_language = self.language
255
+ @language = name
256
+ block.arity == 0 ? instance_eval(&block) : yield(self)
257
+ @language = previous_language
258
+ end
259
+
260
+ # Render the colorscheme
261
+ #
262
+ # @return [String]
263
+ # the colorscheme as a string
264
+ #
265
+ # @api public
266
+ def render
267
+ ColorSchemeWriter.write(self)
268
+ end
269
+
270
+ private
271
+
272
+ # Find a highlight
273
+ #
274
+ # @param [String,Symbol] group
275
+ # the highlight group to find
276
+ #
277
+ # @return [NilClass,Vic::Highlight]
278
+ # the found highlight
279
+ #
280
+ # @api private
281
+ def find_highlight(group)
282
+ highlights.find { |h| /\A#{ group }\z/.match(h.group) }
283
+ end
284
+
285
+ # Find a link
286
+ #
287
+ # @param [String,Symbol] from_group
288
+ # the link from_group
289
+ #
290
+ # @param [String,Symbol] to_group
291
+ # the link to_group
292
+ #
293
+ # @return [NilClass,Vic::Highlight]
294
+ # the found highlight
295
+ #
296
+ # @api private
297
+ def find_link(from_group, to_group)
298
+ @links.find do |l|
299
+ /\A#{ from_group }\z/.match(l.from_group) and /\A#{ to_group }\z/.match(l.to_group)
300
+ end
301
+ end
302
+ end # class ColorScheme
303
+ end # module Vic
@@ -0,0 +1,80 @@
1
+ module Vic
2
+ class ColorSchemeWriter
3
+ def initialize(colorscheme)
4
+ @colorscheme = colorscheme
5
+ end
6
+
7
+ def self.write(colorscheme)
8
+ new(colorscheme).write
9
+ end
10
+
11
+ def write
12
+ lines = [title, info, background, reset, name, highlights, links]
13
+ "%s\n%s\n\n%s\n\n%s\n%s\n\n%s\n%s" % lines
14
+ end
15
+
16
+ private
17
+
18
+ def title
19
+ %(" Title: #{ @colorscheme.title })
20
+ end
21
+
22
+ def info
23
+ return if @colorscheme.info.empty?
24
+ @colorscheme.info.map do |key, val|
25
+ %(" #{ key }: #{ val })
26
+ end.join("\n")
27
+ end
28
+
29
+ def background
30
+ "set background=#{ @colorscheme.background || @colorscheme.background! }"
31
+ end
32
+
33
+ def reset
34
+ <<-VIML.gsub(/^ {6}/, '')
35
+ hi clear
36
+
37
+ if exists("syntax_on")
38
+ syntax reset
39
+ endif
40
+ VIML
41
+ end
42
+
43
+ def name
44
+ %(let g:colors_name="#{ @colorscheme.title }")
45
+ end
46
+
47
+ def highlights
48
+ @colorscheme.highlights.map do |highlight|
49
+ attributes = Highlight.attributes.map do |attribute|
50
+ next unless value = highlight.send(attribute)
51
+
52
+ case value
53
+ when String, Symbol, Integer
54
+ " #{ attribute }=#{ value }"
55
+ when Array
56
+ " #{ attribute }=#{ value.map(&:to_s).map(&:strip).join(',') }"
57
+ end
58
+ end
59
+
60
+ next unless attributes.any?
61
+
62
+ if highlight.force?
63
+ "hi! #{ highlight.group }" << attributes.join
64
+ else
65
+ "hi #{ highlight.group }" << attributes.join
66
+ end
67
+ end.compact.join("\n")
68
+ end
69
+
70
+ def links
71
+ @colorscheme.links.map do |link|
72
+ if link.force?
73
+ "hi! default link #{ link.from_group } #{ link.to_group }"
74
+ else
75
+ "hi default link #{ link.from_group } #{ link.to_group }"
76
+ end
77
+ end.compact.join("\n")
78
+ end
79
+ end # class ColorSchemeWriter
80
+ end # module Vic
@@ -0,0 +1,33 @@
1
+ module Vic
2
+ module Convert
3
+ def self.hex_to_rgb(hex)
4
+ hex.match(/#?(..)(..)(..)/).captures.map { |v| v.to_i(16) }
5
+ end
6
+
7
+ def self.hex_to_xterm(hex)
8
+ rgb = hex_to_rgb(hex)
9
+
10
+ return XtermColor.table.index(rgb) if XtermColor.table.include?(rgb)
11
+
12
+ increments = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]
13
+
14
+ rgb.map! do |part|
15
+ for i in (0...5)
16
+ lower, upper = increments[i], increments[i + 1]
17
+
18
+ next unless part.between?(lower, upper)
19
+
20
+ distance_from_lower = (lower - part).abs
21
+ distance_from_upper = (upper - part).abs
22
+ closest = distance_from_lower < distance_from_upper ? lower : upper
23
+ end
24
+ closest
25
+ end
26
+ XtermColor.table.index(rgb)
27
+ end
28
+
29
+ def self.xterm_to_hex(code)
30
+ '#' + XtermColor.table[code].map { |v| (v.to_s(16) * 2)[0...2] }.join
31
+ end
32
+ end # module Convert
33
+ end # module Vic
@@ -0,0 +1,230 @@
1
+ module Vic
2
+ class Highlight
3
+
4
+ attr_accessor :group
5
+
6
+ def initialize(group, attributes={})
7
+ @group = group
8
+ update_attributes!(attributes)
9
+ end
10
+
11
+ # Updates the highlights attributes
12
+ #
13
+ # @example
14
+ # h = Vic::Highlight.new('Normal', { guibg: '333' })
15
+ # h.guibg # => "#333333"
16
+ # h.update_attributes!({ guibg: '000' })
17
+ # h.guibg # => "#000000"
18
+ #
19
+ # @param [Hash] attributes
20
+ # the attributes to update
21
+ #
22
+ # @return [Vic::Highlight]
23
+ # the updated highlight
24
+ #
25
+ # @api public
26
+ def update_attributes!(attributes={})
27
+ attributes.each_pair do |key, val|
28
+ self.respond_to?(:"#{ key }=") && send(:"#{ key }=", val)
29
+ end
30
+
31
+ # Returning self seems like the right thing to do when a method changes
32
+ # more than one property of an object.
33
+ self
34
+ end
35
+
36
+ # Return the list of highlight attributes
37
+ #
38
+ # @return [Array]
39
+ # the list of highlight attributes
40
+ #
41
+ # @api semipublic
42
+ def self.attributes
43
+ [:term, :start, :stop, :cterm, :ctermbg, :ctermfg, :gui, :guibg, :guifg, :guisp, :font]
44
+ end
45
+
46
+ # Set the force
47
+ #
48
+ # @param [TrueClass,FalseClass] bool
49
+ # a value of true or false
50
+ #
51
+ # @return [TrueClass,FalseClass]
52
+ # the force setting
53
+ #
54
+ # @api public
55
+ def force=(bool)
56
+ @force = !!bool
57
+ end
58
+
59
+ # Return the force setting
60
+ #
61
+ # @return [TrueClass,FalseClass]
62
+ # the force setting
63
+ #
64
+ # @api public
65
+ def force?
66
+ @force
67
+ end
68
+
69
+ # Set the force setting to true
70
+ #
71
+ # @return [TrueClass]
72
+ # the force setting
73
+ #
74
+ # @api public
75
+ def force!
76
+ @force = true
77
+ end
78
+
79
+ # Set both ctermbg and guibg simultaneously
80
+ #
81
+ # @param [String] color
82
+ # the color to use
83
+ #
84
+ # @return [Vic::Highlight]
85
+ # the updated highlight
86
+ #
87
+ # @api public
88
+ def bg=(color)
89
+ color = Color.new(color)
90
+ @ctermbg, @guibg = color.to_cterm, color.to_gui
91
+ self
92
+ end
93
+
94
+ # Set both ctermfg and guifg simultaneously
95
+ #
96
+ # @param [String] color
97
+ # the color to use
98
+ #
99
+ # @return [Vic::Highlight]
100
+ # the updated highlight
101
+ #
102
+ # @api public
103
+ def fg=(color)
104
+ color = Color.new(color)
105
+ @ctermfg, @guifg = color.to_cterm, color.to_gui
106
+ self
107
+ end
108
+
109
+ # Set both cterm and gui simultaneously
110
+ #
111
+ # @param [Array] styles
112
+ # the styles to use
113
+ #
114
+ # @return [Vic::Highlight]
115
+ # the updated highlight
116
+ #
117
+ # @api public
118
+ def style=(styles)
119
+ @cterm, @gui = [select_styles(styles)] * 2
120
+ self
121
+ end
122
+
123
+ attr_accessor :term, :start, :stop
124
+
125
+ attr_reader :cterm, :ctermfg, :ctermbg
126
+
127
+ # Set the cterm value
128
+ #
129
+ # @param [Array,String,Symbol] styles
130
+ # the styles to use
131
+ #
132
+ # @return [Array,Symbol]
133
+ # the cterm value
134
+ #
135
+ # @api public
136
+ def cterm=(*styles)
137
+ @cterm = select_styles(styles)
138
+ end
139
+
140
+ # Set the ctermbg value
141
+ #
142
+ # @param [String,Symbol] color
143
+ # the color to use
144
+ #
145
+ # @return [String,Symbol]
146
+ # the ctermbg color
147
+ #
148
+ # @api public
149
+ def ctermbg=(color)
150
+ @ctermbg = Color.new(color).to_cterm
151
+ end
152
+
153
+ # Set the ctermfg value
154
+ #
155
+ # @param [String,Symbol] color
156
+ # the color to use
157
+ #
158
+ # @return [String,Symbol]
159
+ # the ctermfg color
160
+ #
161
+ # @api public
162
+ def ctermfg=(color)
163
+ @ctermfg = Color.new(color).to_cterm
164
+ end
165
+
166
+ attr_reader :gui, :guibg, :guifg
167
+ attr_accessor :guisp, :font
168
+
169
+ # Set the gui value
170
+ #
171
+ # @param [Array,String,Symbol] styles
172
+ # the styles to use
173
+ #
174
+ # @return [Array,Symbol]
175
+ # the gui value
176
+ #
177
+ # @api public
178
+ def gui=(*styles)
179
+ @gui = select_styles(styles)
180
+ end
181
+
182
+ # Set the guibg value
183
+ #
184
+ # @param [String,Symbol] color
185
+ # the color to use
186
+ #
187
+ # @return [String,Symbol]
188
+ # the guibg color
189
+ #
190
+ # @api public
191
+ def guibg=(color)
192
+ @guibg = Color.new(color).to_gui
193
+ end
194
+
195
+ # Set the guifg value
196
+ #
197
+ # @param [String,Symbol] color
198
+ # the color to use
199
+ #
200
+ # @return [String,Symbol]
201
+ # the guifg color
202
+ #
203
+ # @api public
204
+ def guifg=(color)
205
+ @guifg = Color.new(color).to_gui
206
+ end
207
+
208
+ private
209
+
210
+ # Valid font styles *excluding* none
211
+ FONT_STYLE = /bold|(under(line|curl))|((re|in)verse)|italic|standout/o
212
+
213
+ # Selcect valid styles from a list
214
+ #
215
+ # @param [Mixed] styles
216
+ # the list of styles
217
+ #
218
+ # @return [Array,Symbol]
219
+ # the list of valid styles or "NONE"
220
+ #
221
+ # @api private
222
+ def select_styles(*styles)
223
+ styles.tap(&:compact).flatten!
224
+ if styles.empty? or styles.length == 1 && /\Anone\z/io.match(styles[0])
225
+ return :NONE
226
+ end
227
+ styles.select { |s| FONT_STYLE.match(s) }
228
+ end
229
+ end # class Highlight
230
+ end # module Vic
data/lib/vic/link.rb ADDED
@@ -0,0 +1,44 @@
1
+ module Vic
2
+ class Link
3
+ attr_accessor :from_group, :to_group
4
+
5
+ def initialize(from_group, to_group = :NONE)
6
+ @from_group = from_group
7
+ @to_group = to_group
8
+ @force = false
9
+ end
10
+
11
+ # Set the force
12
+ #
13
+ # @param [TrueClass,FalseClass] bool
14
+ # a value of true or false
15
+ #
16
+ # @return [TrueClass,FalseClass]
17
+ # the force setting
18
+ #
19
+ # @api public
20
+ def force=(bool)
21
+ @force = !!bool
22
+ end
23
+
24
+ # Return the force setting
25
+ #
26
+ # @return [TrueClass,FalseClass]
27
+ # the force setting
28
+ #
29
+ # @api public
30
+ def force?
31
+ @force
32
+ end
33
+
34
+ # Set the force setting to true
35
+ #
36
+ # @return [TrueClass]
37
+ # the force setting
38
+ #
39
+ # @api public
40
+ def force!
41
+ @force = true
42
+ end
43
+ end # class Link
44
+ end # module Vic
@@ -0,0 +1,18 @@
1
+ module Vic
2
+ module XtermColor
3
+ SYSTEM = [[0x00, 0x00, 0x00], [0x80, 0x00, 0x00], [0x00, 0x80, 0x00],
4
+ [0x80, 0x80, 0x00], [0x00, 0x00, 0x80], [0x80, 0x00, 0x80],
5
+ [0x00, 0x80, 0x80], [0xc0, 0xc0, 0xc0], [0x80, 0x80, 0x80],
6
+ [0xff, 0x00, 0x00], [0x00, 0xff, 0x00], [0xff, 0xff, 0x00],
7
+ [0x00, 0x00, 0xff], [0xff, 0x00, 0xff], [0x00, 0xff, 0xff],
8
+ [0xff, 0xff, 0xff]]
9
+
10
+ RGB = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff].repeated_permutation(3).to_a
11
+
12
+ GREYSCALE = (0x08..0xee).step(0x0a).map { |v| [v] * 3 }
13
+
14
+ def self.table
15
+ SYSTEM + RGB + GREYSCALE
16
+ end
17
+ end # module XtermColor
18
+ end # module Vic
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-22 00:00:00.000000000Z
12
+ date: 2012-04-24 00:00:00.000000000Z
13
13
  dependencies: []
14
14
  description: Create Vim colorschemes with Ruby
15
15
  email: cjholdbrooks@gmail.com
@@ -19,12 +19,12 @@ extra_rdoc_files: []
19
19
  files:
20
20
  - lib/vic.rb
21
21
  - lib/vic/color.rb
22
- - lib/vic/color_error.rb
23
- - lib/vic/colorscheme.rb
24
- - lib/vic/colorscheme/highlight.rb
25
- - lib/vic/colorscheme/highlight_set.rb
26
- - lib/vic/colorscheme/highlight/argument.rb
27
- - lib/vic/colorscheme/highlight/argument_set.rb
22
+ - lib/vic/color_scheme.rb
23
+ - lib/vic/color_scheme_writer.rb
24
+ - lib/vic/convert.rb
25
+ - lib/vic/highlight.rb
26
+ - lib/vic/link.rb
27
+ - lib/vic/xterm_color.rb
28
28
  homepage: https://github.com/noprompt/vic
29
29
  licenses: []
30
30
  post_install_message:
@@ -1,7 +0,0 @@
1
- module Vic
2
- class ColorError < StandardError
3
- def initialize(message)
4
- super(message)
5
- end
6
- end
7
- end
@@ -1,141 +0,0 @@
1
- module Vic
2
- class Colorscheme
3
- attr_accessor :colors_name, :information
4
-
5
- # A new instance of Colorscheme. If a block is given with no arguments, the
6
- # the block will be evaluated in the context of the new colorscheme.
7
- # Otherwise the block will yield self.
8
- #
9
- # @param [String] colors_name the name of the colorscheme
10
- # @param [Proc] block the block to be evaluated
11
- # @return [Colorscheme]
12
- def initialize(colors_name, &block)
13
- @colors_name = colors_name
14
- if block_given?
15
- block.arity == 0 ? instance_eval(&block) : yield(self)
16
- end
17
- end
18
-
19
- # Returns/sets the information attribute
20
- #
21
- # @param [Hash] information the information, :author => 'Joel Holdbrooks'
22
- # @return [Hash]
23
- def information(inf={})
24
- (@information ||= {}).merge!(inf) if inf.respond_to? :merge
25
- end
26
- alias_method :info, :information
27
-
28
- # Returns the background color.
29
- #
30
- # @return [String] 'light' or 'dark'
31
- def background
32
- @background ||= background!
33
- end
34
-
35
- # Sets the background color.
36
- #
37
- # @param [String] a value of 'light' or 'dark'
38
- # @return [String] the background attribute
39
- def background=(light_or_dark)
40
- unless (light_or_dark =~ /^light$|^dark$/).nil?
41
- @background = light_or_dark
42
- end
43
- end
44
-
45
- # Sets the background color by attempting to determine it.
46
- #
47
- # @return[String] the background attribute
48
- def background!
49
- @background =
50
- if normal = highlights.find_by_group('Normal')
51
- return 'dark' unless color = normal.guibg
52
- color.partition('#').last.to_i(16) <= 8421504 ? 'dark' : 'light'
53
- else
54
- 'dark'
55
- end
56
- end
57
-
58
- # Returns the set of highlights for the colorscheme
59
- def highlight_set
60
- @highlight_set ||= HighlightSet.new
61
- end
62
- alias_method :highlights, :highlight_set
63
-
64
- # Creates a new highlight
65
- #
66
- # If inside of a language block the langauge name is automatcially prepended
67
- # to the group name of the new highlight.
68
- #
69
- # @see Vic::Highlight
70
- # @return [Vic::Highlight] the new highlight
71
- def highlight(group, args={})
72
- return if args.empty?
73
-
74
- if h = find_highlight(group)
75
- h.update_arguments! args
76
- else
77
- h = Highlight.new "#{language}#{group}", args
78
- highlight_set.add h
79
- end
80
- end
81
- alias_method :hi, :highlight
82
-
83
- def find_highlight(group)
84
- highlight_set.find_by_group(group)
85
- end
86
-
87
- # Sets the current language to name. Any new highlights created will have
88
- # the language name automatically prepended.
89
- #
90
- # @return [String] the new language name
91
- def language=(name)
92
- @language = name
93
- end
94
-
95
- # Returns the current language or temporarily sets the language to name if
96
- # a block is given. If a block is given with no arguments, it will be
97
- # evaluated in the context of the colorscheme, otherwise it will yield the
98
- # colorscheme.
99
- #
100
- # @param [String,Symbol] name the name of the language
101
- # @param [Proc] block the block to be evalauted
102
- # @return [String] the current language
103
- def language(name=nil, &block)
104
- if @language and not name
105
- return @language
106
- elsif name and block_given?
107
- previous_language = self.language
108
- self.language = name
109
- block.arity == 0 ? instance_eval(&block) : yield(self)
110
- self.language = previous_language
111
- end
112
- end
113
-
114
- # Returns the colorscheme header.
115
- #
116
- # @return [String] the colorscheme header
117
- def header
118
- <<-EOT.gsub(/^ {6}/, '')
119
- " Vim color file
120
- #{info.to_a.map do |pair|
121
- pair.join(": ").tap {|s| s[0] = '" ' + s[0].upcase }
122
- end.join("\n")}
123
- set background=#{background}
124
- hi clear
125
-
126
- if exists("syntax_on")
127
- syntax reset
128
- endif
129
-
130
- let g:colors_name="#{colors_name}"
131
- EOT
132
- end
133
-
134
- # Returns the colorscheme as a string
135
- #
136
- # @return [String] the colorscheme
137
- def write
138
- [header, highlights.map(&:write)].join("\n")
139
- end
140
- end
141
- end
@@ -1,97 +0,0 @@
1
- module Vic
2
- class Colorscheme::Highlight
3
-
4
- attr_accessor :group
5
-
6
- # Creates an instance of Vic::Colorscheme::Highlight. Uses
7
- # `update_arguments!` to set the arguments.
8
- #
9
- # @param [String] group the group name, 'Normal', 'Function', etc.
10
- # @param [Hash] args the arguments to set
11
- # @return [Vic::Colorscheme::Highlight] the new highlight
12
- def initialize(group, args={})
13
- # Convert to group name to symbol to ensure consistency
14
- @group = group.to_sym
15
- update_arguments!(args)
16
- end
17
-
18
- # Sets the methods term, term=, start, start=, etc. for settings arguments.
19
- self.class_eval do
20
- %w{term start stop cterm ctermfg ctermbg gui guifg guibg}.each do |m|
21
-
22
- # Getter method
23
- define_method(m) do
24
- arg = argument_set.find_by_key(m)
25
- return arg.val if arg
26
- end
27
-
28
- # Setter method
29
- define_method("#{m}=") do |val|
30
- arg = argument_set.find_by_key(m)
31
- if arg
32
- arg.val = val
33
- else
34
- arg = Argument.new(m, val)
35
- argument_set.add arg
36
- end
37
- end
38
- end
39
- end
40
-
41
- # Sets guifg and ctermfg simultaneously. `hex` is automatically converted to
42
- # the 256 color code for ctermfg.
43
- #
44
- # @param [String] hex a hexidecimal color
45
- def fg=(color)
46
- if color == 'NONE'
47
- self.ctermfg = color
48
- elsif Color.is_hexadecimal?(color)
49
- self.ctermfg = Color.hex_to_256(color)
50
- else
51
- raise ColorError.new "invalid hexadecimal color #{color}"
52
- end
53
-
54
- self.guifg = color
55
- end
56
-
57
- # Sets guibg and ctermbg simultaneously. `hex` is automatically converted to
58
- # the 256 color code for ctermbg.
59
- #
60
- # @param [String] hex a hexidecimal color
61
- def bg=(color)
62
- if color == 'NONE'
63
- self.ctermbg = color
64
- elsif Color.is_hexadecimal?(color)
65
- self.ctermbg = Color.hex_to_256(color)
66
- else
67
- raise ColorError.new "invalid hexadecimal color #{color}"
68
- end
69
-
70
- self.guibg = color
71
- end
72
-
73
- # Updates/sets the current highlight's arguments.
74
- #
75
- # @param [Hash] args the arguments to update/set, `:guibg => '#333333'`
76
- # @return [Vic::Colorscheme::Highlight::ArgumentSet] the updated argument set
77
- def update_arguments!(args={})
78
- args.each {|key, val| send("#{key}=", val)}
79
- arguments
80
- end
81
-
82
- # Returns the set of arguments for the given highlight
83
- #
84
- # @return [Vic::Colorscheme::Highlight::ArgumentSet] the argument set
85
- def argument_set
86
- @argument_set ||= ArgumentSet.new
87
- end
88
- alias_method :arguments, :argument_set
89
-
90
- # Writes the highlight contents.
91
- #
92
- # @return [String] the highlight as a string
93
- def write
94
- "hi #{group} #{arguments.sort_by_key.map(&:write).compact.join(' ')}"
95
- end
96
- end
97
- end
@@ -1,27 +0,0 @@
1
- module Vic
2
- class Colorscheme::Highlight::Argument
3
- VALID = %w{term start stop cterm ctermfg ctermbg gui guifg guibg guisp font}
4
-
5
- attr_accessor :key, :val
6
-
7
- def initialize(key, val)
8
- @key, @val = key, val
9
- end
10
-
11
- # The argument as a string
12
- #
13
- # @return [String,nil] the string if argument has been set
14
- def write
15
- return unless val
16
- "#{key}=#{val.respond_to?(:join) ? val.join(',') : val}"
17
- end
18
-
19
- # Checks if `key` is valid vim key for an argument
20
- #
21
- # @param [String,Symbol]
22
- # @return [true,false] the key is valid
23
- def self.is_valid?(key)
24
- VALID.include?(key.to_s)
25
- end
26
- end
27
- end
@@ -1,41 +0,0 @@
1
- module Vic
2
- class Colorscheme::Highlight::ArgumentSet
3
- include Enumerable
4
-
5
- def arguments
6
- @arguments ||= []
7
- end
8
-
9
- def each
10
- arguments.each {|a| yield a }
11
- end
12
-
13
- # Adds a new argument to the set
14
- #
15
- # @param [Colorscheme::Highlight::Argument] argument the argument to add
16
- # @return [Colorscheme::Highlight::ArgumentSet] the new set of arguments
17
- def add(argument)
18
- if argument.respond_to? :val
19
- arguments.push argument
20
- else
21
- # Raise an Exception
22
- raise TypeError.new("expted type Colorscheme::Highlight::Argument")
23
- end
24
- end
25
-
26
- # Finds an argument by a key.
27
- #
28
- # @param [String,Symbol] key the key to search for
29
- # @return [Colorscheme::Highlight::Argument,nil] the new argument
30
- def find_by_key(key)
31
- find {|a| a.key.to_s == key.to_s }
32
- end
33
-
34
- # Sorts the arguments by key name
35
- #
36
- # @return [Colorscheme::Highlight::ArgumentSet] the sorted set of arguments
37
- def sort_by_key
38
- sort {|a, b| a.key.to_s <=> b.key.to_s }
39
- end
40
- end
41
- end
@@ -1,34 +0,0 @@
1
- module Vic
2
- class Colorscheme::HighlightSet
3
- include Enumerable
4
-
5
- def highlights
6
- @highlights ||= []
7
- end
8
-
9
- def each
10
- highlights.each {|h| yield h }
11
- end
12
-
13
- # Adds a highlight to the set.
14
- #
15
- # @param [Colorscheme::Highlight] highlight the highlight to add
16
- # @return [Colorscheme::HighlightSet] the updated set of highlights
17
- def add(highlight)
18
- if highlight.respond_to? :gui
19
- highlights.push highlight
20
- else
21
- # Raise and Exception
22
- raise TypeError.new("expected type Colorscheme::Vic::Highlight")
23
- end
24
- end
25
-
26
- # Find a highlight by group name
27
- #
28
- # @param [String] group the group name
29
- # @return [Colorscheme::Highlight,nil] the highlight
30
- def find_by_group(group)
31
- find {|h| h.group == group.to_sym }
32
- end
33
- end
34
- end