Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove support for tagged template literals #524

Merged
merged 2 commits into from Nov 10, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
40 changes: 1 addition & 39 deletions readme.md
Expand Up @@ -127,13 +127,6 @@ RAM: ${chalk.green('40%')}
DISK: ${chalk.yellow('70%')}
`);

// ES2015 tagged template literal
log(chalk`
CPU: {red ${cpu.totalPercent}%}
RAM: {green ${ram.used / ram.total * 100}%}
DISK: {rgb(255,131,0) ${disk.used / disk.total * 100}%}
`);

// Use RGB colors in terminal emulators that support it.
log(chalk.rgb(123, 45, 67).underline('Underlined reddish color'));
log(chalk.hex('#DEADED').bold('Bold gray!'));
Expand Down Expand Up @@ -257,38 +250,6 @@ Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color=
- `bgCyanBright`
- `bgWhiteBright`

## Tagged template literal

Chalk can be used as a [tagged template literal](https://exploringjs.com/es6/ch_template-literals.html#_tagged-template-literals).

```js
import chalk from 'chalk';

const miles = 18;
const calculateFeet = miles => miles * 5280;

console.log(chalk`
There are {bold 5280 feet} in a mile.
In {bold ${miles} miles}, there are {green.bold ${calculateFeet(miles)} feet}.
`);
```

Blocks are delimited by an opening curly brace (`{`), a style, some content, and a closing curly brace (`}`).

Template styles are chained exactly like normal Chalk styles. The following three statements are equivalent:

```js
import chalk from 'chalk';

console.log(chalk.bold.rgb(10, 100, 200)('Hello!'));
console.log(chalk.bold.rgb(10, 100, 200)`Hello!`);
console.log(chalk`{bold.rgb(10,100,200) Hello!}`);
```

Note that function styles (`rgb()`, `hex()`, etc.) may not contain spaces between parameters.

All interpolated values (`` chalk`${foo}` ``) are converted to strings via the `.toString()` method. All curly braces (`{` and `}`) in interpolated value strings are escaped.

## 256 and Truecolor color support

Chalk supports 256 colors and [Truecolor](https://gist.github.com/XVilka/8346728) (16 million colors) on supported terminal apps.
Expand Down Expand Up @@ -331,6 +292,7 @@ The maintainers of chalk and thousands of other packages are working with Tideli

## Related

- [chalk-template](https://github.com/chalk/chalk-template) - [Tagged template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates) support for this module
- [chalk-cli](https://github.com/chalk/chalk-cli) - CLI for this module
- [ansi-styles](https://github.com/chalk/ansi-styles) - ANSI escape codes for styling strings in the terminal
- [supports-color](https://github.com/chalk/supports-color) - Detect whether a terminal supports color
Expand Down
31 changes: 2 additions & 29 deletions source/index.d.ts
Expand Up @@ -121,36 +121,9 @@ export interface ColorSupport {
has16m: boolean;
}

interface ChalkFunction {
/**
Use a template string.

@remarks Template literals are unsupported for nested calls (see [issue #341](https://github.com/chalk/chalk/issues/341))

@example
```
import chalk from 'chalk';

log(chalk`
CPU: {red ${cpu.totalPercent}%}
RAM: {green ${ram.used / ram.total * 100}%}
DISK: {rgb(255,131,0) ${disk.used / disk.total * 100}%}
`);
```

@example
```
import chalk from 'chalk';

log(chalk.red.bgBlack`2 + 3 = {bold ${2 + 3}}`)
```
*/
(text: TemplateStringsArray, ...placeholders: unknown[]): string;

export interface ChalkInstance {
(...text: unknown[]): string;
}

export interface ChalkInstance extends ChalkFunction {
/**
The color support for Chalk.

Expand Down Expand Up @@ -358,7 +331,7 @@ Order doesn't matter, and later styles take precedent in case of a conflict.

This simply means that `chalk.red.yellow.green` is equivalent to `chalk.green`.
*/
declare const chalk: ChalkInstance & ChalkFunction;
declare const chalk: ChalkInstance;

export const supportsColor: ColorSupport | false;

Expand Down
46 changes: 5 additions & 41 deletions source/index.js
Expand Up @@ -4,10 +4,8 @@ import {
stringReplaceAll,
stringEncaseCRLFWithFirstIndex,
} from './util.js';
import template from './templates.js';

const {stdout: stdoutColor, stderr: stderrColor} = supportsColor;
const {isArray} = Array;

const GENERATOR = Symbol('GENERATOR');
const STYLER = Symbol('STYLER');
Expand Down Expand Up @@ -41,17 +39,12 @@ export class Chalk {
}

const chalkFactory = options => {
const chalk = {};
const chalk = (...arguments_) => arguments_.join(' ');
applyOptions(chalk, options);

chalk.template = (...arguments_) => chalkTag(chalk.template, ...arguments_);

Object.setPrototypeOf(chalk, createChalk.prototype);
Object.setPrototypeOf(chalk.template, chalk);

chalk.template.Chalk = Chalk;

return chalk.template;
return chalk;
};

function createChalk(options) {
Expand Down Expand Up @@ -157,16 +150,9 @@ const createStyler = (open, close, parent) => {
};

const createBuilder = (self, _styler, _isEmpty) => {
const builder = (...arguments_) => {
if (isArray(arguments_[0]) && isArray(arguments_[0].raw)) {
// Called as a template literal, for example: chalk.red`2 + 3 = {bold ${2+3}}`
return applyStyle(builder, chalkTag(builder, ...arguments_));
}

// Single argument is hot path, implicit coercion is faster than anything
// eslint-disable-next-line no-implicit-coercion
return applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' '));
};
// Single argument is hot path, implicit coercion is faster than anything
// eslint-disable-next-line no-implicit-coercion
const builder = (...arguments_) => applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' '));

// We alter the prototype because we must return a function, but there is
// no way to create a function with a different prototype
Expand Down Expand Up @@ -213,28 +199,6 @@ const applyStyle = (self, string) => {
return openAll + string + closeAll;
};

const chalkTag = (chalk, ...strings) => {
const [firstString] = strings;

if (!isArray(firstString) || !isArray(firstString.raw)) {
// If chalk() was called by itself or with a string,
// return the string itself as a string.
return strings.join(' ');
}

const arguments_ = strings.slice(1);
const parts = [firstString.raw[0]];

for (let i = 1; i < firstString.length; i++) {
parts.push(
String(arguments_[i - 1]).replace(/[{}\\]/g, '\\$&'),
String(firstString.raw[i]),
);
}

return template(chalk, parts.join(''));
};

Object.defineProperties(createChalk.prototype, styles);

const chalk = createChalk();
Expand Down
6 changes: 0 additions & 6 deletions source/index.test-d.ts
Expand Up @@ -34,12 +34,6 @@ expectType<ChalkInstance>(new Chalk({level: 1}));
// -- Properties --
expectType<ColorSupportLevel>(chalk.level);

// -- Template literal --
expectType<string>(chalk``);
const name = 'John';
expectType<string>(chalk`Hello {bold.red ${name}}`);
expectType<string>(chalk`Works with numbers {bold.red ${1}}`);

// -- Color methods --
expectAssignable<colorReturn>(chalk.rgb(0, 0, 0));
expectAssignable<colorReturn>(chalk.hex('#DEADED'));
Expand Down
133 changes: 0 additions & 133 deletions source/templates.js

This file was deleted.