pastel 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a3a74798586ce6f5429d3c76faad4e3445319463
4
- data.tar.gz: c2b581122d3029f273f29d5c6fcb9cbca064cc64
3
+ metadata.gz: 20dcaf43ced285d36ad7074808b52e6963e2da79
4
+ data.tar.gz: 592af5b9be60dbd781e909a3dc29222cfc68eef0
5
5
  SHA512:
6
- metadata.gz: c47eac8d882f22e8dc9c1217497ce9f4a2aea4371d523801e8c37261aad1fc9f03d8f2e7f45c7ab168f22c68621331e9201d7363d5ae357a129596110a7fa27c
7
- data.tar.gz: e7fdf3e1428864ad525fb50dfb3fe6f9f760ce7923d91af73b7f9df054f22e51dbc0db969cbd2def2bcce3b4d6b8337addbc0ac1b406395fb88bf106f5ae8434
6
+ metadata.gz: bf6a4be639512821cf4e990dbb0a6a15a4e0f009912161be8b9f429bf9287985baa02202378d80ae2b2d8b3de218319150b713f929ed6ec5fb17006e96a530e7
7
+ data.tar.gz: 204a5342e5b5e2e29d1cd50896db08c8d543467a18d0efac9cfe39a77536aca277f630a7716981aff33239b1a05cac2701d6644c0f224e232704b90eb6a62ba2
@@ -1,6 +1,12 @@
1
+ 0.4.0 (November 22, 2014)
2
+
3
+ * Fix Delegator#respond_to method to correctly report existence of methods
4
+ * Add ability to #detach color combination for later reuse
5
+ * Add ability to nest styles with blocks
6
+
1
7
  0.3.0 (November 8, 2014)
2
8
 
3
- * Add ability to alias colors through alias_color method
9
+ * Add ability to alias colors through #alias_color method
4
10
  * Add ability to alias colors through the environment variable
5
11
  * Improve performance of Pastel::Color styles and lookup methods
6
12
  * Fix bug concerned with lack of escaping for nested styles
