diff --git a/readme.md b/readme.md index 338f42c..62d0775 100644 --- a/readme.md +++ b/readme.md @@ -78,6 +78,13 @@ RAM: {green ${ram.used / ram.total * 100}%} DISK: {rgb(255,131,0) ${disk.used / disk.total * 100}%} `); +// Nestable style tags +log(chalk.parse(` + + Aren't you glad I didn't say Naranja! + +`)); + // Use RGB colors in terminal emulators that support it. log(chalk.keyword('orange')('Yay for orange colored text!')); log(chalk.rgb(123, 45, 67).underline('Underlined reddish color')); @@ -227,6 +234,25 @@ Note that function styles (`rgb()`, `hsl()`, `keyword()`, etc.) may not contain All interpolated values (`` chalk`${foo}` ``) are converted to strings via the `.toString()` method. All curly braces (`{` and `}`) in interpolated value strings are escaped. +## Style tags + +You can quickly stylize any string that uses html-like tags + +```js +const chalk = require('chalk'); + +const example1 = 'Well that is convinient!' +const example2 = 'All functions are supported' + +console.log(chalk.parse(example1)); +console.log(chalk.parse(example2)); +``` + +- Style tags always come in pairs: An **opening tag** followed by a **closing tag**. +- The **opening tag** name is any style/modifier that is listed above and multiple styles can be chained using a dot. +- The **closing tag** name does not require a matching name, unlike html. +- Styles will cascade, in other words: child tags, as well as sibling tags or text will inherit a parent tag's style. + ## 256 and Truecolor color support Chalk supports 256 colors and [Truecolor](https://gist.github.com/XVilka/8346728) (16 million colors) on supported terminal apps. diff --git a/source/index.js b/source/index.js index 75ec663..44c90ba 100644 --- a/source/index.js +++ b/source/index.js @@ -18,6 +18,25 @@ const levelMapping = [ const styles = Object.create(null); +function parseTaggedString(string) { + const tagPattern = /\<([\w, '().]+)\>([\s\S]+)\<\/\w*\>/g; + const callPattern = /\((.*)\)/; + return string.replace(tagPattern, (_, color, text) => { + let carbonate = chalk; + color.split('.').forEach(c => { + if (callPattern.test(c)) { + const args = JSON.parse(`[${ callPattern.exec(c)[1].replace(/'/g, '"') }]`); + c = /(\w+)/g.exec(c)[0]; + carbonate = carbonate[c] ? carbonate[c].apply(carbonate[c], args) : carbonate; + } else { + carbonate = carbonate[c] || carbonate; + } + }); + text = carbonate(text); + return tagPattern.test(text) ? parseTaggedString(text) : text; + }); +} + const applyOptions = (object, options = {}) => { if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) { throw new Error('The `level` option should be an integer from 0 to 3'); @@ -49,6 +68,8 @@ const chalkFactory = options => { }; chalk.template.Instance = ChalkClass; + + chalk.template.parse = parseTaggedString; return chalk.template; };