Merge remote-tracking branch 'github/pr/19'
diff --git a/mako/lexer.py b/mako/lexer.py
index 2fa08e4..a80b898 100644
--- a/mako/lexer.py
+++ b/mako/lexer.py
@@ -95,31 +95,37 @@
         #          (match and "TRUE" or "FALSE")
         return match
 
-    def parse_until_text(self, *text):
+    def parse_until_text(self, watch_nesting, *text):
         startpos = self.match_position
         text_re = r'|'.join(text)
         brace_level = 0
+        paren_level = 0
+        bracket_level = 0
         while True:
             match = self.match(r'#.*\n')
             if match:
                 continue
-            match = self.match(r'(\"\"\"|\'\'\'|\"|\')((?<!\\)\\\1|.)*?\1',
+            match = self.match(r'(\"\"\"|\'\'\'|\"|\')[^\\]*?(\\.[^\\]*?)*\1',
                                re.S)
             if match:
                 continue
             match = self.match(r'(%s)' % text_re)
-            if match:
-                if match.group(1) == '}' and brace_level > 0:
-                    brace_level -= 1
-                    continue
+            if match and not (watch_nesting
+                              and (brace_level > 0 or paren_level > 0
+                                   or bracket_level > 0)):
                 return \
                     self.text[startpos:
                               self.match_position - len(match.group(1))],\
                     match.group(1)
-            match = self.match(r"(.*?)(?=\"|\'|#|%s)" % text_re, re.S)
+            elif not match:
+                match = self.match(r"(.*?)(?=\"|\'|#|%s)" % text_re, re.S)
             if match:
                 brace_level += match.group(1).count('{')
                 brace_level -= match.group(1).count('}')
+                paren_level += match.group(1).count('(')
+                paren_level -= match.group(1).count(')')
+                bracket_level += match.group(1).count('[')
+                bracket_level -= match.group(1).count(']')
                 continue
             raise exceptions.SyntaxException(
                 "Expected: %s" %
@@ -368,7 +374,7 @@
         match = self.match(r"<%(!)?")
         if match:
             line, pos = self.matched_lineno, self.matched_charpos
-            text, end = self.parse_until_text(r'%>')
+            text, end = self.parse_until_text(False, r'%>')
             # the trailing newline helps
             # compiler.parse() not complain about indentation
             text = adjust_whitespace(text) + "\n"
@@ -384,9 +390,9 @@
         match = self.match(r"\${")
         if match:
             line, pos = self.matched_lineno, self.matched_charpos
-            text, end = self.parse_until_text(r'\|', r'}')
+            text, end = self.parse_until_text(True, r'\|', r'}')
             if end == '|':
-                escapes, end = self.parse_until_text(r'}')
+                escapes, end = self.parse_until_text(True, r'}')
             else:
                 escapes = ""
             text = text.replace('\r\n', '\n')
diff --git a/test/test_lexer.py b/test/test_lexer.py
index 3e97bef..06ebb05 100644
--- a/test/test_lexer.py
+++ b/test/test_lexer.py
@@ -477,9 +477,10 @@
             ])
         )
 
-        template = """
+        template = r"""
 
             ${hello + '''heres '{|}' text | | }''' | escape1}
+            ${'Tricky string: ' + '\\\"\\\'|\\'}
         """
         nodes = Lexer(template).parse()
         self._compare(
@@ -488,7 +489,10 @@
                 Text('\n\n            ', (1, 1)),
                 Expression("hello + '''heres '{|}' text | | }''' ",
                                 ['escape1'], (3, 13)),
-                Text('\n        ', (3, 62))
+                Text('\n            ', (3, 62)),
+                Expression(r"""'Tricky string: ' + '\\\"\\\'|\\'""",
+                                [], (4, 13)),
+                Text('\n        ', (4, 49))
             ])
         )
 
@@ -587,6 +591,15 @@
                       Expression(" {'key': 'value'} ", [], (1, 8)),
                       Text(' after', (1, 29))]))
 
+    def test_tricky_code_6(self):
+        template = \
+            """before ${ (0x5302 | 0x0400) } after"""
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({},
+                      [Text('before ', (1, 1)),
+                      Expression(" (0x5302 | 0x0400) ", [], (1, 8)),
+                      Text(' after', (1, 30))]))
+
     def test_control_lines(self):
         template = \
             """