Ticket #6799: 6799.r11858.diff

File 6799.r11858.diff, 4.9 KB (added by Travis Cline <travis.cline@…>, 14 years ago)
  • django/utils/text.py

    diff --git a/django/utils/text.py b/django/utils/text.py
    index fe46e26..6138041 100644
    a b  
    11import re
    2 from django.conf import settings
    32from django.utils.encoding import force_unicode
    43from django.utils.functional import allow_lazy
    54from django.utils.translation import ugettext_lazy
    def wrap(text, width):  
    3736    return u''.join(_generator())
    3837wrap = allow_lazy(wrap, unicode)
    3938
    40 def truncate_words(s, num):
    41     "Truncates a string after a certain number of words."
     39def truncate_words(s, num, end_text='...'):
     40    """Truncates a string after a certain number of words. Takes an optional
     41    argument of what should be used to notify that the string has been
     42    truncated, defaults to ellipsis (...)"""
    4243    s = force_unicode(s)
    4344    length = int(num)
    4445    words = s.split()
    4546    if len(words) > length:
    4647        words = words[:length]
    47         if not words[-1].endswith('...'):
    48             words.append('...')
     48        if not words[-1].endswith(end_text):
     49            words.append(end_text)
    4950    return u' '.join(words)
    5051truncate_words = allow_lazy(truncate_words, unicode)
    5152
    52 def truncate_html_words(s, num):
    53     """
    54     Truncates html to a certain number of words (not counting tags and
     53def truncate_html_words(s, num, end_text='...'):
     54    """Truncates html to a certain number of words (not counting tags and
    5555    comments). Closes opened tags if they were correctly closed in the given
    56     html.
    57     """
     56    html. Takes an optional argument of what should be used to notify that the
     57    string has been truncated, defaults to ellipsis (...)."""
    5858    s = force_unicode(s)
    5959    length = int(num)
    6060    if length <= 0:
    def truncate_html_words(s, num):  
    6565    re_tag = re.compile(r'<(/)?([^ ]+?)(?: (/)| .*?)?>')
    6666    # Count non-HTML words and keep note of open tags
    6767    pos = 0
    68     ellipsis_pos = 0
     68    end_text_pos = 0
    6969    words = 0
    7070    open_tags = []
    7171    while words <= length:
    def truncate_html_words(s, num):  
    7878            # It's an actual non-HTML word
    7979            words += 1
    8080            if words == length:
    81                 ellipsis_pos = pos
     81                end_text_pos = pos
    8282            continue
    8383        # Check for tag
    8484        tag = re_tag.match(m.group(0))
    85         if not tag or ellipsis_pos:
     85        if not tag or end_text_pos:
    8686            # Don't worry about non tags or tags after our truncate point
    8787            continue
    8888        closing_tag, tagname, self_closing = tag.groups()
    def truncate_html_words(s, num):  
    104104    if words <= length:
    105105        # Don't try to close tags if we don't need to truncate
    106106        return s
    107     out = s[:ellipsis_pos] + ' ...'
     107    out = s[:end_text_pos]
     108    if end_text:
     109        out += ' ' + end_text
    108110    # Close any tags still open
    109111    for tag in open_tags:
    110112        out += '</%s>' % tag
  • tests/regressiontests/utils/tests.py

    diff --git a/tests/regressiontests/utils/tests.py b/tests/regressiontests/utils/tests.py
    index a7a6e4c..46f0b85 100644
    a b Tests for django.utils.  
    44
    55from unittest import TestCase
    66
    7 from django.utils import html, checksums
     7from django.utils import html, checksums, text
    88from django.utils.functional import SimpleLazyObject
    99
    1010import timesince
    class TestUtilsSimpleLazyObject(TestCase):  
    237237        s3 = copy.deepcopy(s)
    238238        self.assertEqual(s3, complex_object())
    239239
     240class TestUtilsText(TestCase):
     241
     242    def test_truncate_words(self):
     243        self.assertEqual(u'The quick brown fox jumped over the lazy dog.',
     244            text.truncate_words(u'The quick brown fox jumped over the lazy dog.', 10))
     245        self.assertEqual(u'The quick brown fox ...',
     246            text.truncate_words('The quick brown fox jumped over the lazy dog.', 4))
     247        self.assertEqual(u'The quick brown fox ....',
     248            text.truncate_words('The quick brown fox jumped over the lazy dog.', 4, '....'))
     249        self.assertEqual(u'<p><strong><em>The quick brown fox jumped over the lazy dog.</em></strong></p>',
     250            text.truncate_html_words('<p><strong><em>The quick brown fox jumped over the lazy dog.</em></strong></p>', 10))
     251        self.assertEqual(u'<p><strong><em>The quick brown fox ...</em></strong></p>',
     252            text.truncate_html_words('<p><strong><em>The quick brown fox jumped over the lazy dog.</em></strong></p>', 4))
     253        self.assertEqual(u'<p><strong><em>The quick brown fox ....</em></strong></p>',
     254            text.truncate_html_words('<p><strong><em>The quick brown fox jumped over the lazy dog.</em></strong></p>', 4, '....'))
     255        self.assertEqual(u'<p><strong><em>The quick brown fox</em></strong></p>',
     256            text.truncate_html_words('<p><strong><em>The quick brown fox jumped over the lazy dog.</em></strong></p>', 4, None))
     257
    240258if __name__ == "__main__":
    241259    import doctest
    242260    doctest.testmod()
Back to Top