pastel 0.1.0 → 0.2.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: df0d822f2378510e2c8f751d179c208585fb2e38
4
- data.tar.gz: bf0a8a93193af9c35ff862e0e69373d97bf29d51
3
+ metadata.gz: eab704ae6d2747d9d0fc40eb19843f91c7dfb331
4
+ data.tar.gz: f51ab97939b6375f973c16d0215398dd6ad9c97f
5
5
  SHA512:
6
- metadata.gz: 7dcf28176858eeaccc03eb33d702214274e72d32082887d66938afa1f7d6f38b24fa7523437ed4249d51e6c7425db729e42ad50cd83daf0747ea953abb96157c
7
- data.tar.gz: c6a17854cb0c7328474da74d4c8ffee8f0af6c757f729bbef91ec02da7202e91d4da108ef318be8dcf4ab51e1fa20a9985cd8e3ed35c4f5f50db3de7e888488d
6
+ metadata.gz: c26988ce864c70a9bb5e23de8d85895e69d2449dbf09a8f5d611e92187b7f64ca02fb1ada0f29a9c0fbf1576e44248be5fff5d06dcd775fb36262a4bb98aa8d1
7
+ data.tar.gz: 29401a138ed3646c77d3b85f49a772266c4acc1662c57d3cd1ae91d8149c1b783e33c262cc5465e73d1b422bb36ded104720d8b13604e580ee9c1ab6d1e7769c
data/CHANGELOG.md ADDED
@@ -0,0 +1,6 @@
1
+ 0.2.0 (October 12, 2014)
2
+
3
+ * Change gemspec to include equatable as dependency
4
+ * Add #supports? to Color to check for terminal color support
5
+ * Add ability to force color support through :enabled option
6
+ * Change Delegator to stop creating instances and improve performance
data/README.md CHANGED
@@ -11,6 +11,8 @@ Terminal output styling with intuitive and clean API that doesn't monkey patch S
11
11
 
12
12
  **Pastel** is minimal and focused to work in all terminal emulators.
13
13
 
