wrap-ansi 6.1.0 → 8.0.1

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.
Files changed (4) hide show
  1. package/index.js +57 -29
  2. package/license +1 -1
  3. package/package.json +15 -12
  4. package/readme.md +6 -12
package/index.js CHANGED
@@ -1,16 +1,21 @@
1
- 'use strict';
2
- const stringWidth = require('string-width');
3
- const stripAnsi = require('strip-ansi');
4
- const ansiStyles = require('ansi-styles');
1
+ import stringWidth from 'string-width';
2
+ import stripAnsi from 'strip-ansi';
3
+ import ansiStyles from 'ansi-styles';
5
4
 
6
5
  const ESCAPES = new Set([
7
6
  '\u001B',
8
- '\u009B'
7
+ '\u009B',
9
8
  ]);
10
9
 
11
10
  const END_CODE = 39;
11
+ const ANSI_ESCAPE_BELL = '\u0007';
12
+ const ANSI_CSI = '[';
13
+ const ANSI_OSC = ']';
14
+ const ANSI_SGR_TERMINATOR = 'm';
15
+ const ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
12
16
 
13
- const wrapAnsi = code => `${ESCAPES.values().next().value}[${code}m`;
17
+ const wrapAnsiCode = code => `${ESCAPES.values().next().value}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
18
+ const wrapAnsiHyperlink = uri => `${ESCAPES.values().next().value}${ANSI_ESCAPE_LINK}${uri}${ANSI_ESCAPE_BELL}`;
14
19
 
15
20
  // Calculate the length of words split on ' ', ignoring
16
21
  // the extra characters added by ansi escape codes
@@ -22,6 +27,7 @@ const wrapWord = (rows, word, columns) => {
22
27
  const characters = [...word];
23
28
 
24
29
  let isInsideEscape = false;
30
+ let isInsideLinkEscape = false;
25
31
  let visible = stringWidth(stripAnsi(rows[rows.length - 1]));
26
32
 
27
33
  for (const [index, character] of characters.entries()) {
@@ -36,12 +42,19 @@ const wrapWord = (rows, word, columns) => {
36
42
 
37
43
  if (ESCAPES.has(character)) {
38
44
  isInsideEscape = true;
39
- } else if (isInsideEscape && character === 'm') {
40
- isInsideEscape = false;
41
- continue;
45
+ isInsideLinkEscape = characters.slice(index + 1).join('').startsWith(ANSI_ESCAPE_LINK);
42
46
  }
43
47
 
44
48
  if (isInsideEscape) {
49
+ if (isInsideLinkEscape) {
50
+ if (character === ANSI_ESCAPE_BELL) {
51
+ isInsideEscape = false;
52
+ isInsideLinkEscape = false;
53
+ }
54
+ } else if (character === ANSI_SGR_TERMINATOR) {
55
+ isInsideEscape = false;
56
+ }
57
+
45
58
  continue;
46
59
  }
47
60
 
@@ -61,8 +74,8 @@ const wrapWord = (rows, word, columns) => {
61
74
  };
62
75
 
63
76
  // Trims spaces from a string ignoring invisible sequences
64
- const stringVisibleTrimSpacesRight = str => {
65
- const words = str.split(' ');
77
+ const stringVisibleTrimSpacesRight = string => {
78
+ const words = string.split(' ');
66
79
  let last = words.length;
67
80
 
68
81
  while (last > 0) {
@@ -74,7 +87,7 @@ const stringVisibleTrimSpacesRight = str => {
74
87
  }
75
88
 
76
89
  if (last === words.length) {
77
- return str;
90
+ return string;
78
91
  }
79
92
 
80
93
  return words.slice(0, last).join(' ') + words.slice(last).join('');
@@ -90,16 +103,16 @@ const exec = (string, columns, options = {}) => {
90
103
  return '';
91
104
  }
92
105
 
93
- let pre = '';
94
- let ret = '';
106
+ let returnValue = '';
95
107
  let escapeCode;
108
+ let escapeUrl;
96
109
 
97
110
  const lengths = wordLengths(string);
98
111
  let rows = [''];
99
112
 
100
113
  for (const [index, word] of string.split(' ').entries()) {
101
114
  if (options.trim !== false) {
102
- rows[rows.length - 1] = rows[rows.length - 1].trimLeft();
115
+ rows[rows.length - 1] = rows[rows.length - 1].trimStart();
103
116
  }
104
117
 
105
118
  let rowLength = stringWidth(rows[rows.length - 1]);
@@ -148,39 +161,54 @@ const exec = (string, columns, options = {}) => {
148
161
  }
149
162
 
150
163
  if (options.trim !== false) {
151
- rows = rows.map(stringVisibleTrimSpacesRight);
164
+ rows = rows.map(row => stringVisibleTrimSpacesRight(row));
152
165
  }
153
166
 
154
- pre = rows.join('\n');
167
+ const pre = [...rows.join('\n')];
155
168
 
156
- for (const [index, character] of [...pre].entries()) {
157
- ret += character;
169
+ for (const [index, character] of pre.entries()) {
170
+ returnValue += character;
158
171
 
159
172
  if (ESCAPES.has(character)) {
160
- const code = parseFloat(/\d[^m]*/.exec(pre.slice(index, index + 4)));
161
- escapeCode = code === END_CODE ? null : code;
173
+ const {groups} = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`).exec(pre.slice(index).join('')) || {groups: {}};
174
+ if (groups.code !== undefined) {
175
+ const code = Number.parseFloat(groups.code);
176
+ escapeCode = code === END_CODE ? undefined : code;
177
+ } else if (groups.uri !== undefined) {
178
+ escapeUrl = groups.uri.length === 0 ? undefined : groups.uri;
179
+ }
162
180
  }
