Permalink
Browse files

Fixed #6668 -- Optimized utils.text wrap function

This fixes a failing test after applying an optimization of the
utils.text.wrap function by user SmileyChris.
  • Loading branch information...
alimony authored and claudep committed May 16, 2014
1 parent b6b873d commit acb20016c0567876e7fc8144ecbe77905ee8388a
Showing with 23 additions and 20 deletions.
  1. +23 −20 django/utils/text.py
View
@@ -34,30 +34,33 @@
def wrap(text, width):
"""
- A word-wrap function that preserves existing line breaks and most spaces in
- the text. Expects that existing line breaks are posix newlines.
+ A word-wrap function that preserves existing line breaks. Expects that
+ existing line breaks are posix newlines.
+
+ All white space is preserved except added line breaks consume the space on
+ which they break the line.
+
+ Long words are not wrapped, so the output text may have lines longer than
+ ``width``.
"""
text = force_text(text)
def _generator():
- it = iter(text.split(' '))
- word = next(it)
- yield word
- pos = len(word) - word.rfind('\n') - 1
- for word in it:
- if "\n" in word:
- lines = word.split('\n')
- else:
- lines = (word,)
- pos += len(lines[0]) + 1
- if pos > width:
- yield '\n'
- pos = len(lines[-1])
- else:
- yield ' '
- if len(lines) > 1:
- pos = len(lines[-1])
- yield word
+ for line in text.splitlines(True): # True keeps trailing linebreaks
+ max_width = min((line.endswith('\n') and width + 1 or width), width)
+ while len(line) > max_width:
+ space = line[:max_width + 1].rfind(' ') + 1
+ if space == 0:
+ space = line.find(' ') + 1
+ if space == 0:
+ yield line
+ line = ''
+ break
+ yield '%s\n' % line[:space - 1]
+ line = line[space:]
+ max_width = min((line.endswith('\n') and width + 1 or width), width)
+ if line:
+ yield line
return ''.join(_generator())
wrap = allow_lazy(wrap, six.text_type)

0 comments on commit acb2001

Please sign in to comment.