14
+ ![screenshot](https://github.com/peter-murach/pastel/raw/master/assets/screenshot.png)
15
+
14
16
  ## Features
15
17
 
16
18
  * Doesn't monkey patch `String`
@@ -42,6 +44,7 @@ Or install it yourself as:
42
44
  * [2.3 Strip](#23-strip)
43
45
  * [2.4 Styles](#24-styles)
44
46
  * [2.5 Valid?](#25-valid)
47
+ * [2.6 Enabled?](#26-enabled)
45
48
  * [3. The available styles](#3-the-available-styles)
46
49
 
47
50
  ## 1 Usage
@@ -66,7 +69,7 @@ You can compose multiple styles through chainable API:
66
69
  pastel.red.on_green.bold('Unicorns!')
67
70
  ```
68
71
 
69
- It supports variable number of arguments with individual styling:
72
+ It supports variable number of arguments:
70
73
 
71
74
  ```ruby
72
75
  pastel.red('Unicorns', 'are', 'running', 'everywhere!')
@@ -85,7 +88,7 @@ pastel.red('Unicorns ', pastel.on_green('everywhere!'))
85
88
  You can pass variable number of styled strings like so:
86
89
 
87
90
  ```ruby
88
- pastel.red('Unicorns', pastel.on_yellow('are running', pastel.bold.underline('everywhere')), '!')
91
+ pastel.red('Unicorns ', pastel.bold.underline('everywhere'), '!')
89
92
  ```
90
93
 
91
94
  Please refer to [3. The available styles](#3-the-available-styles) section for full list of supported styles.
@@ -123,6 +126,21 @@ pastel.valid?(:red) # => true
123
126
  pastel.valid?(:unicorn) # => false
124
127
  ```
125
128
 
129
+ ### 2.6 Enabled?
130
+
131
+ In order to detect if your terminal supports coloring do:
132
+
133
+ ```ruby
134
+ pastel.enabled? # => false
135
+ ```
136
+
137
+ In cases when the color support is not provided no styling will be applied to the colored string. Moreover, you can force **Pastel** to always print out string with coloring switched on:
138
+
139
+ ```ruby
140
+ pastel = Pastel.new(enabled: true)
141
+ pastel.enabled? # => false
142
+ ```
143
+
126
144
  ## 3 The available styles
127
145
 
128
146
  **Pastel** works with terminal emulators that support minimum sixteen colors. It provides `16` basic colors and `8` styles with further `16` bright color pairs. The corresponding bright color is obtained by prepending the `bright` to the normal color name. For example, color `red` will have `bright_red` as its pair.
Binary file
data/lib/pastel.rb CHANGED
@@ -12,8 +12,18 @@ module Pastel
12
12
  # Raised when the style attribute is not supported
13
13
  InvalidAttributeNameError = Class.new(::ArgumentError)
14
14
 
15
- def new
16
- Delegator.for(DecoratorChain.empty)
15
+ # Create Pastel chainable API
16
+ #
17
+ # @example
18
+ # pastel = Pastel.new enabled: true
19
+ #
20
+ # @return [Delegator]
21
+ #
22
+ # @api public
23
+ def new(options = {})
24
+ color = Color.new(options)
25
+ resolver = ColorResolver.new(color)
26
+ Delegator.for(resolver, DecoratorChain.empty)
17
27
  end
18
28
 
19
29
  module_function :new
data/lib/pastel/ansi.rb CHANGED
@@ -30,6 +30,7 @@ module Pastel
30
30
  BRIGHT_BLUE = "\e[94m"
31
31
  BRIGHT_MAGENTA = "\e[95m"
32
32
  BRIGHT_CYAN = "\e[96m"
33
+ BRIGHT_WHITE = "\e[97m"
33
34
 
34
35
  # Escape codes for background color.
35
36
  ON_BLACK = "\e[40m"
@@ -48,6 +49,7 @@ module Pastel
48
49
  ON_BRIGHT_BLUE = "\e[104m"
49
50
  ON_BRIGHT_MAGENTA = "\e[105m"
50
51
  ON_BRIGHT_CYAN = "\e[106m"
52
+ ON_BRIGHT_WHITE = "\e[107m"
51
53
 
52
54
  BACKGROUND_COLORS = constants.grep(/^ON_*/).freeze
53
55
  end # ANSI
data/lib/pastel/color.rb CHANGED
@@ -7,12 +7,13 @@ module Pastel
7
7
  include ANSI
8
8
 
9
9
  attr_reader :enabled
10
+ alias_method :enabled?, :enabled
10
11
 
11
12
  # Initialize a Terminal Color
12
13
  #
13
14
  # @api public
14
- def initialize(enabled = false)
15
- @enabled = enabled
15
+ def initialize(options = {})
16
+ @enabled = options.fetch(:enabled) { supports? }
16
17
  end
17
18
 
18
19
  # Disable coloring of this terminal session
@@ -22,6 +23,22 @@ module Pastel
22
23
  @enabled = false
23
24
  end
24
25
 
26
+ # Detect terminal color support
27
+ #
28
+ # @return [Boolean]
29
+ # true when terminal supports color, false otherwise
30
+ #
31
+ # @api public
32
+ def supports?
33
+ return false unless $stdout.tty?
34
+ return false if ENV['TERM'] == 'dumb'
35
+ if ENV['TERM'] =~ /^screen|^xterm|^vt100|color|ansi|cygwin|linux/i
36
+ return true
37
+ end
38
+ return true if ENV.include?('COLORTERM')
39
+ true
40
+ end
41
+
25
42
  # Apply ANSI color to the given string.
26
43
  #
27
44
  # @param [String] string
@@ -36,7 +53,7 @@ module Pastel
36
53
  #
37
54
  # @api public
38
55
  def decorate(string, *colors)
39
- return string if string.empty?
56
+ return string if string.empty? || !enabled
40
57
  validate(*colors)
41
58
  ansi_colors = colors.map { |color| lookup(color) }
42
59
  ansi_string = "#{ansi_colors.join}#{string}#{ANSI::CLEAR}"
@@ -9,6 +9,11 @@ module Pastel
9
9
  class ColorResolver
10
10
  attr_reader :color
11
11
 
12
+ # Initialize ColorResolver
13
+ #
14
+ # @param [Color] color
15
+ #
16
+ # @api private
12
17
  def initialize(color = Color.new)
13
18
  @color = color
14
19
  end
@@ -7,29 +7,33 @@ module Pastel
7
7
  # @api private
8
8
  class Delegator
9
9
  extend Forwardable
10
+ include Equatable
10
11
 
11
- attr_reader :base
12
-
13
- attr_reader :resolver
12
+ def_delegators '@resolver.color', :valid?, :styles, :strip, :decorate, :enabled?
14
13
 
15
- def_delegators :@color, :valid?, :styles, :strip, :decorate
16
-
17
- def initialize(base)
18
- @base = base
19
- @color = Color.new
20
- @resolver = ColorResolver.new(@color)
14
+ def initialize(resolver, base)
15
+ @resolver = resolver
16
+ @base = base
21
17
  end
22
18
 
23
19
  # @api public
24
- def self.for(value)
25
- new(value)
20
+ def self.for(resolver, base)
21
+ new(resolver, base)
26
22
  end
27
23
 
28
24
  protected
29
25
 
26
+ attr_reader :base
27
+
28
+ attr_reader :resolver
29
+
30
+ def wrap(base)
31
+ self.class.new(resolver, base)
32
+ end
33
+
30
34
  def method_missing(method_name, *args, &block)
31
35
  new_base = base.add(method_name)
32
- delegator = self.class.new(new_base)
36
+ delegator = wrap(new_base)
33
37
  if args.empty?
34
38
  delegator
35
39
  else
@@ -38,7 +42,7 @@ module Pastel
38
42
  end
39
43
 
40
44
  def respond_to_missing?(name, include_all = false)
41
- super || @color.respond_to?(name, include_all)
45
+ super || @resolver.color.respond_to?(name, include_all)
42
46
  end
43
47
  end # Delegator
44
48
  end # Pastel
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
2
 
3
3
  module Pastel
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
data/pastel.gemspec CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
+ spec.add_dependency "equatable", "~> 0.5"
22
+
21
23
  spec.add_development_dependency "bundler", "~> 1.6"
22
- spec.add_development_dependency "equatable", "~> 0.5"
23
24
  end
@@ -5,7 +5,7 @@ require 'spec_helper'
5
5
  RSpec.describe Pastel::Color, '.code' do
6
6
  let(:string) { "This is a \e[1m\e[34mbold blue text\e[0m" }
7
7
 
8
- subject(:color) { described_class.new }
8
+ subject(:color) { described_class.new(enabled: true) }
9
9
 
10
10
  it 'finds single code' do
11
11
  expect(color.code(:black)).to eq(["\e[30m"])
@@ -5,7 +5,7 @@ require 'spec_helper'
5
5
  RSpec.describe Pastel::Color, '.decorate' do
6
6
  let(:string) { 'string' }
7
7
 
8
- subject(:color) { described_class.new }
8
+ subject(:color) { described_class.new(enabled: true) }
9
9
 
10
10
  it "doesn't apply styling to empty string" do
11
11
  expect(color.decorate('')).to eq('')
@@ -3,7 +3,7 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe Pastel::Color, '.strip' do
6
- let(:instance) { described_class.new }
6
+ let(:instance) { described_class.new(enabled: true) }
7
7
 
8
8
  subject(:color) { instance.strip(string) }
9
9
 
@@ -4,7 +4,7 @@ require 'spec_helper'
4
4
 
5
5
  RSpec.describe Pastel::Color do
6
6
 
7
- subject(:color) { described_class.new }
7
+ subject(:color) { described_class.new(enabled: true) }
8
8
 
9
9
  it "exposes all available style ANSI codes" do
10
10
  expect(color.styles[:red]).to eq("\e[31m")
@@ -0,0 +1,46 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Pastel::Color, '.supports?' do
6
+ it "isn't enabled for non tty terminal" do
7
+ allow($stdout).to receive(:tty?).and_return(false)
8
+ color = described_class.new
9
+
10
+ expect(color.enabled?).to eq(false)
11
+ expect(color.decorate("Unicorn", :red)).to eq("Unicorn")
12
+ end
13
+
14
+ it "isn't enabled for dumb terminal" do
15
+ allow($stdout).to receive(:tty?).and_return(true)
16
+ allow(ENV).to receive(:[]).with('TERM').and_return('dumb')
17
+ color = described_class.new
18
+
19
+ expect(color.enabled?).to eq(false)
20
+ end
21
+
22
+ it "is enabled for term with color support" do
23
+ allow($stdout).to receive(:tty?).and_return(true)
24
+ allow(ENV).to receive(:[]).with('TERM').and_return('xterm')
25
+ color = described_class.new
26
+
27
+ expect(color.enabled?).to eq(true)
28
+ end
29
+
30
+ it "is enabled for color terminal" do
31
+ allow($stdout).to receive(:tty?).and_return(true)
32
+ allow(ENV).to receive(:[]).with('TERM').and_return('unknown')
33
+ allow(ENV).to receive(:[]).with('COLORTERM').and_return(true)
34
+ color = described_class.new
35
+
36
+ expect(color.enabled?).to eq(true)
37
+ end
38
+
39
+ it "forces to be enabled with supports? check" do
40
+ color = described_class.new(enabled: false)
41
+ allow(color).to receive(:supports?)
42
+
43
+ expect(color.enabled?).to eq(false)
44
+ expect(color).to_not have_received(:supports?)
45
+ end
46
+ end
@@ -6,16 +6,18 @@ RSpec.describe Pastel::Delegator do
6
6
  describe ".respond_to_missing?" do
7
7
  context 'for a method defined on' do
8
8
  it "returns true" do
9
+ resolver = double(:resolver)
9
10
  chain = double(:chain)
10
- decorator = described_class.new(chain)
11
+ decorator = described_class.new(resolver, chain)
11
12
  expect(decorator.method(:styles)).not_to be_nil
12
13
  end
13
14
  end
14
15
 
15
16
  context "for an undefined method " do
16
17
  it "returns false" do
18
+ resolver = double(:resolver, color: true)
17
19
  chain = double(:chain)
18
- decorator = described_class.new(chain)
20
+ decorator = described_class.new(resolver, chain)
19
21
  expect { decorator.method(:unknown) }.to raise_error(NameError)
20
22
  end
21
23
  end
@@ -4,7 +4,7 @@ require 'spec_helper'
4
4
 
5
5
  RSpec.describe Pastel do
6
6
 
7
- subject(:pastel) { described_class.new }
7
+ subject(:pastel) { described_class.new(enabled: true) }
8
8
 
9
9
  describe 'coloring string' do
10
10
  it "doesn't apply styles to empty string" do
@@ -55,7 +55,11 @@ RSpec.describe Pastel do
55
55
  end
56
56
  end
57
57
 
58
- it "respond to styles method" do
59
- expect(pastel).to respond_to(:styles)
58
+ describe 'options passed in' do
59
+ it "receives enabled option" do
60
+ pastel = described_class.new(enabled: false)
61
+ expect(pastel.enabled?).to eq(false)
62
+ expect(pastel.red('Unicorn', pastel.green('!'))).to eq('Unicorn!')
63
+ end
60
64
  end
61
65
  end
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pastel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.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-10-11 00:00:00.000000000 Z
11
+ date: 2014-10-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bundler
14
+ name: equatable
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ~>
18
18
  - !ruby/object:Gem::Version
19
- version: '1.6'
20
- type: :development
19
+ version: '0.5'
20
+ type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ~>
25
25
  - !ruby/object:Gem::Version
26
- version: '1.6'
26
+ version: '0.5'
27
27
  - !ruby/object:Gem::Dependency
28
- name: equatable
28
+ name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ~>
32
32
  - !ruby/object:Gem::Version
33
- version: '0.5'
33
+ version: '1.6'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ~>
39
39
  - !ruby/object:Gem::Version
40
- version: '0.5'
40
+ version: '1.6'
41
41
  description: Terminal strings styling with intuitive and clean API.
42
42
  email:
43
43
  - ''
@@ -50,10 +50,12 @@ files:
50
50
  - .ruby-gemset
51
51
  - .ruby-version
52
52
  - .travis.yml
53
+ - CHANGELOG.md
53
54
  - Gemfile
54
55
  - LICENSE.txt
55
56
  - README.md
56
57
  - Rakefile
58
+ - assets/screenshot.png
57
59
  - lib/pastel.rb
58
60
  - lib/pastel/ansi.rb
59
61
  - lib/pastel/color.rb
@@ -67,6 +69,7 @@ files:
67
69
  - spec/unit/color/decorate_spec.rb
68
70
  - spec/unit/color/strip_spec.rb
69
71
  - spec/unit/color/styles_spec.rb
72
+ - spec/unit/color/supports_spec.rb
70
73
  - spec/unit/decorator_chain_spec.rb
71
74
  - spec/unit/delegator_spec.rb
72
75
  - spec/unit/new_spec.rb
@@ -103,6 +106,7 @@ test_files:
103
106
  - spec/unit/color/decorate_spec.rb
104
107
  - spec/unit/color/strip_spec.rb
105
108
  - spec/unit/color/styles_spec.rb
109
+ - spec/unit/color/supports_spec.rb
106
110
  - spec/unit/decorator_chain_spec.rb
107
111
  - spec/unit/delegator_spec.rb
108
112
  - spec/unit/new_spec.rb