summaryrefslogtreecommitdiff
path: root/django/utils/text.py
diff options
context:
space:
mode:
authorMarkus Amalthea Magnuson <markus.magnuson@gmail.com>2014-05-16 18:39:03 +0200
committerClaude Paroz <claude@2xlibre.net>2014-05-17 20:42:58 +0200
commitacb20016c0567876e7fc8144ecbe77905ee8388a (patch)
treece5fbc53c731f0575b90885de9be409cd8be4bbc /django/utils/text.py
parentb6b873d2ada0d7c2a616d11f161a7688df15f45f (diff)
downloaddjango-acb20016c0567876e7fc8144ecbe77905ee8388a.tar.gz
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.
Diffstat (limited to 'django/utils/text.py')
-rw-r--r--django/utils/text.py43
1 files changed, 23 insertions, 20 deletions
diff --git a/django/utils/text.py b/django/utils/text.py
index df6e1d0c46..68eb713026 100644
--- a/django/utils/text.py
+++ b/django/utils/text.py
@@ -34,30 +34,33 @@ re_camel_case = re.compile(r'(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))')
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)