diff --git a/index.js b/index.js index a7a7f48..3929a8c 100644 --- a/index.js +++ b/index.js @@ -22,6 +22,19 @@ var styles = (function () { return ret; })(); +// enrich each ansiStyle object with regular expression matching +// all instances of the corresponding code.close +(function () { + var _matchUnescapedCharacters = /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g; + function escapeStr(str) { + return str.replace(_matchUnescapedCharacters, '\\$&'); + } + + Object.keys(ansiStyles).forEach(function (key) { + ansiStyles[key].closeRe = new RegExp(escapeStr(ansiStyles[key].close), 'g'); + }); +})(); + function init() { var ret = {}; @@ -37,7 +50,12 @@ function init() { return self._styles.reduce(function (str, name) { var code = ansiStyles[name]; - return str ? code.open + str + code.close : ''; + return str ? + // Replace any instances already present with a re-opening code + // otherwise only the part of the string until said closing code will be coloured, and the rest will be + // simply 'plain'. + code.open + str.replace(code.closeRe, code.open) + code.close : + ''; }, str); }, styles); diff --git a/readme.md b/readme.md index c19fe21..1982c3e 100644 --- a/readme.md +++ b/readme.md @@ -47,6 +47,9 @@ console.log( chalk.blue.bgRed.bold('Hello world!') ); // nest styles console.log( chalk.red('Hello', chalk.underline.bgBlue('world') + '!') ); +// nest styles of the same type even (colour, underline, background) +console.log( chalk.green('Hello, I'm a green line ' + chalk.blue('with a blue substring') + ' that becomes green again!') ); + // pass in multiple arguments console.log( chalk.blue('Hello', 'World!', 'Foo', 'bar', 'biz', 'baz') ); ``` diff --git a/test.js b/test.js index c65e55b..0dc8eef 100644 --- a/test.js +++ b/test.js @@ -21,6 +21,13 @@ describe('chalk', function () { ); }); + it('should support nesting styles of the same type (color, underline, bg)', function () { + assert.equal( + chalk.red('a' + chalk.blue('b' + chalk.green('c') + 'b') + 'c'), + '\u001b[31ma\u001b[34mb\u001b[32mc\u001b[34mb\u001b[31mc\u001b[39m' + ); + }); + it('should reset all styles with `.reset()`', function () { assert.equal(chalk.reset(chalk.red.bgGreen.underline('foo') + 'foo'), '\u001b[0m\u001b[4m\u001b[42m\u001b[31mfoo\u001b[39m\u001b[49m\u001b[24mfoo\u001b[0m'); });