163
181
 
164
182
  const code = ansiStyles.codes.get(Number(escapeCode));
165
183
 
166
- if (escapeCode && code) {
167
- if (pre[index + 1] === '\n') {
168
- ret += wrapAnsi(code);
169
- } else if (character === '\n') {
170
- ret += wrapAnsi(escapeCode);
184
+ if (pre[index + 1] === '\n') {
185
+ if (escapeUrl) {
186
+ returnValue += wrapAnsiHyperlink('');
187
+ }
188
+
189
+ if (escapeCode && code) {
190
+ returnValue += wrapAnsiCode(code);
191
+ }
192
+ } else if (character === '\n') {
193
+ if (escapeCode && code) {
194
+ returnValue += wrapAnsiCode(escapeCode);
195
+ }
196
+
197
+ if (escapeUrl) {
198
+ returnValue += wrapAnsiHyperlink(escapeUrl);
171
199
  }
172
200
  }
173
201
  }
174
202
 
175
- return ret;
203
+ return returnValue;
176
204
  };
177
205
 
178
206
  // For each newline, invoke the method separately
179
- module.exports = (string, columns, options) => {
207
+ export default function wrapAnsi(string, columns, options) {
180
208
  return String(string)
181
209
  .normalize()
182
210
  .replace(/\r\n/g, '\n')
183
211
  .split('\n')
184
212
  .map(line => exec(line, columns, options))
185
213
  .join('\n');
186
- };
214
+ }
package/license CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
3
+ Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
6
 
package/package.json CHANGED
@@ -1,16 +1,19 @@
1
1
  {
2
2
  "name": "wrap-ansi",
3
- "version": "6.1.0",
3
+ "version": "8.0.1",
4
4
  "description": "Wordwrap a string with ANSI escape codes",
5
5
  "license": "MIT",
6
6
  "repository": "chalk/wrap-ansi",
7
+ "funding": "https://github.com/chalk/wrap-ansi?sponsor=1",
7
8
  "author": {
8
9
  "name": "Sindre Sorhus",
9
10
  "email": "sindresorhus@gmail.com",
10
- "url": "sindresorhus.com"
11
+ "url": "https://sindresorhus.com"
11
12
  },
13
+ "type": "module",
14
+ "exports": "./index.js",
12
15
  "engines": {
13
- "node": ">=8"
16
+ "node": ">=12"
14
17
  },
15
18
  "scripts": {
16
19
  "test": "xo && nyc ava"
@@ -46,16 +49,16 @@
46
49
  "text"
47
50
  ],
48
51
  "dependencies": {
49
- "ansi-styles": "^4.0.0",
50
- "string-width": "^4.1.0",
51
- "strip-ansi": "^5.0.0"
52
+ "ansi-styles": "^6.1.0",
53
+ "string-width": "^5.0.1",
54
+ "strip-ansi": "^7.0.1"
52
55
  },
53
56
  "devDependencies": {
54
- "ava": "^2.1.0",
55
- "chalk": "^2.4.2",
56
- "coveralls": "^3.0.3",
57
- "has-ansi": "^3.0.0",
58
- "nyc": "^14.1.1",
59
- "xo": "^0.24.0"
57
+ "ava": "^3.15.0",
58
+ "chalk": "^4.1.2",
59
+ "coveralls": "^3.1.1",
60
+ "has-ansi": "^5.0.1",
61
+ "nyc": "^15.1.0",
62
+ "xo": "^0.44.0"
60
63
  }
61
64
  }
