Code

Ticket #1919: truncate_words_faster.diff

File truncate_words_faster.diff, 2.0 KB (added by arien <regexbot@…>, 7 years ago)

faster version of the same idea; includes additional tests for trailing whitespace handling

Line 
1Index: django/utils/text.py
2===================================================================
3--- django/utils/text.py        (revision 6670)
4+++ django/utils/text.py        (working copy)
5@@ -36,16 +36,24 @@
6     return u''.join(_generator())
7 wrap = allow_lazy(wrap, unicode)
8 
9+word_re = re.compile(r'\S+')
10 def truncate_words(s, num):
11     "Truncates a string after a certain number of words."
12     s = force_unicode(s)
13     length = int(num)
14-    words = s.split()
15-    if len(words) > length:
16-        words = words[:length]
17-        if not words[-1].endswith('...'):
18-            words.append('...')
19-    return u' '.join(words)
20+    if length < 1:
21+        return u''
22+    words = 0
23+    for match in word_re.finditer(s):
24+        words += 1
25+        if words == length:
26+            end = match.end()
27+            if len(s) > end:
28+                s = s[:end]
29+                if not s.endswith('...'):
30+                    s += ' ...'
31+            break
32+    return s
33 truncate_words = allow_lazy(truncate_words, unicode)
34 
35 def truncate_html_words(s, num):
36Index: tests/regressiontests/defaultfilters/tests.py
37===================================================================
38--- tests/regressiontests/defaultfilters/tests.py       (revision 6670)
39+++ tests/regressiontests/defaultfilters/tests.py       (working copy)
40@@ -98,6 +98,21 @@
41 >>> truncatewords(u'A sentence with a few words in it', 'not a number')
42 u'A sentence with a few words in it'
43 
44+>>> truncatewords(u'Double-spaced  sentence  with  a  few  words', 2)
45+u'Double-spaced  sentence ...'
46+
47+>>> truncatewords(u'  Two leading spaces for this sentence', 3)
48+u'  Two leading spaces ...'
49+
50+>>> truncatewords(u'  Text with leading and trailing whitespace  ', 10)
51+u'  Text with leading and trailing whitespace  '
52+
53+>>> truncatewords(u'  Text with leading and trailing whitespace  ', 6)
54+u'  Text with leading and trailing whitespace ...'
55+
56+>>> truncatewords(u'  Text with leading and trailing whitespace  ', 1)
57+u'  Text ...'
58+
59 >>> truncatewords_html(u'<p>one <a href="#">two - three <br>four</a> five</p>', 0)
60 u''
61