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