wrap-ansi
Advanced tools
Comparing version 2.1.0 to 3.0.0
209
index.js
'use strict'; | ||
var stringWidth = require('string-width'); | ||
var stripAnsi = require('strip-ansi'); | ||
const stringWidth = require('string-width'); | ||
const stripAnsi = require('strip-ansi'); | ||
var ESCAPES = [ | ||
'\u001b', | ||
'\u009b' | ||
]; | ||
const ESCAPES = new Set([ | ||
'\u001B', | ||
'\u009B' | ||
]); | ||
var END_CODE = 39; | ||
const END_CODE = 39; | ||
var ESCAPE_CODES = { | ||
0: 0, | ||
1: 22, | ||
2: 22, | ||
3: 23, | ||
4: 24, | ||
7: 27, | ||
8: 28, | ||
9: 29, | ||
30: 39, | ||
31: 39, | ||
32: 39, | ||
33: 39, | ||
34: 39, | ||
35: 39, | ||
36: 39, | ||
37: 39, | ||
90: 39, | ||
40: 49, | ||
41: 49, | ||
42: 49, | ||
43: 49, | ||
44: 49, | ||
45: 49, | ||
46: 49, | ||
47: 49 | ||
}; | ||
const ESCAPE_CODES = new Map([ | ||
[0, 0], | ||
[1, 22], | ||
[2, 22], | ||
[3, 23], | ||
[4, 24], | ||
[7, 27], | ||
[8, 28], | ||
[9, 29], | ||
[30, 39], | ||
[31, 39], | ||
[32, 39], | ||
[33, 39], | ||
[34, 39], | ||
[35, 39], | ||
[36, 39], | ||
[37, 39], | ||
[90, 39], | ||
[40, 49], | ||
[41, 49], | ||
[42, 49], | ||
[43, 49], | ||
[44, 49], | ||
[45, 49], | ||
[46, 49], | ||
[47, 49] | ||
]); | ||
function wrapAnsi(code) { | ||
return ESCAPES[0] + '[' + code + 'm'; | ||
} | ||
const wrapAnsi = code => `${ESCAPES.values().next().value}[${code}m`; | ||
// calculate the length of words split on ' ', ignoring | ||
// the extra characters added by ansi escape codes. | ||
function wordLengths(str) { | ||
return str.split(' ').map(function (s) { | ||
return stringWidth(s); | ||
}); | ||
} | ||
// Calculate the length of words split on ' ', ignoring | ||
// the extra characters added by ansi escape codes | ||
const wordLengths = str => str.split(' ').map(s => stringWidth(s)); | ||
// wrap a long word across multiple rows. | ||
// ansi escape codes do not count towards length. | ||
function wrapWord(rows, word, cols) { | ||
var insideEscape = false; | ||
var visible = stripAnsi(rows[rows.length - 1]).length; | ||
// Wrap a long word across multiple rows | ||
// Ansi escape codes do not count towards length | ||
const wrapWord = (rows, word, cols) => { | ||
const arr = Array.from(word); | ||
for (var i = 0; i < word.length; i++) { | ||
var x = word[i]; | ||
let insideEscape = false; | ||
let visible = stringWidth(stripAnsi(rows[rows.length - 1])); | ||
rows[rows.length - 1] += x; | ||
for (const item of arr.entries()) { | ||
const i = item[0]; | ||
const char = item[1]; | ||
const charLength = stringWidth(char); | ||
if (ESCAPES.indexOf(x) !== -1) { | ||
if (visible + charLength <= cols) { | ||
rows[rows.length - 1] += char; | ||
} else { | ||
rows.push(char); | ||
visible = 0; | ||
} | ||
if (ESCAPES.has(char)) { | ||
insideEscape = true; | ||
} else if (insideEscape && x === 'm') { | ||
} else if (insideEscape && char === 'm') { | ||
insideEscape = false; | ||
@@ -74,5 +77,5 @@ continue; | ||
visible++; | ||
visible += charLength; | ||
if (visible >= cols && i < word.length - 1) { | ||
if (visible === cols && i < arr.length - 1) { | ||
rows.push(''); | ||
@@ -83,31 +86,41 @@ visible = 0; | ||
// it's possible that the last row we copy over is only | ||
// ansi escape characters, handle this edge-case. | ||
// It's possible that the last row we copy over is only | ||
// ansi escape characters, handle this edge-case | ||
if (!visible && rows[rows.length - 1].length > 0 && rows.length > 1) { | ||
rows[rows.length - 2] += rows.pop(); | ||
} | ||
} | ||
}; | ||
// the wrap-ansi module can be invoked | ||
// in either 'hard' or 'soft' wrap mode. | ||
// The wrap-ansi module can be invoked | ||
// in either 'hard' or 'soft' wrap mode | ||
// | ||
// 'hard' will never allow a string to take up more | ||
// than cols characters. | ||
// than cols characters | ||
// | ||
// 'soft' allows long words to expand past the column length. | ||
function exec(str, cols, opts) { | ||
var options = opts || {}; | ||
// 'soft' allows long words to expand past the column length | ||
const exec = (str, cols, opts) => { | ||
const options = opts || {}; | ||
var pre = ''; | ||
var ret = ''; | ||
var escapeCode; | ||
let pre = ''; | ||
let ret = ''; | ||
let escapeCode; | ||
var lengths = wordLengths(str); | ||
var words = str.split(' '); | ||
var rows = ['']; | ||
const lengths = wordLengths(str); | ||
const words = str.split(' '); | ||
const rows = ['']; | ||
for (var i = 0, word; (word = words[i]) !== undefined; i++) { | ||
var rowLength = stringWidth(rows[rows.length - 1]); | ||
for (const item of Array.from(words).entries()) { | ||
const i = item[0]; | ||
const word = item[1]; | ||
if (rowLength) { | ||
rows[rows.length - 1] = options.trim === false ? rows[rows.length - 1] : rows[rows.length - 1].trim(); | ||
let rowLength = stringWidth(rows[rows.length - 1]); | ||
if (rowLength || word === '') { | ||
if (rowLength === cols && options.wordWrap === false) { | ||
// If we start with a new word but the current row length equals the length of the columns, add a new row | ||
rows.push(''); | ||
rowLength = 0; | ||
} | ||
rows[rows.length - 1] += ' '; | ||
@@ -117,4 +130,4 @@ rowLength++; | ||
// in 'hard' wrap mode, the length of a line is | ||
// never allowed to extend past 'cols'. | ||
// In 'hard' wrap mode, the length of a line is | ||
// never allowed to extend past 'cols' | ||
if (lengths[i] > cols && options.hard) { | ||
@@ -137,23 +150,29 @@ if (rowLength) { | ||
if (rowLength + lengths[i] > cols && options.wordWrap === false) { | ||
wrapWord(rows, word, cols); | ||
continue; | ||
} | ||
rows[rows.length - 1] += word; | ||
} | ||
pre = rows.map(function (r) { | ||
return r.trim(); | ||
}).join('\n'); | ||
pre = rows.map(r => options.trim === false ? r : r.trim()).join('\n'); | ||
for (var j = 0; j < pre.length; j++) { | ||
var y = pre[j]; | ||
for (const item of Array.from(pre).entries()) { | ||
const i = item[0]; | ||
const char = item[1]; | ||
ret += y; | ||
ret += char; | ||
if (ESCAPES.indexOf(y) !== -1) { | ||
var code = parseFloat(/[0-9][^m]*/.exec(pre.slice(j, j + 4))); | ||
if (ESCAPES.has(char)) { | ||
const code = parseFloat(/\d[^m]*/.exec(pre.slice(i, i + 4))); | ||
escapeCode = code === END_CODE ? null : code; | ||
} | ||
if (escapeCode && ESCAPE_CODES[escapeCode]) { | ||
if (pre[j + 1] === '\n') { | ||
ret += wrapAnsi(ESCAPE_CODES[escapeCode]); | ||
} else if (y === '\n') { | ||
const code = ESCAPE_CODES.get(Number(escapeCode)); | ||
if (escapeCode && code) { | ||
if (pre[i + 1] === '\n') { | ||
ret += wrapAnsi(code); | ||
} else if (char === '\n') { | ||
ret += wrapAnsi(escapeCode); | ||
@@ -165,9 +184,11 @@ } | ||
return ret; | ||
} | ||
}; | ||
// for each line break, invoke the method separately. | ||
module.exports = function (str, cols, opts) { | ||
return String(str).split('\n').map(function (substr) { | ||
return exec(substr, cols, opts); | ||
}).join('\n'); | ||
// For each newline, invoke the method separately | ||
module.exports = (str, cols, opts) => { | ||
return String(str) | ||
.normalize() | ||
.split('\n') | ||
.map(line => exec(line, cols, opts)) | ||
.join('\n'); | ||
}; |
126
package.json
{ | ||
"name": "wrap-ansi", | ||
"version": "2.1.0", | ||
"description": "Wordwrap a string with ANSI escape codes", | ||
"license": "MIT", | ||
"repository": "chalk/wrap-ansi", | ||
"author": { | ||
"name": "Sindre Sorhus", | ||
"email": "sindresorhus@gmail.com", | ||
"url": "sindresorhus.com" | ||
}, | ||
"maintainers": [ | ||
"Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)", | ||
"Joshua Appelman <jappelman@xebia.com> (jbnicolai.com)", | ||
"JD Ballard <i.am.qix@gmail.com> (github.com/qix-)", | ||
"Benjamin Coe <ben@npmjs.com> (github.com/bcoe)" | ||
], | ||
"engines": { | ||
"node": ">=0.10.0" | ||
}, | ||
"scripts": { | ||
"test": "xo && nyc ava", | ||
"coveralls": "nyc report --reporter=text-lcov | coveralls" | ||
}, | ||
"files": [ | ||
"index.js" | ||
], | ||
"keywords": [ | ||
"wrap", | ||
"break", | ||
"wordwrap", | ||
"wordbreak", | ||
"linewrap", | ||
"ansi", | ||
"styles", | ||
"color", | ||
"colour", | ||
"colors", | ||
"terminal", | ||
"console", | ||
"cli", | ||
"string", | ||
"tty", | ||
"escape", | ||
"formatting", | ||
"rgb", | ||
"256", | ||
"shell", | ||
"xterm", | ||
"log", | ||
"logging", | ||
"command-line", | ||
"text" | ||
], | ||
"dependencies": { | ||
"string-width": "^1.0.1", | ||
"strip-ansi": "^3.0.1" | ||
}, | ||
"devDependencies": { | ||
"ava": "^0.16.0", | ||
"chalk": "^1.1.0", | ||
"coveralls": "^2.11.4", | ||
"has-ansi": "^2.0.0", | ||
"nyc": "^6.2.1", | ||
"strip-ansi": "^3.0.0", | ||
"xo": "*" | ||
} | ||
"name": "wrap-ansi", | ||
"version": "3.0.0", | ||
"description": "Wordwrap a string with ANSI escape codes", | ||
"license": "MIT", | ||
"repository": "chalk/wrap-ansi", | ||
"author": { | ||
"name": "Sindre Sorhus", | ||
"email": "sindresorhus@gmail.com", | ||
"url": "sindresorhus.com" | ||
}, | ||
"engines": { | ||
"node": ">=4" | ||
}, | ||
"scripts": { | ||
"test": "xo && nyc ava", | ||
"coveralls": "nyc report --reporter=text-lcov | coveralls" | ||
}, | ||
"files": [ | ||
"index.js" | ||
], | ||
"keywords": [ | ||
"wrap", | ||
"break", | ||
"wordwrap", | ||
"wordbreak", | ||
"linewrap", | ||
"ansi", | ||
"styles", | ||
"color", | ||
"colour", | ||
"colors", | ||
"terminal", | ||
"console", | ||
"cli", | ||
"string", | ||
"tty", | ||
"escape", | ||
"formatting", | ||
"rgb", | ||
"256", | ||
"shell", | ||
"xterm", | ||
"log", | ||
"logging", | ||
"command-line", | ||
"text" | ||
], | ||
"dependencies": { | ||
"string-width": "^2.1.1", | ||
"strip-ansi": "^4.0.0" | ||
}, | ||
"devDependencies": { | ||
"ava": "^0.21.0", | ||
"chalk": "^2.0.1", | ||
"coveralls": "^2.11.4", | ||
"has-ansi": "^3.0.0", | ||
"nyc": "^11.0.3", | ||
"strip-ansi": "^4.0.0", | ||
"xo": "^0.18.2" | ||
} | ||
} |
# 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) | ||
> Wordwrap a string with [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors_and_Styles) | ||
> Wordwrap a string with [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors_and_Styles) | ||
@@ -9,3 +9,3 @@ | ||
``` | ||
$ npm install --save wrap-ansi | ||
$ npm install wrap-ansi | ||
``` | ||
@@ -49,2 +49,4 @@ | ||
Type: `Object` | ||
##### hard | ||
@@ -64,3 +66,10 @@ | ||
##### trim | ||
Type: `boolean`<br> | ||
Default: `true` | ||
Whitespace on all lines is removed by default. Set this option to `false` if you don't want to trim. | ||
## Related | ||
@@ -74,4 +83,11 @@ | ||
## Maintainers | ||
- [Sindre Sorhus](https://github.com/sindresorhus) | ||
- [Josh Junon](https://github.com/qix-) | ||
- [Benjamin Coe](https://github.com/bcoe) | ||
## License | ||
MIT © [Sindre Sorhus](https://sindresorhus.com) | ||
MIT |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
8464
155
90
1
+ Addedansi-regex@3.0.1(transitive)
+ Addedis-fullwidth-code-point@2.0.0(transitive)
+ Addedstring-width@2.1.1(transitive)
+ Addedstrip-ansi@4.0.0(transitive)
- Removedansi-regex@2.1.1(transitive)
- Removedcode-point-at@1.1.0(transitive)
- Removedis-fullwidth-code-point@1.0.0(transitive)
- Removednumber-is-nan@1.0.1(transitive)
- Removedstring-width@1.0.2(transitive)
- Removedstrip-ansi@3.0.1(transitive)
Updatedstring-width@^2.1.1
Updatedstrip-ansi@^4.0.0