Source code for mmf.utils.text
"""
Provides a subclass of textwrap.TextWrapper that allows for multiple
paragraphs. Based on http://code.activestate.com/recipes/358228/
"""
import textwrap
import sys, re
[docs]def trim(docstring):
"""Docstring trimmer from PEP0257
>>> trim('')
''
"""
if not docstring:
return ''
# Convert tabs to spaces (following the normal Python rules)
# and split into a list of lines:
lines = docstring.expandtabs().splitlines()
# Determine minimum indentation (first line doesn't count):
indent = sys.maxint
for line in lines[1:]:
stripped = line.lstrip()
if stripped:
indent = min(indent, len(line) - len(stripped))
# Remove indentation (first line is special):
trimmed = [lines[0].strip()]
if indent < sys.maxint:
for line in lines[1:]:
trimmed.append(line[indent:].rstrip())
# Strip off trailing and leading blank lines:
while trimmed and not trimmed[-1]:
trimmed.pop()
while trimmed and not trimmed[0]:
trimmed.pop(0)
# Return a single string:
return '\n'.join(trimmed)
[docs]class DocWrapper(textwrap.TextWrapper):
"""Wrap text in a document, processing each paragraph
individually.
>>> DocWrapper(initial_indent=' ').fill("Hi")
' Hi'
>>> a = '''This is an example of how to use a
... long multiline string to document a
... parameter. This paragraph will be
... wrapped, but special formatting should
... be preserved if it is indented:
... 1) A series of points
... 2) Here is a longer point
...
... You can use paragraphs too! They will
... also be wrapped for you.'''
>>> print DocWrapper(width=66).fill(a)
This is an example of how to use a long multiline string to
document a parameter. This paragraph will be wrapped, but special
formatting should be preserved if it is indented:
1) A series of points
2) Here is a longer point
<BLANKLINE>
You can use paragraphs too! They will also be wrapped for you.
>>> b = ('''This is an example of a docstring which has some
... formatting:
... 1) Here is an indented point w/o wrapping.
... 2) Another indented point. This one is a''' +
... ''' very long line. This should *not* be wrapped.
... ''')
>>> print DocWrapper(width=66).fill(b) # doctest: +ELLIPSIS
This is an example of a docstring which has some formatting:
1) Here is an indented point w/o wrapping.
2) Another indented point. This one is a very long line.\
This should *not* be wrapped.
"""
[docs] def wrap(self, text):
"""Override textwrap.TextWrapper to process 'text' properly when
multiple paragraphs present"""
text = trim(text)
paragraphs = []
paragraph = []
for line in text.split("\n"):
if "" == line or line.startswith(" "):
# Paragraph done
if paragraph:
paragraphs.append("\n".join(paragraph))
paragraph = []
# Add line, but Don't wrap.
paragraphs.append(line)
else:
paragraph.append(line)
if paragraph:
paragraphs.append("\n".join(paragraph))
paragraph = []
#para_edge = re.compile(r"(\n\s*\n)", re.MULTILINE)
#paragraphs = para_edge.split(text)
wrapped_lines = []
for para in paragraphs:
if para == '' or para.isspace():
if not self.replace_whitespace:
# Do not take the leading and trailing newlines since
# joining the list with newlines (as self.fill will do)
# will put them back in.
if self.expand_tabs: # pragma: nocover
para = para.expandtabs()
wrapped_lines.append(para[1:-1])
else:
# self.fill will end up putting in the needed newline to
# space out the paragraphs
wrapped_lines.append('')
elif para.startswith(' '):
# Don't wrap preformatted lines
wrapped_lines.append(self.subsequent_indent + para)
else:
wrapped_lines.extend(textwrap.TextWrapper.wrap(self, para))
return wrapped_lines