chalk 2.0.1 → 2.1.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.
- package/index.js +16 -10
- package/package.json +5 -4
- package/readme.md +9 -5
- package/templates.js +94 -141
package/index.js
CHANGED
|
@@ -19,13 +19,14 @@ function applyOptions(obj, options) {
|
|
|
19
19
|
options = options || {};
|
|
20
20
|
|
|
21
21
|
// Detect level if not set manually
|
|
22
|
-
|
|
22
|
+
const scLevel = supportsColor ? supportsColor.level : 0;
|
|
23
|
+
obj.level = options.level === undefined ? scLevel : options.level;
|
|
23
24
|
obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0;
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
function Chalk(options) {
|
|
27
|
-
// We check for this.template here since calling chalk.constructor()
|
|
28
|
-
// by itself will have a `this` of a previously constructed chalk object
|
|
28
|
+
// We check for this.template here since calling `chalk.constructor()`
|
|
29
|
+
// by itself will have a `this` of a previously constructed chalk object
|
|
29
30
|
if (!this || !(this instanceof Chalk) || this.template) {
|
|
30
31
|
const chalk = {};
|
|
31
32
|
applyOptions(chalk, options);
|
|
@@ -142,7 +143,7 @@ function build(_styles, key) {
|
|
|
142
143
|
builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey';
|
|
143
144
|
|
|
144
145
|
// `__proto__` is used because we must return a function, but there is
|
|
145
|
-
// no way to create a function with a different prototype
|
|
146
|
+
// no way to create a function with a different prototype
|
|
146
147
|
builder.__proto__ = proto; // eslint-disable-line no-proto
|
|
147
148
|
|
|
148
149
|
return builder;
|
|
@@ -152,7 +153,11 @@ function applyStyle() {
|
|
|
152
153
|
// Support varags, but simply cast to string in case there's only one arg
|
|
153
154
|
const args = arguments;
|
|
154
155
|
const argsLen = args.length;
|
|
155
|
-
let str =
|
|
156
|
+
let str = String(arguments[0]);
|
|
157
|
+
|
|
158
|
+
if (argsLen === 0) {
|
|
159
|
+
return '';
|
|
160
|
+
}
|
|
156
161
|
|
|
157
162
|
if (argsLen > 1) {
|
|
158
163
|
// Don't slice `arguments`, it prevents V8 optimizations
|
|
@@ -192,17 +197,18 @@ function applyStyle() {
|
|
|
192
197
|
}
|
|
193
198
|
|
|
194
199
|
function chalkTag(chalk, strings) {
|
|
195
|
-
const args = [].slice.call(arguments, 2);
|
|
196
|
-
|
|
197
200
|
if (!Array.isArray(strings)) {
|
|
198
|
-
|
|
201
|
+
// If chalk() was called by itself or with a string,
|
|
202
|
+
// return the string itself as a string.
|
|
203
|
+
return [].slice.call(arguments, 1).join(' ');
|
|
199
204
|
}
|
|
200
205
|
|
|
206
|
+
const args = [].slice.call(arguments, 2);
|
|
201
207
|
const parts = [strings.raw[0]];
|
|
202
208
|
|
|
203
209
|
for (let i = 1; i < strings.length; i++) {
|
|
204
|
-
parts.push(args[i - 1]
|
|
205
|
-
parts.push(strings.raw[i]);
|
|
210
|
+
parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&'));
|
|
211
|
+
parts.push(String(strings.raw[i]));
|
|
206
212
|
}
|
|
207
213
|
|
|
208
214
|
return template(chalk, parts.join(''));
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chalk",
|
|
3
|
-
"version": "2.0
|
|
4
|
-
"description": "Terminal string styling done right
|
|
3
|
+
"version": "2.1.0",
|
|
4
|
+
"description": "Terminal string styling done right",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "chalk/chalk",
|
|
7
7
|
"engines": {
|
|
8
8
|
"node": ">=4"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
-
"test": "xo && nyc
|
|
11
|
+
"test": "xo && nyc ava",
|
|
12
12
|
"bench": "matcha benchmark.js",
|
|
13
13
|
"coveralls": "nyc report --reporter=text-lcov | coveralls"
|
|
14
14
|
},
|
|
@@ -45,10 +45,11 @@
|
|
|
45
45
|
"supports-color": "^4.0.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
+
"ava": "*",
|
|
48
49
|
"coveralls": "^2.11.2",
|
|
50
|
+
"execa": "^0.7.0",
|
|
49
51
|
"import-fresh": "^2.0.0",
|
|
50
52
|
"matcha": "^0.7.0",
|
|
51
|
-
"mocha": "*",
|
|
52
53
|
"nyc": "^11.0.2",
|
|
53
54
|
"resolve-from": "^3.0.0",
|
|
54
55
|
"xo": "*"
|
package/readme.md
CHANGED
|
@@ -11,9 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
[](https://travis-ci.org/chalk/chalk) [](https://coveralls.io/github/chalk/chalk?branch=master) [](https://www.youtube.com/watch?v=9auOCbH5Ns4) [](https://github.com/sindresorhus/xo)
|
|
13
13
|
|
|
14
|
-
[
|
|
15
|
-
|
|
16
|
-
**Chalk is a clean and focused alternative.**
|
|
14
|
+
### [See what's new in Chalk 2](https://github.com/chalk/chalk/releases/tag/v2.0.0)
|
|
17
15
|
|
|
18
16
|

|
|
19
17
|
|
|
@@ -183,8 +181,7 @@ Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color=
|
|
|
183
181
|
- `magenta`
|
|
184
182
|
- `cyan`
|
|
185
183
|
- `white`
|
|
186
|
-
- `gray`
|
|
187
|
-
- `blackBright`
|
|
184
|
+
- `gray` ("bright black")
|
|
188
185
|
- `redBright`
|
|
189
186
|
- `greenBright`
|
|
190
187
|
- `yellowBright`
|
|
@@ -278,6 +275,11 @@ The following color models can be used:
|
|
|
278
275
|
If you're on Windows, do yourself a favor and use [`cmder`](http://cmder.net/) instead of `cmd.exe`.
|
|
279
276
|
|
|
280
277
|
|
|
278
|
+
## Origin story
|
|
279
|
+
|
|
280
|
+
[colors.js](https://github.com/Marak/colors.js) used to be the most popular string styling module, but it has serious deficiencies like extending `String.prototype` which causes all kinds of [problems](https://github.com/yeoman/yo/issues/68) and the package is unmaintained. Although there are other packages, they either do too much or not enough. Chalk is a clean and focused alternative.
|
|
281
|
+
|
|
282
|
+
|
|
281
283
|
## Related
|
|
282
284
|
|
|
283
285
|
- [chalk-cli](https://github.com/chalk/chalk-cli) - CLI for this module
|
|
@@ -289,6 +291,8 @@ If you're on Windows, do yourself a favor and use [`cmder`](http://cmder.net/) i
|
|
|
289
291
|
- [wrap-ansi](https://github.com/chalk/wrap-ansi) - Wordwrap a string with ANSI escape codes
|
|
290
292
|
- [slice-ansi](https://github.com/chalk/slice-ansi) - Slice a string with ANSI escape codes
|
|
291
293
|
- [color-convert](https://github.com/qix-/color-convert) - Converts colors between different models
|
|
294
|
+
- [chalk-animation](https://github.com/bokub/chalk-animation) - Animate strings in the terminal
|
|
295
|
+
- [gradient-string](https://github.com/bokub/gradient-string) - Apply color gradients to strings
|
|
292
296
|
|
|
293
297
|
|
|
294
298
|
## Maintainers
|
package/templates.js
CHANGED
|
@@ -1,175 +1,128 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
+
const TEMPLATE_REGEX = /(?:\\(u[a-f0-9]{4}|x[a-f0-9]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi;
|
|
3
|
+
const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g;
|
|
4
|
+
const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/;
|
|
5
|
+
const ESCAPE_REGEX = /\\(u[0-9a-f]{4}|x[0-9a-f]{2}|.)|([^\\])/gi;
|
|
6
|
+
|
|
7
|
+
const ESCAPES = {
|
|
8
|
+
n: '\n',
|
|
9
|
+
r: '\r',
|
|
10
|
+
t: '\t',
|
|
11
|
+
b: '\b',
|
|
12
|
+
f: '\f',
|
|
13
|
+
v: '\v',
|
|
14
|
+
0: '\0',
|
|
15
|
+
'\\': '\\',
|
|
16
|
+
e: '\u001b',
|
|
17
|
+
a: '\u0007'
|
|
18
|
+
};
|
|
2
19
|
|
|
3
|
-
function
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
contents: []
|
|
8
|
-
};
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const zeroBound = n => n < 0 ? 0 : n;
|
|
12
|
-
const lastIndex = a => zeroBound(a.length - 1);
|
|
20
|
+
function unescape(c) {
|
|
21
|
+
if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) {
|
|
22
|
+
return String.fromCharCode(parseInt(c.slice(1), 16));
|
|
23
|
+
}
|
|
13
24
|
|
|
14
|
-
|
|
25
|
+
return ESCAPES[c] || c;
|
|
26
|
+
}
|
|
15
27
|
|
|
16
|
-
|
|
17
|
-
const
|
|
28
|
+
function parseArguments(name, args) {
|
|
29
|
+
const results = [];
|
|
30
|
+
const chunks = args.trim().split(/\s*,\s*/g);
|
|
31
|
+
let matches;
|
|
18
32
|
|
|
19
|
-
for (
|
|
20
|
-
if (
|
|
21
|
-
|
|
33
|
+
for (const chunk of chunks) {
|
|
34
|
+
if (!isNaN(chunk)) {
|
|
35
|
+
results.push(Number(chunk));
|
|
36
|
+
} else if ((matches = chunk.match(STRING_REGEX))) {
|
|
37
|
+
results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, chr) => escape ? unescape(escape) : chr));
|
|
22
38
|
} else {
|
|
23
|
-
|
|
39
|
+
throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`);
|
|
24
40
|
}
|
|
25
41
|
}
|
|
26
42
|
|
|
27
|
-
return
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Checks if the character at position i in string is a normal character a.k.a a non control character.
|
|
32
|
-
* */
|
|
33
|
-
const isNormalCharacter = (string, i) => {
|
|
34
|
-
const char = string[i];
|
|
35
|
-
const backslash = '\\';
|
|
36
|
-
|
|
37
|
-
if (!(char === backslash || char === '{' || char === '}')) {
|
|
38
|
-
return true;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const n = i === 0 ? 0 : takeWhileReverse(string, x => x === '\\', zeroBound(i - 1)).length;
|
|
43
|
+
return results;
|
|
44
|
+
}
|
|
42
45
|
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
function parseStyle(style) {
|
|
47
|
+
STYLE_REGEX.lastIndex = 0;
|
|
45
48
|
|
|
46
|
-
const
|
|
49
|
+
const results = [];
|
|
50
|
+
let matches;
|
|
47
51
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
* which remove a style from the list if present.
|
|
51
|
-
* */
|
|
52
|
-
const sumStyles = data => {
|
|
53
|
-
const negateRegex = /^~.+/;
|
|
54
|
-
let out = [];
|
|
52
|
+
while ((matches = STYLE_REGEX.exec(style)) !== null) {
|
|
53
|
+
const name = matches[1];
|
|
55
54
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
out = out.filter(x => x !== exclude);
|
|
55
|
+
if (matches[2]) {
|
|
56
|
+
const args = parseArguments(name, matches[2]);
|
|
57
|
+
results.push([name].concat(args));
|
|
60
58
|
} else {
|
|
61
|
-
|
|
59
|
+
results.push([name]);
|
|
62
60
|
}
|
|
63
61
|
}
|
|
64
62
|
|
|
65
|
-
return
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Takes a string and parses it into a tree of data objects which inherit styles from their parent.
|
|
70
|
-
* */
|
|
71
|
-
function parse(string) {
|
|
72
|
-
const root = data(null);
|
|
73
|
-
let pushingStyle = false;
|
|
74
|
-
|
|
75
|
-
let current = root;
|
|
63
|
+
return results;
|
|
64
|
+
}
|
|
76
65
|
|
|
77
|
-
|
|
78
|
-
|
|
66
|
+
function buildStyle(chalk, styles) {
|
|
67
|
+
const enabled = {};
|
|
79
68
|
|
|
80
|
-
|
|
81
|
-
|
|
69
|
+
for (const layer of styles) {
|
|
70
|
+
for (const style of layer.styles) {
|
|
71
|
+
enabled[style[0]] = layer.inverse ? null : style.slice(1);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
82
74
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
75
|
+
let current = chalk;
|
|
76
|
+
for (const styleName of Object.keys(enabled)) {
|
|
77
|
+
if (Array.isArray(enabled[styleName])) {
|
|
78
|
+
if (!(styleName in current)) {
|
|
79
|
+
throw new Error(`Unknown Chalk style: ${styleName}`);
|
|
87
80
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (' \t'.indexOf(char) > -1) {
|
|
92
|
-
pushingStyle = false;
|
|
93
|
-
} else if (char === '\n') {
|
|
94
|
-
pushingStyle = false;
|
|
95
|
-
addNormalCharacter();
|
|
96
|
-
} else if (char === '.') {
|
|
97
|
-
current.styles.push('');
|
|
81
|
+
|
|
82
|
+
if (enabled[styleName].length > 0) {
|
|
83
|
+
current = current[styleName].apply(current, enabled[styleName]);
|
|
98
84
|
} else {
|
|
99
|
-
current
|
|
85
|
+
current = current[styleName];
|
|
100
86
|
}
|
|
101
|
-
} else if (isNormalCharacter(string, i)) {
|
|
102
|
-
addNormalCharacter();
|
|
103
|
-
} else if (char === '{') {
|
|
104
|
-
pushingStyle = true;
|
|
105
|
-
const nCurrent = data(current);
|
|
106
|
-
current.contents.push(nCurrent);
|
|
107
|
-
current = nCurrent;
|
|
108
|
-
} else if (char === '}') {
|
|
109
|
-
current = current.parent;
|
|
110
87
|
}
|
|
111
88
|
}
|
|
112
89
|
|
|
113
|
-
|
|
114
|
-
throw new Error('literal template has an unclosed block');
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
return root;
|
|
90
|
+
return current;
|
|
118
91
|
}
|
|
119
92
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
93
|
+
module.exports = (chalk, tmp) => {
|
|
94
|
+
const styles = [];
|
|
95
|
+
const chunks = [];
|
|
96
|
+
let chunk = [];
|
|
97
|
+
|
|
98
|
+
// eslint-disable-next-line max-params
|
|
99
|
+
tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => {
|
|
100
|
+
if (escapeChar) {
|
|
101
|
+
chunk.push(unescape(escapeChar));
|
|
102
|
+
} else if (style) {
|
|
103
|
+
const str = chunk.join('');
|
|
104
|
+
chunk = [];
|
|
105
|
+
chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str));
|
|
106
|
+
styles.push({inverse, styles: parseStyle(style)});
|
|
107
|
+
} else if (close) {
|
|
108
|
+
if (styles.length === 0) {
|
|
109
|
+
throw new Error('Found extraneous } in Chalk template literal');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
chunks.push(buildStyle(chalk, styles)(chunk.join('')));
|
|
113
|
+
chunk = [];
|
|
114
|
+
styles.pop();
|
|
133
115
|
} else {
|
|
134
|
-
|
|
116
|
+
chunk.push(chr);
|
|
135
117
|
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return flat;
|
|
139
|
-
}
|
|
118
|
+
});
|
|
140
119
|
|
|
141
|
-
|
|
142
|
-
if (!chalk[style]) {
|
|
143
|
-
throw new Error(`invalid Chalk style: ${style}`);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
120
|
+
chunks.push(chunk.join(''));
|
|
146
121
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
function parseStyle(chalk, style) {
|
|
151
|
-
const fnMatch = style.match(/^\s*(\w+)\s*\(\s*([^)]*)\s*\)\s*/);
|
|
152
|
-
if (!fnMatch) {
|
|
153
|
-
assertStyle(chalk, style);
|
|
154
|
-
return chalk[style];
|
|
122
|
+
if (styles.length > 0) {
|
|
123
|
+
const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`;
|
|
124
|
+
throw new Error(errMsg);
|
|
155
125
|
}
|
|
156
126
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
assertStyle(chalk, name);
|
|
161
|
-
|
|
162
|
-
return chalk[name].apply(chalk, args);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Performs the actual styling of the string, essentially lifted from cli.js.
|
|
167
|
-
* */
|
|
168
|
-
function style(chalk, flat) {
|
|
169
|
-
return flat.map(data => {
|
|
170
|
-
const fn = data.styles.reduce(parseStyle, chalk);
|
|
171
|
-
return fn(data.content.replace(/\n$/, ''));
|
|
172
|
-
}).join('');
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
module.exports = (chalk, string) => style(chalk, flatten(parse(string)));
|
|
127
|
+
return chunks.join('');
|
|
128
|
+
};
|