pastel 0.6.1 → 0.8.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 +5 -5
- data/CHANGELOG.md +66 -12
- data/README.md +38 -29
- data/lib/pastel/alias_importer.rb +9 -7
- data/lib/pastel/ansi.rb +2 -2
- data/lib/pastel/color.rb +64 -24
- data/lib/pastel/color_parser.rb +24 -18
- data/lib/pastel/color_resolver.rb +3 -1
- data/lib/pastel/decorator_chain.rb +52 -8
- data/lib/pastel/delegator.rb +57 -26
- data/lib/pastel/detached.rb +41 -5
- data/lib/pastel/version.rb +2 -2
- data/lib/pastel.rb +17 -19
- metadata +35 -104
- data/.gitignore +0 -22
- data/.rspec +0 -3
- data/.travis.yml +0 -25
- data/Gemfile +0 -15
- data/Rakefile +0 -8
- data/assets/pastel_logo.png +0 -0
- data/assets/screenshot.png +0 -0
- data/benchmarks/nesting_speed.rb +0 -41
- data/benchmarks/speed.rb +0 -45
- data/examples/palette.rb +0 -14
- data/pastel.gemspec +0 -26
- data/spec/spec_helper.rb +0 -45
- data/spec/unit/alias_color_spec.rb +0 -24
- data/spec/unit/alias_importer_spec.rb +0 -29
- data/spec/unit/color/alias_color_spec.rb +0 -40
- data/spec/unit/color/code_spec.rb +0 -24
- data/spec/unit/color/colored_spec.rb +0 -15
- data/spec/unit/color/decorate_spec.rb +0 -79
- data/spec/unit/color/equal_spec.rb +0 -22
- data/spec/unit/color/lookup_spec.rb +0 -17
- data/spec/unit/color/new_spec.rb +0 -10
- data/spec/unit/color/strip_spec.rb +0 -56
- data/spec/unit/color/styles_spec.rb +0 -10
- data/spec/unit/color/valid_spec.rb +0 -19
- data/spec/unit/color_parser_spec.rb +0 -67
- data/spec/unit/decorate_dsl_spec.rb +0 -94
- data/spec/unit/decorator_chain_spec.rb +0 -47
- data/spec/unit/delegator_spec.rb +0 -38
- data/spec/unit/detach_spec.rb +0 -48
- data/spec/unit/new_spec.rb +0 -52
- data/spec/unit/respond_to_spec.rb +0 -17
- data/spec/unit/undecorate_spec.rb +0 -12
- data/tasks/console.rake +0 -10
- data/tasks/coverage.rake +0 -11
- data/tasks/spec.rake +0 -29
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: '06693f6ff4f804468ff3802df48c725067fb8eb425e9ba4301627f7c496099bb'
|
|
4
|
+
data.tar.gz: 0752767e8bbe626d683e5eb8b576f5c1229c322f72475d41b1041f4f15eb2c11
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2239724d8aa9165ec045a2f43b6b8ce336c35ad487bc9e5ca1a8005c0321c682a73fff711316710848fee9931790c47a72dc5469afda25e98975bf6c38a9dfc5
|
|
7
|
+
data.tar.gz: b8f59e4fa1c52973d91d41d4e3f8602da3b164a41125a7416c7f119f53f880e81f4d3a79ea52e25b4e9de4dcb338d37ff1045f9b7b4437056cb7dc1597ce87df
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,53 @@
|
|
|
1
1
|
# Change log
|
|
2
2
|
|
|
3
|
+
## [v0.8.0] - 2020-07-04
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
* Change gemspec to require Ruby 2.0 or higher
|
|
7
|
+
* Change Pastel#new to use keyword arguments in place of hash options
|
|
8
|
+
* Change to freeze all strings
|
|
9
|
+
* Remove equatable dependency
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
* Fix Pastel#strip to recognise no-number reset by DanielVartanov(@DanielVartanov)
|
|
13
|
+
* Fix Pastel#undecorate to correctly assign styles for nested colors
|
|
14
|
+
|
|
15
|
+
## [v0.7.4] - 2020-05-08
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
* Fix ColorParser#undecorate to require direct dependency by Nick Pezza(@npezza93)
|
|
19
|
+
|
|
20
|
+
## [v0.7.3] - 2019-06-16
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
* Change gemspec to load required files directly without git
|
|
24
|
+
* Change to update tty-color & equatable dependency versions
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
* Fix Delegator warning
|
|
28
|
+
|
|
29
|
+
## [v0.7.2] - 2017-11-09
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
* Change to load relative file paths
|
|
33
|
+
* Change to allow `#alias_color` to accept multiple colors by Jared Ning (@ordinaryzelig)
|
|
34
|
+
|
|
35
|
+
## [v0.7.1] - 2017-01-09
|
|
36
|
+
|
|
37
|
+
### Changed
|
|
38
|
+
* Change to load specific files when needed
|
|
39
|
+
* Change to freeze ANSI attributes
|
|
40
|
+
* Change to directly assign enabled attribute
|
|
41
|
+
|
|
42
|
+
## [v0.7.0] - 2016-12-27
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
* Enabled colors on Windows by default
|
|
46
|
+
* Update tty-color dependency
|
|
47
|
+
|
|
48
|
+
### Fixed
|
|
49
|
+
* Fix Color#decorate to prevent redecoration with the same color
|
|
50
|
+
|
|
3
51
|
## [v0.6.1] - 2016-04-09
|
|
4
52
|
|
|
5
53
|
### Fixed
|
|
@@ -8,7 +56,7 @@
|
|
|
8
56
|
## [v0.6.0] - 2016-01-15
|
|
9
57
|
|
|
10
58
|
### Added
|
|
11
|
-
* Add helper functions #foreground?, #
|
|
59
|
+
* Add helper functions #foreground?, #background?, #style to ANSI module
|
|
12
60
|
* Add ColorParser for parsing color symbols out of text
|
|
13
61
|
* Add Pastel#undecorate for parsing color names out of strings
|
|
14
62
|
|
|
@@ -86,14 +134,20 @@
|
|
|
86
134
|
* Change gemspec to include equatable as dependency
|
|
87
135
|
* Change Delegator to stop creating instances and improve performance
|
|
88
136
|
|
|
89
|
-
[v0.
|
|
90
|
-
[v0.
|
|
91
|
-
[v0.
|
|
92
|
-
[v0.
|
|
93
|
-
[v0.
|
|
94
|
-
[v0.
|
|
95
|
-
[v0.
|
|
96
|
-
[v0.
|
|
97
|
-
[v0.
|
|
98
|
-
[v0.2
|
|
99
|
-
[v0.1
|
|
137
|
+
[v0.8.0]: https://github.com/piotrmurach/pastel/compare/v0.7.4...v0.8.0
|
|
138
|
+
[v0.7.4]: https://github.com/piotrmurach/pastel/compare/v0.7.3...v0.7.4
|
|
139
|
+
[v0.7.3]: https://github.com/piotrmurach/pastel/compare/v0.7.2...v0.7.3
|
|
140
|
+
[v0.7.2]: https://github.com/piotrmurach/pastel/compare/v0.7.1...v0.7.2
|
|
141
|
+
[v0.7.1]: https://github.com/piotrmurach/pastel/compare/v0.7.0...v0.7.1
|
|
142
|
+
[v0.7.0]: https://github.com/piotrmurach/pastel/compare/v0.6.1...v0.7.0
|
|
143
|
+
[v0.6.1]: https://github.com/piotrmurach/pastel/compare/v0.6.0...v0.6.1
|
|
144
|
+
[v0.6.0]: https://github.com/piotrmurach/pastel/compare/v0.5.3...v0.6.0
|
|
145
|
+
[v0.5.3]: https://github.com/piotrmurach/pastel/compare/v0.5.2...v0.5.3
|
|
146
|
+
[v0.5.2]: https://github.com/piotrmurach/pastel/compare/v0.5.1...v0.5.2
|
|
147
|
+
[v0.5.1]: https://github.com/piotrmurach/pastel/compare/v0.5.0...v0.5.1
|
|
148
|
+
[v0.5.0]: https://github.com/piotrmurach/pastel/compare/v0.4.0...v0.5.0
|
|
149
|
+
[v0.4.0]: https://github.com/piotrmurach/pastel/compare/v0.3.0...v0.4.0
|
|
150
|
+
[v0.3.0]: https://github.com/piotrmurach/pastel/compare/v0.2.1...v0.3.0
|
|
151
|
+
[v0.2.1]: https://github.com/piotrmurach/pastel/compare/v0.2.0...v0.2.1
|
|
152
|
+
[v0.2.0]: https://github.com/piotrmurach/pastel/compare/v0.1.0...v0.2.0
|
|
153
|
+
[v0.1.0]: https://github.com/piotrmurach/pastel/compare/v0.1.0
|
data/README.md
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
<img width="215" src="https://cdn.rawgit.com/piotrmurach/pastel/master/assets/pastel_logo.png" alt="pastel logo" />
|
|
3
3
|
</div>
|
|
4
|
+
|
|
4
5
|
# Pastel
|
|
6
|
+
|
|
5
7
|
[][gem]
|
|
6
8
|
[][travis]
|
|
9
|
+
[][appveyor]
|
|
7
10
|
[][codeclimate]
|
|
8
11
|
[][coverage]
|
|
9
12
|
[][inchpages]
|
|
10
13
|
|
|
11
14
|
[gem]: http://badge.fury.io/rb/pastel
|
|
12
15
|
[travis]: http://travis-ci.org/piotrmurach/pastel
|
|
16
|
+
[appveyor]: https://ci.appveyor.com/project/piotrmurach/pastel
|
|
13
17
|
[codeclimate]: https://codeclimate.com/github/piotrmurach/pastel
|
|
14
18
|
[coverage]: https://coveralls.io/github/piotrmurach/pastel
|
|
15
19
|
[inchpages]: http://inch-ci.org/github/piotrmurach/pastel
|
|
@@ -35,7 +39,7 @@
|
|
|
35
39
|
|
|
36
40
|
Add this line to your application's Gemfile:
|
|
37
41
|
|
|
38
|
-
gem
|
|
42
|
+
gem "pastel"
|
|
39
43
|
|
|
40
44
|
And then execute:
|
|
41
45
|
|
|
@@ -72,7 +76,7 @@ Or install it yourself as:
|
|
|
72
76
|
```ruby
|
|
73
77
|
pastel = Pastel.new
|
|
74
78
|
|
|
75
|
-
puts pastel.red(
|
|
79
|
+
puts pastel.red("Unicorns!")
|
|
76
80
|
```
|
|
77
81
|
|
|
78
82
|
**Pastel** doesn't print the colored string out, just returns it, you'll have to print it yourself.
|
|
@@ -80,46 +84,46 @@ puts pastel.red('Unicorns!')
|
|
|
80
84
|
You can compose multiple styles through chainable API:
|
|
81
85
|
|
|
82
86
|
```ruby
|
|
83
|
-
pastel.red.on_green.bold(
|
|
87
|
+
pastel.red.on_green.bold("Unicorns!")
|
|
84
88
|
```
|
|
85
89
|
|
|
86
90
|
It allows you to combine styled strings with unstyled ones:
|
|
87
91
|
|
|
88
92
|
```ruby
|
|
89
|
-
pastel.red(
|
|
93
|
+
pastel.red("Unicorns") + " will rule " + pastel.green("the World!")
|
|
90
94
|
```
|
|
91
95
|
|
|
92
96
|
It supports variable number of arguments:
|
|
93
97
|
|
|
94
98
|
```ruby
|
|
95
|
-
pastel.red(
|
|
99
|
+
pastel.red("Unicorns", "are", "running", "everywhere!")
|
|
96
100
|
```
|
|
97
101
|
|
|
98
102
|
You can also nest styles as follows:
|
|
99
103
|
|
|
100
104
|
```ruby
|
|
101
|
-
pastel.red(
|
|
105
|
+
pastel.red("Unicorns ", pastel.on_green("everywhere!"))
|
|
102
106
|
```
|
|
103
107
|
|
|
104
108
|
Nesting is smart enough to know where one color ends and another one starts:
|
|
105
109
|
|
|
106
110
|
```ruby
|
|
107
|
-
pastel.red(
|
|
111
|
+
pastel.red("Unicorns " + pastel.green("everywhere") + pastel.on_yellow("!"))
|
|
108
112
|
```
|
|
109
113
|
|
|
110
114
|
You can also nest styles inside blocks:
|
|
111
115
|
|
|
112
116
|
```ruby
|
|
113
|
-
pastel.red.on_green(
|
|
114
|
-
green.on_red(
|
|
115
|
-
yellow(
|
|
117
|
+
pastel.red.on_green("Unicorns") {
|
|
118
|
+
green.on_red("will ", "dominate") {
|
|
119
|
+
yellow("the world!")
|
|
116
120
|
}
|
|
117
121
|
}
|
|
118
122
|
```
|
|
119
123
|
|
|
120
|
-
When dealing with multiline strings you can set `eachline` option(more info see [eachline](#
|
|
124
|
+
When dealing with multiline strings you can set `eachline` option(more info see [eachline](#211-eachline)):
|
|
121
125
|
|
|
122
|
-
```
|
|
126
|
+
```ruby
|
|
123
127
|
pastel = Pastel.new(eachline: "\n")
|
|
124
128
|
```
|
|
125
129
|
|
|
@@ -129,8 +133,8 @@ You can also predefine needed styles and reuse them:
|
|
|
129
133
|
error = pastel.red.bold.detach
|
|
130
134
|
warning = pastel.yellow.detach
|
|
131
135
|
|
|
132
|
-
puts error.(
|
|
133
|
-
puts warning.(
|
|
136
|
+
puts error.("Error!")
|
|
137
|
+
puts warning.("Warning")
|
|
134
138
|
```
|
|
135
139
|
|
|
136
140
|
If your output is redirected to a file, you probably don't want Pastel to add color to your text.
|
|
@@ -139,7 +143,7 @@ See https://github.com/piotrmurach/pastel#210-enabled for a way to easily accomp
|
|
|
139
143
|
**Pastel** has companion library called `pastel-cli` that allows you to style text in terminal via `pastel` executable:
|
|
140
144
|
|
|
141
145
|
```bash
|
|
142
|
-
$ pastel green
|
|
146
|
+
$ pastel green "Unicorns & rainbows!"
|
|
143
147
|
```
|
|
144
148
|
|
|
145
149
|
## 2 Interface
|
|
@@ -151,7 +155,7 @@ pastel.`<color>[.<color>...](string, [string...])`
|
|
|
151
155
|
Color styles are invoked as method calls with a string argument. A given color can take any number of strings as arguments. Then it returns a colored string which isn't printed out to terminal. You need to print it yourself if you need to. This is done so that you can save it as a string, pass to something else, send it to a file handle and so on.
|
|
152
156
|
|
|
153
157
|
```ruby
|
|
154
|
-
pastel.red(
|
|
158
|
+
pastel.red("Unicorns ", pastel.bold.underline("everywhere"), "!")
|
|
155
159
|
```
|
|
156
160
|
|
|
157
161
|
Please refer to [3. Supported Colors](#3-supported-colors) section for full list of supported styles.
|
|
@@ -161,7 +165,7 @@ Please refer to [3. Supported Colors](#3-supported-colors) section for full list
|
|
|
161
165
|
This method is a lower level string styling call that takes as the first argument the string to style followed by any number of color attributes, and returns string wrapped in styles.
|
|
162
166
|
|
|
163
167
|
```ruby
|
|
164
|
-
pastel.decorate(
|
|
168
|
+
pastel.decorate("Unicorn", :green, :on_blue, :bold)
|
|
165
169
|
```
|
|
166
170
|
|
|
167
171
|
This method will be useful in situations where colors are provided as a list of parameters that have been generated dynamically.
|
|
@@ -172,7 +176,7 @@ It performs the opposite to `decorate` method by turning color escape sequences
|
|
|
172
176
|
|
|
173
177
|
```ruby
|
|
174
178
|
pastel.undecorate("\e[32mfoo\e[0m \e[31mbar\e[0m")
|
|
175
|
-
# => [{foreground: :green, text:
|
|
179
|
+
# => [{foreground: :green, text: "foo"}, {text: " "}, {foreground: :red, text: "bar"}]
|
|
176
180
|
```
|
|
177
181
|
|
|
178
182
|
To translate the color name into sequence use [lookup](#27-lookup)
|
|
@@ -184,9 +188,9 @@ The `detach` method allows to keep all the associated colors with the detached i
|
|
|
184
188
|
```ruby
|
|
185
189
|
notice = pastel.blue.bold.detach
|
|
186
190
|
|
|
187
|
-
notice.call(
|
|
188
|
-
notice.(
|
|
189
|
-
notice[
|
|
191
|
+
notice.call("Unicorns running")
|
|
192
|
+
notice.("Unicorns running")
|
|
193
|
+
notice["Unicorns running"]
|
|
190
194
|
```
|
|
191
195
|
|
|
192
196
|
### 2.5 Strip
|
|
@@ -210,7 +214,8 @@ pastel.styles
|
|
|
210
214
|
To perform translation of color name into ansi escape code use `lookup`:
|
|
211
215
|
|
|
212
216
|
```ruby
|
|
213
|
-
|
|
217
|
+
pastel.lookup(:red) # => "\e[31m"
|
|
218
|
+
pastel.lookup(:reset) # => "\e[0m"
|
|
214
219
|
```
|
|
215
220
|
|
|
216
221
|
### 2.8 Valid?
|
|
@@ -264,16 +269,16 @@ pastel.red("foo\nbar") # => "\e[31mfoo\e[0m\n\e[31mbar\e[0m"
|
|
|
264
269
|
|
|
265
270
|
### 2.12 Alias Color
|
|
266
271
|
|
|
267
|
-
In order to setup an alias for
|
|
272
|
+
In order to setup an alias for standard colors do:
|
|
268
273
|
|
|
269
274
|
```ruby
|
|
270
|
-
pastel.alias_color(:funky, :red)
|
|
275
|
+
pastel.alias_color(:funky, :red, :bold)
|
|
271
276
|
```
|
|
272
277
|
|
|
273
|
-
From that point forward, `:funky` alias can be passed to `decorate`, `valid?` with the same meaning as standard
|
|
278
|
+
From that point forward, `:funky` alias can be passed to `decorate`, `valid?` with the same meaning as standard colors:
|
|
274
279
|
|
|
275
280
|
```ruby
|
|
276
|
-
pastel.funky.on_green(
|
|
281
|
+
pastel.funky.on_green("unicorn") # => will use :red, :bold color
|
|
277
282
|
```
|
|
278
283
|
|
|
279
284
|
This method allows you to give more meaningful names to existing colors.
|
|
@@ -343,10 +348,10 @@ Generic styles:
|
|
|
343
348
|
|
|
344
349
|
This environment variable allows you to specify custom color aliases at runtime that will be understood by **Pastel**. The environment variable is read and used when the instance of **Pastel** is created. You can also use `alias_color` to create aliases.
|
|
345
350
|
|
|
346
|
-
Only alphanumeric and `_` are allowed in the alias names with the following format:
|
|
351
|
+
Only alphanumeric and `_` and `.` are allowed in the alias names with the following format:
|
|
347
352
|
|
|
348
353
|
```ruby
|
|
349
|
-
PASTEL_COLORS_ALIASES=
|
|
354
|
+
PASTEL_COLORS_ALIASES="newcolor_1=red,newcolor_2=on_green,funky=red.bold"
|
|
350
355
|
```
|
|
351
356
|
|
|
352
357
|
## 5. Command line
|
|
@@ -365,6 +370,10 @@ $ pastel green 'Unicorns & rainbows!'
|
|
|
365
370
|
4. Push to the branch (`git push origin my-new-feature`)
|
|
366
371
|
5. Create a new Pull Request
|
|
367
372
|
|
|
373
|
+
## Code of Conduct
|
|
374
|
+
|
|
375
|
+
Everyone interacting in the Pastel project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/piotrmurach/pastel/blob/master/CODE_OF_CONDUCT.md).
|
|
376
|
+
|
|
368
377
|
## Copyright
|
|
369
378
|
|
|
370
|
-
Copyright (c) 2014
|
|
379
|
+
Copyright (c) 2014 Piotr Murach. See LICENSE for further details.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Pastel
|
|
4
4
|
# A class responsible for importing color aliases
|
|
@@ -18,21 +18,23 @@ module Pastel
|
|
|
18
18
|
# Import aliases from the environment
|
|
19
19
|
#
|
|
20
20
|
# @example
|
|
21
|
-
# importer = Pastel::AliasImporter.new(Pastel::Color.new)
|
|
21
|
+
# importer = Pastel::AliasImporter.new(Pastel::Color.new, {})
|
|
22
22
|
# importer.import
|
|
23
23
|
#
|
|
24
24
|
# @return [nil]
|
|
25
25
|
#
|
|
26
26
|
# @api public
|
|
27
27
|
def import
|
|
28
|
-
color_aliases = env[
|
|
28
|
+
color_aliases = env["PASTEL_COLORS_ALIASES"]
|
|
29
29
|
return unless color_aliases
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
|
|
31
|
+
color_aliases.split(",").each do |color_alias|
|
|
32
|
+
new_color, old_colors = color_alias.split("=")
|
|
33
|
+
if !new_color || !old_colors
|
|
33
34
|
output.puts "Bad color mapping `#{color_alias}`"
|
|
34
35
|
else
|
|
35
|
-
color.alias_color(new_color,
|
|
36
|
+
color.alias_color(new_color.to_sym,
|
|
37
|
+
*old_colors.split(".").map(&:to_sym))
|
|
36
38
|
end
|
|
37
39
|
end
|
|
38
40
|
end
|
data/lib/pastel/ansi.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Pastel
|
|
4
4
|
# Mixin that provides ANSI codes
|
|
@@ -51,7 +51,7 @@ module Pastel
|
|
|
51
51
|
on_bright_magenta: 105,
|
|
52
52
|
on_bright_cyan: 106,
|
|
53
53
|
on_bright_white: 107
|
|
54
|
-
}
|
|
54
|
+
}.freeze
|
|
55
55
|
|
|
56
56
|
module_function
|
|
57
57
|
|
data/lib/pastel/color.rb
CHANGED
|
@@ -1,28 +1,29 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "ansi"
|
|
2
4
|
|
|
3
5
|
module Pastel
|
|
4
6
|
# A class responsible for coloring strings.
|
|
5
7
|
class Color
|
|
6
|
-
include Equatable
|
|
7
8
|
include ANSI
|
|
8
9
|
|
|
9
10
|
# All color aliases
|
|
10
11
|
ALIASES = {}
|
|
11
12
|
|
|
12
13
|
# Match all color escape sequences
|
|
13
|
-
ANSI_COLOR_REGEXP = /\x1b
|
|
14
|
+
ANSI_COLOR_REGEXP = /\x1b\[{1,2}[0-9;:?]*m/mo.freeze
|
|
14
15
|
|
|
15
16
|
attr_reader :enabled
|
|
16
|
-
|
|
17
|
+
alias enabled? enabled
|
|
17
18
|
|
|
18
19
|
attr_reader :eachline
|
|
19
20
|
|
|
20
21
|
# Initialize a Terminal Color
|
|
21
22
|
#
|
|
22
23
|
# @api public
|
|
23
|
-
def initialize(
|
|
24
|
-
@enabled =
|
|
25
|
-
@eachline =
|
|
24
|
+
def initialize(enabled: nil, eachline: false)
|
|
25
|
+
@enabled = enabled
|
|
26
|
+
@eachline = eachline
|
|
26
27
|
@cache = {}
|
|
27
28
|
end
|
|
28
29
|
|
|
@@ -53,7 +54,7 @@ module Pastel
|
|
|
53
54
|
def decorate(string, *colors)
|
|
54
55
|
return string if blank?(string) || !enabled || colors.empty?
|
|
55
56
|
|
|
56
|
-
ansi_colors = lookup(*colors)
|
|
57
|
+
ansi_colors = lookup(*colors.dup.uniq)
|
|
57
58
|
if eachline
|
|
58
59
|
string.dup.split(eachline).map! do |line|
|
|
59
60
|
apply_codes(line, ansi_colors)
|
|
@@ -100,7 +101,7 @@ module Pastel
|
|
|
100
101
|
#
|
|
101
102
|
# @api public
|
|
102
103
|
def strip(*strings)
|
|
103
|
-
modified = strings.map { |string| string.dup.gsub(ANSI_COLOR_REGEXP,
|
|
104
|
+
modified = strings.map { |string| string.dup.gsub(ANSI_COLOR_REGEXP, "") }
|
|
104
105
|
modified.size == 1 ? modified[0] : modified
|
|
105
106
|
end
|
|
106
107
|
|
|
@@ -191,29 +192,67 @@ module Pastel
|
|
|
191
192
|
colors.all? { |color| style_names.include?(color.to_sym) }
|
|
192
193
|
end
|
|
193
194
|
|
|
194
|
-
# Define a new
|
|
195
|
+
# Define a new colors alias
|
|
195
196
|
#
|
|
196
197
|
# @param [String] alias_name
|
|
197
|
-
# the
|
|
198
|
-
# @param [String] color
|
|
199
|
-
# the
|
|
198
|
+
# the colors alias to define
|
|
199
|
+
# @param [Array[Symbol,String]] color
|
|
200
|
+
# the colors the alias will correspond to
|
|
200
201
|
#
|
|
201
|
-
# @return [String]
|
|
202
|
-
# the standard color
|
|
202
|
+
# @return [Array[String]]
|
|
203
|
+
# the standard color values of the alias
|
|
203
204
|
#
|
|
204
205
|
# @api public
|
|
205
|
-
def alias_color(alias_name,
|
|
206
|
-
validate(
|
|
206
|
+
def alias_color(alias_name, *colors)
|
|
207
|
+
validate(*colors)
|
|
207
208
|
|
|
208
209
|
if !(alias_name.to_s =~ /^[\w]+$/)
|
|
209
|
-
|
|
210
|
+
raise InvalidAliasNameError, "Invalid alias name `#{alias_name}`"
|
|
210
211
|
elsif ANSI::ATTRIBUTES[alias_name]
|
|
211
|
-
|
|
212
|
-
|
|
212
|
+
raise InvalidAliasNameError,
|
|
213
|
+
"Cannot alias standard color `#{alias_name}`"
|
|
213
214
|
end
|
|
214
215
|
|
|
215
|
-
ALIASES[alias_name.to_sym] = ANSI::ATTRIBUTES[
|
|
216
|
-
|
|
216
|
+
ALIASES[alias_name.to_sym] = colors.map(&ANSI::ATTRIBUTES.method(:[]))
|
|
217
|
+
colors
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# Compare colors for equality of attributes
|
|
221
|
+
#
|
|
222
|
+
# @return [Boolean]
|
|
223
|
+
#
|
|
224
|
+
# @api public
|
|
225
|
+
def eql?(other)
|
|
226
|
+
instance_of?(other.class) &&
|
|
227
|
+
enabled.eql?(other.enabled) && eachline.eql?(other.eachline)
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# Compare colors for equivalence of attributes
|
|
231
|
+
#
|
|
232
|
+
# @return [Boolean]
|
|
233
|
+
#
|
|
234
|
+
# @api public
|
|
235
|
+
def ==(other)
|
|
236
|
+
other.is_a?(self.class) &&
|
|
237
|
+
enabled == other.enabled && eachline == other.eachline
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
# Inspect this instance attributes
|
|
241
|
+
#
|
|
242
|
+
# @return [String]
|
|
243
|
+
#
|
|
244
|
+
# @api public
|
|
245
|
+
def inspect
|
|
246
|
+
"#<#{self.class.name} enabled=#{enabled.inspect} eachline=#{eachline.inspect}>"
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
# Hash for this instance and its attributes
|
|
250
|
+
#
|
|
251
|
+
# @return [Numeric]
|
|
252
|
+
#
|
|
253
|
+
# @api public
|
|
254
|
+
def hash
|
|
255
|
+
[self.class, enabled, eachline].hash
|
|
217
256
|
end
|
|
218
257
|
|
|
219
258
|
private
|
|
@@ -224,13 +263,14 @@ module Pastel
|
|
|
224
263
|
#
|
|
225
264
|
# @api private
|
|
226
265
|
def blank?(value)
|
|
227
|
-
value.nil? || !value.respond_to?(:to_str) || value.to_s ==
|
|
266
|
+
value.nil? || !value.respond_to?(:to_str) || value.to_s == ""
|
|
228
267
|
end
|
|
229
268
|
|
|
230
269
|
# @api private
|
|
231
270
|
def validate(*colors)
|
|
232
271
|
return if valid?(*colors)
|
|
233
|
-
|
|
272
|
+
|
|
273
|
+
raise InvalidAttributeNameError, "Bad style or unintialized constant, " \
|
|
234
274
|
" valid styles are: #{style_names.join(', ')}."
|
|
235
275
|
end
|
|
236
276
|
end # Color
|
data/lib/pastel/color_parser.rb
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "strscan"
|
|
4
|
+
|
|
5
|
+
require_relative "ansi"
|
|
2
6
|
|
|
3
7
|
module Pastel
|
|
4
8
|
# Responsible for parsing color symbols out of text with color escapes
|
|
@@ -9,15 +13,16 @@ module Pastel
|
|
|
9
13
|
class ColorParser
|
|
10
14
|
include ANSI
|
|
11
15
|
|
|
12
|
-
ESC = "\x1b"
|
|
13
|
-
CSI = "\["
|
|
16
|
+
ESC = "\x1b"
|
|
17
|
+
CSI = "\["
|
|
14
18
|
|
|
15
19
|
# Parse color escape sequences into a list of hashes
|
|
16
20
|
# corresponding to the color attributes being set by these
|
|
17
21
|
# sequences
|
|
18
22
|
#
|
|
19
23
|
# @example
|
|
20
|
-
# parse("\e[32mfoo\e[0m")
|
|
24
|
+
# parse("\e[32mfoo\e[0m")
|
|
25
|
+
# # => [{foreground: :green, text: "foo"}
|
|
21
26
|
#
|
|
22
27
|
# @param [String] text
|
|
23
28
|
# the text to parse for presence of color ansi codes
|
|
@@ -30,20 +35,19 @@ module Pastel
|
|
|
30
35
|
state = {}
|
|
31
36
|
result = []
|
|
32
37
|
ansi_stack = []
|
|
33
|
-
text_chunk =
|
|
38
|
+
text_chunk = []
|
|
34
39
|
|
|
35
40
|
until scanner.eos?
|
|
36
41
|
char = scanner.getch
|
|
37
42
|
# match control
|
|
38
43
|
if char == ESC && (delim = scanner.getch) == CSI
|
|
39
|
-
if scanner.scan(/^
|
|
44
|
+
if scanner.scan(/^0?m/) # reset
|
|
40
45
|
unpack_ansi(ansi_stack) { |attr, name| state[attr] = name }
|
|
41
46
|
ansi_stack = []
|
|
42
47
|
elsif scanner.scan(/^([1-9;:]+)m/)
|
|
43
48
|
# ansi codes separated by text
|
|
44
49
|
if !text_chunk.empty? && !ansi_stack.empty?
|
|
45
50
|
unpack_ansi(ansi_stack) { |attr, name| state[attr] = name }
|
|
46
|
-
ansi_stack = []
|
|
47
51
|
end
|
|
48
52
|
scanner[1].split(/:|;/).each do |code|
|
|
49
53
|
ansi_stack << code
|
|
@@ -51,10 +55,10 @@ module Pastel
|
|
|
51
55
|
end
|
|
52
56
|
|
|
53
57
|
if !text_chunk.empty?
|
|
54
|
-
state[:text] = text_chunk
|
|
58
|
+
state[:text] = text_chunk.join
|
|
55
59
|
result.push(state)
|
|
56
60
|
state = {}
|
|
57
|
-
text_chunk
|
|
61
|
+
text_chunk.clear
|
|
58
62
|
end
|
|
59
63
|
elsif char == ESC # broken escape
|
|
60
64
|
text_chunk << char + delim.to_s
|
|
@@ -64,12 +68,12 @@ module Pastel
|
|
|
64
68
|
end
|
|
65
69
|
|
|
66
70
|
if !text_chunk.empty?
|
|
67
|
-
state[:text] = text_chunk
|
|
71
|
+
state[:text] = text_chunk.join
|
|
68
72
|
end
|
|
69
73
|
if !ansi_stack.empty?
|
|
70
74
|
unpack_ansi(ansi_stack) { |attr, name| state[attr] = name}
|
|
71
75
|
end
|
|
72
|
-
if state.
|
|
76
|
+
if !state[:text].to_s.empty?
|
|
73
77
|
result.push(state)
|
|
74
78
|
end
|
|
75
79
|
result
|
|
@@ -84,10 +88,8 @@ module Pastel
|
|
|
84
88
|
#
|
|
85
89
|
# @api private
|
|
86
90
|
def self.unpack_ansi(ansi_stack)
|
|
87
|
-
ansi_stack.each do |
|
|
88
|
-
|
|
89
|
-
attr = attribute_for(ansi)
|
|
90
|
-
yield attr, name
|
|
91
|
+
ansi_stack.each do |code|
|
|
92
|
+
yield(attribute_name(code), color_name(code))
|
|
91
93
|
end
|
|
92
94
|
end
|
|
93
95
|
|
|
@@ -99,7 +101,7 @@ module Pastel
|
|
|
99
101
|
# @return [Symbol]
|
|
100
102
|
#
|
|
101
103
|
# @api private
|
|
102
|
-
def self.
|
|
104
|
+
def self.attribute_name(ansi)
|
|
103
105
|
if ANSI.foreground?(ansi)
|
|
104
106
|
:foreground
|
|
105
107
|
elsif ANSI.background?(ansi)
|
|
@@ -109,9 +111,13 @@ module Pastel
|
|
|
109
111
|
end
|
|
110
112
|
end
|
|
111
113
|
|
|
114
|
+
# Convert ANSI code to color name
|
|
115
|
+
#
|
|
116
|
+
# @return [String]
|
|
117
|
+
#
|
|
112
118
|
# @api private
|
|
113
|
-
def self.
|
|
114
|
-
ATTRIBUTES.key(
|
|
119
|
+
def self.color_name(ansi_code)
|
|
120
|
+
ATTRIBUTES.key(ansi_code.to_i)
|
|
115
121
|
end
|
|
116
122
|
end # Parser
|
|
117
123
|
end # Pastel
|