From 10014acc559c8932ace62d86b81da50b0c0df04f Mon Sep 17 00:00:00 2001 From: Sanchit Mathew Date: Fri, 5 Feb 2021 23:22:28 +0530 Subject: [PATCH 1/4] Changed JinjaOptionalContainer to accept & use the nodes list directly from calling functions --- curlylint/ast.py | 19 ++----------------- curlylint/parse.py | 11 +---------- 2 files changed, 3 insertions(+), 27 deletions(-) diff --git a/curlylint/ast.py b/curlylint/ast.py index a4ec33f..8581d6a 100644 --- a/curlylint/ast.py +++ b/curlylint/ast.py @@ -197,25 +197,10 @@ def __str__(self): @attr.s(frozen=True) class JinjaOptionalContainer(Jinja): - first_opening_if = attr.ib() # JinjaTag - opening_tag = attr.ib() # OpeningTag - first_closing_if = attr.ib() # JinjaTag - content = attr.ib() # Interpolated - second_opening_if = attr.ib() # JinjaTag - closing_tag = attr.ib() # ClosingTag - second_closing_if = attr.ib() # JinjaTag + nodes = attr.ib(factory=list) def __str__(self): - nodes = [ - self.first_opening_if, - self.opening_tag, - self.first_closing_if, - self.content, - self.second_opening_if, - self.closing_tag, - self.second_closing_if, - ] - return "".join(str(n) for n in nodes) + return "".join(str(n) for n in self.nodes) @attr.s(frozen=True) diff --git a/curlylint/parse.py b/curlylint/parse.py index f66a8fa..98c95bf 100644 --- a/curlylint/parse.py +++ b/curlylint/parse.py @@ -522,16 +522,7 @@ def make_raw_text_element_parser(config, tag_name, jinja): def _combine_optional_container(locations, nodes): - return JinjaOptionalContainer( - first_opening_if=nodes[0], - opening_tag=nodes[1], - first_closing_if=nodes[2], - content=nodes[3], - second_opening_if=nodes[4], - closing_tag=nodes[5], - second_closing_if=nodes[6], - **locations, - ) + return JinjaOptionalContainer(nodes=nodes, **locations) # Awkward hack to handle optional HTML containers, for example: From 1db90a338add9d9d2c587c1a7768532bca03ba30 Mon Sep 17 00:00:00 2001 From: Sanchit Mathew Date: Fri, 5 Feb 2021 23:22:39 +0530 Subject: [PATCH 2/4] Added implementation for if-else based optional container --- curlylint/parse.py | 46 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/curlylint/parse.py b/curlylint/parse.py index 98c95bf..727b9a1 100644 --- a/curlylint/parse.py +++ b/curlylint/parse.py @@ -535,10 +535,20 @@ def _combine_optional_container(locations, nodes): # # {% endif %} # -# Currently, this only works with `if` statements and the two conditions -# must be exactly the same. +# OR +# +# {% if a %} +#
+# {% else %} +#
+# {% endif %} +#
+# +# Currently, this only works with `if` statements. The two conditions +# must be exactly the same in the first case. def make_jinja_optional_container_parser(config, content, jinja): jinja_if = make_jinja_tag_parser(P.string("if")) + jinja_else = make_jinja_tag_parser(P.string("else")) jinja_endif = make_jinja_tag_parser(P.string("endif")) opening_tag = make_opening_tag_parser(config, jinja, allow_slash=False) @@ -573,7 +583,37 @@ def opt_container_impl(): c_second_if_node, ] - return locate(opt_container_impl).combine(_combine_optional_container) + @P.generate + def ifelse_opt_container_impl(): + o_if_node = yield jinja_if.skip(whitespace) + o_first_tag_node = yield opening_tag.skip(whitespace) + o_else_node = yield jinja_else.skip(whitespace) + o_last_tag_node = yield opening_tag.skip(whitespace) + if o_last_tag_node.name != o_first_tag_node.name: + yield P.fail( + "Expected '" + o_first_tag_node.name + "' to be in else block" + ) + return + o_endif_node = yield jinja_endif.skip(whitespace) + html_tag_name = o_first_tag_node.name + if isinstance(html_tag_name, str): + closing_tag = make_closing_tag_parser(P.string(html_tag_name)) + else: + assert isinstance(html_tag_name, Jinja) + closing_tag = make_closing_tag_parser(jinja) + c_tag_node = yield closing_tag + return [ + o_if_node, + o_first_tag_node, + o_else_node, + o_last_tag_node, + o_endif_node, + c_tag_node, + ] + + return locate(opt_container_impl).combine( + _combine_optional_container + ) | locate(ifelse_opt_container_impl).combine(_combine_optional_container) def make_jinja_parser(config, content): From db07dc76e476a8513e7f19d17f3db9719b0b1461 Mon Sep 17 00:00:00 2001 From: Sanchit Mathew Date: Fri, 5 Feb 2021 23:56:12 +0530 Subject: [PATCH 3/4] Added test cases --- curlylint/parse_test.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/curlylint/parse_test.py b/curlylint/parse_test.py index 3527c10..1104d80 100644 --- a/curlylint/parse_test.py +++ b/curlylint/parse_test.py @@ -325,6 +325,18 @@ def test_optional_container(): src = '{% if a %}{% endif %}cd{% if a %}{% endif %}' assert src == str(content.parse(src)) + src = "{% if a %}
{% else %}
{% endif %}
" + assert src == str(content.parse(src)) + + src = "{% if a %}
{% else %}
{% endif %}
" + assert src == str(content.parse(src)) + + src = "{% if a %}
{% else %}
{% endif %}
{% if a %}
{% endif %}foobar{% if a %}
{% endif %}" + assert src == str(content.parse(src)) + + src = "{% if a %}
{% endif %}foobar{% if a %}
{% endif %}{% if a %}
{% else %}
{% endif %}
" + assert src == str(content.parse(src)) + src = """ {% if a %} {% endif %} c d From 994f112691b448908fccaad773914a2776f49246 Mon Sep 17 00:00:00 2001 From: Sanchit Mathew Date: Tue, 9 Feb 2021 14:27:47 +0530 Subject: [PATCH 4/4] Added content nodes --- curlylint/parse.py | 3 +++ curlylint/parse_test.py | 22 ++++++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/curlylint/parse.py b/curlylint/parse.py index 727b9a1..5451f0e 100644 --- a/curlylint/parse.py +++ b/curlylint/parse.py @@ -542,6 +542,7 @@ def _combine_optional_container(locations, nodes): # {% else %} #
# {% endif %} +# foo #
# # Currently, this only works with `if` statements. The two conditions @@ -601,6 +602,7 @@ def ifelse_opt_container_impl(): else: assert isinstance(html_tag_name, Jinja) closing_tag = make_closing_tag_parser(jinja) + content_nodes = yield content c_tag_node = yield closing_tag return [ o_if_node, @@ -608,6 +610,7 @@ def ifelse_opt_container_impl(): o_else_node, o_last_tag_node, o_endif_node, + content_nodes, c_tag_node, ] diff --git a/curlylint/parse_test.py b/curlylint/parse_test.py index 1104d80..7fff2c6 100644 --- a/curlylint/parse_test.py +++ b/curlylint/parse_test.py @@ -331,10 +331,28 @@ def test_optional_container(): src = "{% if a %}