cli-color
Advanced tools
Comparing version 0.3.3 to 1.0.0
144
index.js
'use strict'; | ||
var d = require('d') | ||
, assign = require('es5-ext/object/assign') | ||
, forEach = require('es5-ext/object/for-each') | ||
, map = require('es5-ext/object/map') | ||
, repeat = require('es5-ext/string/#/repeat') | ||
, memoize = require('memoizee') | ||
, memoizeMethods = require('memoizee/methods') | ||
, tty = require('tty') | ||
var d = require('d'); | ||
, join = Array.prototype.join, defineProperty = Object.defineProperty | ||
, defineProperties = Object.defineProperties, abs = Math.abs | ||
, floor = Math.floor, max = Math.max, min = Math.min | ||
, mods, proto, getFn, getMove, xtermMatch | ||
, up, down, right, left, getHeight, memoized; | ||
mods = assign({ | ||
// Style | ||
bold: { _bold: [1, 22] }, | ||
italic: { _italic: [3, 23] }, | ||
underline: { _underline: [4, 24] }, | ||
blink: { _blink: [5, 25] }, | ||
inverse: { _inverse: [7, 27] }, | ||
strike: { _strike: [9, 29] } | ||
}, | ||
// Color | ||
['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'] | ||
.reduce(function (obj, color, index) { | ||
// foreground | ||
obj[color] = { _fg: [30 + index, 39] }; | ||
obj[color + 'Bright'] = { _fg: [90 + index, 39] }; | ||
// background | ||
obj['bg' + color[0].toUpperCase() + color.slice(1)] = | ||
{ _bg: [40 + index, 49] }; | ||
obj['bg' + color[0].toUpperCase() + color.slice(1) + 'Bright'] = | ||
{ _bg: [100 + index, 49] }; | ||
return obj; | ||
}, {})); | ||
// Some use cli-color as: console.log(clc.red('Error!')); | ||
// Which is inefficient as on each call it configures new clc object | ||
// with memoization we reuse once created object | ||
memoized = memoize(function (scope, mod) { | ||
return defineProperty(getFn(), '_cliColorData', | ||
d(assign({}, scope._cliColorData, mod))); | ||
module.exports = Object.defineProperties(require('./bare'), { | ||
windowSize: d(require('./window-size')), | ||
erase: d(require('./erase')), | ||
move: d(require('./move')), | ||
beep: d(require('./beep')), | ||
columns: d(require('./columns')), | ||
strip: d(require('./strip')), | ||
throbber: d(require('./throbber')), | ||
reset: d(require('./reset')), | ||
art: d(require('./art')) | ||
}); | ||
proto = Object.create(Function.prototype, assign(map(mods, function (mod) { | ||
return d.gs(function () { return memoized(this, mod); }); | ||
}), memoizeMethods({ | ||
// xterm (255) color | ||
xterm: d(function (code) { | ||
code = isNaN(code) ? 255 : min(max(code, 0), 255); | ||
return defineProperty(getFn(), '_cliColorData', | ||
d(assign({}, this._cliColorData, { | ||
_fg: [xtermMatch ? xtermMatch[code] : ('38;5;' + code), 39] | ||
}))); | ||
}), | ||
bgXterm: d(function (code) { | ||
code = isNaN(code) ? 255 : min(max(code, 0), 255); | ||
return defineProperty(getFn(), '_cliColorData', | ||
d(assign({}, this._cliColorData, { | ||
_bg: [xtermMatch ? (xtermMatch[code] + 10) : ('48;5;' + code), 49] | ||
}))); | ||
}) | ||
}))); | ||
if (process.platform === 'win32') { | ||
xtermMatch = require('./lib/xterm-match'); | ||
} | ||
getFn = function () { | ||
var fn = function (/*…msg*/) { | ||
var start = '', end = ''; | ||
forEach(fn._cliColorData, function (mod) { | ||
end = '\x1b[' + mod[1] + 'm' + end; | ||
start += '\x1b[' + mod[0] + 'm'; | ||
}, null, true); | ||
return start + join.call(arguments, ' ') + end; | ||
}; | ||
fn.__proto__ = proto; | ||
return fn; | ||
}; | ||
getMove = function (control) { | ||
return function (num) { | ||
num = isNaN(num) ? 0 : max(floor(num), 0); | ||
return num ? ('\x1b[' + num + control) : ''; | ||
}; | ||
}; | ||
module.exports = defineProperties(getFn(), { | ||
width: d.gs(process.stdout.getWindowSize ? function () { | ||
return process.stdout.getWindowSize()[0]; | ||
} : function () { | ||
return tty.getWindowSize ? tty.getWindowSize()[1] : 0; | ||
}), | ||
height: d.gs(getHeight = process.stdout.getWindowSize ? function () { | ||
return process.stdout.getWindowSize()[1]; | ||
} : function () { | ||
return tty.getWindowSize ? tty.getWindowSize()[0] : 0; | ||
}), | ||
reset: d.gs(function () { | ||
return repeat.call('\n', getHeight() - 1) + '\x1bc'; | ||
}), | ||
up: d(up = getMove('A')), | ||
down: d(down = getMove('B')), | ||
right: d(right = getMove('C')), | ||
left: d(left = getMove('D')), | ||
move: d(function (x, y) { | ||
x = isNaN(x) ? 0 : floor(x); | ||
y = isNaN(y) ? 0 : floor(y); | ||
return ((x > 0) ? right(x) : left(-x)) + ((y > 0) ? down(y) : up(-y)); | ||
}), | ||
moveTo: d(function (x, y) { | ||
x = isNaN(x) ? 1 : (max(floor(x), 0) + 1); | ||
y = isNaN(y) ? 1 : (max(floor(y), 0) + 1); | ||
return '\x1b[' + y + ';' + x + 'H'; | ||
}), | ||
bol: d(function (n/*, erase*/) { | ||
var dir; | ||
n = isNaN(n) ? 0 : Number(n); | ||
dir = (n >= 0) ? 'E' : 'F'; | ||
n = floor(abs(n)); | ||
return arguments[1] ? | ||
(((!n || (dir === 'F')) ? '\x1b[0E\x1bK' : '') + | ||
repeat.call('\x1b[1' + dir + '\x1b[K', n)) : '\x1b[' + n + dir; | ||
}), | ||
beep: d('\x07'), | ||
xtermSupported: d(!xtermMatch), | ||
_cliColorData: d({}) | ||
}); |
{ | ||
"name": "cli-color", | ||
"version": "0.3.3", | ||
"version": "1.0.0", | ||
"description": "Colors, formatting and other tools for the console", | ||
@@ -22,4 +22,6 @@ "author": "Mariusz Nowak <medyk@medikoo.com> (http://www.medikoo.com/)", | ||
"dependencies": { | ||
"d": "~0.1.1", | ||
"es5-ext": "~0.10.6", | ||
"ansi-regex": "^1.1.1", | ||
"d": "^0.1.1", | ||
"es5-ext": "^0.10.7", | ||
"es6-iterator": "^0.1.3", | ||
"memoizee": "~0.3.8", | ||
@@ -29,5 +31,5 @@ "timers-ext": "0.1" | ||
"devDependencies": { | ||
"tad": "~0.2.2", | ||
"xlint": "~0.2.2", | ||
"xlint-jslint-medikoo": "~0.1.2" | ||
"tad": "^0.2.2", | ||
"xlint": "^0.2.2", | ||
"xlint-jslint-medikoo": "^0.1.2" | ||
}, | ||
@@ -34,0 +36,0 @@ "scripts": { |
137
README.md
@@ -36,2 +36,8 @@ # cli-color | ||
Styled text can be nested: | ||
```javascript | ||
console.log(clc.red('red ' + clc.blue('blue') + ' red')); | ||
``` | ||
__Best way is to predefine needed stylings and then use it__: | ||
@@ -457,3 +463,3 @@ | ||
#### Terminal reset | ||
#### Reset | ||
@@ -463,5 +469,55 @@ Terminal can be cleared with `clc.reset` | ||
```javascript | ||
console.log(clc.reset); | ||
process.stdout.write(clc.reset); | ||
``` | ||
#### Erase | ||
##### clc.erase.screen | ||
Entire screen | ||
```javascript | ||
process.stdout.write(clc.erase.screen); | ||
``` | ||
##### clc.erase.screenLeft | ||
Left portion of a screen | ||
```javascript | ||
process.stdout.write(clc.erase.screenLeft); | ||
``` | ||
##### clc.erase.screenRight | ||
Right portion of a screen | ||
```javascript | ||
process.stdout.write(clc.erase.screenRight); | ||
``` | ||
##### clc.erase.line | ||
Current line | ||
```javascript | ||
process.stdout.write(clc.erase.line); | ||
``` | ||
##### clc.erase.lineRight | ||
Right portion of current line | ||
```javascript | ||
process.stdout.write(clc.erase.lineRight); | ||
``` | ||
##### clc.erase.lineLeft | ||
Left portion of current line | ||
```javascript | ||
process.stdout.write(clc.erase.lineLeft); | ||
``` | ||
#### Move around functions | ||
@@ -477,3 +533,3 @@ | ||
##### clc.moveTo(x, y) | ||
##### clc.move.to(x, y) | ||
@@ -483,53 +539,82 @@ Absolute move. Sets cursor position at _x_ column and _y_ row | ||
```javascript | ||
process.stdout.write(clc.moveTo(0, 0)); // Move cursor to first row and first column in terminal window | ||
process.stdout.write(clc.move.to(0, 0)); // Move cursor to first row and first column in terminal window | ||
``` | ||
##### clc.bol([n[, erase]]) | ||
##### clc.move.up(n) | ||
Move cursor to the begining of the line, with _n_ we may specify how many lines away we want to move, value can be positive or negative. Additionally we may decide to clear lines content with _erase_ | ||
Move cursor up _n_ rows | ||
```javascript | ||
process.stdout.write(clc.bol(-2)); // Move cursor two lines back and place it at begin of the line | ||
process.stdout.write(clc.move.up(2)); | ||
``` | ||
##### clc.up(n) | ||
##### clc.move.down(n) | ||
Move cursor up _n_ rows | ||
Move cursor down _n_ rows | ||
##### clc.down(n) | ||
```javascript | ||
process.stdout.write(clc.move.down(2)); | ||
``` | ||
Move cursor down _n_ rows | ||
##### clc.move.right(n) | ||
##### clc.right(n) | ||
Move cursor right _n_ columns | ||
##### clc.left(n) | ||
```javascript | ||
process.stdout.write(clc.move.right(2)); | ||
``` | ||
##### clc.move.left(n) | ||
Move cursor left _n_ columns | ||
```javascript | ||
process.stdout.write(clc.move.left(2)); | ||
``` | ||
##### clc.move.lines(n) | ||
Move cursor `n` lines forward if `n` is positive, otherwise `n` lines backward. | ||
```javascript | ||
process.stdout.write(clc.move.lines(2)); | ||
``` | ||
#### Terminal characteristics | ||
##### clc.width | ||
##### clc.windowSize.width | ||
Returns terminal width | ||
##### clc.height | ||
##### clc.windowSize.height | ||
Returns terminal height | ||
### Additional functionalities (provided as separate modules) | ||
### Additional functionalities | ||
#### trim(formatedText) _(cli-color/trim)_ | ||
#### clc.strip(formatedText) | ||
Trims ANSI formatted string to plain text | ||
Strips ANSI formatted string to plain text | ||
```javascript | ||
var ansiTrim = require('cli-color/trim'); | ||
var ansiStrip = require('cli-color/strip'); | ||
var plain = ansiTrim(formatted); | ||
var plain = ansiStrip(formatted); | ||
``` | ||
#### throbber(write, interval[, format]) _(cli-color/throbber)_ | ||
#### clc.art(text, styleConf) | ||
Create a text-graphical art. Within `styleConf`, string replacements needs to be defined, which are then used to convert `text` to styled graphical text. | ||
```javascript | ||
var text = '.........\n' + | ||
'. Hello .\n' + | ||
'.........\n'; | ||
var style = { ".": clc.yellowBright("X") }; | ||
process.stdout.write(clc.art(text, style)); | ||
``` | ||
##### throbber(write, interval[, format]) | ||
Writes throbber string to _write_ function at given _interval_. Optionally throbber output can be formatted with given _format_ function | ||
@@ -553,1 +638,9 @@ | ||
$ npm test | ||
## Contributors | ||
* [@rentalhost](https://github.com/rentalhost) (David Rodrigues) | ||
* Help with support for nested styles. Introduction of `clc.art` module, and significant improvements to tests coverage. | ||
'use strict'; | ||
var bareTests = require('./bare'); | ||
module.exports = function (t, a) { | ||
var x, y; | ||
bareTests(t, a); | ||
a(t('test'), 'test', "Plain"); | ||
a(t('test', 'foo', 3, { toString: function () { return 'bar'; } }), | ||
'test foo 3 bar', "Plain: Many args"); | ||
a(typeof t.windowSize.width, 'number', "Width"); | ||
a(t.red('foo'), '\x1b[31mfoo\x1b[39m', "Foreground"); | ||
a(t.red('foo', 'bar', 3), '\x1b[31mfoo bar 3\x1b[39m', | ||
"Foreground: Many args"); | ||
a(t.red.yellow('foo', 'bar', 3), '\x1b[33mfoo bar 3\x1b[39m', | ||
"Foreground: Overriden"); | ||
a(t.bgRed('foo', 'bar'), '\x1b[41mfoo bar\x1b[49m', "Background"); | ||
a(t.bgRed.bgYellow('foo', 'bar', 3), '\x1b[43mfoo bar 3\x1b[49m', | ||
"Background: Overriden"); | ||
a(t.blue.bgYellow('foo', 'bar'), '\x1b[43m\x1b[34mfoo bar\x1b[39m\x1b[49m', | ||
"Foreground & Background"); | ||
a(t.blue.bgYellow.red.bgMagenta('foo', 'bar'), | ||
'\x1b[45m\x1b[31mfoo bar\x1b[39m\x1b[49m', | ||
"Foreground & Background: Overriden"); | ||
a(t.bold('foo', 'bar'), '\x1b[1mfoo bar\x1b[22m', "Format"); | ||
a(t.blink('foobar'), '\x1b[5mfoobar\x1b[25m', "Format: blink"); | ||
a(t.bold.blue('foo', 'bar', 3), '\x1b[1m\x1b[34mfoo bar 3\x1b[39m\x1b[22m', | ||
"Foreground & Format"); | ||
a(t.redBright('foo', 'bar'), '\x1b[91mfoo bar\x1b[39m', "Bright"); | ||
a(t.bgRedBright('foo', 3), '\x1b[101mfoo 3\x1b[49m', "Bright background"); | ||
a(t.blueBright.bgYellowBright.red.bgMagenta('foo', 'bar'), | ||
'\x1b[45m\x1b[31mfoo bar\x1b[39m\x1b[49m', | ||
"Foreground & Background: Bright: Overriden"); | ||
x = t.red; | ||
y = x.bold; | ||
a(x('foo', 'red') + ' ' + y('foo', 'boldred'), | ||
'\x1b[31mfoo red\x1b[39m \x1b[1m\x1b[31mfoo boldred\x1b[39m\x1b[22m', | ||
"Detached extension"); | ||
if (t.xtermSupported) { | ||
a(t.xterm(12).bgXterm(67)('foo', 'xterm'), | ||
'\x1b[48;5;67m\x1b[38;5;12mfoo xterm\x1b[39m\x1b[49m', "Xterm"); | ||
a(t.redBright.bgBlueBright.xterm(12).bgXterm(67)('foo', 'xterm'), | ||
'\x1b[48;5;67m\x1b[38;5;12mfoo xterm\x1b[39m\x1b[49m', | ||
"Xterm: Override & Bright"); | ||
a(t.xterm(12).bgXterm(67).redBright.bgMagentaBright('foo', 'xterm'), | ||
'\x1b[105m\x1b[91mfoo xterm\x1b[39m\x1b[49m', | ||
"Xterm: Override & Bright #2"); | ||
} else { | ||
a(t.xterm(12).bgXterm(67)('foo', 'xterm'), | ||
'\x1b[100m\x1b[94mfoo xterm\x1b[39m\x1b[49m', "Xterm"); | ||
} | ||
a(typeof t.width, 'number', "Width"); | ||
a(typeof t.height, 'number', "Height"); | ||
a(/\n*\x1bc/.test(t.reset), true, "Reset"); | ||
a(t.up(), '', "Up: No argument"); | ||
a(t.up({}), '', "Up: Not a number"); | ||
a(t.up(-34), '', "Up: Negative"); | ||
a(t.up(34), '\x1b[34A', "Up: Positive"); | ||
a(t.down(), '', "Down: No argument"); | ||
a(t.down({}), '', "Down: Not a number"); | ||
a(t.down(-34), '', "Down: Negative"); | ||
a(t.down(34), '\x1b[34B', "Down: Positive"); | ||
a(t.right(), '', "Right: No argument"); | ||
a(t.right({}), '', "Right: Not a number"); | ||
a(t.right(-34), '', "Right: Negative"); | ||
a(t.right(34), '\x1b[34C', "Right: Positive"); | ||
a(t.left(), '', "Left: No argument"); | ||
a(t.left({}), '', "Left: Not a number"); | ||
a(t.left(-34), '', "Left: Negative"); | ||
a(t.left(34), '\x1b[34D', "Left: Positive"); | ||
a(t.move(), '', "Move: No arguments"); | ||
a(t.move({}, {}), '', "Move: Bad arguments"); | ||
a(t.move({}, 12), '\x1b[12B', "Move: One direction"); | ||
a(t.move(0, -12), '\x1b[12A', "Move: One negative direction"); | ||
a(t.move(-42, -2), '\x1b[42D\x1b[2A', "Move: two negatives"); | ||
a(t.move.up(34), '\x1b[34A', "Up: Positive"); | ||
a(t.move(2, 35), '\x1b[2C\x1b[35B', "Move: two positives"); | ||
a(t.moveTo(), '\x1b[1;1H', "MoveTo: No arguments"); | ||
a(t.moveTo({}, {}), '\x1b[1;1H', "MoveTo: Bad arguments"); | ||
a(t.moveTo({}, 12), '\x1b[13;1H', "MoveTo: One direction"); | ||
a(t.moveTo(2, -12), '\x1b[1;3H', "MoveTo: One negative direction"); | ||
a(t.moveTo(-42, -2), '\x1b[1;1H', "MoveTo: two negatives"); | ||
a(t.moveTo(2, 35), '\x1b[36;3H', "MoveTo: two positives"); | ||
a(t.erase.screen, '\x1b[2J', "Erase"); | ||
a(t.bol(), '\x1b[0E', "Bol: No argument"); | ||
a(t.bol({}), '\x1b[0E', "Bol: Not a number"); | ||
a(t.bol(-34), '\x1b[34F', "Bol: Negative"); | ||
a(t.bol(34), '\x1b[34E', "Bol: Positive"); | ||
a(t.bol({}, true), '\x1b[0E\x1bK', "Bol: Erase: Not a number"); | ||
a(t.bol(-2, true), '\x1b[0E\x1bK\x1b[1F\x1b[K\x1b[1F\x1b[K', | ||
"Bol: Erase: Negative"); | ||
a(t.bol(2, true), '\x1b[1E\x1b[K\x1b[1E\x1b[K', | ||
"Bol: Erase: Positive"); | ||
a(t.beep, '\x07', "Beep"); | ||
}; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
75586
37
921
1
641
6
2
+ Addedansi-regex@^1.1.1
+ Addedes6-iterator@^0.1.3
+ Addedansi-regex@1.1.1(transitive)
Updatedd@^0.1.1
Updatedes5-ext@^0.10.7