- rewrote the "whitespace adjuster" function to work with more elaborate combinations of quotes and comments [ticket:75]
diff --git a/CHANGES b/CHANGES index 863896e..4e5a3ce 100644 --- a/CHANGES +++ b/CHANGES
@@ -16,6 +16,9 @@ present [ticket:71] - format_exceptions will apply the encoding options of html_error_template() to the buffered output +- rewrote the "whitespace adjuster" function to work with + more elaborate combinations of quotes and comments + [ticket:75] 0.1.10 - fixed propagation of 'caller' such that nested %def calls
diff --git a/lib/mako/lexer.py b/lib/mako/lexer.py index a504c1e..621a92e 100644 --- a/lib/mako/lexer.py +++ b/lib/mako/lexer.py
@@ -272,7 +272,7 @@ if match: (line, pos) = (self.matched_lineno, self.matched_charpos) (text, end) = self.parse_until_text(r'%>') - text = adjust_whitespace(text) + text = adjust_whitespace(text) + "\n" # the trailing newline helps compiler.parse() not complain about indentation self.append_node(parsetree.Code, self.escape_code(text), match.group(1)=='!', lineno=line, pos=pos) return True else:
diff --git a/lib/mako/pygen.py b/lib/mako/pygen.py index 7310ffe..b73325f 100644 --- a/lib/mako/pygen.py +++ b/lib/mako/pygen.py
@@ -213,30 +213,55 @@ """remove the left-whitespace margin of a block of Python code.""" state = [False, False] (backslashed, triplequoted) = (0, 1) + def in_multi_line(line): - current_state = (state[backslashed] or state[triplequoted]) + start_state = (state[backslashed] or state[triplequoted]) + if re.search(r"\\$", line): state[backslashed] = True else: state[backslashed] = False - line = re.split(r'#', line)[0] - triples = len(re.findall(r"\"\"\"|\'\'\'", line)) - if triples == 1 or triples % 2 != 0: - state[triplequoted] = not state[triplequoted] - return current_state + + def match(reg, t): + m = re.match(reg, t) + if m: + return m, t[len(m.group(0)):] + else: + return None, t + + while line: + if state[triplequoted]: + m, line = match(r"%s" % state[triplequoted], line) + if m: + state[triplequoted] = False + else: + m, line = match(r".*?(?=%s|$)" % state[triplequoted], line) + else: + m, line = match(r'#', line) + if m: + return start_state + + m, line = match(r"\"\"\"|\'\'\'", line) + if m: + state[triplequoted] = m.group(0) + continue + + m, line = match(r".*?(?=\"\"\"|\'\'\'|#|$)", line) + + return start_state def _indent_line(line, stripspace = ''): return re.sub(r"^%s" % stripspace, '', line) - stream = StringIO() + lines = [] stripspace = None for line in re.split(r'\r?\n', text): if in_multi_line(line): - stream.write(line + "\n") + lines.append(line) else: line = string.expandtabs(line) if stripspace is None and re.search(r"^[ \t]*[^# \t]", line): stripspace = re.match(r"^([ \t]*)", line).group(1) - stream.write(_indent_line(line, stripspace) + "\n") - return stream.getvalue() + lines.append(_indent_line(line, stripspace)) + return "\n".join(lines)
diff --git a/test/pygen.py b/test/pygen.py index 9485b74..95444dd 100644 --- a/test/pygen.py +++ b/test/pygen.py
@@ -162,9 +162,78 @@ for x in range(0,15): print x print "hi" - """ + def test_blank_lines(self): + text = """ + print "hi" # a comment + + # more comments + + print g +""" + assert adjust_whitespace(text) == \ +""" +print "hi" # a comment + +# more comments + +print g +""" + + def test_open_quotes_with_pound(self): + text = ''' + print """ this is text + # and this is text + # and this is too """ +''' + assert adjust_whitespace(text) == \ +''' +print """ this is text + # and this is text + # and this is too """ +''' + + def test_quote_with_comments(self): + text= """ + print 'hi' + # this is a comment + # another comment + x = 7 # someone's '''comment + print ''' + there + ''' + # someone else's comment +""" + + assert adjust_whitespace(text) == \ +""" +print 'hi' +# this is a comment +# another comment +x = 7 # someone's '''comment +print ''' + there + ''' +# someone else's comment +""" + + + def test_quotes_with_pound(self): + text = ''' + if True: + """#""" + elif False: + "bar" +''' + assert adjust_whitespace(text) == \ +''' +if True: + """#""" +elif False: + "bar" +''' + def test_quotes(self): text = """ print ''' aslkjfnas kjdfn @@ -180,7 +249,6 @@ asdkfjnads kfajns ''' if x: print y - """ if __name__ == '__main__':