Ticket #6668: faster_wrap.diff

File faster_wrap.diff, 3.3 KB (added by SmileyChris, 7 years ago)

and here's the patch

  • django/utils/text.py

     
    1010
    1111def wrap(text, width):
    1212    """
    13     A word-wrap function that preserves existing line breaks and most spaces in
    14     the text. Expects that existing line breaks are posix newlines.
     13    A word-wrap function that preserves existing line breaks. Expects that
     14    existing line breaks are posix newlines.
     15
     16    All white space is preserved except added line breaks consume the space on
     17    which they break the line.
     18
     19    Long words are not wrapped, so the output text may have lines longer than
     20    ``width``.
    1521    """
    1622    text = force_unicode(text)
    1723    def _generator():
    18         it = iter(text.split(' '))
    19         word = it.next()
    20         yield word
    21         pos = len(word) - word.rfind('\n') - 1
    22         for word in it:
    23             if "\n" in word:
    24                 lines = word.split('\n')
    25             else:
    26                 lines = (word,)
    27             pos += len(lines[0]) + 1
    28             if pos > width:
    29                 yield '\n'
    30                 pos = len(lines[-1])
    31             else:
    32                 yield ' '
    33                 if len(lines) > 1:
    34                     pos = len(lines[-1])
    35             yield word
     24        for line in text.splitlines(True):   # True keeps trailing linebreaks
     25            quote = ''
     26            max_width = (line.endswith('\n') and width + 1 or width)
     27            while len(line) > max_width:
     28                space = line[:max_width+1].rfind(' ') + 1
     29                if space == 0:
     30                    space = line.find(' ') + 1
     31                    if space == 0:
     32                        yield line
     33                        line = ''
     34                        break
     35                yield '%s\n' % line[:space-1]
     36                line = line[space:]
     37                max_width = (line.endswith('\n') and width + 1 or width)
     38            if line:
     39                yield line
    3640    return u''.join(_generator())
    3741wrap = allow_lazy(wrap, unicode)
    3842
  • tests/regressiontests/utils/tests.py

     
    88
    99import timesince
    1010import datastructures
     11import text
    1112
    1213# Extra tests
    1314__test__ = {
    1415    'timesince': timesince,
    1516    'datastructures': datastructures,
     17    'text': text,
    1618}
    1719
    1820class TestUtilsHtml(TestCase):
  • tests/regressiontests/utils/text.py

     
     1r"""
     2>>> from django.utils.text import wrap
     3
     4>>> wrap('1234 67 9', 100)
     5u'1234 67 9'
     6>>> wrap('1234 67 9', 9)
     7u'1234 67 9'
     8>>> wrap('1234 67 9', 8)
     9u'1234 67\n9'
     10
     11>>> wrap('short\na long line', 7)
     12u'short\na long\nline'
     13
     14>>> wrap('do-not-break-long-words please? ok', 8)
     15u'do-not-break-long-words\nplease?\nok'
     16
     17>>> long_word = 'l%sng' % ('0123456789'*100)
     18>>> wrap(long_word, 50) == long_word
     19True
     20>>> out = wrap('a %s word' % long_word, 10)
     21>>> '%s...%s' % (out[:20], out[-20:])
     22u'a\nl01234567890123456...7890123456789ng\nword'
     23"""
Back to Top