package/readme.md CHANGED
@@ -1,20 +1,18 @@
1
- # wrap-ansi [![Build Status](https://travis-ci.org/chalk/wrap-ansi.svg?branch=master)](https://travis-ci.org/chalk/wrap-ansi) [![Coverage Status](https://coveralls.io/repos/github/chalk/wrap-ansi/badge.svg?branch=master)](https://coveralls.io/github/chalk/wrap-ansi?branch=master)
1
+ # wrap-ansi
2
2
 
3
3
  > Wordwrap a string with [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors_and_Styles)
4
4
 
5
-
6
5
  ## Install
7
6
 
8
7
  ```
9
8
  $ npm install wrap-ansi
10
9
  ```
11
10
 
12
-
13
11
  ## Usage
14
12
 
15
13
  ```js
16
- const chalk = require('chalk');
17
- const wrapAnsi = require('wrap-ansi');
14
+ import chalk from 'chalk';
15
+ import wrapAnsi from 'wrap-ansi';
18
16
 
19
17
  const input = 'The quick brown ' + chalk.red('fox jumped over ') +
20
18
  'the lazy ' + chalk.green('dog and then ran away with the unicorn.');
@@ -24,7 +22,6 @@ console.log(wrapAnsi(input, 20));
24
22
 
25
23
  <img width="331" src="screenshot.png">
26
24
 
27
-
28
25
  ## API
29
26
 
30
27
  ### wrapAnsi(string, columns, options?)
@@ -49,26 +46,25 @@ Type: `object`
49
46
 
50
47
  ##### hard
51
48
 
52
- Type: `boolean`<br>
49
+ Type: `boolean`\
53
50
  Default: `false`
54
51
 
55
52
  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.
56
53
 
57
54
  ##### wordWrap
58
55
 
59
- Type: `boolean`<br>
56
+ Type: `boolean`\
60
57
  Default: `true`
61
58
 
62
59
  By default, an attempt is made to split words at spaces, ensuring that they don't extend past the configured columns. If wordWrap is `false`, each column will instead be completely filled splitting words as necessary.
63
60
 
64
61
  ##### trim
65
62
 
66
- Type: `boolean`<br>
63
+ Type: `boolean`\
67
64
  Default: `true`
68
65
 
69
66
  Whitespace on all lines is removed by default. Set this option to `false` if you don't want to trim.
70
67
 
71
-
72
68
  ## Related
73
69
 
74
70
  - [slice-ansi](https://github.com/chalk/slice-ansi) - Slice a string with ANSI escape codes
@@ -76,14 +72,12 @@ Whitespace on all lines is removed by default. Set this option to `false` if you
76
72
  - [chalk](https://github.com/chalk/chalk) - Terminal string styling done right
77
73
  - [jsesc](https://github.com/mathiasbynens/jsesc) - Generate ASCII-only output from Unicode strings. Useful for creating test fixtures.
78
74
 
79
-
80
75
  ## Maintainers
81
76
 
82
77
  - [Sindre Sorhus](https://github.com/sindresorhus)
83
78
  - [Josh Junon](https://github.com/qix-)
84
79
  - [Benjamin Coe](https://github.com/bcoe)
85
80
 
86
-
87
81
  ---
88
82
 
89
83
  <div align="center">