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
45
if hasattr(os, "unsetenv"):
48
import bzrlib, bzrlib.help
50
#>>> 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
58
def man_escape(string):
57
"""Escapes strings for man page compatibility"""
58
59
result = string.replace("\\","\\\\")
59
60
result = result.replace("`","\\`")
60
61
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)
68
def parse_line(self, line):
72
class CommandListParser(Parser):
74
"""Parser for output of "bzr help commands".
76
The parsed content can then be used to
77
- write a "COMMAND OVERVIEW" section into a man page
78
- provide a list of all commands
81
def __init__(self,params):
83
self.command_usage = []
84
self.all_commands = []
85
self.usage_exp = re.compile("([a-z0-9-]+).*")
86
self.descr_exp = re.compile(" ([A-Z].*)\s*")
92
def parse_line(self, line):
93
m = self.usage_exp.match(line)
97
self.command_usage.append((self.command,self.usage,self.descr))
98
self.all_commands.append(self.command)
100
self.command = m.groups()[0]
102
raise Error, "matching usage line in state %d" % state
105
m = self.descr_exp.match(line)
108
self.descr = m.groups()[0]
110
raise Error, "matching descr line in state %d" % state
113
raise Error, "Cannot parse this line"
118
self.command_usage.append((self.command,self.usage,self.descr))
119
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"
121
raise Error, "ending parse in state %d" % state
123
def write_to_manpage(self, outfile):
124
bzrcmd = self.params["bzrcmd"]
125
outfile.write('.SH "COMMAND OVERVIEW"\n')
126
for (command,usage,descr) in self.command_usage:
127
outfile.write('.TP\n.B "%s %s"\n%s\n\n' % (bzrcmd, usage, descr))
132
def __init__(self, parser):
135
def write(self, data):
138
for line in data.split('\n'):
139
self.parser.parse_line(line)
142
def write_command_details(params, command, usage, descr, outfile):
143
x = ('.SS "%s %s"\n.B "%s"\n.PP\n.B "Usage:"\n%s %s\n\n' %
149
outfile.write(man_escape(x))
129
152
man_preamble = """\
130
Man page for %(bzrcmd)s (bazaar-ng)
153
.\\\" Man page for %(bzrcmd)s (bazaar-ng)
132
155
.\\\" Large parts of this file are autogenerated from the output of
133
156
.\\\" \"%(bzrcmd)s help commands\"
170
196
is to look for external command.
173
E-Mail address of the user. Overrides default user config.
200
E-Mail address of the user. Overrides
201
.I "~/.bzr.conf/email" and
204
.I "John Doe <john@example.com>"
176
E-Mail address of the user. Overriddes default user config.
208
E-Mail address of the user. Overridden by the content of the file
209
.I "~/.bzr.conf/email"
210
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>
216
Directory where all the user\'s settings are stored.
218
.I "~/.bzr.conf/email"
219
Stores name and email address of the user. Overrides content of
221
environment variable. Example content:
222
.I "John Doe <john@example.com>"
188
.UR http://www.bazaar-vcs.org/
189
.BR http://www.bazaar-vcs.org/
225
.UR http://www.bazaar-ng.org/
226
.BR http://www.bazaar-ng.org/,
227
.UR http://www.bazaar-ng.org/doc/
228
.BR http://www.bazaar-ng.org/doc/
236
"datestamp": time.strftime("%Y-%m-%d",tt),
237
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S +0000",tt),
238
"version": bzrlib.__version__,
241
clp = CommandListParser(params)
242
bzrlib.help.help("commands", outfile=HelpReader(clp))
246
if len(sys.argv) == 2:
247
filename = sys.argv[1]
251
outfile = open(filename,"w")
253
outfile.write(man_preamble % params)
254
outfile.write(man_escape(man_head % params))
255
clp.write_to_manpage(outfile)
258
# This doesn't do more than the summary so far.
259
#outfile.write('.SH "DETAILED COMMAND DESCRIPTION"\n')
260
#for (command,usage,descr) in clp.command_usage:
261
# write_command_details(params, command, usage, descr, outfile = outfile)
263
outfile.write(man_escape(man_foot % params))
266
if __name__ == '__main__':