wrap-ansi 0.1.0 → 2.0.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 +139 -15
- package/package.json +9 -4
- package/readme.md +16 -5
package/index.js
CHANGED
@@ -1,18 +1,65 @@
|
|
1
1
|
'use strict';
|
2
|
-
var
|
2
|
+
var stringWidth = require('string-width');
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
var ESCAPES = [
|
5
|
+
'\u001b',
|
6
|
+
'\u009b'
|
7
|
+
];
|
8
|
+
|
9
|
+
var END_CODE = 39;
|
10
|
+
|
11
|
+
var ESCAPE_CODES = {
|
12
|
+
0: 0,
|
13
|
+
1: 22,
|
14
|
+
2: 22,
|
15
|
+
3: 23,
|
16
|
+
4: 24,
|
17
|
+
7: 27,
|
18
|
+
8: 28,
|
19
|
+
9: 29,
|
20
|
+
30: 39,
|
21
|
+
31: 39,
|
22
|
+
32: 39,
|
23
|
+
33: 39,
|
24
|
+
34: 39,
|
25
|
+
35: 39,
|
26
|
+
36: 39,
|
27
|
+
37: 39,
|
28
|
+
90: 39,
|
29
|
+
40: 49,
|
30
|
+
41: 49,
|
31
|
+
42: 49,
|
32
|
+
43: 49,
|
33
|
+
44: 49,
|
34
|
+
45: 49,
|
35
|
+
46: 49,
|
36
|
+
47: 49
|
37
|
+
};
|
38
|
+
|
39
|
+
function wrapAnsi(code) {
|
40
|
+
return ESCAPES[0] + '[' + code + 'm';
|
41
|
+
}
|
42
|
+
|
43
|
+
// calculate the length of words split on ' ', ignoring
|
44
|
+
// the extra characters added by ansi escape codes.
|
45
|
+
function wordLengths(str) {
|
46
|
+
return str.split(' ').map(function (s) {
|
47
|
+
return stringWidth(s);
|
48
|
+
});
|
49
|
+
}
|
50
|
+
|
51
|
+
// wrap a long word across multiple rows.
|
52
|
+
// ansi escape codes do not count towards length.
|
53
|
+
function wrapWord(rows, word, cols) {
|
6
54
|
var insideEscape = false;
|
7
|
-
var visible =
|
8
|
-
var lastSpace = 0;
|
55
|
+
var visible = rows[rows.length - 1].length;
|
9
56
|
|
10
|
-
for (var i = 0; i <
|
11
|
-
var x =
|
57
|
+
for (var i = 0; i < word.length; i++) {
|
58
|
+
var x = word[i];
|
12
59
|
|
13
|
-
|
60
|
+
rows[rows.length - 1] += x;
|
14
61
|
|
15
|
-
if (x
|
62
|
+
if (ESCAPES.indexOf(x) !== -1) {
|
16
63
|
insideEscape = true;
|
17
64
|
} else if (insideEscape && x === 'm') {
|
18
65
|
insideEscape = false;
|
@@ -23,16 +70,93 @@ module.exports = function (str, cols) {
|
|
23
70
|
continue;
|
24
71
|
}
|
25
72
|
|
26
|
-
|
27
|
-
lastSpace = i;
|
28
|
-
}
|
73
|
+
visible++;
|
29
74
|
|
30
|
-
if (
|
31
|
-
|
32
|
-
lastSpace = 0;
|
75
|
+
if (visible >= cols && i < word.length - 1) {
|
76
|
+
rows.push('');
|
33
77
|
visible = 0;
|
34
78
|
}
|
35
79
|
}
|
36
80
|
|
81
|
+
// it's possible that the last row we copy over is only
|
82
|
+
// ansi escape characters, handle this edge-case.
|
83
|
+
if (!visible && rows[rows.length - 1].length > 0 && rows.length > 1) {
|
84
|
+
rows[rows.length - 2] += rows.pop();
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
// the wrap-ansi module can be invoked
|
89
|
+
// in either 'hard' or 'soft' wrap mode.
|
90
|
+
//
|
91
|
+
// 'hard' will never allow a string to take up more
|
92
|
+
// than cols characters.
|
93
|
+
//
|
94
|
+
// 'soft' allows long words to expand past the column length.
|
95
|
+
function exec(str, cols, opts) {
|
96
|
+
var options = opts || {};
|
97
|
+
|
98
|
+
var pre = '';
|
99
|
+
var ret = '';
|
100
|
+
var escapeCode;
|
101
|
+
|
102
|
+
var lengths = wordLengths(str);
|
103
|
+
var words = str.split(' ');
|
104
|
+
var rows = [''];
|
105
|
+
|
106
|
+
for (var i = 0, word; (word = words[i]) !== undefined; i++) {
|
107
|
+
var rowLength = stringWidth(rows[rows.length - 1]);
|
108
|
+
|
109
|
+
if (rowLength) {
|
110
|
+
rows[rows.length - 1] += ' ';
|
111
|
+
rowLength++;
|
112
|
+
}
|
113
|
+
|
114
|
+
// in 'hard' wrap mode, the length of a line is
|
115
|
+
// never allowed to extend past 'cols'.
|
116
|
+
if (lengths[i] > cols && options.hard) {
|
117
|
+
if (rowLength) {
|
118
|
+
rows.push('');
|
119
|
+
}
|
120
|
+
wrapWord(rows, word, cols);
|
121
|
+
continue;
|
122
|
+
}
|
123
|
+
|
124
|
+
if (rowLength + lengths[i] > cols && rowLength > 0) {
|
125
|
+
rows.push('');
|
126
|
+
}
|
127
|
+
|
128
|
+
rows[rows.length - 1] += word;
|
129
|
+
}
|
130
|
+
|
131
|
+
pre = rows.map(function (r) {
|
132
|
+
return r.trim();
|
133
|
+
}).join('\n');
|
134
|
+
|
135
|
+
for (var j = 0; j < pre.length; j++) {
|
136
|
+
var y = pre[j];
|
137
|
+
|
138
|
+
ret += y;
|
139
|
+
|
140
|
+
if (ESCAPES.indexOf(y) !== -1) {
|
141
|
+
var code = parseFloat(/[0-9][^m]*/.exec(pre.slice(j, j + 4)));
|
142
|
+
escapeCode = code === END_CODE ? null : code;
|
143
|
+
}
|
144
|
+
|
145
|
+
if (escapeCode && ESCAPE_CODES[escapeCode]) {
|
146
|
+
if (pre[j + 1] === '\n') {
|
147
|
+
ret += wrapAnsi(ESCAPE_CODES[escapeCode]);
|
148
|
+
} else if (y === '\n') {
|
149
|
+
ret += wrapAnsi(escapeCode);
|
150
|
+
}
|
151
|
+
}
|
152
|
+
}
|
153
|
+
|
37
154
|
return ret;
|
155
|
+
}
|
156
|
+
|
157
|
+
// for each line break, invoke the method separately.
|
158
|
+
module.exports = function (str, cols, opts) {
|
159
|
+
return String(str).split('\n').map(function (substr) {
|
160
|
+
return exec(substr, cols, opts);
|
161
|
+
}).join('\n');
|
38
162
|
};
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "wrap-ansi",
|
3
|
-
"version": "0.
|
3
|
+
"version": "2.0.0",
|
4
4
|
"description": "Wordwrap a string with ANSI escape codes",
|
5
5
|
"license": "MIT",
|
6
6
|
"repository": "chalk/wrap-ansi",
|
@@ -12,13 +12,15 @@
|
|
12
12
|
"maintainers": [
|
13
13
|
"Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)",
|
14
14
|
"Joshua Appelman <jappelman@xebia.com> (jbnicolai.com)",
|
15
|
-
"JD Ballard <i.am.qix@gmail.com> (github.com/qix-)"
|
15
|
+
"JD Ballard <i.am.qix@gmail.com> (github.com/qix-)",
|
16
|
+
"Benjamin Coe <ben@npmjs.com> (github.com/bcoe)"
|
16
17
|
],
|
17
18
|
"engines": {
|
18
19
|
"node": ">=0.10.0"
|
19
20
|
},
|
20
21
|
"scripts": {
|
21
|
-
"test": "xo && node test.js"
|
22
|
+
"test": "xo && nyc node test.js",
|
23
|
+
"coverage": "nyc --reporter=text-lcov node test.js | coveralls"
|
22
24
|
},
|
23
25
|
"files": [
|
24
26
|
"index.js"
|
@@ -51,11 +53,14 @@
|
|
51
53
|
"text"
|
52
54
|
],
|
53
55
|
"dependencies": {
|
54
|
-
"
|
56
|
+
"string-width": "^1.0.1"
|
55
57
|
},
|
56
58
|
"devDependencies": {
|
57
59
|
"ava": "0.0.4",
|
58
60
|
"chalk": "^1.1.0",
|
61
|
+
"coveralls": "^2.11.4",
|
62
|
+
"has-ansi": "^2.0.0",
|
63
|
+
"nyc": "^3.2.2",
|
59
64
|
"strip-ansi": "^3.0.0",
|
60
65
|
"xo": "*"
|
61
66
|
}
|
package/readme.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# wrap-ansi [](https://travis-ci.org/chalk/wrap-ansi)
|
1
|
+
# wrap-ansi [](https://travis-ci.org/chalk/wrap-ansi) [](https://coveralls.io/github/chalk/wrap-ansi?branch=master)
|
2
2
|
|
3
3
|
> Wordwrap a string with [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors_and_Styles)
|
4
4
|
|
@@ -13,10 +13,10 @@ $ npm install --save wrap-ansi
|
|
13
13
|
## Usage
|
14
14
|
|
15
15
|
```js
|
16
|
-
|
17
|
-
|
16
|
+
const chalk = require('chalk');
|
17
|
+
const wrapAnsi = require('wrap-ansi');
|
18
18
|
|
19
|
-
|
19
|
+
const input = 'The quick brown ' + chalk.red('fox jumped over ') +
|
20
20
|
'the lazy ' + chalk.green('dog and then ran away with the unicorn.');
|
21
21
|
|
22
22
|
console.log(wrapAnsi(input, 20));
|
@@ -27,7 +27,9 @@ console.log(wrapAnsi(input, 20));
|
|
27
27
|
|
28
28
|
## API
|
29
29
|
|
30
|
-
### wrapAnsi(input, columns)
|
30
|
+
### wrapAnsi(input, columns, [options])
|
31
|
+
|
32
|
+
Wrap words to the specified column width.
|
31
33
|
|
32
34
|
#### input
|
33
35
|
|
@@ -41,10 +43,19 @@ Type: `number`
|
|
41
43
|
|
42
44
|
Number of columns to wrap the text to.
|
43
45
|
|
46
|
+
#### options.hard
|
47
|
+
|
48
|
+
Type: `boolean`
|
49
|
+
Default: `false`
|
50
|
+
|
51
|
+
By default the wrap is soft, meaning long words may extend past the column width. Setting this to `true` will make it hard wrap at the column width.
|
52
|
+
|
44
53
|
|
45
54
|
## Related
|
46
55
|
|
56
|
+
- [slice-ansi](https://github.com/chalk/slice-ansi) - Slice a string with ANSI escape codes
|
47
57
|
- [chalk](https://github.com/chalk/chalk) - Terminal string styling done right
|
58
|
+
- [jsesc](https://github.com/mathiasbynens/jsesc) - Generate ASCII-only output from Unicode strings. Useful for creating test fixtures.
|
48
59
|
|
49
60
|
|
50
61
|
## License
|