aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Ronacher <armin.ronacher@active-4.com>2017-01-06 13:08:57 +0100
committerGitHub <noreply@github.com>2017-01-06 13:08:57 +0100
commit49c382a1d0577d3aacf726e62830fc04ac8fec84 (patch)
tree51026ad7735ef3952faf3758259a0b6f3dd8be26
parent5453db1711eeb33c68ed1126764ab691b81d1472 (diff)
parent9f9606bc93da879db2071c2112f90437c5ac2eb3 (diff)
downloadjinja-49c382a1d0577d3aacf726e62830fc04ac8fec84.tar.gz
Merge pull request #610 from jab/jab-do_truncate
Fix and improve do_truncate
-rw-r--r--jinja2/filters.py24
-rw-r--r--tests/test_filters.py8
2 files changed, 18 insertions, 14 deletions
diff --git a/jinja2/filters.py b/jinja2/filters.py
index c93c8ff0..33e0ff14 100644
--- a/jinja2/filters.py
+++ b/jinja2/filters.py
@@ -463,31 +463,35 @@ def do_indent(s, width=4, indentfirst=False):
return rv
-def do_truncate(s, length=255, killwords=False, end='...'):
+def do_truncate(s, length=255, killwords=False, end='...', leeway=5):
"""Return a truncated copy of the string. The length is specified
with the first parameter which defaults to ``255``. If the second
parameter is ``true`` the filter will cut the text at length. Otherwise
it will discard the last word. If the text was in fact
truncated it will append an ellipsis sign (``"..."``). If you want a
different ellipsis sign than ``"..."`` you can specify it using the
- third parameter.
+ third parameter. Strings that only exceed the length by the tolerance
+ margin given in the fourth parameter will not be truncated.
.. sourcecode:: jinja
- {{ "foo bar baz"|truncate(9) }}
- -> "foo ..."
- {{ "foo bar baz"|truncate(9, True) }}
+ {{ "foo bar baz qux"|truncate(9) }}
+ -> "foo..."
+ {{ "foo bar baz qux"|truncate(9, True) }}
-> "foo ba..."
+ {{ "foo bar baz qux"|truncate(11) }}
+ -> "foo bar baz qux"
+ {{ "foo bar baz qux"|truncate(11, False, '...', 0) }}
+ -> "foo bar..."
"""
- if len(s) <= length:
+ assert length >= len(end), 'expected length >= %s, got %s' % (len(end), length)
+ assert leeway >= 0, 'expected leeway >= 0, got %s' % leeway
+ if len(s) <= length + leeway:
return s
- elif killwords:
+ if killwords:
return s[:length - len(end)] + end
-
result = s[:length - len(end)].rsplit(' ', 1)[0]
- if len(result) < length:
- result += ' '
return result + end
diff --git a/tests/test_filters.py b/tests/test_filters.py
index f8a2f196..ba57136d 100644
--- a/tests/test_filters.py
+++ b/tests/test_filters.py
@@ -239,7 +239,7 @@ class TestFilter(object):
out = tmpl.render(data='foobar baz bar' * 1000,
smalldata='foobar baz bar')
msg = 'Current output: %s' % out
- assert out == 'foobar baz b>>>|foobar baz >>>|foobar baz bar', msg
+ assert out == 'foobar baz b>>>|foobar baz>>>|foobar baz bar', msg
def test_truncate_very_short(self, env):
tmpl = env.from_string(
@@ -247,12 +247,12 @@ class TestFilter(object):
'{{ "foo bar baz"|truncate(9, true) }}'
)
out = tmpl.render()
- assert out == 'foo ...|foo ba...', out
+ assert out == 'foo bar baz|foo bar baz', out
def test_truncate_end_length(self, env):
- tmpl = env.from_string('{{ "Joel is a slug"|truncate(9, true) }}')
+ tmpl = env.from_string('{{ "Joel is a slug"|truncate(7, true) }}')
out = tmpl.render()
- assert out == 'Joel i...', 'Current output: %s' % out
+ assert out == 'Joel...', 'Current output: %s' % out
def test_upper(self, env):
tmpl = env.from_string('{{ "foo"|upper }}')