Fix python2.5 compatibility (and earlier ?) by borrowing

TextWrapper._wrap_chunk from python 2.7

Should fix issue #37
pull/62/head
Christophe de Vienne 2012-08-29 12:52:00 +02:00
rodzic 4622af7831
commit 5444186f67
2 zmienionych plików z 90 dodań i 2 usunięć

Wyświetl plik

@ -10,7 +10,7 @@ Copyright, 2005: Max M <maxm@mxm.dk>
"""
import re
import textwrap
import icalendar.tools
from types import TupleType, ListType
from icalendar.caselessdict import CaselessDict
SequenceTypes = [TupleType, ListType]
@ -36,7 +36,7 @@ def foldline(text, lenght=75, newline='\r\n'):
"""
return newline.join(
textwrap.wrap(text, lenght,
icalendar.tools.wrap(text, lenght,
subsequent_indent=' ',
drop_whitespace=False,
break_long_words=True,

Wyświetl plik

@ -1,4 +1,6 @@
import random
import sys
import textwrap
from string import ascii_letters, digits
from datetime import datetime
@ -43,6 +45,92 @@ class UIDGenerator:
return vText('%s-%s@%s' % (vDatetime(datetime.today()).to_ical(), unique, host_name))
if sys.version_info[0:2] <= (2, 5):
class TextWrapper(textwrap.TextWrapper):
"""A TextWrapper that borrow its _wrap_chunks implementation
from python 2.7
"""
def __init__(self, **kw):
self.drop_whitespace = kw.pop('drop_whitespace', True)
textwrap.TextWrapper.__init__(self, **kw)
def _wrap_chunks(self, chunks):
"""_wrap_chunks(chunks : [string]) -> [string]
Wrap a sequence of text chunks and return a list of lines of
length 'self.width' or less. (If 'break_long_words' is false,
some lines may be longer than this.) Chunks correspond roughly
to words and the whitespace between them: each chunk is
indivisible (modulo 'break_long_words'), but a line break can
come between any two chunks. Chunks should not have internal
whitespace; ie. a chunk is either all whitespace or a "word".
Whitespace chunks will be removed from the beginning and end of
lines, but apart from that whitespace is preserved.
"""
lines = []
if self.width <= 0:
raise ValueError("invalid width %r (must be > 0)" % self.width)
# Arrange in reverse order so items can be efficiently popped
# from a stack of chucks.
chunks.reverse()
while chunks:
# Start the list of chunks that will make up the current line.
# cur_len is just the length of all the chunks in cur_line.
cur_line = []
cur_len = 0
# Figure out which static string will prefix this line.
if lines:
indent = self.subsequent_indent
else:
indent = self.initial_indent
# Maximum width for this line.
width = self.width - len(indent)
# First chunk on line is whitespace -- drop it, unless this
# is the very beginning of the text (ie. no lines started yet).
if self.drop_whitespace and chunks[-1].strip() == '' and lines:
del chunks[-1]
while chunks:
l = len(chunks[-1])
# Can at least squeeze this chunk onto the current line.
if cur_len + l <= width:
cur_line.append(chunks.pop())
cur_len += l
# Nope, this line is full.
else:
break
# The current line is full, and the next chunk is too big to
# fit on *any* line (not just this one).
if chunks and len(chunks[-1]) > width:
self._handle_long_word(chunks, cur_line, cur_len, width)
# If the last chunk on this line is all whitespace, drop it.
if self.drop_whitespace and cur_line and cur_line[-1].strip() == '':
del cur_line[-1]
# Convert current line back to a string and store it in list
# of all lines (return value).
if cur_line:
lines.append(indent + ''.join(cur_line))
return lines
else:
TextWrapper = textwrap.TextWrapper
def wrap(text, width=70, **kwargs):
w = TextWrapper(width=width, **kwargs)
return w.wrap(text)
if __name__ == "__main__":
import doctest, tools
# import and test this file