From 8c3953cdf094af5d8f767a8a6fbc34860efee3ac Mon Sep 17 00:00:00 2001
From: Tangent Wantwight <tangent128@gmail.com>
Date: Mon, 21 Aug 2023 23:57:27 -0400
Subject: [PATCH] Implement \ suppression in {}

---
 src/notcl.test.ts | 19 +++++++------------
 src/notcl.ts      |  5 ++++-
 2 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/src/notcl.test.ts b/src/notcl.test.ts
index eeee40b..b956aef 100644
--- a/src/notcl.test.ts
+++ b/src/notcl.test.ts
@@ -112,12 +112,13 @@ b`)
     it("can parse nested braces with text", () =>
       expect(parse("{a{b}c}")).toEqual([true, [[{ text: "a{b}c" }]]]));
 
-    it.failing("doesn't count suppressed braces for nesting", () =>
-      expect(parse(String.raw`{a\{b}`)).toEqual([true, [[{ text: "a\\{b" }]]])
-    );
-    it.failing("doesn't count suppressed braces for unnesting", () =>
-      expect(parse(String.raw`{a\}b}`)).toEqual([true, [[{ text: "a\\}b" }]]])
-    );
+    it("does not allow trailing characters after a closing brace", () =>
+      expect(parse("{}a")).toMatchObject([false, {}]));
+
+    it("doesn't count suppressed braces for nesting", () =>
+      expect(parse(String.raw`{a\{b}`)).toEqual([true, [[{ text: "a\\{b" }]]]));
+    it("doesn't count suppressed braces for unnesting", () =>
+      expect(parse(String.raw`{a\}b}`)).toEqual([true, [[{ text: "a\\}b" }]]]));
     it("nests braces after suppressed backslashes", () =>
       expect(parse(String.raw`{a\\{b}}`)).toEqual([
         true,
@@ -143,12 +144,6 @@ b`)
       ).toEqual([true, [[{ text: "\\\\ " }]]]));
   });
 
-  // Braces
-  //   nesting
-  //   escapes
-  //     {, }, correct newline folding
-  //   no trailing chars
-
   // "Quotes"
   //   no trailing chars
 
diff --git a/src/notcl.ts b/src/notcl.ts
index 1efe060..abf92a7 100644
--- a/src/notcl.ts
+++ b/src/notcl.ts
@@ -31,7 +31,10 @@ const Brace: Pattern<string> = Sequence(
       Use(() => Brace)
         .expects("{")
         .map((text) => `{${text}}`),
-      Regex(/[^{}]+/y)
+      Regex(/\\./y)
+        .expects("\\")
+        .map(([escape]) => escape),
+      Regex(/[^\\{}]+/y)
         .expects("text")
         .map(([text]) => text)
     )