everyday-cli-utils 1.1.0 → 1.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 22981760ec07c6812935693a6ee28d02441e6bb1
4
- data.tar.gz: f888f94e58a15d8bb2bfdb5ea04af6903dfe43b8
3
+ metadata.gz: eab4ed95a5c1dc20cf4e4faa6202989b19a85d97
4
+ data.tar.gz: 00c28312e37700149f707cd2a718c05e8331859a
5
5
  SHA512:
6
- metadata.gz: 86fd47cad9ba83012945384c904870a346c374deda57a085221b1244cde553da9832473b66962aaa6c858549668f94937f1040149aa0ad8ae6ea6b591df1905f
7
- data.tar.gz: 01344d8e1f8bbef5f4a4eb7d8da778474344dcdbfdbf8b948500b63c56e3cc991aeea1b6a7de48dca02dbc1f8d38bbad367d8b0f3e091b4938a54786e3d0a60b
6
+ metadata.gz: aa9403aff6a4d6d30698ed1119b98cba40697a9519f6d31c18157d581fd6f0c6d99fcd13f7177a28a3036ac9fc573f8114a36acc01dca34a4596256313900ac4
7
+ data.tar.gz: eec2dcca50851e200c609ef100cee89f982d5669d0434f700b2e927acca5e6fe401d17e56409282b6a51f7a69310fd26404f98ad948326c14653d32fa468020a
data/README.md CHANGED
@@ -6,7 +6,9 @@
6
6
  [![Code Climate](https://codeclimate.com/github/henderea/everyday-cli-utils.png)](https://codeclimate.com/github/henderea/everyday-cli-utils)
7
7
  [![Coverage Status](https://coveralls.io/repos/henderea/everyday-cli-utils/badge.png?branch=master)](https://coveralls.io/r/henderea/everyday-cli-utils?branch=master)
8
8
 
9
- A few CLI and general utilities. Includes a numbered-menu select loop utility, a ANSI formatting escape code handler, a text-based histogram maker, k-means and n-means (k-means with minimum optimal k) calculators, various collection utility methods, a Curses wrapper with up/down scrolling and more handled easily, and a utility for using OptionParser with less code.
9
+ A few CLI and general utilities. Includes a numbered-menu select loop utility, a ANSI formatting escape code handler, a text-based histogram maker, k-means and n-means (k-means with minimum optimal k) calculators, various collection utility methods, and a utility for using OptionParser with less code.
10
+
11
+ Note: The curses utility has been moved to the `everyday-curses` gem
10
12
 
11
13
  ## Issue Tracking
12
14
  Please use <https://everydayprogramminggenius.atlassian.net/browse/ECU> for issue tracking.
@@ -155,10 +157,38 @@ Much shorter, right?
155
157
 
156
158
  There is also a static version of the method in `EverydayCliUtils::Format` that takes the string as a parameter, for those of you that use the "safe" version.
157
159
 
160
+ Here's the two-letter color keys:
161
+
162
+ ```ruby
163
+ {
164
+ 'bk' => :black,
165
+ 'rd' => :red,
166
+ 'gr' => :green,
167
+ 'yw' => :yellow,
168
+ 'bl' => :blue,
169
+ 'pu' => :purple,
170
+ 'cy' => :cyan,
171
+ 'wh' => :white,
172
+ 'no' => :none
173
+ }
174
+ ```
175
+
158
176
  As of version 0.5.0, there is now a `String#mycenter` method that takes a length and an optional character (defaults to `' '`) and centers the string using that character and length. This is designed to mimic the built-in `String#center` method, but add support for handling the formatting, since formatting is done by adding non-printing characters to the string. If you were to use the built-in `center` method, you would be adding too little padding.
159
177
 
160
178
  There is also a static version of the method in `EverydayCliUtils::Format` that takes the string as a parameter, for those of you that use the "safe" version.
161
179
 
180
+ As of version 1.2.0, there is now support for using color profiles in `String#format_all`. Here's an example:
181
+
182
+ ```ruby
183
+ EverydayCliUtils::Format.color_profile(:p1, bold: true, underline: true, fgcolor: :yellow, bgcolor: :green)
184
+ EverydayCliUtils::Format.color_profile(:p2, underline: true, fgcolor: :yellow)
185
+ 'abc {def}(:p1) ghi {jkl}(:p2) mno'.format_all
186
+ ```
187
+
188
+ This gives the same result as the earlier example. With color profiles, you define it once and can use it as many times as you want. So if you have an application that lets the user choose colors for certain things, you can define a color profile with the chosen colors once and re-use it as many times as you want.
189
+
190
+ Please note that if you define a second color profile with the same id, it will overwrite the first one.
191
+
162
192
  ###EverydayCliUtils::Histogram
163
193
 
164
194
  Create a text-based histogram. This is an extension to the `Enumerable` module, unless you import `:histogram_safe`, in which case you can use the static methods in `EverydayCliUtils::Histogram`, with an added first parameter of the collection.
@@ -250,66 +280,6 @@ Return the data joined into a single string with `join_str` in between the eleme
250
280
  ####Hash.expand
251
281
  Takes a shorthand hash (like `{ [:a, :b, :c, :d] => '1-4', e: '5' }`) and turns it into a full hash (like `{ a: '1-4', b: '1-4', c: '1-4', d: '1-4', :e => '5' }`)
252
282
 
253
- ###EverydayCliUtils::MyCurses
254
-
255
- Encapsulates the code for dealing with the curses library.
256
-
257
- ###Fields:
258
- ####MyCurses.headers
259
- An array storing the header lines that will be printed out with `MyCurses.myprints`.
260
-
261
- ####MyCurses.bodies
262
- An array storing the body lines that will be printed out with `MyCurses.myprints`.
263
-
264
- ####MyCurses.footers
265
- An array storing the footer lines that will be printed out with `MyCurses.myprints`.
266
-
267
- ###Methods:
268
-
269
- ####MyCurses.new(use\_curses, linesh, linesf)
270
- Initializes the class and sets the basic options.
271
-
272
- ######Parameters
273
- * `use_curses`: `true` to use curses, `false` to use `puts`
274
- * `linesh`: the number of header lines
275
- * `linesf`: the number of footer lines
276
-
277
- ####MyCurses.clear
278
- Clear the `headers`, `bodies`, and `footers` arrays
279
-
280
- ####MyCurses.myprints
281
- Print out all of the lines stored in the `headers`, `bodies`, and `footers` arrays. If `use_curses` is `true`, it will use curses and allow for scrolling. Otherwise, it will just print out all of the lines with `puts`
282
-
283
- ####MyCurses.read\_ch
284
- Update the character from the body pad.
285
-
286
- ####MyCurses.clear\_ch
287
- Clear out any newline, ENTER, UP, or DOWN characters from the queue.
288
-
289
- ####MyCurses.scroll\_iteration
290
- Update the display (including doing any scrolling) and read the next character.
291
-
292
- ####MyCurses.header\_live\_append(str)
293
- Append `str` to the header pad immediately and update it. Does not modify the `headers` array.
294
-
295
- ######Parameters
296
- * `str`: the string to append
297
-
298
- ####MyCurses.body\_live\_append(str)
299
- Append `str` to the body pad immediately and update it. Does not modify the `bodies` array.
300
-
301
- ######Parameters
302
- * `str`: the string to append
303
-
304
- ####MyCurses.footer\_live\_append(str)
305
- Append `str` to the footer pad immediately and update it. Does not modify the `footers` array.
306
-
307
- ######Parameters
308
- * `str`: the string to append
309
-
310
- ####MyCurses.dispose
311
- Close out the curses screen if curses was used.
312
-
313
283
  ###EverydayCliUtils::Option
314
284
 
315
285
  Some utility methods for the `OptionParser` class.
@@ -108,14 +108,15 @@ module EverydayCliUtils
108
108
  colors = 'bk|rd|gr|yw|bl|pu|cy|wh|no'
109
109
  color_map = { 'bk' => :black, 'rd' => :red, 'gr' => :green, 'yw' => :yellow, 'bl' => :blue, 'pu' => :purple, 'cy' => :cyan, 'wh' => :white, 'no' => :none }
110
110
  regex = /\{(.+?)\}\((bd)?(ul)?(?:f(#{colors}))?(?:b(#{colors}))?\)/
111
- text.gsub(regex) { |m|
111
+ regex2 = /\{(.+?)\}\(:(.+?)\)/
112
+ text.gsub(regex) { |_|
112
113
  txt = $1
113
114
  bold = !$2.nil?
114
115
  underline = !$3.nil?
115
116
  fg = $4.nil? ? nil : color_map[$4]
116
117
  bg = $5.nil? ? nil : color_map[$5]
117
118
  format(txt, build_string(bold, underline, fg, bg))
118
- }
119
+ }.gsub(regex2) { |_| format($1, color_profile_string($2.to_sym)) }
119
120
  end
120
121
 
121
122
  def self.mycenter(str, len, char = ' ')
@@ -125,5 +126,19 @@ module EverydayCliUtils
125
126
  a = len - tlen - b
126
127
  "#{char * b}#{str}#{char * a}"
127
128
  end
129
+
130
+ ColorProfile = Struct.new(:bold, :underline, :fgcolor, :bgcolor)
131
+
132
+ def self.color_profile(id, options = {})
133
+ @color_profiles ||= {}
134
+ @color_profiles[id] = ColorProfile.new(options[:bold], options[:underline], options[:fgcolor] || nil, options[:bgcolor] || nil)
135
+ end
136
+
137
+ def self.color_profile_string(id)
138
+ @color_profiles ||= {}
139
+ profile = @color_profiles[id]
140
+ profile.nil? ? nil : self::build_string(profile.bold, profile.underline, profile.fgcolor, profile.bgcolor)
141
+ end
128
142
  end
143
+
129
144
  end
@@ -1,3 +1,3 @@
1
1
  module EverydayCliUtils
2
- VERSION = '1.1.0'
2
+ VERSION = '1.2.0'
3
3
  end
@@ -68,6 +68,14 @@ describe EverydayCliUtils::Format do
68
68
  str.format_all.should eq expected
69
69
  end
70
70
 
71
+ it 'allows color profiles for use in shorthand for formatting in-string' do
72
+ EverydayCliUtils::Format.color_profile(:p1, bold: true, underline: true, fgcolor: :yellow, bgcolor: :green)
73
+ EverydayCliUtils::Format.color_profile(:p2, underline: true, fgcolor: :yellow)
74
+ str = 'abc {def}(:p1) ghi {jkl}(:p2) mno'
75
+ expected = "abc #{'def'.format_bold_underline_fg_yellow_bg_green} ghi #{'jkl'.format_underline_fg_yellow} mno"
76
+ str.format_all.should eq expected
77
+ end
78
+
71
79
  it 'allows centering a formatted string' do
72
80
  str = 'abc'
73
81
  str2 = str.center(10)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: everyday-cli-utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Henderson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-29 00:00:00.000000000 Z
11
+ date: 2014-01-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -103,12 +103,10 @@ files:
103
103
  - everyday-cli-utils.gemspec
104
104
  - lib/everyday-cli-utils.rb
105
105
  - lib/everyday-cli-utils/ask.rb
106
- - lib/everyday-cli-utils/curses_utils.rb
107
106
  - lib/everyday-cli-utils/format.rb
108
107
  - lib/everyday-cli-utils/histogram.rb
109
108
  - lib/everyday-cli-utils/kmeans.rb
110
109
  - lib/everyday-cli-utils/maputil.rb
111
- - lib/everyday-cli-utils/mycurses.rb
112
110
  - lib/everyday-cli-utils/option.rb
113
111
  - lib/everyday-cli-utils/safe/format.rb
114
112
  - lib/everyday-cli-utils/safe/histogram.rb
@@ -1,40 +0,0 @@
1
- #module EverydayCliUtils
2
- # module CursesUtils
3
- # COLOR_TO_CURSES = {
4
- # :black => Curses::COLOR_BLACK,
5
- # :red => Curses::COLOR_RED,
6
- # :green => Curses::COLOR_GREEN,
7
- # :yellow => Curses::COLOR_YELLOW,
8
- # :blue => Curses::COLOR_BLUE,
9
- # :purple => Curses::COLOR_MAGENTA,
10
- # :cyan => Curses::COLOR_CYAN,
11
- # :white => Curses::COLOR_WHITE,
12
- # :none => -1,
13
- # }
14
- #
15
- # def find_color(bgcolor, fgcolor)
16
- # @colors.find_index { |v| v[0] == (fgcolor || :none) && v[1] == (bgcolor || :none) }
17
- # end
18
- #
19
- # def add_color(bgcolor, fgcolor)
20
- # Curses::init_pair(@colors.count + 1, COLOR_TO_CURSES[fgcolor || :none], COLOR_TO_CURSES[bgcolor || :none])
21
- # ind = @colors.count + 1
22
- # @colors << [fgcolor || :none, bgcolor || :none]
23
- # ind
24
- # end
25
- #
26
- #
27
- # private
28
- # def handle_color(fgcolor, bgcolor)
29
- # return 0 if (fgcolor.nil? || fgcolor == :none) && (bgcolor.nil? || bgcolor == :none)
30
- # ind = find_color(bgcolor, fgcolor)
31
- # ind = ind.nil? ? add_color(bgcolor, fgcolor) : ind + 1
32
- # Curses::color_pair(ind)
33
- # end
34
- #
35
- # def get_format(str)
36
- # bold, underline, fgcolor, bgcolor = Format::parse_format(str)
37
- # (bold ? Curses::A_BOLD : 0) | (underline ? Curses::A_UNDERLINE : 0) | handle_color(fgcolor, bgcolor)
38
- # end
39
- # end
40
- #end
@@ -1,199 +0,0 @@
1
- #require 'curses'
2
- #require_relative 'format'
3
- #require_relative 'curses_utils'
4
- #
5
- #module EverydayCliUtils
6
- # class MyCurses
7
- # include CursesUtils
8
- # #region External
9
- # def initialize(use_curses, linesh, linesf)
10
- # @use_curses = use_curses
11
- # @linesh = linesh
12
- # @linesf = linesf
13
- # @colors = []
14
- # @headers = []
15
- # @bodies = []
16
- # @footers = []
17
- # @cur_l = 0
18
- # @max_l = 0
19
- # @ch = nil
20
- # setup_curses(linesf, linesh) if @use_curses
21
- # end
22
- #
23
- # def setup_curses(linesf, linesh)
24
- # Curses::noecho
25
- # Curses::init_screen
26
- # @subpad_start = linesh
27
- # update_subpad_size
28
- # @padh = Curses::Pad.new(linesh, Curses::cols)
29
- # @padb = Curses::Pad.new(Curses::lines - linesh - linesf, Curses::cols)
30
- # @padf = Curses::Pad.new(linesf, Curses::cols)
31
- # configure_curses
32
- # end
33
- #
34
- # def configure_curses
35
- # @padh.keypad(true)
36
- # @padh.clear
37
- # @padh.nodelay = true
38
- # @padb.keypad(true)
39
- # @padb.clear
40
- # @padb.nodelay = true
41
- # @padf.keypad(true)
42
- # @padf.clear
43
- # @padf.nodelay = true
44
- # Curses::cbreak
45
- # Curses::start_color
46
- # Curses::use_default_colors
47
- # end
48
- #
49
- # def clear
50
- # @headers = []
51
- # @bodies = []
52
- # @footers = []
53
- # end
54
- #
55
- # def myprints
56
- # @use_curses ? print_curses : print_normal
57
- # end
58
- #
59
- # def print_normal
60
- # @headers.each { |v| puts v }
61
- # @bodies.each { |v| puts v }
62
- # @footers.each { |v| puts v }
63
- # end
64
- #
65
- # def print_curses
66
- # resize_curses
67
- # myprint(@headers.join("\n"), @padh)
68
- # myprint(@bodies.join("\n"), @padb)
69
- # myprint(@footers.join("\n"), @padf)
70
- # update_max_l
71
- # @cur_l = [@cur_l, @max_l].min
72
- # padh_refresh
73
- # padb_refresh
74
- # padf_refresh
75
- # end
76
- #
77
- # def resize_curses
78
- # @padh.resize(@headers.count, Curses::cols)
79
- # @padb.resize(@bodies.count, Curses::cols)
80
- # @padf.resize(@footers.count, Curses::cols)
81
- # @padh.clear
82
- # @padb.clear
83
- # @padf.clear
84
- # @padh.setpos(0, 0)
85
- # @padb.setpos(0, 0)
86
- # @padf.setpos(0, 0)
87
- # end
88
- #
89
- # def read_ch
90
- # @ch = @padf.getch
91
- # end
92
- #
93
- # def clear_ch
94
- # read_ch
95
- # while @ch == 10 || @ch == Curses::Key::ENTER || @ch == Curses::Key::UP || @ch == Curses::Key::DOWN
96
- # read_ch
97
- # end
98
- # end
99
- #
100
- # def scroll_iteration
101
- # old_subpad_size = @subpad_size
102
- # update_subpad_size
103
- # update_max_l
104
- # update_scroll(@subpad_size != old_subpad_size)
105
- # sleep(0.05)
106
- # read_ch
107
- # end
108
- #
109
- # def header_live_append(str)
110
- # @padh << str
111
- # padh_refresh
112
- # end
113
- #
114
- # def body_live_append(str)
115
- # @padb << str
116
- # padb_refresh
117
- # end
118
- #
119
- # def footer_live_append(str)
120
- # @padf << str
121
- # padf_refresh
122
- # end
123
- #
124
- # def dispose
125
- # Curses::close_screen if @use_curses
126
- # end
127
- #
128
- # #endregion
129
- #
130
- # #region Internal
131
- # def myputs(text, pad)
132
- # myprint("#{text}\n", pad)
133
- # end
134
- #
135
- # def myprint(text, pad)
136
- # if @use_curses
137
- # if text.include?("\e")
138
- # pieces = text.scan(/#{"\e"}\[(.+?)m([^#{"\e"}]+?)#{"\e"}\[0m|([^#{"\e"}]+)/)
139
- # pieces.each { |v|
140
- # if v[2].nil?
141
- # pad.attron(get_format(v[0])) {
142
- # pad << v[1]
143
- # }
144
- # else
145
- # pad << v[2]
146
- # end
147
- # }
148
- # else
149
- # pad << text
150
- # end
151
- # else
152
- # print text
153
- # end
154
- # end
155
- #
156
- # def update_max_l
157
- # @max_l = [0, @bodies.count - @subpad_size].max
158
- # end
159
- #
160
- # def update_subpad_size
161
- # Curses::refresh
162
- # @subpad_size = Curses::lines - @linesh - @linesf
163
- # end
164
- #
165
- # def padh_refresh
166
- # @padh.refresh(0, 0, 0, 0, @subpad_start - 1, Curses::cols - 1)
167
- # end
168
- #
169
- # def padb_refresh
170
- # @padb.refresh(@cur_l, 0, @subpad_start, 0, @subpad_start + @subpad_size - 1, Curses::cols - 1)
171
- # end
172
- #
173
- # def padf_refresh
174
- # @padf.refresh(0, 0, @subpad_start + [@subpad_size, @bodies.count].min, 0, @subpad_start + [@subpad_size, @bodies.count].min + @footers.count, Curses::cols - 1)
175
- # end
176
- #
177
- # def update_scroll(force_refresh = false)
178
- # if @ch == Curses::Key::UP
179
- # @cur_l = [0, @cur_l - 1].max
180
- # elsif @ch == Curses::Key::DOWN
181
- # @cur_l = [@max_l, @cur_l + 1].min
182
- # end
183
- # @cur_l = [@cur_l, @max_l].min
184
- # if @ch == Curses::Key::UP || @ch == Curses::Key::DOWN || force_refresh
185
- # Curses::refresh
186
- # padh_refresh
187
- # padb_refresh
188
- # padf_refresh
189
- # end
190
- # @cur_l
191
- # end
192
- #
193
- # #endregion
194
- #
195
- # attr_reader :ch
196
- # attr_accessor :bodies, :headers, :footers
197
- # private :myputs, :myprint, :update_max_l, :update_subpad_size, :padh_refresh, :padb_refresh, :padf_refresh, :update_scroll
198
- # end
199
- #end