The language allows us to do this (for convenience). This PR adds fixes support for that.
The technique used is a bit similar to the one I used for Syntax
Highlighting.
Before
A "comment" block was considered a "raw" tag block. We'd parse it like this:
match /{%-?\s*comment\s*-?%}/
that's the .blockStart of the tag
match all characters until one that is followed by /{%-?\s*endcomment\s*-?%}/
that's the body of the tag
match /{%-?\s*endcomment\s*-?%}/
that's the .blockEnd of the tag
This approach didn't work for nested tags, since we'd match over the {% comment %} of the nested comment and stop at the {% endcomment %} of the nested comment. Leaving us with a dangling comment body and {% endcomment %}.
Something like this:
{% comment %}
This is inside the comment
{% comment %}
nested
{% endcomment}
This is outside the comment since we stoped parsing on the previous line
{% endcomment %}
After
Slightly different algorithm. We parse like this:
match /{%-?\s*comment\s*-?%}/
that's the .blockStart of the tag
match as many of the following two things (the concatenated list is the body of the tag):
Another comment block (recursive rule)
all characters until one that is followed by one of those two:
/{%-?\s*comment\s*-?%}
/{%-?\s*endcomment\s*-?%}/
match /{%-?\s*endcomment\s*-?%}
that's the .blockEnd of the tag
The "trick" here is that we stop parsing on nested {% comment %} and try to recurse on the rule.
So this will work:
{% comment %}
This is inside the comment
{% comment %}
this is nested inside a recursed rule
{% endcomment %}
This is inside the top comment
{% endcomment %}
Fixes #74
The language allows us to do this (for convenience). This PR adds fixes support for that.
The technique used is a bit similar to the one I used for Syntax Highlighting.
Before
A "comment" block was considered a "raw" tag block. We'd parse it like this:
/{%-?\s*comment\s*-?%}/
.blockStart
of the tag/{%-?\s*endcomment\s*-?%}/
body
of the tag/{%-?\s*endcomment\s*-?%}/
.blockEnd
of the tagThis approach didn't work for nested tags, since we'd match over the
{% comment %}
of the nested comment and stop at the{% endcomment %}
of the nested comment. Leaving us with a dangling comment body and{% endcomment %}
.Something like this:
After
Slightly different algorithm. We parse like this:
/{%-?\s*comment\s*-?%}/
.blockStart
of the tag/{%-?\s*comment\s*-?%}
/{%-?\s*endcomment\s*-?%}/
/{%-?\s*endcomment\s*-?%}
.blockEnd
of the tagThe "trick" here is that we stop parsing on nested
{% comment %}
and try to recurse on the rule.So this will work: