wrap-ansi 3.0.1 → 4.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 +39 -77
- package/package.json +60 -60
package/index.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
'use strict';
|
2
2
|
const stringWidth = require('string-width');
|
3
3
|
const stripAnsi = require('strip-ansi');
|
4
|
+
const ansiStyles = require('ansi-styles');
|
4
5
|
|
5
6
|
const ESCAPES = new Set([
|
6
7
|
'\u001B',
|
@@ -9,63 +10,33 @@ const ESCAPES = new Set([
|
|
9
10
|
|
10
11
|
const END_CODE = 39;
|
11
12
|
|
12
|
-
const ESCAPE_CODES = new Map([
|
13
|
-
[0, 0],
|
14
|
-
[1, 22],
|
15
|
-
[2, 22],
|
16
|
-
[3, 23],
|
17
|
-
[4, 24],
|
18
|
-
[7, 27],
|
19
|
-
[8, 28],
|
20
|
-
[9, 29],
|
21
|
-
[30, 39],
|
22
|
-
[31, 39],
|
23
|
-
[32, 39],
|
24
|
-
[33, 39],
|
25
|
-
[34, 39],
|
26
|
-
[35, 39],
|
27
|
-
[36, 39],
|
28
|
-
[37, 39],
|
29
|
-
[90, 39],
|
30
|
-
[40, 49],
|
31
|
-
[41, 49],
|
32
|
-
[42, 49],
|
33
|
-
[43, 49],
|
34
|
-
[44, 49],
|
35
|
-
[45, 49],
|
36
|
-
[46, 49],
|
37
|
-
[47, 49]
|
38
|
-
]);
|
39
|
-
|
40
13
|
const wrapAnsi = code => `${ESCAPES.values().next().value}[${code}m`;
|
41
14
|
|
42
15
|
// Calculate the length of words split on ' ', ignoring
|
43
16
|
// the extra characters added by ansi escape codes
|
44
|
-
const wordLengths =
|
17
|
+
const wordLengths = string => string.split(' ').map(character => stringWidth(character));
|
45
18
|
|
46
19
|
// Wrap a long word across multiple rows
|
47
20
|
// Ansi escape codes do not count towards length
|
48
|
-
const wrapWord = (rows, word,
|
49
|
-
const
|
21
|
+
const wrapWord = (rows, word, columns) => {
|
22
|
+
const characters = [...word];
|
50
23
|
|
51
24
|
let insideEscape = false;
|
52
25
|
let visible = stringWidth(stripAnsi(rows[rows.length - 1]));
|
53
26
|
|
54
|
-
for (const
|
55
|
-
const
|
56
|
-
const char = item[1];
|
57
|
-
const charLength = stringWidth(char);
|
27
|
+
for (const [index, character] of characters.entries()) {
|
28
|
+
const characterLength = stringWidth(character);
|
58
29
|
|
59
|
-
if (visible +
|
60
|
-
rows[rows.length - 1] +=
|
30
|
+
if (visible + characterLength <= columns) {
|
31
|
+
rows[rows.length - 1] += character;
|
61
32
|
} else {
|
62
|
-
rows.push(
|
33
|
+
rows.push(character);
|
63
34
|
visible = 0;
|
64
35
|
}
|
65
36
|
|
66
|
-
if (ESCAPES.has(
|
37
|
+
if (ESCAPES.has(character)) {
|
67
38
|
insideEscape = true;
|
68
|
-
} else if (insideEscape &&
|
39
|
+
} else if (insideEscape && character === 'm') {
|
69
40
|
insideEscape = false;
|
70
41
|
continue;
|
71
42
|
}
|
@@ -74,9 +45,9 @@ const wrapWord = (rows, word, cols) => {
|
|
74
45
|
continue;
|
75
46
|
}
|
76
47
|
|
77
|
-
visible +=
|
48
|
+
visible += characterLength;
|
78
49
|
|
79
|
-
if (visible ===
|
50
|
+
if (visible === columns && index < characters.length - 1) {
|
80
51
|
rows.push('');
|
81
52
|
visible = 0;
|
82
53
|
}
|
@@ -93,33 +64,27 @@ const wrapWord = (rows, word, cols) => {
|
|
93
64
|
// in either 'hard' or 'soft' wrap mode
|
94
65
|
//
|
95
66
|
// 'hard' will never allow a string to take up more
|
96
|
-
// than
|
67
|
+
// than columns characters
|
97
68
|
//
|
98
69
|
// 'soft' allows long words to expand past the column length
|
99
|
-
const exec = (
|
100
|
-
|
101
|
-
|
102
|
-
if (str.trim() === '') {
|
103
|
-
return options.trim === false ? str : str.trim();
|
70
|
+
const exec = (string, columns, options = {}) => {
|
71
|
+
if (string.trim() === '') {
|
72
|
+
return options.trim === false ? string : string.trim();
|
104
73
|
}
|
105
74
|
|
106
75
|
let pre = '';
|
107
76
|
let ret = '';
|
108
77
|
let escapeCode;
|
109
78
|
|
110
|
-
const lengths = wordLengths(
|
111
|
-
const words = str.split(' ');
|
79
|
+
const lengths = wordLengths(string);
|
112
80
|
const rows = [''];
|
113
81
|
|
114
|
-
for (const
|
115
|
-
const i = item[0];
|
116
|
-
const word = item[1];
|
117
|
-
|
82
|
+
for (const [index, word] of string.split(' ').entries()) {
|
118
83
|
rows[rows.length - 1] = options.trim === false ? rows[rows.length - 1] : rows[rows.length - 1].trim();
|
119
84
|
let rowLength = stringWidth(rows[rows.length - 1]);
|
120
85
|
|
121
86
|
if (rowLength || word === '') {
|
122
|
-
if (rowLength ===
|
87
|
+
if (rowLength === columns && options.wordWrap === false) {
|
123
88
|
// If we start with a new word but the current row length equals the length of the columns, add a new row
|
124
89
|
rows.push('');
|
125
90
|
rowLength = 0;
|
@@ -130,51 +95,48 @@ const exec = (str, cols, opts) => {
|
|
130
95
|
}
|
131
96
|
|
132
97
|
// In 'hard' wrap mode, the length of a line is
|
133
|
-
// never allowed to extend past '
|
134
|
-
if (lengths[
|
98
|
+
// never allowed to extend past 'columns'
|
99
|
+
if (lengths[index] > columns && options.hard) {
|
135
100
|
if (rowLength) {
|
136
101
|
rows.push('');
|
137
102
|
}
|
138
|
-
wrapWord(rows, word,
|
103
|
+
wrapWord(rows, word, columns);
|
139
104
|
continue;
|
140
105
|
}
|
141
106
|
|
142
|
-
if (rowLength + lengths[
|
143
|
-
if (options.wordWrap === false && rowLength <
|
144
|
-
wrapWord(rows, word,
|
107
|
+
if (rowLength + lengths[index] > columns && rowLength > 0) {
|
108
|
+
if (options.wordWrap === false && rowLength < columns) {
|
109
|
+
wrapWord(rows, word, columns);
|
145
110
|
continue;
|
146
111
|
}
|
147
112
|
|
148
113
|
rows.push('');
|
149
114
|
}
|
150
115
|
|
151
|
-
if (rowLength + lengths[
|
152
|
-
wrapWord(rows, word,
|
116
|
+
if (rowLength + lengths[index] > columns && options.wordWrap === false) {
|
117
|
+
wrapWord(rows, word, columns);
|
153
118
|
continue;
|
154
119
|
}
|
155
120
|
|
156
121
|
rows[rows.length - 1] += word;
|
157
122
|
}
|
158
123
|
|
159
|
-
pre = rows.map(
|
160
|
-
|
161
|
-
for (const item of Array.from(pre).entries()) {
|
162
|
-
const i = item[0];
|
163
|
-
const char = item[1];
|
124
|
+
pre = rows.map(row => options.trim === false ? row : row.trim()).join('\n');
|
164
125
|
|
165
|
-
|
126
|
+
for (const [index, character] of [...pre].entries()) {
|
127
|
+
ret += character;
|
166
128
|
|
167
|
-
if (ESCAPES.has(
|
168
|
-
const code = parseFloat(/\d[^m]*/.exec(pre.slice(
|
129
|
+
if (ESCAPES.has(character)) {
|
130
|
+
const code = parseFloat(/\d[^m]*/.exec(pre.slice(index, index + 4)));
|
169
131
|
escapeCode = code === END_CODE ? null : code;
|
170
132
|
}
|
171
133
|
|
172
|
-
const code =
|
134
|
+
const code = ansiStyles.codes.get(Number(escapeCode));
|
173
135
|
|
174
136
|
if (escapeCode && code) {
|
175
|
-
if (pre[
|
137
|
+
if (pre[index + 1] === '\n') {
|
176
138
|
ret += wrapAnsi(code);
|
177
|
-
} else if (
|
139
|
+
} else if (character === '\n') {
|
178
140
|
ret += wrapAnsi(escapeCode);
|
179
141
|
}
|
180
142
|
}
|
@@ -184,10 +146,10 @@ const exec = (str, cols, opts) => {
|
|
184
146
|
};
|
185
147
|
|
186
148
|
// For each newline, invoke the method separately
|
187
|
-
module.exports = (
|
188
|
-
return String(
|
149
|
+
module.exports = (string, columns, options) => {
|
150
|
+
return String(string)
|
189
151
|
.normalize()
|
190
152
|
.split('\n')
|
191
|
-
.map(line => exec(line,
|
153
|
+
.map(line => exec(line, columns, options))
|
192
154
|
.join('\n');
|
193
155
|
};
|
package/package.json
CHANGED
@@ -1,62 +1,62 @@
|
|
1
1
|
{
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
2
|
+
"name": "wrap-ansi",
|
3
|
+
"version": "4.0.0",
|
4
|
+
"description": "Wordwrap a string with ANSI escape codes",
|
5
|
+
"license": "MIT",
|
6
|
+
"repository": "chalk/wrap-ansi",
|
7
|
+
"author": {
|
8
|
+
"name": "Sindre Sorhus",
|
9
|
+
"email": "sindresorhus@gmail.com",
|
10
|
+
"url": "sindresorhus.com"
|
11
|
+
},
|
12
|
+
"engines": {
|
13
|
+
"node": ">=6"
|
14
|
+
},
|
15
|
+
"scripts": {
|
16
|
+
"test": "xo && nyc ava"
|
17
|
+
},
|
18
|
+
"files": [
|
19
|
+
"index.js"
|
20
|
+
],
|
21
|
+
"keywords": [
|
22
|
+
"wrap",
|
23
|
+
"break",
|
24
|
+
"wordwrap",
|
25
|
+
"wordbreak",
|
26
|
+
"linewrap",
|
27
|
+
"ansi",
|
28
|
+
"styles",
|
29
|
+
"color",
|
30
|
+
"colour",
|
31
|
+
"colors",
|
32
|
+
"terminal",
|
33
|
+
"console",
|
34
|
+
"cli",
|
35
|
+
"string",
|
36
|
+
"tty",
|
37
|
+
"escape",
|
38
|
+
"formatting",
|
39
|
+
"rgb",
|
40
|
+
"256",
|
41
|
+
"shell",
|
42
|
+
"xterm",
|
43
|
+
"log",
|
44
|
+
"logging",
|
45
|
+
"command-line",
|
46
|
+
"text"
|
47
|
+
],
|
48
|
+
"dependencies": {
|
49
|
+
"ansi-styles": "^3.2.0",
|
50
|
+
"string-width": "^2.1.1",
|
51
|
+
"strip-ansi": "^4.0.0"
|
52
|
+
},
|
53
|
+
"devDependencies": {
|
54
|
+
"ava": "^0.25.0",
|
55
|
+
"chalk": "^2.0.1",
|
56
|
+
"coveralls": "^3.0.0",
|
57
|
+
"has-ansi": "^3.0.0",
|
58
|
+
"nyc": "^13.0.1",
|
59
|
+
"strip-ansi": "^4.0.0",
|
60
|
+
"xo": "^0.22.0"
|
61
|
+
}
|
62
62
|
}
|