[Zope] wrapping email at 72 characters ?
Chris McDonough
chrism@zope.com
09 Aug 2002 10:28:43 -0400
Here is a slightly more complicated set of functions that allow for
wrapping text (it comes from BackTalk's TextBlockFormatter module):
import string, math
def format(text, max_width=80, indent=0, trailing_lines_indent_more=0):
text = string.expandtabs(string.replace(text, '\r', ''))
lines = string.split(text, '\n')
aggregate = []
for line in lines:
if len(line) <= max_width-1:
# this line is short enough to output
aggregate.append(line)
else:
lines = splitlongline(line, max_width)
aggregate.extend(lines)
out = []
i = 0
for line in aggregate:
spaces = ' ' * indent
if i != 0 and trailing_lines_indent_more:
spaces = spaces + (' ' * trailing_lines_indent_more)
out.append('%s%s' % (spaces, line))
i = i + 1
return string.join(out, '\n')
def splitword(word, max_width=80, linepos=0):
# some lines may have single words that exceed the max_width
# We want to break apart long words into as many chunks as necessary
if len(word) <= max_width:
return [word]
first_chunk_len = max_width-1-linepos
firstchunk = word[:first_chunk_len]
word = word[first_chunk_len:]
numchunks = int(math.ceil(len(word) / float(max_width-1)))
index = 0
tmp = [firstchunk]
for chunknum in range(numchunks):
chunk = word[index:index+max_width-1]
tmp.append(chunk)
index = index + max_width-1
return tmp
def splitlongline(line, max_width=80):
# split a "long" line defined by max_width into a list of lines
line = string.strip(line)
words = string.split(line, ' ')
wordnum = 0
# iterate over all the words in the line, extending the word list
# necessary for too-long words
aggregate = []
linelen = 0
wordnum = 0
while words:
word = words.pop(0)
if not word: continue
if len(word) > max_width:
new_words = splitword(word, max_width, linelen)
word = new_words[0]
for new_word in new_words[1:]:
words.insert(wordnum, new_word)
wordnum = wordnum + 1
if words:
next_word = words[0]
else:
next_word = None
if next_word is None:
aggregate.append(word)
wordnum = wordnum + 1
continue
maybe_len = linelen + len(word) + len(next_word)
if maybe_len >= max_width-1:
aggregate.append(word)
aggregate.append(None)
linelen = 0
else:
aggregate.append(word)
linelen = linelen + len(word) + 1
wordnum = wordnum + 1
s = ""
last = None
for item in aggregate:
if item is None:
s = '%s\n' % s
elif last is None:
s = '%s%s' % (s, item)
else:
s = '%s %s' % (s, item)
last = item
return string.split(s, '\n')
long = """
To turn a component into a product you must fulfill many contracts. For
the most part these contracts are not yet defined in terms of
interfaces. Instead you must subclass from base classes that implement
the contracts. This makes building products confusing, and this is an
area that we are actively working on improving.
Hereisalonglinethatshouldbecaughtandbrokenupbytheformatter,hopefullyitllgetsplitupwhenirunitthroughthere."""
long2 = """
Hereisalonglinethatshouldbecaughtandbrokenupbytheformatter,hopefullyitllgetsplitupwhenirunitthroughthere."""
long3 = """
To turn a component into a product you must fulfill many contracts. For
the most part these contracts are not yet defined in terms of
interfaces.
Instead you must subclass from base classes that implement the
contracts. This makes building products confusing, and this is an area
that we are
actively working on improving.
Hereisalonglinethatshouldbecaughtandbrokenupbytheformatter,hopefullyitllgetsplitupwhenirunitthroughthere."""
if __name__ == '__main__':
print format(long, 60, 10)
print format(long)
print format(long2, 60, 10)
print format(long2)
print format(long3, 60, 10)
print format(long3)
On Thu, 2002-08-08 at 21:53, Jens Vagelpohl wrote:
> so you add a check in there to see if it is a single or a multiple newline
> in one place and modify the behavior. no problem.
>
> jens
>
> On Thursday, August 8, 2002, at 05:21 , Paul Winkler wrote:
>
> > On Thu, Aug 08, 2002 at 08:01:15AM -0400, Jens Vagelpohl wrote:
> >> code that does the following whould do it:
> >>
> >> - read 72 characters into the email body
> >> - go backwards from there until you encounter an empty space
> >> - replace the empty space with a newline character
> >> - repeat the preceding steps, starting from the first character after the
> >> newline you just inserted.
> >>
> >> if there is already newlines in the body of text you can replace all of
> >> them with empty spaces before you start parsing.
> >
> > but then you would lose double-newline paragraph boundaries.
> >
>
>
> _______________________________________________
> Zope maillist - Zope@zope.org
> http://lists.zope.org/mailman/listinfo/zope
> ** No cross posts or HTML encoding! **
> (Related lists -
> http://lists.zope.org/mailman/listinfo/zope-announce
> http://lists.zope.org/mailman/listinfo/zope-dev )