- 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')