- fix to parsing of code/expression blocks to insure that non-ascii characters, combined
with a template that indicates a non-standard encoding, are expanded into backslash-escaped
glyphs before being AST parsed [ticket:11]
diff --git a/CHANGES b/CHANGES
index 1c9e240..40e9b12 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,8 @@
+0.1.2
+- fix to parsing of code/expression blocks to insure that non-ascii characters, combined
+with a template that indicates a non-standard encoding, are expanded into backslash-escaped 
+glyphs before being AST parsed [ticket:11]
+
 0.1.1
 - buffet plugin supports string-based templates, allows ToscaWidgets to work [ticket:8]
 - AST parsing fixes: fixed TryExcept identifier parsing
diff --git a/lib/mako/lexer.py b/lib/mako/lexer.py
index 3fbcb47..e622da5 100644
--- a/lib/mako/lexer.py
+++ b/lib/mako/lexer.py
@@ -87,10 +87,16 @@
             elif len(self.control_line) and not self.control_line[-1].is_ternary(node.keyword):
                 raise exceptions.SyntaxException("Keyword '%s' not a legal ternary for keyword '%s'" % (node.keyword, self.control_line[-1].keyword), self.matched_lineno, self.matched_charpos, self.filename)
 
+    def escape_code(self, text):
+        if self.encoding:
+            return text.encode('ascii', 'backslashreplace')
+        else:
+            return text
+            
     def parse(self):
-        encoding = self.match_encoding()
-        if encoding:
-            self.text = self.text.decode(encoding)
+        self.encoding = self.match_encoding()
+        if self.encoding:
+            self.text = self.text.decode(self.encoding)
 
         length = len(self.text)
             
@@ -218,7 +224,7 @@
             (line, pos) = (self.matched_lineno, self.matched_charpos)
             (text, end) = self.parse_until_text(r'%>')
             text = adjust_whitespace(text)
-            self.append_node(parsetree.Code, text, match.group(1)=='!', lineno=line, pos=pos)
+            self.append_node(parsetree.Code, self.escape_code(text), match.group(1)=='!', lineno=line, pos=pos)
             return True
         else:
             return False
@@ -232,7 +238,7 @@
                 (escapes, end) = self.parse_until_text(r'}')
             else:
                 escapes = ""
-            self.append_node(parsetree.Expression, text, escapes.strip(), lineno=line, pos=pos)
+            self.append_node(parsetree.Expression, self.escape_code(text), escapes.strip(), lineno=line, pos=pos)
             return True
         else:
             return False
@@ -254,7 +260,7 @@
                         raise exceptions.SyntaxException("No starting keyword '%s' for '%s'" % (keyword, text), self.matched_lineno, self.matched_charpos, self.filename)
                     elif self.control_line[-1].keyword != keyword:
                         raise exceptions.SyntaxException("Keyword '%s' doesn't match keyword '%s'" % (text, self.control_line[-1].keyword), self.matched_lineno, self.matched_charpos, self.filename)
-                self.append_node(parsetree.ControlLine, keyword, isend, text)
+                self.append_node(parsetree.ControlLine, keyword, isend, self.escape_code(text))
             else:
                 self.append_node(parsetree.Comment, text)
             return True
diff --git a/test/template.py b/test/template.py
index fdb87f5..1dc3433 100644
--- a/test/template.py
+++ b/test/template.py
@@ -30,6 +30,31 @@
         template = Template(val)
         assert template.render_unicode() == u"""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petit voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""
 
+    def test_unicode_literal_in_expr(self):
+        template = Template(u"""# -*- coding: utf-8 -*-
+        ${u"Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petit voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"}
+        """.encode('utf-8'))
+        assert template.render_unicode().strip() == u"""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petit voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""
+
+    def test_unicode_literal_in_code(self):
+        template = Template(u"""# -*- coding: utf-8 -*-
+        <%
+            context.write(u"Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petit voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »")
+        %>
+        """.encode('utf-8'))
+        assert template.render_unicode().strip() == u"""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petit voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""
+
+    def test_unicode_literal_in_controlline(self):
+        template = Template(u"""# -*- coding: utf-8 -*-
+        <%
+            x = u"drôle de petit voix m’a réveillé."
+        %>
+        % if x==u"drôle de petit voix m’a réveillé.":
+            hi, ${x}
+        % endif
+        """.encode('utf-8'))
+        assert template.render_unicode().strip() == u"""hi, drôle de petit voix m’a réveillé."""
+        
     def test_encoding(self):
         val = u"""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petit voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""
         template = Template(val, output_encoding='utf-8')