summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2019-11-11 13:08:43 -0500
committerNed Batchelder <ned@nedbatchelder.com>2019-11-11 13:09:59 -0500
commit694435b844760ca0443cf87bf73a537f06c37d7d (patch)
treed566b186426ed17872463250b1e67632e1f28490
parent99f8007f4210b3117c0bfc963ad6873e9b263408 (diff)
downloadpython-coveragepy-git-694435b844760ca0443cf87bf73a537f06c37d7d.tar.gz
Templite {% joined %} is more convenient than trailing hyphens
-rw-r--r--coverage/htmlfiles/pyfile.html52
-rw-r--r--coverage/templite.py19
-rw-r--r--tests/test_templite.py18
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}}&nbsp;</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}}&nbsp;</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ǝɥ",