diff options
author | Ned Batchelder <ned@nedbatchelder.com> | 2019-11-11 13:08:43 -0500 |
---|---|---|
committer | Ned Batchelder <ned@nedbatchelder.com> | 2019-11-11 13:09:59 -0500 |
commit | 694435b844760ca0443cf87bf73a537f06c37d7d (patch) | |
tree | d566b186426ed17872463250b1e67632e1f28490 | |
parent | 99f8007f4210b3117c0bfc963ad6873e9b263408 (diff) | |
download | python-coveragepy-git-694435b844760ca0443cf87bf73a537f06c37d7d.tar.gz |
Templite {% joined %} is more convenient than trailing hyphens
-rw-r--r-- | coverage/htmlfiles/pyfile.html | 52 | ||||
-rw-r--r-- | coverage/templite.py | 19 | ||||
-rw-r--r-- | tests/test_templite.py | 18 |
3 files changed, 59 insertions, 30 deletions
diff --git a/coverage/htmlfiles/pyfile.html b/coverage/htmlfiles/pyfile.html index 01659dd8..eb0f99c8 100644 --- a/coverage/htmlfiles/pyfile.html +++ b/coverage/htmlfiles/pyfile.html @@ -68,34 +68,34 @@ </div> <div id="source"> - {# These are the source lines, which are very sensitive to whitespace. -#} - {# The `{ # - # }` below are comments which slurp up the following space. -#} {% for line in lines -%} - <p id="t{{line.number}}" class="{{line.css_class}}">{#-#} - <span class="n"><a href="#t{{line.number}}">{{line.number}}</a></span>{#-#} - <span class="t">{{line.html}} </span>{#-#} - {% if line.context_list -%} - <input type="checkbox" id="ctxs{{line.number}}" />{#-#} - {% endif -%} - {# Things that should float right in the line. -#} - <span class="r">{#-#} - {% if line.annotate -%} - <span class="annotate short">{{line.annotate}}</span>{#-#} - <span class="annotate long">{{line.annotate_long}}</span>{#-#} - {% endif -%} - {% if line.contexts -%} - <label for="ctxs{{line.number}}" class="ctx">{{ line.contexts_label }}</label>{#-#} - {% endif -%} - </span>{#-#} - {# Things that should appear below the line. -#} - {% if line.context_list -%} - <span class="ctxs">{#-#} - {% for context in line.context_list -%} - <span>{{context}}</span>{#-#} - {% endfor -%} - </span>{#-#} - {% endif -%} + {% joined %} + <p id="t{{line.number}}" class="{{line.css_class}}"> + <span class="n"><a href="#t{{line.number}}">{{line.number}}</a></span> + <span class="t">{{line.html}} </span> + {% if line.context_list %} + <input type="checkbox" id="ctxs{{line.number}}" /> + {% endif %} + {# Things that should float right in the line. #} + <span class="r"> + {% if line.annotate %} + <span class="annotate short">{{line.annotate}}</span> + <span class="annotate long">{{line.annotate_long}}</span> + {% endif %} + {% if line.contexts %} + <label for="ctxs{{line.number}}" class="ctx">{{ line.contexts_label }}</label> + {% endif %} + </span> + {# Things that should appear below the line. #} + {% if line.context_list %} + <span class="ctxs"> + {% for context in line.context_list %} + <span>{{context}}</span> + {% endfor %} + </span> + {% endif %} </p> + {% endjoined %} {% endfor %} </div> diff --git a/coverage/templite.py b/coverage/templite.py index b546ef7c..7d4024e0 100644 --- a/coverage/templite.py +++ b/coverage/templite.py @@ -90,7 +90,10 @@ class Templite(object): {# This will be ignored #} - Any of these constructs can have a hypen at the end (`-}}`, `-%}`, `-#}`), + Lines between `{% joined %}` and `{% endjoined %}` will have lines stripped + and joined. Be careful, this could join words together! + + Any of these constructs can have a hyphen at the end (`-}}`, `-%}`, `-#}`), which will collapse the whitespace following the tag. Construct a Templite with the template text, then use `render` against a @@ -154,7 +157,7 @@ class Templite(object): # Split the text to form a list of tokens. tokens = re.split(r"(?s)({{.*?}}|{%.*?%}|{#.*?#})", text) - squash = False + squash = in_joined = False for token in tokens: if token.startswith('{'): @@ -196,6 +199,9 @@ class Templite(object): ) ) code.indent() + elif words[0] == 'joined': + ops_stack.append('joined') + in_joined = True elif words[0].startswith('end'): # Endsomething. Pop the ops stack. if len(words) != 1: @@ -206,12 +212,17 @@ class Templite(object): start_what = ops_stack.pop() if start_what != end_what: self._syntax_error("Mismatched end tag", end_what) - code.dedent() + if end_what == 'joined': + in_joined = False + else: + code.dedent() else: self._syntax_error("Don't understand tag", words[0]) else: # Literal content. If it isn't empty, output it. - if squash: + if in_joined: + token = re.sub(r"\s*\n\s*", "", token.strip()) + elif squash: token = token.lstrip() if token: buffered.append(repr(token)) diff --git a/tests/test_templite.py b/tests/test_templite.py index be58fe91..321db830 100644 --- a/tests/test_templite.py +++ b/tests/test_templite.py @@ -270,6 +270,24 @@ class TempliteTest(CoverageTest): ) self.try_render(" hello ", {}, " hello ") + def test_eat_whitespace(self): + self.try_render( + "Hey!\n" + "{% joined %}\n" + "@{% for n in nums %}\n" + " {% for a in abc %}\n" + " {# this disappears completely #}\n" + " X\n" + " Y\n" + " {{a}}\n" + " {{n }}\n" + " {% endfor %}\n" + "{% endfor %}!\n" + "{% endjoined %}\n", + {'nums': [0, 1, 2], 'abc': ['a', 'b', 'c']}, + "Hey!\n@XYa0XYb0XYc0XYa1XYb1XYc1XYa2XYb2XYc2!\n" + ) + def test_non_ascii(self): self.try_render( u"{{where}} ollǝɥ", |