console-glitter 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c6dc7f133fc08089409ca94c2faccc434cfadc80
4
+ data.tar.gz: e7ded778c22128e5378af28f24c1463cc8616aed
5
+ SHA512:
6
+ metadata.gz: fd4af9e20d868a6159feb8f728df53b9ff45e84524054690df857fc2adbb2c7b0a6392e044ab2fbf41107769a25196779d6f34b9a939f95b132b352857c1ecb2
7
+ data.tar.gz: 29da738fc607e8016e35cc67118957141174407bbfc82dbccf68af8d99a635808ae79ec24ba1b7144a97e4cd0572150b555d1b232aa97d91ae59e95d201438ee
@@ -0,0 +1,152 @@
1
+ require 'console-glitter/version'
2
+ require 'console-glitter/ansi'
3
+
4
+ module ConsoleGlitter
5
+ module UI extend self
6
+ extend ANSI
7
+ # Public: Prompt user for input, allowing for a default answer and a list
8
+ # of valid responses to be provided.
9
+ #
10
+ # question - Query to be presented to the user.
11
+ # options - Hash containing arguments defining acceptable responses.
12
+ # (default: {}):
13
+ # :default_answer - String containing the default answer. If
14
+ # this is nil, a non-empty answer MUST be
15
+ # given.
16
+ # :allow_empty - Whether or not to allow empty responses.
17
+ # Unless explicitly allowed, empty answers
18
+ # will be rejected.
19
+ # :valid_answers - An Array containing all valid responses. If
20
+ # this is empty, any answer will be accepted
21
+ # (except empty answers as specified above).
22
+ #
23
+ # Returns a String containing the answer provided by the user.
24
+ def prompt(question, options = {})
25
+ default = options[:default_answer].to_s
26
+ allow_empty = options[:allow_empty]
27
+ valid = options[:valid_answers] || []
28
+
29
+ default_display = " [#{default.strip}]" unless default.empty?
30
+ question.strip!
31
+
32
+ answer = nil
33
+ while answer.nil?
34
+ print "#{question}#{default_display}> "
35
+ answer = $stdin.readline.strip
36
+ answer = default if answer.empty?
37
+
38
+ if answer.empty?
39
+ answer = nil unless allow_empty
40
+ elsif valid.any?
41
+ answer = nil unless valid.grep(answer).any?
42
+ end
43
+ end
44
+
45
+ answer
46
+ end
47
+
48
+ # Public: Wrap Console#prompt but accept only a Y/N response.
49
+ #
50
+ # question - String containing the question to present to the user.
51
+ # args - Hash containing arguments to control acceptable responses.
52
+ # (default: {}):
53
+ # :default_answer - String containing the default answer.
54
+ #
55
+ # Returns true or false corresponding to Y or N answer respectively.
56
+ def prompt_yn(question, args = {})
57
+ args[:valid_answers] = []
58
+ answer = nil
59
+
60
+ until answer =~ /^[yn]/i
61
+ answer = prompt(question, args)
62
+ end
63
+
64
+ /^n/i.match(answer).nil?
65
+ end
66
+
67
+ # Public: Render a "spinner" on the command line and yield to a block,
68
+ # reporting success if nothing is raised, or else reporting failure.
69
+ #
70
+ # message - Message to be displayed describing the task being evaluated.
71
+ # block - Block to be yielded to determine pass or fail.
72
+ #
73
+ # Returns the result of the yielded block if successful.
74
+ # Raises whatever is raised inside the yielded block.
75
+ def spinner(message, &block)
76
+ success = nil
77
+ result = nil
78
+
79
+ pre = "\r#{bold}#{white} [#{reset}"
80
+ post = "#{bold}#{white}] #{reset}#{message}"
81
+ pre_ok = "\r#{bold}#{white} [#{green} ok "
82
+ pre_fail = "\r#{bold}#{white} [#{red}fail"
83
+
84
+ thread = Thread.new do
85
+ step = 0
86
+ spin = [" ", ". ", ".. ", "... ", "....", " ...", " ..", " ."]
87
+ while success.nil?
88
+ print "#{pre}#{spin[step % 8]}#{post}"
89
+ step += 1
90
+ sleep 0.5
91
+ end
92
+
93
+ if success
94
+ print "#{pre_ok}#{post}\n"
95
+ else
96
+ print "#{pre_fail}#{post}\n"
97
+ end
98
+ end
99
+
100
+ begin
101
+ result = yield
102
+ success = true
103
+ thread.join
104
+ return result
105
+ rescue
106
+ success = false
107
+ thread.join
108
+ raise
109
+ end
110
+ end
111
+
112
+ # Public: Generate a formatted, printable table.
113
+ #
114
+ # rows - An Array containing Hashes which contain desired options to
115
+ # display. (e.g. [{"col1" => "a", "col2" => "b"}])
116
+ # labels - Hash containing key-value pairs to label each key in options.
117
+ # (default: nil)
118
+ #
119
+ # Returns a String containing the grid.
120
+ # Raises ArgumentError if anything but an Array is passed as rows.
121
+ def build_grid(rows, labels = nil)
122
+ if labels.nil?
123
+ labels = rows[0].keys.reduce({}) { |c,e| c.merge({e => e}) }
124
+ end
125
+
126
+ keys = labels.keys
127
+
128
+ max_width = labels.reduce({}) do |c,e|
129
+ c.merge({e[0]=> ([labels] + rows).map { |r| r[e[0]].length }.max})
130
+ end
131
+
132
+ grid_rule = max_width.reduce('+') do |c,e|
133
+ c + ('-' * (e[1] + 2)) + '+'
134
+ end
135
+ grid_rule << "\n"
136
+
137
+ grid = grid_rule.dup
138
+ grid << keys.reduce('|') do |c,e|
139
+ c + " #{bold}% #{max_width[e]}s#{reset} |" % labels[e]
140
+ end
141
+ grid << "\n"
142
+
143
+ grid << rows.reduce(grid_rule) do |c,e|
144
+ content = keys.reduce('') do |s,k|
145
+ s + " % #{max_width[k]}s |" % e[k]
146
+ end
147
+ c + "|#{content}\n"
148
+ end
149
+ grid << grid_rule
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,148 @@
1
+ module ConsoleGlitter
2
+ module ANSI extend self
3
+ # Public: Return an appropriate escape sequence depending upon the current
4
+ # platform.
5
+ #
6
+ # sequence - Control code(s) to be escaped. Multiple codes may be chained,
7
+ # separated by ';'.
8
+ #
9
+ # Examples
10
+ #
11
+ # ConsoleGlitter::ANSI.escape 0
12
+ # # => "\033[0m"
13
+ #
14
+ # Returns a String.
15
+ def escape(sequence)
16
+ RUBY_PLATFORM =~ /win/i ? '' : "\033[#{sequence}m"
17
+ end
18
+
19
+ # Public: Generate an escape sequence to set the foreground color to an
20
+ # approximation of a 4 or 8 bit per channel hex RGB color a la CSS.
21
+ #
22
+ # color - String containing hex digits describing the color to convert.
23
+ # May be 4 or 8 bits per channel (3 or 6 characters long,
24
+ # respectively).
25
+ #
26
+ # Examples
27
+ #
28
+ # ConsoleGlitter::ANSI.hex_color("00FFFF")
29
+ # # => "\033[38;5;51m"
30
+ # ConsoleGlitter::ANSI.hex_color("F0F")
31
+ # # => "\033[38;5;201m"
32
+ #
33
+ # Returns the appropriate escape code as a Fixnum.
34
+ def hex_color(color)
35
+ escape [38, 5, closest(color)].join(';')
36
+ end
37
+
38
+ # Public: Generate an escape sequence to set the bg color to an
39
+ # approximation of a 4 or 8 bit per channel hex RGB color a la CSS.
40
+ #
41
+ # color - String containing hex digits describing the color to convert.
42
+ # May be 4 or 8 bits per channel (3 or 6 characters long,
43
+ # respectively).
44
+ #
45
+ # Examples
46
+ #
47
+ # ConsoleGlitter::ANSI.bg_hex_color("00FFFF")
48
+ # # => "\033[38;5;51m"
49
+ # ConsoleGlitter::ANSI.bg_hex_color("F0F")
50
+ # # => "\033[38;5;201m"
51
+ #
52
+ # Returns the appropriate escape code as a Fixnum.
53
+ def bg_hex_color(color)
54
+ escape [48, 5, closest(color)].join(';')
55
+ end
56
+
57
+ private
58
+
59
+ # Internal: Allow on-the-fly definition of ANSI control sequences. Methods
60
+ # are created for convenience which will either wrap the result of a block
61
+ # in the tag specified and a reset tag, or else simply return the code in
62
+ # question.
63
+ #
64
+ # name - String or Symbol containing the name of the constant to be
65
+ # defined.
66
+ # code - ANSI escape code to be saved.
67
+ #
68
+ # Returns nothing.
69
+ #
70
+ # Signature
71
+ #
72
+ # <name>(block)
73
+ #
74
+ # name - Name specified.
75
+ # block - Optional block to be evaluated, the result of which will placed
76
+ # in between the escape code specified.
77
+ def ansi(name, code)
78
+ code = escape(code)
79
+
80
+ define_method(name.to_sym) do |&block|
81
+ if block
82
+ "#{code}#{block.call}#{reset}"
83
+ else
84
+ code
85
+ end
86
+ end
87
+ end
88
+
89
+ # Internal: Parse a string describing either a 4 or 8 bit-per-channel color
90
+ # (similar to CSS formatting), matching it with the closest approximation
91
+ # for 256 color mode.
92
+ #
93
+ # color - String containing hex digits describing the color to convert.
94
+ # May be 4 or 8 bits per channel (3 or 6 characters long,
95
+ # respectively).
96
+ #
97
+ # Examples
98
+ #
99
+ # ConsoleGlitter::ANSI.closest("00FFFF")
100
+ # # => 51
101
+ # ConsoleGlitter::ANSI.closest("F0F")
102
+ # # => 201
103
+ #
104
+ # Returns the appropriate escape code as a Fixnum.
105
+ def closest(color)
106
+ bpc = 4
107
+ bpc *= 2 if color.length > 3
108
+ color = color.to_i(16)
109
+
110
+ blue = color % (1 << bpc)
111
+ green = ((color - blue) % (1 << (bpc * 2))) >> bpc
112
+ red = (color - (blue + green)) >> (bpc * 2)
113
+
114
+ # 216 (6**3) colors are mapped in 256 color mode (40 colors are otherwise
115
+ # reserved for normal and bold standard colors from 0x00 to 0x0f in
116
+ # addition to a 24 color gradient from black to white from 0xe8 - 0xff.)
117
+ [blue,green,red].each_with_index.map do |c,i|
118
+ (c/(((1 << bpc)-1)/5)) * 6**i
119
+ end.
120
+ reduce(&:+) + 0x10
121
+ end
122
+
123
+ # Define most common ANSI sequences
124
+ ansi :reset, 0
125
+ ansi :bold, 1
126
+ ansi :faint, 2
127
+ ansi :underline, 4
128
+ ansi :blink, 5
129
+
130
+ ansi :black, 30
131
+ ansi :red, 31
132
+ ansi :green, 32
133
+ ansi :brown, 33
134
+ ansi :blue, 34
135
+ ansi :magenta, 35
136
+ ansi :cyan, 36
137
+ ansi :white, 37
138
+
139
+ ansi :bg_black, 40
140
+ ansi :bg_red, 41
141
+ ansi :bg_green, 42
142
+ ansi :bg_brown, 43
143
+ ansi :bg_blue, 44
144
+ ansi :bg_magenta, 45
145
+ ansi :bg_cyan, 46
146
+ ansi :bg_white, 47
147
+ end
148
+ end
@@ -0,0 +1,3 @@
1
+ module ConsoleGlitter
2
+ VERSION = '0.1.0'
3
+ end
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: console-glitter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Chris Wuest
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-01-07 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Tools for building nice looking CLI applications
14
+ email: chris@chriswuest.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/console-glitter.rb
20
+ - lib/console-glitter/ansi.rb
21
+ - lib/console-glitter/version.rb
22
+ homepage: http://github.com/cwuest/console-glitter
23
+ licenses:
24
+ - MIT
25
+ metadata: {}
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubyforge_project:
42
+ rubygems_version: 2.0.5
43
+ signing_key:
44
+ specification_version: 4
45
+ summary: Tools for prettier CLI apps
46
+ test_files: []
47
+ has_rdoc: