Skip to content

Commit

Permalink
don't replace percent when it is not the first non-whitespace character
Browse files Browse the repository at this point in the history
  • Loading branch information
cocolato committed Jan 26, 2024
1 parent ab8e747 commit ff8ce2e
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 14 deletions.
17 changes: 13 additions & 4 deletions mako/lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ def parse(self):
continue
if self.match_python_block():
continue
if self.match_percent():
continue
if self.match_text():
continue

Expand Down Expand Up @@ -352,18 +354,25 @@ def match_end(self):
else:
return True

def match_percent(self):
match = self.match(r"(?<=^)(\s*)%%(%*)", re.M)
if match:
self.append_node(
parsetree.Text, match.group(1) + "%" + match.group(2)
)
return True
else:
return False

def match_text(self):
match = self.match(
r"""
(.*?) # anything, followed by:
(
(?<=\n)(?=[ \t]*(?=%(?!%)|\#\#)) # an eval or line-based
(?<=\n)(?=[ \t]*(?=%|\#\#)) # an eval or line-based
# comment, preceded by a
# consumed newline and whitespace
|
(?<!%)(?=%%+) # consume the first percent sign
# out of a group of percent signs
|
(?=\${) # an expression
|
(?=</?[%&]) # a substitution or block or call start or end
Expand Down
63 changes: 53 additions & 10 deletions test/test_lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,10 @@ def test_percent_escape(self):
TemplateNode(
{},
[
Text("""\n\n""", (1, 1)),
Text("""% some whatever.\n\n """, (3, 2)),
Text("% more some whatever\n", (5, 6)),
Text("\n\n%", (1, 1)),
Text(" some whatever.\n\n", (3, 3)),
Text(" %", (5, 1)),
Text(" more some whatever\n", (5, 7)),
ControlLine("if", "if foo:", False, (6, 1)),
ControlLine("if", "endif", True, (7, 1)),
Text(" ", (8, 1)),
Expand All @@ -222,11 +223,12 @@ def test_percent_escape2(self):
TemplateNode(
{},
[
Text("% do something\n", (1, 2)),
Text(
"%% do something\nif <some condition>:\n ", (2, 2)
),
Text("%%% do something\n ", (4, 6)),
Text("%", (1, 1)),
Text(" do something\n", (1, 3)),
Text("%%", (2, 1)),
Text(" do something\nif <some condition>:\n", (2, 4)),
Text(" %%%", (4, 1)),
Text(" do something\n ", (4, 9)),
],
),
)
Expand All @@ -245,15 +247,56 @@ def test_percent_escape_with_control_block(self):
[
Text("\n", (1, 1)),
ControlLine("for", "for i in [1, 2, 3]:", False, (2, 1)),
Text(" ", (3, 1)),
Text("% do something ", (3, 6)),
Text(" %", (3, 1)),
Text(" do something ", (3, 7)),
Expression("i", [], (3, 21)),
Text("\n", (3, 25)),
ControlLine("for", "endfor", True, (4, 1)),
],
),
)

def test_inline_percent(self):
template = """
%% foo
bar %% baz
"""
node = Lexer(template).parse()
self._compare(
node,
TemplateNode(
{},
[Text("\n%", (1, 1)), Text(" foo\nbar %% baz\n", (2, 3))],
),
)

def test_inline_percent_with_control_block(self):
template = """
% for i in [1, 2, 3]:
%% foo
bar %% baz
% endfor
"""
node = Lexer(template).parse()
self._compare(
node,
TemplateNode(
{},
[
Text("\n", (1, 1)),
ControlLine(
"for", "for i in [1, 2, 3]:", False, (2, 1)
),
Text("%", (3, 1)),
Text(" foo\nbar ", (3, 3)),
Text("%", (3, 3)),
Text("%", (3, 3)),
Text(" baz\n", (4, 7)),
ControlLine("for", "endfor", True, (5, 1)),
],
),
)

def test_old_multiline_comment(self):
template = """#*"""
node = Lexer(template).parse()
Expand Down
18 changes: 18 additions & 0 deletions test/test_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -1699,3 +1699,21 @@ def test_percent_escape2(self):
" % do something 2",
" % do something 3",
]

def test_inline_percent(self):
t = Template(
"""
% for i in [1, 2, 3]:
%% foo
bar %% baz
% endfor
"""
)
assert result_raw_lines(t.render()) == [
"% foo",
"bar %% baz",
"% foo",
"bar %% baz",
"% foo",
"bar %% baz",
]

0 comments on commit ff8ce2e

Please sign in to comment.