Re: Optparse and help formatting?
- From: Tim Chase <python.list@xxxxxxxxxxxxxxxxx>
- Date: Sun, 30 Sep 2007 07:37:10 -0500
I've been learning the ropes of the optparse module and have been
having some trouble getting the help to format the way I want.
A quick perusal of the 'optparse.py' code shows me this:
========
[...]
class OptionParser([...]):
def __init__([...],
formatter=None,
[...]):
[...]
if formatter is None:
formatter = IndentedHelpFormatter()
[...]
========
So, the OptionParser init method accepts the help formatter as the
'formatter' argument, defaulting to a new instance of
IndentedHelpFormatter.
Presumably, it's a matter of subclassing 'optparse.HelpFormatter' and
overriding the behaviour you want to change, then passing an instance
of your new class as the 'formatter' argument to the 'OptionParser()'
invocation.
Ben, thanks for pointing me in the right direction. Digging in
this code, it looks like textwrap.[fill|wrap] method calls were
what was eating my NL and munging my tabs.
While not a terribly elegant solution, as there's no easy way to
intercept the two bits I want without copying and pasting a large
bit of the format_description and format_option methods just to
change the behavior of one call to textwrap.*, I did manage to
get it working as desired.
In the event that anybody else needs the solution I hacked
together, I've pasted it below which, as Ben suggests, can be
used with
parser = OptionParser(...
formatter=IndentedHelpFormatterWithNL()
)
Hope this helps somebody else too.
-tim
class IndentedHelpFormatterWithNL(IndentedHelpFormatter):
def format_description(self, description):
if not description: return ""
desc_width = self.width - self.current_indent
indent = " "*self.current_indent
# the above is still the same
bits = description.split('\n')
formatted_bits = [
textwrap.fill(bit,
desc_width,
initial_indent=indent,
subsequent_indent=indent)
for bit in bits]
result = "\n".join(formatted_bits) + "\n"
return result
def format_option(self, option):
# The help for each option consists of two parts:
# * the opt strings and metavars
# eg. ("-x", or "-fFILENAME, --file=FILENAME")
# * the user-supplied help string
# eg. ("turn on expert mode", "read data from FILENAME")
#
# If possible, we write both of these on the same line:
# -x turn on expert mode
#
# But if the opt string list is too long, we put the help
# string on a second line, indented to the same column it would
# start in if it fit on the first line.
# -fFILENAME, --file=FILENAME
# read data from FILENAME
result = []
opts = self.option_strings[option]
opt_width = self.help_position - self.current_indent - 2
if len(opts) > opt_width:
opts = "%*s%s\n" % (self.current_indent, "", opts)
indent_first = self.help_position
else: # start help on same line as opts
opts = "%*s%-*s " % (self.current_indent, "", opt_width, opts)
indent_first = 0
result.append(opts)
if option.help:
help_text = self.expand_default(option)
# Everything is the same up through here
help_lines = []
for para in help_text.split("\n"):
help_lines.extend(textwrap.wrap(para, self.help_width))
# Everything is the same after here
result.append("%*s%s\n" % (
indent_first, "", help_lines[0]))
result.extend(["%*s%s\n" % (self.help_position, "", line)
for line in help_lines[1:]])
elif opts[-1] != "\n":
result.append("\n")
return "".join(result)
.
- Follow-Ups:
- Re: Optparse and help formatting?
- From: Steven D'Aprano
- Re: Optparse and help formatting?
- References:
- Optparse and help formatting?
- From: Tim Chase
- Re: Optparse and help formatting?
- From: Ben Finney
- Optparse and help formatting?
- Prev by Date: Re: which language allows you to change an argument's value?
- Next by Date: Re: Optparse and help formatting?
- Previous by thread: Re: Optparse and help formatting?
- Next by thread: Re: Optparse and help formatting?
- Index(es):
Relevant Pages
|