├── screenshots └── colors.png ├── .travis.yml ├── lib ├── maps │ ├── zebra.js │ ├── america.js │ ├── random.js │ └── rainbow.js ├── index.js ├── custom │ ├── trap.js │ └── zalgo.js ├── system │ └── supports-colors.js ├── styles.js ├── extendStringPrototype.js └── colors.js ├── themes └── generic-logging.js ├── safe.js ├── package.json ├── MIT-LICENSE.txt ├── tests ├── safe-test.js └── basic-test.js ├── examples ├── normal-usage.js └── safe-string.js └── ReadMe.md /screenshots/colors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oxUnd/colors.js/master/screenshots/colors.png -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.11" 4 | - "0.10" 5 | - "0.8" 6 | - "0.6" -------------------------------------------------------------------------------- /lib/maps/zebra.js: -------------------------------------------------------------------------------- 1 | var colors = require('../colors'); 2 | 3 | module['exports'] = function (letter, i, exploded) { 4 | return i % 2 === 0 ? letter : colors.inverse(letter); 5 | }; -------------------------------------------------------------------------------- /themes/generic-logging.js: -------------------------------------------------------------------------------- 1 | module['exports'] = { 2 | silly: 'rainbow', 3 | input: 'grey', 4 | verbose: 'cyan', 5 | prompt: 'grey', 6 | info: 'green', 7 | data: 'grey', 8 | help: 'cyan', 9 | warn: 'yellow', 10 | debug: 'blue', 11 | error: 'red' 12 | }; -------------------------------------------------------------------------------- /safe.js: -------------------------------------------------------------------------------- 1 | // 2 | // Remark: Requiring this file will use the "safe" colors API which will not touch String.prototype 3 | // 4 | // var colors = require('colors/safe); 5 | // colors.red("foo") 6 | // 7 | // 8 | var colors = require('./lib/colors'); 9 | module['exports'] = colors; -------------------------------------------------------------------------------- /lib/maps/america.js: -------------------------------------------------------------------------------- 1 | var colors = require('../colors'); 2 | 3 | module['exports'] = (function() { 4 | return function (letter, i, exploded) { 5 | if(letter === " ") return letter; 6 | switch(i%3) { 7 | case 0: return colors.red(letter); 8 | case 1: return colors.white(letter) 9 | case 2: return colors.blue(letter) 10 | } 11 | } 12 | })(); -------------------------------------------------------------------------------- /lib/maps/random.js: -------------------------------------------------------------------------------- 1 | var colors = require('../colors'); 2 | 3 | module['exports'] = (function () { 4 | var available = ['underline', 'inverse', 'grey', 'yellow', 'red', 'green', 'blue', 'white', 'cyan', 'magenta']; 5 | return function(letter, i, exploded) { 6 | return letter === " " ? letter : colors[available[Math.round(Math.random() * (available.length - 1))]](letter); 7 | }; 8 | })(); -------------------------------------------------------------------------------- /lib/maps/rainbow.js: -------------------------------------------------------------------------------- 1 | var colors = require('../colors'); 2 | 3 | module['exports'] = (function () { 4 | var rainbowColors = ['red', 'yellow', 'green', 'blue', 'magenta']; //RoY G BiV 5 | return function (letter, i, exploded) { 6 | if (letter === " ") { 7 | return letter; 8 | } else { 9 | return colors[rainbowColors[i++ % rainbowColors.length]](letter); 10 | } 11 | }; 12 | })(); 13 | 14 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | var colors = require('./colors'); 2 | module['exports'] = colors; 3 | 4 | // Remark: By default, colors will add style properties to String.prototype 5 | // 6 | // If you don't wish to extend String.prototype you can do this instead and native String will not be touched 7 | // 8 | // var colors = require('colors/safe); 9 | // colors.red("foo") 10 | // 11 | // 12 | var extendStringPrototype = require('./extendStringPrototype')(); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "colors", 3 | "description": "get colors in your node.js console", 4 | "version": "1.0.3", 5 | "author": "Marak Squires", 6 | "homepage": "https://github.com/Marak/colors.js", 7 | "bugs": "https://github.com/Marak/colors.js/issues", 8 | "keywords": [ "ansi", "terminal", "colors" ], 9 | "repository": { 10 | "type": "git", 11 | "url": "http://github.com/Marak/colors.js.git" 12 | }, 13 | "license": "MIT", 14 | "scripts": { 15 | "test": "node tests/basic-test.js && node tests/safe-test.js" 16 | }, 17 | "engines": { 18 | "node": ">=0.1.90" 19 | }, 20 | "main": "./lib/index" 21 | } 22 | -------------------------------------------------------------------------------- /MIT-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Original Library 2 | - Copyright (c) Marak Squires 3 | 4 | Additional Functionality 5 | - Copyright (c) Sindre Sorhus (sindresorhus.com) 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. -------------------------------------------------------------------------------- /tests/safe-test.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'), 2 | colors = require('../safe'); 3 | 4 | var s = 'string'; 5 | 6 | function a(s, code) { 7 | return '\x1B[' + code.toString() + 'm' + s + '\x1B[39m'; 8 | } 9 | 10 | function aE(s, color, code) { 11 | assert.equal(colors[color](s), a(s, code)); 12 | assert.equal(colors.strip(s), s); 13 | } 14 | 15 | function h(s, color) { 16 | return '' + s + ''; 17 | } 18 | 19 | var stylesColors = ['white', 'black', 'blue', 'cyan', 'green', 'magenta', 'red', 'yellow']; 20 | var stylesAll = stylesColors.concat(['bold', 'italic', 'underline', 'inverse', 'rainbow']); 21 | 22 | colors.mode = 'console'; 23 | assert.equal(colors.bold(s), '\x1B[1m' + s + '\x1B[22m'); 24 | assert.equal(colors.italic(s), '\x1B[3m' + s + '\x1B[23m'); 25 | assert.equal(colors.underline(s), '\x1B[4m' + s + '\x1B[24m'); 26 | assert.equal(colors.strikethrough(s), '\x1B[9m' + s + '\x1B[29m'); 27 | assert.equal(colors.inverse(s), '\x1B[7m' + s + '\x1B[27m'); 28 | 29 | assert.ok(colors.rainbow); 30 | 31 | aE(s, 'white', 37); 32 | aE(s, 'grey', 90); 33 | aE(s, 'black', 30); 34 | aE(s, 'blue', 34); 35 | aE(s, 'cyan', 36); 36 | aE(s, 'green', 32); 37 | aE(s, 'magenta', 35); 38 | aE(s, 'red', 31); 39 | aE(s, 'yellow', 33); 40 | 41 | assert.equal(s, 'string'); 42 | colors.setTheme({error:'red'}); 43 | 44 | assert.equal(typeof(colors.red("astring")), 'string'); 45 | assert.equal(typeof(colors.error("astring")), 'string'); -------------------------------------------------------------------------------- /tests/basic-test.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'), 2 | colors = require('../lib/index'); 3 | 4 | var s = 'string'; 5 | 6 | function a(s, code) { 7 | return '\x1B[' + code.toString() + 'm' + s + '\x1B[39m'; 8 | } 9 | 10 | function aE(s, color, code) { 11 | assert.equal(s[color], a(s, code)); 12 | assert.equal(colors[color](s), a(s, code)); 13 | assert.equal(s[color], colors[color](s)); 14 | assert.equal(s[color].strip, s); 15 | assert.equal(s[color].strip, colors.strip(s)); 16 | } 17 | 18 | function h(s, color) { 19 | return '' + s + ''; 20 | } 21 | 22 | var stylesColors = ['white', 'black', 'blue', 'cyan', 'green', 'magenta', 'red', 'yellow']; 23 | var stylesAll = stylesColors.concat(['bold', 'italic', 'underline', 'inverse', 'rainbow']); 24 | 25 | colors.mode = 'console'; 26 | assert.equal(s.bold, '\x1B[1m' + s + '\x1B[22m'); 27 | assert.equal(s.italic, '\x1B[3m' + s + '\x1B[23m'); 28 | assert.equal(s.underline, '\x1B[4m' + s + '\x1B[24m'); 29 | assert.equal(s.strikethrough, '\x1B[9m' + s + '\x1B[29m'); 30 | assert.equal(s.inverse, '\x1B[7m' + s + '\x1B[27m'); 31 | 32 | assert.ok(s.rainbow); 33 | 34 | aE(s, 'white', 37); 35 | aE(s, 'grey', 90); 36 | aE(s, 'black', 30); 37 | aE(s, 'blue', 34); 38 | aE(s, 'cyan', 36); 39 | aE(s, 'green', 32); 40 | aE(s, 'magenta', 35); 41 | aE(s, 'red', 31); 42 | aE(s, 'yellow', 33); 43 | 44 | assert.equal(s, 'string'); 45 | 46 | colors.setTheme({error:'red'}); 47 | 48 | assert.equal(typeof("astring".red),'string'); 49 | assert.equal(typeof("astring".error),'string'); 50 | 51 | -------------------------------------------------------------------------------- /lib/custom/trap.js: -------------------------------------------------------------------------------- 1 | module['exports'] = function runTheTrap (text, options) { 2 | var result = ""; 3 | text = text || "Run the trap, drop the bass"; 4 | text = text.split(''); 5 | var trap = { 6 | a: ["\u0040", "\u0104", "\u023a", "\u0245", "\u0394", "\u039b", "\u0414"], 7 | b: ["\u00df", "\u0181", "\u0243", "\u026e", "\u03b2", "\u0e3f"], 8 | c: ["\u00a9", "\u023b", "\u03fe"], 9 | d: ["\u00d0", "\u018a", "\u0500" , "\u0501" ,"\u0502", "\u0503"], 10 | e: ["\u00cb", "\u0115", "\u018e", "\u0258", "\u03a3", "\u03be", "\u04bc", "\u0a6c"], 11 | f: ["\u04fa"], 12 | g: ["\u0262"], 13 | h: ["\u0126", "\u0195", "\u04a2", "\u04ba", "\u04c7", "\u050a"], 14 | i: ["\u0f0f"], 15 | j: ["\u0134"], 16 | k: ["\u0138", "\u04a0", "\u04c3", "\u051e"], 17 | l: ["\u0139"], 18 | m: ["\u028d", "\u04cd", "\u04ce", "\u0520", "\u0521", "\u0d69"], 19 | n: ["\u00d1", "\u014b", "\u019d", "\u0376", "\u03a0", "\u048a"], 20 | o: ["\u00d8", "\u00f5", "\u00f8", "\u01fe", "\u0298", "\u047a", "\u05dd", "\u06dd", "\u0e4f"], 21 | p: ["\u01f7", "\u048e"], 22 | q: ["\u09cd"], 23 | r: ["\u00ae", "\u01a6", "\u0210", "\u024c", "\u0280", "\u042f"], 24 | s: ["\u00a7", "\u03de", "\u03df", "\u03e8"], 25 | t: ["\u0141", "\u0166", "\u0373"], 26 | u: ["\u01b1", "\u054d"], 27 | v: ["\u05d8"], 28 | w: ["\u0428", "\u0460", "\u047c", "\u0d70"], 29 | x: ["\u04b2", "\u04fe", "\u04fc", "\u04fd"], 30 | y: ["\u00a5", "\u04b0", "\u04cb"], 31 | z: ["\u01b5", "\u0240"] 32 | } 33 | text.forEach(function(c){ 34 | c = c.toLowerCase(); 35 | var chars = trap[c] || [" "]; 36 | var rand = Math.floor(Math.random() * chars.length); 37 | if (typeof trap[c] !== "undefined") { 38 | result += trap[c][rand]; 39 | } else { 40 | result += c; 41 | } 42 | }); 43 | return result; 44 | 45 | } 46 | -------------------------------------------------------------------------------- /lib/system/supports-colors.js: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) Sindre Sorhus (sindresorhus.com) 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | 24 | */ 25 | 26 | var argv = process.argv; 27 | 28 | module.exports = (function () { 29 | if (argv.indexOf('--no-color') !== -1 || 30 | argv.indexOf('--color=false') !== -1) { 31 | return false; 32 | } 33 | 34 | if (argv.indexOf('--color') !== -1 || 35 | argv.indexOf('--color=true') !== -1 || 36 | argv.indexOf('--color=always') !== -1) { 37 | return true; 38 | } 39 | 40 | if (process.stdout && !process.stdout.isTTY) { 41 | return false; 42 | } 43 | 44 | if (process.platform === 'win32') { 45 | return true; 46 | } 47 | 48 | if ('COLORTERM' in process.env) { 49 | return true; 50 | } 51 | 52 | if (process.env.TERM === 'dumb') { 53 | return false; 54 | } 55 | 56 | if (/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i.test(process.env.TERM)) { 57 | return true; 58 | } 59 | 60 | return false; 61 | })(); -------------------------------------------------------------------------------- /examples/normal-usage.js: -------------------------------------------------------------------------------- 1 | var colors = require('../lib/index'); 2 | 3 | console.log("First some yellow text".yellow); 4 | 5 | console.log("Underline that text".yellow.underline); 6 | 7 | console.log("Make it bold and red".red.bold); 8 | 9 | console.log(("Double Raindows All Day Long").rainbow) 10 | 11 | console.log("Drop the bass".trap) 12 | 13 | console.log("DROP THE RAINBOW BASS".trap.rainbow) 14 | 15 | 16 | console.log('Chains are also cool.'.bold.italic.underline.red); // styles not widely supported 17 | 18 | console.log('So '.green + 'are'.underline + ' ' + 'inverse'.inverse + ' styles! '.yellow.bold); // styles not widely supported 19 | console.log("Zebras are so fun!".zebra); 20 | 21 | // 22 | // Remark: .strikethrough may not work with Mac OS Terminal App 23 | // 24 | console.log("This is " + "not".strikethrough + " fun."); 25 | 26 | console.log('Background color attack!'.black.bgWhite) 27 | console.log('Use random styles on everything!'.random) 28 | console.log('America, Heck Yeah!'.america) 29 | 30 | 31 | console.log('Setting themes is useful') 32 | 33 | // 34 | // Custom themes 35 | // 36 | console.log('Generic logging theme as JSON'.green.bold.underline); 37 | // Load theme with JSON literal 38 | colors.setTheme({ 39 | silly: 'rainbow', 40 | input: 'grey', 41 | verbose: 'cyan', 42 | prompt: 'grey', 43 | info: 'green', 44 | data: 'grey', 45 | help: 'cyan', 46 | warn: 'yellow', 47 | debug: 'blue', 48 | error: 'red' 49 | }); 50 | 51 | // outputs red text 52 | console.log("this is an error".error); 53 | 54 | // outputs yellow text 55 | console.log("this is a warning".warn); 56 | 57 | // outputs grey text 58 | console.log("this is an input".input); 59 | 60 | console.log('Generic logging theme as file'.green.bold.underline); 61 | 62 | // Load a theme from file 63 | colors.setTheme(__dirname + '/../themes/generic-logging.js'); 64 | 65 | // outputs red text 66 | console.log("this is an error".error); 67 | 68 | // outputs yellow text 69 | console.log("this is a warning".warn); 70 | 71 | // outputs grey text 72 | console.log("this is an input".input); 73 | 74 | //console.log("Don't summon".zalgo) -------------------------------------------------------------------------------- /examples/safe-string.js: -------------------------------------------------------------------------------- 1 | var colors = require('../safe'); 2 | 3 | console.log(colors.yellow("First some yellow text")); 4 | 5 | console.log(colors.yellow.underline("Underline that text")); 6 | 7 | console.log(colors.red.bold("Make it bold and red")); 8 | 9 | console.log(colors.rainbow("Double Raindows All Day Long")) 10 | 11 | console.log(colors.trap("Drop the bass")) 12 | 13 | console.log(colors.rainbow(colors.trap("DROP THE RAINBOW BASS"))); 14 | 15 | console.log(colors.bold.italic.underline.red('Chains are also cool.')); // styles not widely supported 16 | 17 | 18 | console.log(colors.green('So ') + colors.underline('are') + ' ' + colors.inverse('inverse') + colors.yellow.bold(' styles! ')); // styles not widely supported 19 | 20 | console.log(colors.zebra("Zebras are so fun!")); 21 | 22 | console.log("This is " + colors.strikethrough("not") + " fun."); 23 | 24 | 25 | console.log(colors.black.bgWhite('Background color attack!')); 26 | console.log(colors.random('Use random styles on everything!')) 27 | console.log(colors.america('America, Heck Yeah!')); 28 | 29 | console.log('Setting themes is useful') 30 | 31 | // 32 | // Custom themes 33 | // 34 | //console.log('Generic logging theme as JSON'.green.bold.underline); 35 | // Load theme with JSON literal 36 | colors.setTheme({ 37 | silly: 'rainbow', 38 | input: 'grey', 39 | verbose: 'cyan', 40 | prompt: 'grey', 41 | info: 'green', 42 | data: 'grey', 43 | help: 'cyan', 44 | warn: 'yellow', 45 | debug: 'blue', 46 | error: 'red' 47 | }); 48 | 49 | // outputs red text 50 | console.log(colors.error("this is an error")); 51 | 52 | // outputs yellow text 53 | console.log(colors.warn("this is a warning")); 54 | 55 | // outputs grey text 56 | console.log(colors.input("this is an input")); 57 | 58 | 59 | // console.log('Generic logging theme as file'.green.bold.underline); 60 | 61 | // Load a theme from file 62 | colors.setTheme(__dirname + '/../themes/generic-logging.js'); 63 | 64 | // outputs red text 65 | console.log(colors.error("this is an error")); 66 | 67 | // outputs yellow text 68 | console.log(colors.warn("this is a warning")); 69 | 70 | // outputs grey text 71 | console.log(colors.input("this is an input")); 72 | 73 | // console.log(colors.zalgo("Don't summon him")) 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /lib/styles.js: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) Sindre Sorhus (sindresorhus.com) 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | 24 | */ 25 | 26 | var styles = {}; 27 | module['exports'] = styles; 28 | 29 | var codes = { 30 | reset: [0, 0], 31 | 32 | bold: [1, 22], 33 | dim: [2, 22], 34 | italic: [3, 23], 35 | underline: [4, 24], 36 | inverse: [7, 27], 37 | hidden: [8, 28], 38 | strikethrough: [9, 29], 39 | 40 | black: [30, 39], 41 | red: [31, 39], 42 | green: [32, 39], 43 | yellow: [33, 39], 44 | blue: [34, 39], 45 | magenta: [35, 39], 46 | cyan: [36, 39], 47 | white: [37, 39], 48 | gray: [90, 39], 49 | grey: [90, 39], 50 | 51 | bgBlack: [40, 49], 52 | bgRed: [41, 49], 53 | bgGreen: [42, 49], 54 | bgYellow: [43, 49], 55 | bgBlue: [44, 49], 56 | bgMagenta: [45, 49], 57 | bgCyan: [46, 49], 58 | bgWhite: [47, 49], 59 | 60 | // legacy styles for colors pre v1.0.0 61 | blackBG: [40, 49], 62 | redBG: [41, 49], 63 | greenBG: [42, 49], 64 | yellowBG: [43, 49], 65 | blueBG: [44, 49], 66 | magentaBG: [45, 49], 67 | cyanBG: [46, 49], 68 | whiteBG: [47, 49] 69 | 70 | }; 71 | 72 | Object.keys(codes).forEach(function (key) { 73 | var val = codes[key]; 74 | var style = styles[key] = []; 75 | style.open = '\u001b[' + val[0] + 'm'; 76 | style.close = '\u001b[' + val[1] + 'm'; 77 | }); -------------------------------------------------------------------------------- /lib/custom/zalgo.js: -------------------------------------------------------------------------------- 1 | // please no 2 | module['exports'] = function zalgo(text, options) { 3 | text = text || " he is here "; 4 | var soul = { 5 | "up" : [ 6 | '̍', '̎', '̄', '̅', 7 | '̿', '̑', '̆', '̐', 8 | '͒', '͗', '͑', '̇', 9 | '̈', '̊', '͂', '̓', 10 | '̈', '͊', '͋', '͌', 11 | '̃', '̂', '̌', '͐', 12 | '̀', '́', '̋', '̏', 13 | '̒', '̓', '̔', '̽', 14 | '̉', 'ͣ', 'ͤ', 'ͥ', 15 | 'ͦ', 'ͧ', 'ͨ', 'ͩ', 16 | 'ͪ', 'ͫ', 'ͬ', 'ͭ', 17 | 'ͮ', 'ͯ', '̾', '͛', 18 | '͆', '̚' 19 | ], 20 | "down" : [ 21 | '̖', '̗', '̘', '̙', 22 | '̜', '̝', '̞', '̟', 23 | '̠', '̤', '̥', '̦', 24 | '̩', '̪', '̫', '̬', 25 | '̭', '̮', '̯', '̰', 26 | '̱', '̲', '̳', '̹', 27 | '̺', '̻', '̼', 'ͅ', 28 | '͇', '͈', '͉', '͍', 29 | '͎', '͓', '͔', '͕', 30 | '͖', '͙', '͚', '̣' 31 | ], 32 | "mid" : [ 33 | '̕', '̛', '̀', '́', 34 | '͘', '̡', '̢', '̧', 35 | '̨', '̴', '̵', '̶', 36 | '͜', '͝', '͞', 37 | '͟', '͠', '͢', '̸', 38 | '̷', '͡', ' ҉' 39 | ] 40 | }, 41 | all = [].concat(soul.up, soul.down, soul.mid), 42 | zalgo = {}; 43 | 44 | function randomNumber(range) { 45 | var r = Math.floor(Math.random() * range); 46 | return r; 47 | } 48 | 49 | function is_char(character) { 50 | var bool = false; 51 | all.filter(function (i) { 52 | bool = (i === character); 53 | }); 54 | return bool; 55 | } 56 | 57 | 58 | function heComes(text, options) { 59 | var result = '', counts, l; 60 | options = options || {}; 61 | options["up"] = options["up"] || true; 62 | options["mid"] = options["mid"] || true; 63 | options["down"] = options["down"] || true; 64 | options["size"] = options["size"] || "maxi"; 65 | text = text.split(''); 66 | for (l in text) { 67 | if (is_char(l)) { 68 | continue; 69 | } 70 | result = result + text[l]; 71 | counts = {"up" : 0, "down" : 0, "mid" : 0}; 72 | switch (options.size) { 73 | case 'mini': 74 | counts.up = randomNumber(8); 75 | counts.min = randomNumber(2); 76 | counts.down = randomNumber(8); 77 | break; 78 | case 'maxi': 79 | counts.up = randomNumber(16) + 3; 80 | counts.min = randomNumber(4) + 1; 81 | counts.down = randomNumber(64) + 3; 82 | break; 83 | default: 84 | counts.up = randomNumber(8) + 1; 85 | counts.mid = randomNumber(6) / 2; 86 | counts.down = randomNumber(8) + 1; 87 | break; 88 | } 89 | 90 | var arr = ["up", "mid", "down"]; 91 | for (var d in arr) { 92 | var index = arr[d]; 93 | for (var i = 0 ; i <= counts[index]; i++) { 94 | if (options[index]) { 95 | result = result + soul[index][randomNumber(soul[index].length)]; 96 | } 97 | } 98 | } 99 | } 100 | return result; 101 | } 102 | // don't summon him 103 | return heComes(text); 104 | } 105 | -------------------------------------------------------------------------------- /lib/extendStringPrototype.js: -------------------------------------------------------------------------------- 1 | var colors = require('./colors'); 2 | 3 | module['exports'] = function () { 4 | 5 | // 6 | // Extends prototype of native string object to allow for "foo".red syntax 7 | // 8 | var addProperty = function (color, func) { 9 | String.prototype.__defineGetter__(color, func); 10 | }; 11 | 12 | var sequencer = function sequencer (map, str) { 13 | return function () { 14 | var exploded = this.split(""), i = 0; 15 | exploded = exploded.map(map); 16 | return exploded.join(""); 17 | } 18 | }; 19 | 20 | addProperty('strip', function () { 21 | return colors.strip(this); 22 | }); 23 | 24 | addProperty('stripColors', function () { 25 | return colors.strip(this); 26 | }); 27 | 28 | addProperty("trap", function(){ 29 | return colors.trap(this); 30 | }); 31 | 32 | addProperty("zalgo", function(){ 33 | return colors.zalgo(this); 34 | }); 35 | 36 | addProperty("zebra", function(){ 37 | return colors.zebra(this); 38 | }); 39 | 40 | addProperty("rainbow", function(){ 41 | return colors.rainbow(this); 42 | }); 43 | 44 | addProperty("random", function(){ 45 | return colors.random(this); 46 | }); 47 | 48 | addProperty("america", function(){ 49 | return colors.america(this); 50 | }); 51 | 52 | // 53 | // Iterate through all default styles and colors 54 | // 55 | var x = Object.keys(colors.styles); 56 | x.forEach(function (style) { 57 | addProperty(style, function () { 58 | return colors.stylize(this, style); 59 | }); 60 | }); 61 | 62 | function applyTheme(theme) { 63 | // 64 | // Remark: This is a list of methods that exist 65 | // on String that you should not overwrite. 66 | // 67 | var stringPrototypeBlacklist = [ 68 | '__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', 'charAt', 'constructor', 69 | 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf', 'charCodeAt', 70 | 'indexOf', 'lastIndexof', 'length', 'localeCompare', 'match', 'replace', 'search', 'slice', 'split', 'substring', 71 | 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toUpperCase', 'trim', 'trimLeft', 'trimRight' 72 | ]; 73 | 74 | Object.keys(theme).forEach(function (prop) { 75 | if (stringPrototypeBlacklist.indexOf(prop) !== -1) { 76 | console.log('warn: '.red + ('String.prototype' + prop).magenta + ' is probably something you don\'t want to override. Ignoring style name'); 77 | } 78 | else { 79 | if (typeof(theme[prop]) === 'string') { 80 | colors[prop] = colors[theme[prop]]; 81 | addProperty(prop, function () { 82 | return colors[theme[prop]](this); 83 | }); 84 | } 85 | else { 86 | addProperty(prop, function () { 87 | var ret = this; 88 | for (var t = 0; t < theme[prop].length; t++) { 89 | ret = exports[theme[prop][t]](ret); 90 | } 91 | return ret; 92 | }); 93 | } 94 | } 95 | }); 96 | } 97 | 98 | colors.setTheme = function (theme) { 99 | if (typeof theme === 'string') { 100 | try { 101 | colors.themes[theme] = require(theme); 102 | applyTheme(colors.themes[theme]); 103 | return colors.themes[theme]; 104 | } catch (err) { 105 | console.log(err); 106 | return err; 107 | } 108 | } else { 109 | applyTheme(theme); 110 | } 111 | }; 112 | 113 | }; -------------------------------------------------------------------------------- /ReadMe.md: -------------------------------------------------------------------------------- 1 | # colors.js 2 | 3 | ## get color and style in your node.js console 4 | 5 | 6 | 7 | ## Installation 8 | 9 | npm install colors 10 | 11 | ## colors and styles! 12 | 13 | ### text colors 14 | 15 | - black 16 | - red 17 | - green 18 | - yellow 19 | - blue 20 | - magenta 21 | - cyan 22 | - white 23 | - gray 24 | - grey 25 | 26 | ### background colors 27 | 28 | 29 | 30 | - bgBlack 31 | - bgRed 32 | - bgGreen 33 | - bgYellow 34 | - bgBlue 35 | - bgMagenta 36 | - bgCyan 37 | - bgWhite 38 | 39 | ### styles 40 | 41 | - reset 42 | - bold 43 | - dim 44 | - italic 45 | - underline 46 | - inverse 47 | - hidden 48 | - strikethrough 49 | 50 | ### extras 51 | 52 | - rainbow 53 | - zebra 54 | - america 55 | - trap 56 | - random 57 | 58 | 59 | ## Usage 60 | 61 | By popular demand, `colors` now ships with two types of usages! 62 | 63 | The super nifty way 64 | 65 | ```js 66 | var colors = require('colors'); 67 | 68 | console.log('hello'.green); // outputs green text 69 | console.log('i like cake and pies'.underline.red) // outputs red underlined text 70 | console.log('inverse the color'.inverse); // inverses the color 71 | console.log('OMG Rainbows!'.rainbow); // rainbow 72 | console.log('Run the trap'.trap); // Drops the bass 73 | 74 | ``` 75 | 76 | or a slightly less nifty way which doesn't extend `String.prototype` 77 | 78 | ```js 79 | var colors = require('colors/safe'); 80 | 81 | console.log(colors.green('hello')); // outputs green text 82 | console.log(colors.red.underline('i like cake and pies')) // outputs red underlined text 83 | console.log(colors.inverse('inverse the color')); // inverses the color 84 | console.log(colors.rainbow('OMG Rainbows!')); // rainbow 85 | console.log(colors.trap('Run the trap')); // Drops the bass 86 | 87 | ``` 88 | 89 | I prefer the first way. Some people seem to be afraid of extending `String.prototype` and prefer the second way. 90 | 91 | If you are writing good code you will never have an issue with the first approach. If you really don't want to touch `String.prototype`, the second usage will not touch `String` native object. 92 | 93 | ## Disabling Colors 94 | 95 | To disable colors you can pass the following arguments in the command line to your application: 96 | 97 | ```bash 98 | node myapp.js --no-color 99 | ``` 100 | 101 | ## Console.log [string substitution](http://nodejs.org/docs/latest/api/console.html#console_console_log_data) 102 | 103 | ```js 104 | var name = 'Marak'; 105 | console.log(colors.green('Hello %s'), name); 106 | // outputs -> 'Hello Marak' 107 | ``` 108 | 109 | ## Custom themes 110 | 111 | ### Using standard API 112 | 113 | ```js 114 | 115 | var colors = require('colors'); 116 | 117 | colors.setTheme({ 118 | silly: 'rainbow', 119 | input: 'grey', 120 | verbose: 'cyan', 121 | prompt: 'grey', 122 | info: 'green', 123 | data: 'grey', 124 | help: 'cyan', 125 | warn: 'yellow', 126 | debug: 'blue', 127 | error: 'red' 128 | }); 129 | 130 | // outputs red text 131 | console.log("this is an error".error); 132 | 133 | // outputs yellow text 134 | console.log("this is a warning".warn); 135 | ``` 136 | 137 | ### Using string safe API 138 | 139 | ```js 140 | var colors = require('colors/safe'); 141 | 142 | // set single property 143 | var error = colors.red; 144 | error('this is red'); 145 | 146 | // set theme 147 | colors.setTheme({ 148 | silly: 'rainbow', 149 | input: 'grey', 150 | verbose: 'cyan', 151 | prompt: 'grey', 152 | info: 'green', 153 | data: 'grey', 154 | help: 'cyan', 155 | warn: 'yellow', 156 | debug: 'blue', 157 | error: 'red' 158 | }); 159 | 160 | // outputs red text 161 | console.log(colors.error("this is an error")); 162 | 163 | // outputs yellow text 164 | console.log(colors.warn("this is a warning")); 165 | ``` 166 | 167 | *Protip: There is a secret undocumented style in `colors`. If you find the style you can summon him.* -------------------------------------------------------------------------------- /lib/colors.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | The MIT License (MIT) 4 | 5 | Original Library 6 | - Copyright (c) Marak Squires 7 | 8 | Additional functionality 9 | - Copyright (c) Sindre Sorhus (sindresorhus.com) 10 | 11 | Permission is hereby granted, free of charge, to any person obtaining a copy 12 | of this software and associated documentation files (the "Software"), to deal 13 | in the Software without restriction, including without limitation the rights 14 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | copies of the Software, and to permit persons to whom the Software is 16 | furnished to do so, subject to the following conditions: 17 | 18 | The above copyright notice and this permission notice shall be included in 19 | all copies or substantial portions of the Software. 20 | 21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | THE SOFTWARE. 28 | 29 | */ 30 | 31 | var colors = {}; 32 | module['exports'] = colors; 33 | 34 | colors.themes = {}; 35 | 36 | var ansiStyles = colors.styles = require('./styles'); 37 | var defineProps = Object.defineProperties; 38 | 39 | colors.supportsColor = require('./system/supports-colors'); 40 | 41 | if (typeof colors.enabled === "undefined") { 42 | colors.enabled = colors.supportsColor; 43 | } 44 | 45 | colors.stripColors = colors.strip = function(str){ 46 | return ("" + str).replace(/\x1B\[\d+m/g, ''); 47 | }; 48 | 49 | 50 | var stylize = colors.stylize = function stylize (str, style) { 51 | if (!colors.enabled) { 52 | return str+''; 53 | } 54 | 55 | return ansiStyles[style].open + str + ansiStyles[style].close; 56 | } 57 | 58 | var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; 59 | var escapeStringRegexp = function (str) { 60 | if (typeof str !== 'string') { 61 | throw new TypeError('Expected a string'); 62 | } 63 | return str.replace(matchOperatorsRe, '\\$&'); 64 | } 65 | 66 | function build(_styles) { 67 | var builder = function builder() { 68 | return applyStyle.apply(builder, arguments); 69 | }; 70 | builder._styles = _styles; 71 | // __proto__ is used because we must return a function, but there is 72 | // no way to create a function with a different prototype. 73 | builder.__proto__ = proto; 74 | return builder; 75 | } 76 | 77 | var styles = (function () { 78 | var ret = {}; 79 | ansiStyles.grey = ansiStyles.gray; 80 | Object.keys(ansiStyles).forEach(function (key) { 81 | ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); 82 | ret[key] = { 83 | get: function () { 84 | return build(this._styles.concat(key)); 85 | } 86 | }; 87 | }); 88 | return ret; 89 | })(); 90 | 91 | var proto = defineProps(function colors() {}, styles); 92 | 93 | function applyStyle() { 94 | var args = arguments; 95 | var argsLen = args.length; 96 | var str = argsLen !== 0 && String(arguments[0]); 97 | if (argsLen > 1) { 98 | for (var a = 1; a < argsLen; a++) { 99 | str += ' ' + args[a]; 100 | } 101 | } 102 | 103 | if (!colors.enabled || !str) { 104 | return str; 105 | } 106 | 107 | var nestedStyles = this._styles; 108 | 109 | var i = nestedStyles.length; 110 | while (i--) { 111 | var code = ansiStyles[nestedStyles[i]]; 112 | str = code.open + str.replace(code.closeRe, code.open) + code.close; 113 | } 114 | 115 | return str; 116 | } 117 | 118 | function applyTheme (theme) { 119 | for (var style in theme) { 120 | (function(style){ 121 | colors[style] = function(str){ 122 | return colors[theme[style]](str); 123 | }; 124 | })(style) 125 | } 126 | } 127 | 128 | colors.setTheme = function (theme) { 129 | if (typeof theme === 'string') { 130 | try { 131 | colors.themes[theme] = require(theme); 132 | applyTheme(colors.themes[theme]); 133 | return colors.themes[theme]; 134 | } catch (err) { 135 | console.log(err); 136 | return err; 137 | } 138 | } else { 139 | applyTheme(theme); 140 | } 141 | }; 142 | 143 | function init() { 144 | var ret = {}; 145 | Object.keys(styles).forEach(function (name) { 146 | ret[name] = { 147 | get: function () { 148 | return build([name]); 149 | } 150 | }; 151 | }); 152 | return ret; 153 | } 154 | 155 | var sequencer = function sequencer (map, str) { 156 | var exploded = str.split(""), i = 0; 157 | exploded = exploded.map(map); 158 | return exploded.join(""); 159 | }; 160 | 161 | // custom formatter methods 162 | colors.trap = require('./custom/trap'); 163 | colors.zalgo = require('./custom/zalgo'); 164 | 165 | // maps 166 | colors.maps = {}; 167 | colors.maps.america = require('./maps/america'); 168 | colors.maps.zebra = require('./maps/zebra'); 169 | colors.maps.rainbow = require('./maps/rainbow'); 170 | colors.maps.random = require('./maps/random') 171 | 172 | for (var map in colors.maps) { 173 | (function(map){ 174 | colors[map] = function (str) { 175 | return sequencer(colors.maps[map], str); 176 | } 177 | })(map) 178 | } 179 | 180 | defineProps(colors, init()); --------------------------------------------------------------------------------