Repository: chalk/chalk (js)

Issue:
Bug: bracketed Unicode escapes not supported
<!-- Issuehunt Badges -->
[<img alt="Issuehunt badges" src="https://img.shields.io/badge/IssueHunt-%2450%20Funded-%2300A156.svg" />](https://issuehunt.io/r/chalk/chalk/issues/349)
<!-- /Issuehunt Badges -->


Repro:

```js
// example.js
const chalk = require('chalk')

console.log(chalk`\u{2192} Running test {bold foo}...`)
```

Expected output:
<pre><code>&#x2192; Running test <strong>foo</strong>...</code></pre>

Actual output:
```
Error: Found extraneous } in Chalk template literal
    at node_modules/chalk/templates.js:109:11
    at String.replace (<anonymous>)
    at module.exports (node_modules/chalk/templates.js:99:6)
    at chalkTag (node_modules/chalk/index.js:221:9)
    at Chalk.chalk.template (node_modules/chalk/index.js:36:20)
    at Object.<anonymous> (example.js:3:17)
```


<!-- Issuehunt content -->

---

<details>
<summary>
<b>IssueHunt Summary</b>
</summary>


### Backers (Total: $50.00)

- [<img src='https://avatars3.githubusercontent.com/u/44827199?v=4' alt='issuehunt' width=24 height=24> issuehunt](https://issuehunt.io/u/issuehunt) ($50.00)
### Submitted pull Requests
- [#350 Fix bracketed unicode escapes in template literals](https://issuehunt.io/r/chalk/chalk/pull/350)
---

#### [Become a backer now!](https://issuehunt.io/r/chalk/chalk/issues/349)
#### [Or submit a pull request to get the deposits!](https://issuehunt.io/r/chalk/chalk/issues/349)
### Tips

- Checkout the [Issuehunt explorer](https://issuehunt.io/r/chalk/chalk/) to discover more funded issues.
- Need some help from other developers? [Add your repositories](https://issuehunt.io/r/new) on IssueHunt to raise funds.
---
IssueHunt has been backed by the following sponsors. [Become a sponsor](https://issuehunt.io/membership/members)
</details>
<!-- /Issuehunt content-->

Pull request:
Fix support for bracketed Unicode escapes in template literals
Fixes #349.


<!-- Issuehunt content -->

---

<details>
<summary>
<b>IssueHunt Summary</b>
</summary>

### Referenced issues

This pull request has been submitted to:
- [#349: Bug: bracketed Unicode escapes not supported](https://issuehunt.io/repos/11855195/issues/349)
---

IssueHunt has been backed by the following sponsors. [Become a sponsor](https://issuehunt.io/membership/members)
</details>
<!-- /Issuehunt content-->

Patch:
diff --git a/readme.md b/readme.md
index 5e96212..78af5ae 100644
--- a/readme.md
+++ b/readme.md
@@ -176,7 +176,7 @@ Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color=
 - `red`
 - `green`
 - `yellow`
-- `blue` *(On Windows the bright version is used since normal blue is illegible)*
+- `blue`
 - `magenta`
 - `cyan`
 - `white`
diff --git a/templates.js b/templates.js
index 6cdddea..fe94642 100644
--- a/templates.js
+++ b/templates.js
@@ -1,8 +1,8 @@
 'use strict';
-const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi;
+const TEMPLATE_REGEX = /(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi;
 const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g;
 const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/;
-const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi;
+const ESCAPE_REGEX = /\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.)|([^\\])/gi;
 
 const ESCAPES = new Map([
 	['n', '\n'],
@@ -18,10 +18,17 @@ const ESCAPES = new Map([
 ]);
 
 function unescape(c) {
-	if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) {
+	const u = c[0] === 'u';
+	const bracket = c[1] === '{';
+
+	if ((u && !bracket && c.length === 5) || (c[0] === 'x' && c.length === 3)) {
 		return String.fromCharCode(parseInt(c.slice(1), 16));
 	}
 
+	if (u && bracket) {
+		return String.fromCodePoint(parseInt(c.slice(2, -1), 16));
+	}
+
 	return ESCAPES.get(c) || c;
 }
 


Test patch:
diff --git a/test/template-literal.js b/test/template-literal.js
index 1f388c8..ae4a0bc 100644
--- a/test/template-literal.js
+++ b/test/template-literal.js
@@ -168,3 +168,10 @@ test('should properly handle undefined template interpolated values', t => {
 	t.is(instance`hello ${undefined}`, 'hello undefined');
 	t.is(instance`hello ${null}`, 'hello null');
 });
+
+test('should allow bracketed Unicode escapes', t => {
+	const instance = new chalk.Instance({level: 3});
+	t.is(instance`\u{AB}`, '\u{AB}');
+	t.is(instance`This is a {bold \u{AB681}} test`, 'This is a \u001B[1m\u{AB681}\u001B[22m test');
+	t.is(instance`This is a {bold \u{10FFFF}} test`, 'This is a \u001B[1m\u{10FFFF}\u001B[22m test');
+});