data/README.md CHANGED
@@ -2,12 +2,14 @@
2
2
  [![Gem Version](https://badge.fury.io/rb/pastel.png)][gem]
3
3
  [![Build Status](https://secure.travis-ci.org/peter-murach/pastel.png?branch=master)][travis]
4
4
  [![Code Climate](https://codeclimate.com/github/peter-murach/pastel.png)][codeclimate]
5
+ [![Coverage Status](https://coveralls.io/repos/peter-murach/pastel/badge.png)][coverage]
5
6
 
6
7
  [gem]: http://badge.fury.io/rb/pastel
7
8
  [travis]: http://travis-ci.org/peter-murach/pastel
8
9
  [codeclimate]: https://codeclimate.com/github/peter-murach/pastel
10
+ [coverage]: https://coveralls.io/r/peter-murach/pastel
9
11
 
10
- Terminal output styling with intuitive and clean API that doesn't monkey patch String class.
12
+ > Terminal output styling with intuitive and clean API that doesn't monkey patch String class.
11
13
 
12
14
  **Pastel** is minimal and focused to work in all terminal emulators.
13
15
 
@@ -43,11 +45,12 @@ Or install it yourself as:
43
45
  * [2. Interface](#2-interface)
44
46
  * [2.1 Color](#21-color)
45
47
  * [2.2 Decorate](#22-decorate)
46
- * [2.3 Strip](#23-strip)
47
- * [2.4 Styles](#24-styles)
48
- * [2.5 Valid?](#25-valid)
49
- * [2.6 Enabled?](#26-enabled)
50
- * [2.7 Alias Color](#27-alias-color)
48
+ * [2.3 Detach](#23-detach)
49
+ * [2.4 Strip](#24-strip)
50
+ * [2.5 Styles](#25-styles)
51
+ * [2.6 Valid?](#26-valid)
52
+ * [2.7 Enabled?](#27-enabled)
53
+ * [2.8 Alias Color](#28-alias-color)
51
54
  * [3. Supported Colors](#3-supported-colors)
52
55
  * [4. Environment](#4-environment)
53
56
 
@@ -58,19 +61,19 @@ Or install it yourself as:
58
61
  ```ruby
59
62
  pastel = Pastel.new
60
63
 
61
- pastel.red('Unicorns!')
64
+ puts pastel.red('Unicorns!')
62
65
  ```
63
66
 
64
- It allows you to combine styled strings with regular ones:
67
+ You can compose multiple styles through chainable API:
65
68
 
66
69
  ```ruby
67
- pastel.red('Unicorns') + ' will rule ' + pastel.green('the World!')
70
+ pastel.red.on_green.bold('Unicorns!')
68
71
  ```
69
72
 
70
- You can compose multiple styles through chainable API:
73
+ It allows you to combine styled strings with unstyled ones:
71
74
 
72
75
  ```ruby
73
- pastel.red.on_green.bold('Unicorns!')
76
+ pastel.red('Unicorns') + ' will rule ' + pastel.green('the World!')
74
77
  ```
75
78
 
76
79
  It supports variable number of arguments:
@@ -85,6 +88,32 @@ You can also nest styles as follows:
85
88
  pastel.red('Unicorns ', pastel.on_green('everywhere!'))
86
89
  ```
87
90
 
91
+ Nesting is smart enough to know where one color ends and another one starts:
92
+
93
+ ```ruby
94
+ pastel.red('Unicorns ' + pastel.green('everywhere') + pastel.on_yellow('!'))
95
+ ```
96
+
97
+ You can also nest styles inside blocks:
98
+
99
+ ```ruby
100
+ pastel.red.on_green('Unicorns') {
101
+ green.on_red('will ', 'dominate') {
102
+ yellow('the world!')
103
+ }
104
+ }
105
+ ```
106
+
107
+ You can also predefine needed styles and reuse them:
108
+
109
+ ```ruby
110
+ error = pastel.red.on_bold.detach
111
+ warning = pastel.yellow.detach
112
+
113
+ puts error('Error!')
114
+ puts warning('Warning')
115
+ ```
116
+
88
117
  ## 2 Interface
89
118
 
90
119
  ### 2.1 Color
@@ -107,15 +136,25 @@ pastel.decorate('Unicorn', :green, :on_blue, :bold)
107
136
 
108
137
  This method will be useful in situations where colors are provided as a list of parameters.
109
138
 
110
- ### 2.3 Strip
139
+ ### 2.3 Detach
140
+
141
+ The `detach` method allows to keep all the coloring for later reference. This method is useful when detached colors are being resued frequently and thus shorthand version is preferred.
142
+
143
+ ```ruby
144
+ notice = pastel.blue.bold.detach
145
+ puts notice.call('Unicorns running')
146
+ puts notice.call('They are super wild')
147
+ ```
148
+
149
+ ### 2.4 Strip
111
150
 
112
151
  Strip all color sequence characters from the provided strings. The return value will be eithre array of modified strings or a single string. The arguments are not modified.
113
152
 
114
153
  ```ruby
115
- pastel.strip("\e[1m\e[34mbold blue text\e[0m"") # => "bold blue text"
154
+ pastel.strip("\e[1m\e[34mbold blue text\e[0m") # => "bold blue text"
116
155
  ```
117
156
 
118
- ### 2.4 Styles
157
+ ### 2.5 Styles
119
158
 
120
159
  To get a full list of supported styles with the corresponding color codes do:
121
160
 
@@ -123,7 +162,7 @@ To get a full list of supported styles with the corresponding color codes do:
123
162
  pastel.styles
124
163
  ```
125
164
 
126
- ### 2.5 Valid?
165
+ ### 2.6 Valid?
127
166
 
128
167
  Determine whether a color or a list of colors are valid. `valid?` takes one or more attribute strings or symbols and returns true if all attributes are known and false otherwise.
129
168
 
@@ -132,7 +171,7 @@ pastel.valid?(:red, :blue) # => true
132
171
  pastel.valid?(:unicorn) # => false
133
172
  ```
134
173
 
135
- ### 2.6 Enabled?
174
+ ### 2.7 Enabled?
136
175
 
137
176
  In order to detect if your terminal supports coloring do:
138
177
 
@@ -147,7 +186,7 @@ pastel = Pastel.new(enabled: true)
147
186
  pastel.enabled? # => false
148
187
  ```
149
188
 
150
- ### 2.7 Alias Color
189
+ ### 2.8 Alias Color
151
190
 
152
191
  In order to setup an alias for the standard color do:
153
192
 
@@ -231,7 +270,7 @@ This environment variable allows you to specify custom color aliases at runtime
231
270
  Only alphanumeric and `_` are allowed in the alias names with the following format:
232
271
 
233
272
  ```ruby
234
- PASTEL_COLORS_ALIASES='newcolor_1=red,newcolor_2=on_gree'
273
+ PASTEL_COLORS_ALIASES='newcolor_1=red,newcolor_2=on_green'
235
274
  ```
236
275
 
237
276
  ## Contributing
@@ -0,0 +1,26 @@
1
+ require 'pastel'
2
+ require 'benchmark/ips'
3
+
4
+ pastel = Pastel.new
5
+
6
+ Benchmark.ips do |bench|
7
+ bench.config(time: 5, warmup: 2)
8
+
9
+ bench.report('regular nesting') do
10
+ pastel.red.on_green('Unicorns' +
11
+ pastel.green.on_red('will ', 'dominate' + pastel.yellow('the world!')))
12
+ end
13
+
14
+ bench.report('block nesting') do
15
+ pastel.red.on_green('Unicorns') do
16
+ green.on_red('will ', 'dominate') do
17
+ yellow('the world!')
18
+ end
19
+ end
20
+ end
21
+
22
+ bench.compare!
23
+ end
24
+
25
+ # regular nesting: 2800/s
26
+ # block nesting: 2600/s
@@ -6,11 +6,16 @@ pastel = Pastel.new
6
6
  Benchmark.ips do |bench|
7
7
  bench.config(time: 5, warmup: 2)
8
8
 
9
- bench.report('styles') do
10
- pastel.styles
9
+ bench.report('color decorate') do
10
+ pastel.decorate('string', :red, :on_green, :bold)
11
11
  end
12
12
 
13
- bench.report('decorate') do
14
- pastel.decorate('string', :red, :on_green, :bold)
13
+ bench.report('dsl styling') do
14
+ pastel.red.on_green.bold('string')
15
15
  end
16
+
17
+ bench.compare!
16
18
  end
19
+
20
+ # color decorate: 14K/s
21
+ # dsl styling: 10K/s
@@ -8,6 +8,7 @@ require 'pastel/alias_importer'
8
8
  require 'pastel/color'
9
9
  require 'pastel/color_resolver'
10
10
  require 'pastel/delegator'
11
+ require 'pastel/detached'
11
12
  require 'pastel/decorator_chain'
12
13
  require 'pastel/version'
13
14
 
@@ -21,9 +21,12 @@ module Pastel
21
21
  # Resolve uncolored string
22
22
  #
23
23
  # @api private
24
- def resolve(base, *args)
25
- unprocessed_string = args.join
26
- color.decorate(unprocessed_string, *base)
24
+ def resolve(base, unprocessed_string)
25
+ if base.to_a.last == :detach
26
+ Detached.new(color, *base.to_a[0...-1])
27
+ else
28
+ color.decorate(unprocessed_string, *base)
29
+ end
27
30
  end
28
31
  end # ColorResolver
29
32
  end # Pastel
@@ -8,8 +8,6 @@ module Pastel
8
8
  include Enumerable
9
9
  include Equatable
10
10
 
11
- attr_reader :decorators
12
-
13
11
  def initialize(decorators = [])
14
12
  @decorators = decorators
15
13
  end
@@ -36,5 +34,9 @@ module Pastel
36
34
  def self.empty
37
35
  new([])
38
36
  end
37
+
38
+ protected
39
+
40
+ attr_reader :decorators
39
41
  end # DecoratorChain
40
42
  end # Patel
@@ -44,6 +44,9 @@ module Pastel
44
44
 
45
45
  attr_reader :resolver
46
46
 
47
+ # Wrap colors
48
+ #
49
+ # @api private
47
50
  def wrap(base)
48
51
  self.class.new(resolver, base)
49
52
  end
@@ -51,15 +54,25 @@ module Pastel
51
54
  def method_missing(method_name, *args, &block)
52
55
  new_base = base.add(method_name)
53
56
  delegator = wrap(new_base)
54
- if args.empty?
57
+ if args.empty? && !(method_name.to_sym == :detach)
55
58
  delegator
56
59
  else
57
- resolver.resolve(new_base, *args)
60
+ string = args.join
61
+ string << evaluate_block(&block) if block_given?
62
+ resolver.resolve(new_base, string)
58
63
  end
59
64
  end
60
65
 
61
66
  def respond_to_missing?(name, include_all = false)
62
- super || @resolver.color.respond_to?(name, include_all)
67
+ resolver.color.respond_to?(name, include_all) || valid?(name) || super
68
+ end
69
+
70
+ # Evaluate color block
71
+ #
72
+ # @api private
73
+ def evaluate_block(&block)
74
+ delegator = self.class.new(resolver, DecoratorChain.empty)
75
+ delegator.instance_eval(&block)
63
76
  end
64
77
  end # Delegator
65
78
  end # Pastel
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+
3
+ module Pastel
4
+ # A class representing detached color
5
+ class Detached
6
+ include Equatable
7
+
8
+ def initialize(color, *styles)
9
+ @color = color
10
+ @styles = styles.dup
11
+ freeze
12
+ end
13
+
14
+ # Decorate the values corresponding to styles
15
+ #
16
+ # @example
17
+ #
18
+ # @param [String] value
19
+ # the stirng to decorate with styles
20
+ #
21
+ # @return [String]
22
+ #
23
+ # @api public
24
+ def call(*args)
25
+ value = args.join
26
+ @color.decorate(value, *styles)
27
+ end
28
+
29
+ private
30
+
31
+ # @api private
32
+ attr_reader :styles
33
+ end # Detached
34
+ end # Pastel
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
2
 
3
3
  module Pastel
4
- VERSION = "0.3.0"
4
+ VERSION = "0.4.0"
5
5
  end
@@ -1,5 +1,20 @@
1
1
  # encoding: utf-8
2
2
 
3
+ if RUBY_VERSION > '1.9' and (ENV['COVERAGE'] || ENV['TRAVIS'])
4
+ require 'simplecov'
5
+ require 'coveralls'
6
+
7
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
8
+ SimpleCov::Formatter::HTMLFormatter,
9
+ Coveralls::SimpleCov::Formatter
10
+ ]
11
+
12
+ SimpleCov.start do
13
+ command_name 'spec'
14
+ add_filter 'spec'
15
+ end
16
+ end
17
+
3
18
  require 'pastel'
4
19
 
5
20
  RSpec.configure do |config|
@@ -7,6 +7,11 @@ RSpec.describe Pastel::Color, '.decorate' do
7
7
 
8
8
  subject(:color) { described_class.new(enabled: true) }
9
9
 
10
+ it "doesn't output styling when disabled" do
11
+ color = described_class.new(enabled: false)
12
+ expect(color.decorate('foo', :red)).to eq('foo')
13
+ end
14
+
10
15
  it "doesn't apply styling to empty string" do
11
16
  expect(color.decorate('')).to eq('')
12
17
  end
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Pastel, '.detach' do
6
+
7
+ subject(:pastel) { described_class.new(enabled: true) }
8
+
9
+ it "detaches colors combination" do
10
+ error = pastel.red.bold.detach
11
+ expect(error.call('unicorn')).to eq("\e[31;1municorn\e[0m")
12
+ expect(error.call('error')).to eq("\e[31;1merror\e[0m")
13
+ end
14
+
15
+ it "calls detached colors with no arguments" do
16
+ warning = pastel.yellow.detach
17
+ expect(warning.call('')).to eq('')
18
+ end
19
+
20
+ it "inspects detached colors" do
21
+ warning = pastel.yellow.bold.detach
22
+ expect(warning.inspect).to eq('#<Pastel::Detached styles=[:yellow, :bold]>')
23
+ end
24
+
25
+ it "accepts multiple strings" do
26
+ error = pastel.red.bold.detach
27
+ expect(error.call('Unicorns', ' run ', 'wild')).
28
+ to eq("\e[31;1mUnicorns run wild\e[0m")
29
+ end
30
+ end
@@ -59,6 +59,17 @@ RSpec.describe Pastel do
59
59
  to eq("\e[31mr\e[32mg\e[31mr\e[0m")
60
60
  end
61
61
 
62
+ it "allows to nest styles within block" do
63
+ string = pastel.red.on_green('Unicorns' +
64
+ pastel.green.on_red('will ', 'dominate' + pastel.yellow('the world!')))
65
+
66
+ expect(pastel.red.on_green('Unicorns') do
67
+ green.on_red('will ', 'dominate') do
68
+ yellow('the world!')
69
+ end
70
+ end).to eq(string)
71
+ end
72
+
62
73
  it "raises error when chained with unrecognized color" do
63
74
  expect {
64
75
  pastel.unknown.on_red('unicorn')
@@ -0,0 +1,19 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Pastel, '.respond_to?' do
6
+ subject(:pastel) { described_class.new(enabled: true) }
7
+
8
+ it "responds correctly to color method" do
9
+ expect(pastel.respond_to?(:decorate)).to eq(true)
10
+ end
11
+
12
+ it "responds correctly to color property" do
13
+ expect(pastel.respond_to?(:red)).to eq(true)
14
+ end
15
+
16
+ it "responds correctly to unkown method" do
17
+ expect(pastel.respond_to?(:unknown)).to eq(false)
18
+ end
19
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pastel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Murach
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-08 00:00:00.000000000 Z
11
+ date: 2014-11-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: equatable
@@ -56,6 +56,7 @@ files:
56
56
  - README.md
57
57
  - Rakefile
58
58
  - assets/screenshot.png
59
+ - benchmarks/nesting_speed.rb
59
60
  - benchmarks/speed.rb
60
61
  - lib/pastel.rb
61
62
  - lib/pastel/alias_importer.rb
@@ -64,6 +65,7 @@ files:
64
65
  - lib/pastel/color_resolver.rb
65
66
  - lib/pastel/decorator_chain.rb
66
67
  - lib/pastel/delegator.rb
68
+ - lib/pastel/detached.rb
67
69
  - lib/pastel/version.rb
68
70
  - pastel.gemspec
69
71
  - spec/spec_helper.rb
@@ -77,7 +79,9 @@ files:
77
79
  - spec/unit/color/supports_spec.rb
78
80
  - spec/unit/decorator_chain_spec.rb
79
81
  - spec/unit/delegator_spec.rb
82
+ - spec/unit/detach_spec.rb
80
83
  - spec/unit/new_spec.rb
84
+ - spec/unit/respond_to_spec.rb
81
85
  - tasks/console.rake
82
86
  - tasks/coverage.rake
83
87
  - tasks/spec.rake
@@ -117,5 +121,7 @@ test_files:
117
121
  - spec/unit/color/supports_spec.rb
118
122
  - spec/unit/decorator_chain_spec.rb
119
123
  - spec/unit/delegator_spec.rb
124
+ - spec/unit/detach_spec.rb
120
125
  - spec/unit/new_spec.rb
126
+ - spec/unit/respond_to_spec.rb
121
127
  has_rdoc: