14
17
# along with this program; if not, write to the Free Software
15
18
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
"""man.py - create man page from built-in bzr help and static text
20
* use usage information instead of simple "bzr foo" in COMMAND OVERVIEW
20
#<<< code taken from bzr (C) Canonical
25
version_info = sys.version_info
26
except AttributeError:
27
version_info = 1, 5 # 1.5 or older
30
REINVOKE = "__BZR_REINVOKE"
33
if version_info < NEED_VERS:
34
if not os.environ.has_key(REINVOKE):
35
# mutating os.environ doesn't work in old Pythons
36
os.putenv(REINVOKE, "1")
37
for python in 'python2.4', 'python2.3':
39
os.execvp(python, [python] + sys.argv)
42
print >>sys.stderr, "bzr-man.py: error: cannot find a suitable python interpreter"
43
print >>sys.stderr, " (need %d.%d or later)" % NEED_VERS
47
import bzrlib, bzrlib.help
49
#>>> code taken from bzr (C) Canonical
31
import bzrlib.commands
34
def get_filename(options):
35
"""Provides name of manpage"""
36
return "%s.1" % (options.bzr_name)
39
def infogen(options, outfile):
40
"""Assembles a man page"""
44
{ "bzrcmd": options.bzr_name,
45
"datestamp": time.strftime("%Y-%m-%d",tt),
46
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S +0000",tt),
47
"version": bzrlib.__version__,
49
outfile.write(man_preamble % params)
50
outfile.write(man_escape(man_head % params))
51
outfile.write(man_escape(getcommand_list(params)))
52
outfile.write(man_escape(getcommand_help(params)))
53
outfile.write(man_escape(man_foot % params))
56
57
def man_escape(string):
57
"""Escapes strings for man page compatibility"""
58
58
result = string.replace("\\","\\\\")
59
59
result = result.replace("`","\\`")
60
60
result = result.replace("'","\\'")
65
def command_name_list():
66
"""Builds a list of command names from bzrlib"""
67
command_names = bzrlib.commands.builtin_command_names()
72
def getcommand_list (params):
73
"""Builds summary help for command names in manpage format"""
74
bzrcmd = params["bzrcmd"]
75
output = '.SH "COMMAND OVERVIEW"\n'
76
for cmd_name in command_name_list():
77
cmd_object = bzrlib.commands.get_cmd_object(cmd_name)
80
cmd_help = cmd_object.help()
82
firstline = cmd_help.split('\n', 1)[0]
83
usage = bzrlib.help.command_usage(cmd_object)
84
tmp = '.TP\n.B "%s"\n%s\n' % (usage, firstline)
67
def parse_line(self, line):
71
class CommandListParser(Parser):
73
"""Parser for output of "bzr help commands".
75
The parsed content can then be used to
76
- write a "COMMAND OVERVIEW" section into a man page
77
- provide a list of all commands
80
def __init__(self,params):
82
self.command_usage = []
83
self.all_commands = []
84
self.usage_exp = re.compile("([a-z0-9-]+).*")
85
self.descr_exp = re.compile(" ([A-Z].*)\s*")
91
def parse_line(self, line):
92
m = self.usage_exp.match(line)
96
self.command_usage.append((self.command,self.usage,self.descr))
97
self.all_commands.append(self.command)
99
self.command = m.groups()[0]
101
raise Error, "matching usage line in state %d" % state
104
m = self.descr_exp.match(line)
107
self.descr = m.groups()[0]
109
raise Error, "matching descr line in state %d" % state
112
raise Error, "Cannot parse this line"
117
self.command_usage.append((self.command,self.usage,self.descr))
118
self.all_commands.append(self.command)
87
raise RuntimeError, "Command '%s' has no help text" % (cmd_name)
91
def getcommand_help(params):
92
"""Shows individual options for a bzr command"""
93
output='.SH "COMMAND REFERENCE"\n'
94
for cmd_name in command_name_list():
95
cmd_object = bzrlib.commands.get_cmd_object(cmd_name)
98
output = output + format_command(params, cmd_object)
102
def format_command (params, cmd):
103
"""Provides long help for each public command"""
104
subsection_header = '.SS "%s"\n' % (bzrlib.help.command_usage(cmd))
105
doc = "%s\n" % (cmd.__doc__)
106
docsplit = cmd.__doc__.split('\n')
107
doc = '\n'.join([docsplit[0]] + [line[4:] for line in docsplit[1:]])
109
options = cmd.options()
111
option_str = "\nOptions:\n"
112
for option_name, option in sorted(options.items()):
113
l = ' --' + option_name
114
if option.type is not None:
115
l += ' ' + option.argname.upper()
116
short_name = option.short_name()
118
assert len(short_name) == 1
119
l += ', -' + short_name
120
l += (30 - len(l)) * ' ' + option.help
121
# TODO: Split help over multiple lines with
122
# correct indenting and wrapping.
123
wrapped = textwrap.fill(l, initial_indent='',
124
subsequent_indent=30*' ')
125
option_str = option_str + wrapped + '\n'
126
return subsection_header + option_str + "\n" + doc + "\n"
120
raise Error, "ending parse in state %d" % state
122
def write_to_manpage(self, outfile):
123
bzrcmd = self.params["bzrcmd"]
124
outfile.write('.SH "COMMAND OVERVIEW"\n')
125
for (command,usage,descr) in self.command_usage:
126
outfile.write('.TP\n.B "%s %s"\n%s\n\n' % (bzrcmd, usage, descr))
131
def __init__(self, parser):
134
def write(self, data):
137
for line in data.split('\n'):
138
self.parser.parse_line(line)
141
def write_command_details(params, command, usage, descr, outfile):
142
x = ('.SS "%s %s"\n.B "%s"\n.PP\n.B "Usage:"\n%s %s\n\n' %
148
outfile.write(man_escape(x))
129
151
man_preamble = """\
130
Man page for %(bzrcmd)s (bazaar-ng)
152
.\\\" Man page for %(bzrcmd)s (bazaar-ng)
132
154
.\\\" Large parts of this file are autogenerated from the output of
133
155
.\\\" \"%(bzrcmd)s help commands\"
170
195
is to look for external command.
173
E-Mail address of the user. Overrides default user config.
199
E-Mail address of the user. Overrides
200
.I "~/.bzr.conf/email" and
203
.I "John Doe <john@example.com>"
176
E-Mail address of the user. Overriddes default user config.
207
E-Mail address of the user. Overridden by the content of the file
208
.I "~/.bzr.conf/email"
209
and of the environment variable
179
.I "~/.bazaar/bazaar.conf/"
180
Contains the default user config. Only one section, [DEFAULT] is allowed. A
181
typical default config file may be similiar to:
186
.B email=John Doe <jdoe@isp.com>
215
Directory where all the user\'s settings are stored.
217
.I "~/.bzr.conf/email"
218
Stores name and email address of the user. Overrides content of
220
environment variable. Example content:
221
.I "John Doe <john@example.com>"
188
.UR http://www.bazaar-vcs.org/
189
.BR http://www.bazaar-vcs.org/
224
.UR http://www.bazaar-ng.org/
225
.BR http://www.bazaar-ng.org/,
226
.UR http://www.bazaar-ng.org/doc/
227
.BR http://www.bazaar-ng.org/doc/
235
"datestamp": time.strftime("%Y-%m-%d",tt),
236
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S +0000",tt),
237
"version": bzrlib.__version__,
240
clp = CommandListParser(params)
241
bzrlib.help.help("commands", outfile=HelpReader(clp))
245
if len(sys.argv) == 2:
246
filename = sys.argv[1]
250
outfile = open(filename,"w")
252
outfile.write(man_preamble % params)
253
outfile.write(man_escape(man_head % params))
254
clp.write_to_manpage(outfile)
257
# This doesn't do more than the summary so far.
258
#outfile.write('.SH "DETAILED COMMAND DESCRIPTION"\n')
259
#for (command,usage,descr) in clp.command_usage:
260
# write_command_details(params, command, usage, descr, outfile = outfile)
262
outfile.write(man_escape(man_foot % params))
265
if __name__ == '__main__':