term_color 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d7de87ceb0f3dfa90c19e011c9e2cddc1bf767a92ec88868e13574336601ba92
4
+ data.tar.gz: 20101cdbcf43876dfa89cab889443850a8f59d742db7dbd3a5d66336d34994da
5
+ SHA512:
6
+ metadata.gz: 36863a07e2d674605356d73295d0a903413fd713041abb977868b37cf4661e2ad07e5b3e0f4c461605c2b6fed05bf97eec5756a9ceae3a2f208ab6fe744f1266
7
+ data.tar.gz: 31333b2890a8497edd93781f62a4239692f4981d2bd719c2e45ee641b7406c9fa99d2d8da1ffd0940716e25968f17131512d149996393afb65027d1fc591ba30
data/README.md ADDED
@@ -0,0 +1,110 @@
1
+ # TermColor
2
+
3
+ Rule-based text coloring/styling library for terminal text
4
+
5
+ ## Overview
6
+
7
+ ### Justifying Features
8
+
9
+ - Define named text style rules once, combining fg/bg color and styling that can be reused through out application
10
+ - Able to manually specify what gets reset after style use is finished in a line, which parts to reset, etc.
11
+ - Streamline including multiple styles within a single string, including allowing nested rules
12
+
13
+ ### Requirements
14
+
15
+ - Tested/developed for Ruby 2.6.1
16
+
17
+ ## Concepts/Syntax
18
+
19
+ Rules are grouped into `RuleSets`, which are represented by instances of {TermColor::RuleSet}.
20
+
21
+ ### Rule Set
22
+
23
+ A set is constructed from a Hash of rule, where they keys are rule names and the values are the rule definition hashes.
24
+
25
+ ```ruby
26
+ rules = {
27
+ # Rule named :title
28
+ title: { fg: :yellow, enable: :underline }
29
+ }
30
+ # Create instance of RuleSet
31
+ rule_set = TermColor.create_rule_set(rules)
32
+ # or
33
+ rule_set = TermColor::RuleSet.new(rules)
34
+ ```
35
+
36
+ #### Applying to Text
37
+
38
+ Once you've got a `RuleSet` instance, calling its `apply` or `print`/`printf` methods with a string parameter will give back a copy of that string with styles applied
39
+
40
+ __Methods__
41
+
42
+ - `apply` - {TermColor::RuleSet#apply}
43
+ - `print` - {TermColor::RuleSet#print}
44
+ - `printf` - {TermColor::RuleSet#printf}
45
+
46
+ __Use__
47
+
48
+ - To apply a style to a section of the input string, surround it with `%rule_name` and `%%`
49
+ - E.g.: `"%titleTitle Text%%"`
50
+ - `%%` indicates the end of rule application, after which any `after` rules will get applied
51
+ - Including `%%` when no rule is active will apply the `default` rule's `:after` options, which can either be overridden in your rule set, or make use of the built-in version which simply resets all colors and text styling to system default
52
+ - Rule application can be nested (`"%titleTitle of %otherBook%%%%"`)
53
+
54
+ ### Rule Definitions
55
+
56
+ _For more details on rule definitions, see {file:docs/rule_dsl.md Rule DSL} ([View on GitHub](https://github.com/vdtdev/term_color/blob/master/docs/rule_dsl.md))_
57
+
58
+ Rule definitions are just hashes that include rule options. The included options can be divided into `:inside` (applied to text rule is applied to) and `:after` (applied to text following text rule is applied to). If neither of these sub hashes are included, all options are treated as being for `:inside`, and an `:after` set is auto-generated to unapply style changes made inside rule for following text. To prevent an `:after` section from being automatically generated, either include your own `:after` section or include `after: {}`.
59
+
60
+ ```ruby
61
+ # No groups, after will be generated
62
+ rule = { fg: :red }
63
+ # Same as above but with groups. after will be generated
64
+ rule = { inside: { fg: :red } }
65
+ # No groups, skip after generation by setting it to
66
+ # empty hash of options
67
+ rule = { fg: :red, after: {} }
68
+ # Both groups, same as others but with explicitly set after options,
69
+ # no auto-generation
70
+ rule = { inside: { fg: :red }, after: { reset: :fg } }
71
+ ```
72
+
73
+ For more details on rule definitions, see {file:docs/rule_dsl.md Rule DSL} ([View on GitHub]{https://github.com/vdtdev/term_color/blob/master/docs/rule_dsl.md})
74
+
75
+ ## Examples
76
+
77
+ [If example images are missing, view readme on github](https://github.com/vdtdev/term_color/blob/master/README.md)
78
+
79
+ ### Basic
80
+
81
+ ```ruby
82
+ rule_set = TermColor.create_rule_set({
83
+ opt: { fg: :cyan },
84
+ err: { fg: :red }
85
+ })
86
+
87
+ rule_set.printf "%errInvalid%% option: %opt%s%%\n", "fruit"
88
+ ```
89
+
90
+ ![](./file/docs/example_1.png)
91
+ ![](./docs/example_1.png)
92
+
93
+ ### Nested /w XTerm RGB
94
+
95
+ ```ruby
96
+ rule_set = TermColor.create_rule_set({
97
+ title: { fg: :yellow, enable: :underline },
98
+ emph: { fg: [0xa0,0xa0,0xff], enable: :italic },
99
+ author: { fg: :green, bg: :blue, enable: :bold }
100
+ })
101
+
102
+ rule_set.print "book: %%titleHarry Potter (%emph%%)%% by %authorJ. K. Rowling%%\n"
103
+ ```
104
+
105
+ ![](./file/docs/example_2.png)
106
+ ![](./docs/example_2.png)
107
+
108
+ ## License
109
+
110
+ (c) 2020, Wade H. (vdtdev.prod@gmail.com). All Rights Reserved. Released under MIT license.
@@ -0,0 +1,316 @@
1
+ module TermColor
2
+ ##
3
+ # Rule processor
4
+ # @example Basic Rule
5
+ # # Foreground color set to blue
6
+ # # Underline style turned on
7
+ # # Not broken into `a:` and `z:`, so rules will
8
+ # # be treated as `a:`, `z:` will be auto-generated
9
+ # # to reset forground color and disable underline
10
+ # rule = { fg: :blue, enable: :underline }
11
+ # @example Full after reset
12
+ # # Insize: (`a:`) Foreground yellow, bg red, dark style on
13
+ # # After: Resets all color and style options to default,
14
+ # # including those set by other rules
15
+ # rule = {
16
+ # a: {
17
+ # fg: :yellow, bg: :red, enable: :dark
18
+ # },
19
+ # z: {
20
+ # reset: :all
21
+ # }
22
+ # }
23
+ # @example Italic red, only clearing color at end
24
+ # # Inside: red fg, italic style
25
+ # # After: color will reset to default, italic will remain on
26
+ # rule = { a: { fg: :red, enable: :italic }, z: { reset: :fg }}
27
+ # @author Wade H. <vdtdev.prod@gmail.com>
28
+ module Rule
29
+ extend self
30
+
31
+ ##
32
+ # Named Standard ANSI Color constants
33
+ # (Basic named values for `fg` and `bg` rule option attributes)
34
+ Colors = {
35
+ black: 0,
36
+ red: 1,
37
+ green: 2,
38
+ yellow: 3,
39
+ blue: 4,
40
+ magenta: 5,
41
+ cyan: 6,
42
+ white: 7
43
+ }.freeze
44
+
45
+ ##
46
+ # Numerical modifiers used with Color Values
47
+ # to target foreground or background.
48
+ #
49
+ # - For {Colors Named Standard Colors}, value is added to given
50
+ # color's numerical value
51
+ # - For XTerm 256/16m color codes, value is added to mode base
52
+ #
53
+ # @example Named Standard Color Background
54
+ # { bg: :red } #=> 40 + 1 = 41
55
+ # @example XTerm 256 Foreground
56
+ # { fg: [208] } #=> 8 + 30 = 38
57
+ ColorTargets = {
58
+ fg: 30, # Foreground target
59
+ bg: 40 # Background target
60
+ }.freeze
61
+
62
+ ##
63
+ # Style option constants
64
+ # (Values that can be included in style `enable` and `disable`
65
+ # rule option attributes)
66
+ Styles = {
67
+ bold: 1,
68
+ ##
69
+ # Alias for bold
70
+ intense: 1,
71
+ dim: 2,
72
+ ##
73
+ # Alias for dim
74
+ dark: 2,
75
+ italic: 3,
76
+ underline: 4,
77
+ inverse: 7,
78
+ strikethrough: 9
79
+ }.freeze
80
+
81
+ ##
82
+ # Style action codes
83
+ # (Numerical modifiers applied to {Styles Style Codes} to
84
+ # enable/disable them based on which option attribute action
85
+ # was used)
86
+ # @example Disable italic
87
+ # (:disable) + (:italic) #=> 20 + 3 = 23
88
+ StyleActions = {
89
+ # Enable style(s) action
90
+ enable: 0,
91
+ # Disable style(s) action
92
+ disable: 20
93
+ }
94
+
95
+ ##
96
+ # Reset option constants
97
+ # (Values for `reset` rule option attribute)
98
+ Resets = {
99
+ # Reset everything
100
+ all: 0,
101
+ # Reset foreground color only
102
+ fg: 39,
103
+ # Reset background color only
104
+ bg: 49
105
+ }.freeze
106
+
107
+ ##
108
+ # Descriptive aliases for part names
109
+ Parts = {
110
+ # Style applied on rule open
111
+ inside: :inside,
112
+ # Style appled when rule close is given
113
+ after: :after
114
+ }
115
+
116
+ ##
117
+ # Valid rule operations mapped to accepted const values
118
+ # (colors [fg, bg] can also accept integers)
119
+ Ops = {
120
+ # Foreground color option
121
+ fg: Colors.keys,
122
+ # Background color option
123
+ bg: Colors.keys,
124
+ # Enable style(s) action
125
+ enable: Styles.keys,
126
+ # Disable style(s) action
127
+ disable: Styles.keys,
128
+ # Reset action
129
+ reset: [
130
+ :fg, # Reset fg color
131
+ :bg, # Reset bg color
132
+ :style, # Reset all styles
133
+ :all # Reset colors and styles
134
+ ]
135
+ }
136
+
137
+ ##
138
+ # Value added to ColorTarget when using XTerm colors
139
+ XTERM_COLOR_TARGET = 8
140
+ ##
141
+ # Mode constant for XTerm 256 Colors
142
+ XTERM_COLOR_256 = 5
143
+ ##
144
+ # Mode constant for XTerm 16m Colors
145
+ XTERM_COLOR_16M = 2
146
+
147
+ ##
148
+ # Structure used to hold compiled rule
149
+ # @!attribute [r] original
150
+ # Original rule hash
151
+ # @return [Hash]
152
+ # @!attribute [r] evaluated
153
+ # Evaluated copy of rule, including generated :after.
154
+ # Consists of code arrays
155
+ # @return [Hash]
156
+ # @!attribute [r] rule
157
+ # Hash of inside and after ANSI code strings
158
+ # @return [Hash]
159
+ Compiled = Struct.new(:original, :evaluated, :rule) do
160
+ ##
161
+ # Get codes for part of compiled rule
162
+ def codes(part)
163
+ rule[part]
164
+ end
165
+ end
166
+
167
+ ##
168
+ # Compile rule into frozen instance of `Compiled` struct
169
+ # @param [Hash] rule Rule hash
170
+ # @return [Compiled] Frozen instance of `Compiled` struct
171
+ # containing compiled rule
172
+ def compile(rule)
173
+ evaluated = evaluate(rule)
174
+ return Compiled.new(
175
+ rule,
176
+ evaluated,
177
+ codes(evaluated)
178
+ ).freeze
179
+ end
180
+
181
+ private
182
+
183
+ def evaluate_ops(ops)
184
+ codes = []
185
+ v_ops = ops.filter{|k,v| Ops.keys.include?(k.to_sym)}
186
+ color_keys = ColorTargets.keys
187
+ style_keys = StyleActions.keys
188
+ reset_keys = Resets.keys
189
+ v_ops.each_pair do |k,v|
190
+ k=k.to_sym
191
+ if color_keys.include?(k)
192
+ codes << resolve_color(v, k)
193
+ elsif style_keys.include?(k)
194
+ [v].flatten.each do |val|
195
+ codes << resolve_style(val, k)
196
+ end
197
+ elsif k == :reset
198
+ [v].flatten.each do |val|
199
+ codes << resolve_reset(val)
200
+ end
201
+ end
202
+ end
203
+ codes = codes.flatten.compact.uniq
204
+ end
205
+
206
+ def resolve_color(color, target = :fg)
207
+ if color.is_a?(Array)
208
+ color = color[0..2]
209
+ return xterm_color(color, target)
210
+ end
211
+
212
+ if !color.is_a?(Integer)
213
+
214
+ if color.is_a?(Hash) && ColorsAdvanced.keys.include?(color.keys[0])
215
+ return self.method(ColorsAdvanced[color.keys[0]]).call(color.values[0])
216
+ end
217
+ color = Colors[color.to_sym].to_i
218
+ end
219
+ (color + ColorTargets[target.to_sym].to_i)
220
+ end
221
+
222
+ def resolve_style(style, state = :enable)
223
+ if !style.is_a?(Integer)
224
+ style = Styles[style.to_sym].to_i
225
+ end
226
+ (style + StyleActions[state.to_sym].to_i)
227
+ end
228
+
229
+ def resolve_reset(target)
230
+ if Resets.keys.include?(target.to_sym)
231
+ return Resets[target.to_sym]
232
+ elsif Styles.keys.include?(target.to_sym)
233
+ return resolve_style(target, :disable)
234
+ else
235
+ return nil
236
+ end
237
+ end
238
+
239
+ def xterm_color(val,target)
240
+ r,g,b = [val].flatten
241
+ if g.nil? && b.nil?
242
+ [
243
+ ColorTargets[target] + XTERM_COLOR_TARGET,
244
+ XTERM_COLOR_256,
245
+ r
246
+ ].join(';')
247
+ else
248
+ [
249
+ ColorTargets[target] + XTERM_COLOR_TARGET,
250
+ XTERM_COLOR_16M,
251
+ r,g,b
252
+ ].join(';')
253
+ end
254
+ end
255
+
256
+ ##
257
+ # Evaluate rule, returning new hash containing list of numerical
258
+ # codes to use for inside (`:inside`) and after (`:after`)
259
+ # @param [Hash] rule Rule hash to evaluate
260
+ # @return [Hash] evaluated version of rule, containing code numbers
261
+ def evaluate(rule)
262
+ # error if not hash
263
+ return nil if !rule.is_a?(Hash)
264
+
265
+ inside_part_key = Parts[:inside]
266
+ after_part_key = Parts[:after]
267
+ rule_keys = rule.keys.map{|k|k.to_sym}
268
+
269
+ # Find 'inside' rule options
270
+ if rule_keys.include?(inside_part_key)
271
+ # 'inside' key explicitly defined, so pull from that
272
+ inside_part = rule[:inside]
273
+ else
274
+ # no 'inside' key, so pull from entire hash excluding
275
+ # 'after' key, if present
276
+ inside_part = rule.filter { |k,v| k != after_part_key }
277
+ end
278
+
279
+ # Find 'after' rule options, using nil if not present
280
+ # This means that if it is defined but as an empty hash,
281
+ # no 'after' rule options will be auto-generated
282
+ after_part = rule.fetch(after_part_key, nil)
283
+
284
+ # Auto-generate 'after' rule options if not explicitly defined
285
+ if after_part.nil?
286
+ resets = inside_part.keys.filter { |k| ColorTargets.keys.include?(k) }
287
+ disables = inside_part.fetch(:enable, [])
288
+ after_part = {}
289
+ after_part[:reset] = resets if resets.length > 0
290
+ after_part[:disable] = disables if disables.length > 0
291
+ end
292
+
293
+ parts = {}
294
+
295
+ parts[inside_part_key] = evaluate_ops(inside_part)
296
+ parts[after_part_key] = evaluate_ops(after_part)
297
+
298
+ return parts.merge({evaluated: true})
299
+
300
+ end
301
+
302
+ ##
303
+ # Return ANSI color codes from evaluated rule
304
+ # @param [Hash] rule Full rule
305
+ # @return [Hash] Hash with code strings for `:inside` and `:after`
306
+ def codes(rule)
307
+ code = Proc.new {|c| "\e[#{c}m" }
308
+ inside = Parts[:inside]
309
+ after = Parts[:after]
310
+ {
311
+ (inside) => rule[inside].map{|c| code.call(c) }.join(''),
312
+ (after) => rule[after].map{|c| code.call(c) }.join('')
313
+ }
314
+ end
315
+ end
316
+ end
@@ -0,0 +1,214 @@
1
+ module TermColor
2
+ ##
3
+ # TermColor style rule setc class
4
+ # @author Wade H. <vdtdev.prod@gmail.com>
5
+ # @license MIT
6
+ class RuleSet
7
+
8
+ ##
9
+ # Symbol used as prefix for rule name to denote rule start
10
+ RULE_SYMBOL='%'
11
+ ##
12
+ # String used to denote rule close / reset
13
+ RESET_SYMBOL='%%'
14
+
15
+ DEFAULT_RESET_RULE = {z: {reset: :all} }
16
+
17
+ attr_reader :rules, :regexs
18
+
19
+ ##
20
+ # Construct new rule set
21
+ # @param [Hash] rules Hash of rule names mapping to rule hashes,
22
+ # which can define before rules (`a:`), after rules (`z:`) or both.
23
+ # - If neither are given, content is treated as though it was inside a `a:` key.
24
+ # - If `a:` only is given, {TermColor::Rule#evaluate Rule evaluate method} attempts to
25
+ # auto guess `z:`, resetting any used color or style rules from `a:`
26
+ # @see TermColor::Rule
27
+ # @example
28
+ # rules = RuleSet.new({
29
+ # # Green underlined text; will auto reset fg and disable underline
30
+ # # for close, since no z: is provided
31
+ # name: {fg: :green, enable: :underline},
32
+ # # Italic text; will auto generate z: that disables italic
33
+ # quote: { enable: :italic },
34
+ # # A weird rule that will make fg red inside rule,
35
+ # # and change fg to blue after rule block ends
36
+ # weird: { a: { fg: :red }, z: { fg: :blue }}
37
+ # })
38
+ #
39
+ # print rules.colorize("%nameJohn%%: '%%quoteRoses are %%weirdRed%% (blue)%%.\n")
40
+ # # Result will be:
41
+ # # fg green+underline "John"
42
+ # # regular ": "
43
+ # # italic "Roses are "
44
+ # # fg red (still italic) "Red"
45
+ # # (fg blue)(still italic) "(blue)"
46
+ # # (regular) "."
47
+ def initialize(rules)
48
+ @base_rules = rules
49
+ @base_rules[:default] = @base_rules.fetch(:default, DEFAULT_RESET_RULE)
50
+ evaluate_rules
51
+ build_regexs
52
+ end
53
+
54
+ ##
55
+ # Apply styling to string using rule set
56
+ # @param [String] text Text to parse for stylization
57
+ # @return [String] Text with ANSI style codes injected
58
+ def apply(text)
59
+ raw = process_text(text)
60
+ last_rule = nil
61
+ str = ''
62
+ raw.each do |r|
63
+ if r.is_a?(Symbol)
64
+ # if (r == :close_rule && !last_rule.nil?)
65
+ # str.concat(Rule.codes(@rules[last_rule][:z]))
66
+ # last_rule = nil
67
+ # elsif r == :default
68
+ # str.concat(Rule.codes(@rules[r][:z]))
69
+ # last_rule = nil
70
+ # else
71
+ # last_rule = r
72
+ # str.concat(Rule.codes(@rules[r][:a]))
73
+ # end
74
+ if (r == :default) && !last_rule.nil?
75
+ str.concat(@rules[last_rule].codes(Rule::Parts[:after]))
76
+ last_rule = nil
77
+ elsif r == :default
78
+ str.concat(@rules[r].codes(Rule::Parts[:after]))
79
+ last_rule = nil
80
+ else
81
+ last_rule = r
82
+ str.concat(@rules[r].codes(Rule::Parts[:inside]))
83
+ end
84
+ else
85
+ str.concat(r)
86
+ end
87
+ end
88
+ str
89
+ end
90
+
91
+ ##
92
+ # Wraps STDOUT print method, passing output of `apply` to `print`
93
+ # @param [Array] args Print arguments, including TermColor style tags
94
+ # @param [Hash] opts Optional params
95
+ # @option opts [IO] :out Optional override for IO class to call `print`
96
+ # on (default `$stdout`)
97
+ def print(*args,**opts)
98
+ stdout = opts.fetch(:out, $stdout)
99
+ t = args.map{|a|apply(a)}
100
+ stdout.print *t
101
+ end
102
+
103
+ ##
104
+ # Wraps STDOUT printf method, passing output of `apply` to `print`
105
+ # Doesn't actually use `printf`, instead passes result of
106
+ # `format_string % args` to `print`.
107
+ # @param [String] format_string printf format string,
108
+ # including TermColor style tags
109
+ # @param [Array] args printf values to use with format string
110
+ # @param [Hash] opts Optional params
111
+ # @option opts [IO] :out Optional override for IO class to call `print`
112
+ # on (default `$stdout`)
113
+ def printf(format_string,*args,**opts)
114
+ stdout = opts.fetch(:out, $stdout)
115
+
116
+ # Sanitize rule symbols
117
+ sanitized = format_string.dup
118
+ @rules.keys.each { |k| sanitized.gsub!("#{RULE_SYMBOL}#{k.to_s}","#{255.chr}#{k.to_s}") }
119
+ sanitized.gsub!(RESET_SYMBOL, 255.chr*2)
120
+
121
+ t = sanitized % args
122
+ # Reinstate rule symbols
123
+ @rules.keys.each { |k| t.gsub!("#{255.chr}#{k.to_s}","#{RULE_SYMBOL}#{k.to_s}") }
124
+ t.gsub!(255.chr*2,RESET_SYMBOL)
125
+
126
+ stdout.print apply(t)
127
+ end
128
+
129
+ private
130
+
131
+ def evaluate_rules
132
+ @rules = {}
133
+ @base_rules.each_pair do |k,v|
134
+ @rules[k] = Rule.compile(v)
135
+ end
136
+ end
137
+
138
+ def build_regexs
139
+ @regexs = {}
140
+ src = @rules
141
+ src.each_pair do |k,v|
142
+ @regexs[k] = Regexp.compile(
143
+ "(?<#{k.to_s}>(#{RULE_SYMBOL}#{k.to_s}))"
144
+ )
145
+ end
146
+ @regexs[:default] = Regexp.compile(
147
+ "(?<default>(#{RESET_SYMBOL}))"
148
+ )
149
+ end
150
+
151
+ def locate_rules_in_string(text)
152
+ tracking = {}
153
+ @regexs.keys.each do |k|
154
+ tracking[k] = {index: 0, done: false}
155
+ end
156
+ tracking_done = Proc.new {
157
+ tracking.values.select{|t|!t[:done]}.length == 0
158
+ }
159
+ is_done = false
160
+
161
+ locations = []
162
+ # binding.pry
163
+ until is_done do
164
+ @regexs.each_pair do |k,v|
165
+ t = tracking[k]
166
+ # print "Tracking #{k} (#{t})\n"
167
+ unless t[:done]
168
+ m = v.match(text,t[:index])
169
+ if m.nil?
170
+ # print "No matches found\n"
171
+ tracking[k][:done] = true
172
+ else
173
+ tracking[k][:index] = m.end(0)
174
+ a=m.begin(0);b=m.end(0)
175
+ locations << {
176
+ symbol: k,
177
+ begin: a,
178
+ sym_end: b - 1,
179
+ continue_pos: b
180
+ }
181
+ # print "\tMatch found (#{a}..#{b}): #{text[a..b]}\n"
182
+ end
183
+ end
184
+ end
185
+ is_done = tracking_done.call()
186
+ end
187
+ locations.sort{|a,b|a[:continue_pos]<=>b[:continue_pos]}
188
+ end
189
+
190
+ def process_text(text)
191
+ locations = locate_rules_in_string(text)
192
+
193
+ working = []
194
+ return [text] if locations.length == 0
195
+
196
+ if locations[0][:begin] > 0
197
+ working << text[0..locations[0][:begin]-1]
198
+ end
199
+
200
+ locations.each_with_index do |l,i|
201
+ is_last = locations.length - 1 - i == 0
202
+ end_pos = -1
203
+ if !is_last
204
+ end_pos = locations[i+1][:begin] - 1
205
+ end
206
+
207
+ working << l[:symbol]
208
+ working << text[l[:continue_pos]..end_pos]
209
+ end
210
+ working
211
+ end
212
+
213
+ end
214
+ end
data/lib/term_color.rb ADDED
@@ -0,0 +1,16 @@
1
+ require_relative './term_color/rule.rb'
2
+ require_relative './term_color/rule_set.rb'
3
+ ##
4
+ # Main TermColor module
5
+ # @author Wade H. <vdtdev.prod@gmail.com>
6
+ module TermColor
7
+ extend self
8
+
9
+ ##
10
+ # Alias for constructing a new RuleSet
11
+ # @see TermColor::RuleSet
12
+ def create_rule_set(rules={})
13
+ TermColor::RuleSet.new(rules)
14
+ end
15
+
16
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: term_color
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Wade H.
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-02-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 3.7.0
20
+ - - "~>"
21
+ - !ruby/object:Gem::Version
22
+ version: '3.7'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 3.7.0
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '3.7'
33
+ description: " Rule-based tool for easily applying color and styling to terminal
34
+ text output.\n"
35
+ email: vdtdev.prod@gmail.com
36
+ executables: []
37
+ extensions: []
38
+ extra_rdoc_files: []
39
+ files:
40
+ - README.md
41
+ - lib/term_color.rb
42
+ - lib/term_color/rule.rb
43
+ - lib/term_color/rule_set.rb
44
+ homepage: https://github.com/vdtdev/term_color
45
+ licenses:
46
+ - MIT
47
+ metadata:
48
+ source_code_uri: https://github.com/vdtdev/term_color
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ requirements: []
64
+ rubygems_version: 3.0.1
65
+ signing_key:
66
+ specification_version: 4
67
+ summary: Terminal Colors
68
+ test_files: []