When using Python\'s textwrap library, how can I turn this:
short line,
long line xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TextWrapper is not designed to handle text that already has newlines in it.
There are a two things you may want to do when your document already has newlines:
1) Keep old newlines, and only wrap lines that are longer than the limit.
You can subclass TextWrapper as follows:
class DocumentWrapper(textwrap.TextWrapper):
def wrap(self, text):
split_text = text.split('\n')
lines = [line for para in split_text for line in textwrap.TextWrapper.wrap(self, para)]
return lines
Then use it the same way as textwrap:
d = DocumentWrapper(width=90)
wrapped_str = d.fill(original_str)
Gives you:
short line,
long line xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxx
2) Remove the old newlines and wrap everything.
original_str.replace('\n', '')
wrapped_str = textwrap.fill(original_str, width=90)
Gives you
short line, long line xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
(TextWrapper doesn't do either of these - it just ignores the existing newlines, which leads to a weirdly formatted result)
I had to a similar problem formatting dynamically generated docstrings. I wanted to preserve the newlines put in place by hand and split any lines over a certain length. Reworking the answer by @far a bit, this solution worked for me. I only include it here for posterity:
import textwrap
wrapArgs = {'width': 90, 'break_long_words': True, 'replace_whitespace': False}
fold = lambda line, wrapArgs: textwrap.fill(line, **wrapArgs)
body = '\n'.join([fold(line, wrapArgs) for line in body.splitlines()])