[Python-Dev] Where to put wrap_text()?

Greg Ward gward@python.net
Sat, 1 Jun 2002 09:42:36 -0400


Hidden away in distutils.fancy_getopt is an exceedingly handy function
called wrap_text().  It does just what you might expect from the name:

def wrap_text (text, width):
    """wrap_text(text : string, width : int) -> [string]

    Split 'text' into multiple lines of no more than 'width' characters
    each, and return the list of strings that results.
    """

Surprise surprise, Optik uses this.  I've never been terribly happy
about importing it from distutils.fancy_getopt, and putting Optik into
the standard library as OptionParser is a great opportunity for putting
wrap_text somewhere more sensible.

I happen to think that wrap_text() is useful for more than just
auto-formatting --help messages, so hiding it away in OptionParser.py
doesn't seem right.  Also, Perl has a Text::Wrap module that's been part
of the standard library for not-quite-forever -- so shouln't Python have
one too?

Proposal: a new standard library module, wrap_text, which combines the
best of distutils.fancy_getopt.wrap_text() and Text::Wrap.  Right now,
I'm thinking of an interface something like this:

  wrap(text : string, width : int) -> [string]

    Split 'text' into multiple lines of no more than 'width' characters
    each, and return the list of strings that results.  Tabs in 'text'
    are expanded with string.expandtabs(), and all other whitespace
    characters (including newline) are converted to space.

[This is identical to distutils.fancy_getopt.wrap_text(), but the
docstring is more complete.]

  wrap_nomunge(text : string, width : int) -> [string]

    Same as wrap(), without munging whitespace.

[Not sure if this is really useful to expose publicly.  Opinions?]

  fill(text : string,
       width : int,
       initial_tab : string = "",
       subsequent_tab : string = "")
  -> string

    Reformat the paragraph in 'text' to fit in lines of no more than
    'width' columns.  The first line is prefixed with 'initial_tab',
    and subsequent lines are prefixed with 'subsequent_tab'; the
    lengths of the tab strings are accounted for when wrapping lines
    to fit in 'width' columns.

[This is just a glorified "\n".join(wrap(...)); the idea to add initial_tab
and subsequent_tab was stolen from Perl's Text::Wrap.]

I'll go whip up some code and submit a patch to SF.  If people like it,
I'll even write some tests and documentation too.

        Greg
-- 
Greg Ward - Unix nerd                                   gward@python.net
http://starship.python.net/~gward/
Support bacteria -- it's the only culture some people have!