Re-update to rcsparse r2495 to get all the goodness of the new update script.
[cvs2svn.git] / cvs2svn_lib / man_writer.py
blobca54129370e41253372a1c7073ecfde4e88e25c7
1 # (Be in -*- python -*- mode.)
3 # ====================================================================
4 # Copyright (c) 2009 CollabNet. All rights reserved.
6 # This software is licensed as described in the file COPYING, which
7 # you should have received as part of this distribution. The terms
8 # are also available at http://subversion.tigris.org/license-1.html.
9 # If newer versions of this license are posted there, you may use a
10 # newer version instead, at your option.
12 # This software consists of voluntary contributions made by many
13 # individuals. For exact contribution history, see the revision
14 # history and logs, available at http://cvs2svn.tigris.org/.
15 # ====================================================================
17 """This module contains the ManWriter class for outputting manpages."""
20 import optparse
21 import re
24 whitespace_re = re.compile(r'\s+')
26 def wrap(s, width=70):
27 # Convert all whitespace substrings to single spaces:
28 s = whitespace_re.sub(' ', s)
29 s = s.strip()
30 retval = []
31 while s:
32 if len(s) <= width:
33 retval.append(s)
34 break
35 i = s.rfind(' ', 0, width + 1)
36 if i == -1:
37 # There were no spaces within the first width+1 characters; break
38 # at the next space after width:
39 i = s.find(' ', width + 1)
40 if i == -1:
41 # There were no spaces in s at all.
42 retval.append(s)
43 break
45 retval.append(s[:i].rstrip())
46 s = s[i+1:].lstrip()
48 for (i,line) in enumerate(retval):
49 if line.startswith('\'') or line.startswith('.'):
50 # These are roff control characters and have to be escaped:
51 retval[i] = '\\' + line
53 return '\n'.join(retval)
56 class ManOption(optparse.Option):
57 """An optparse.Option that holds an explicit string for the man page."""
59 def __init__(self, *args, **kw):
60 self.man_help = kw.pop('man_help')
61 optparse.Option.__init__(self, *args, **kw)
64 class ManWriter(object):
65 def __init__(
66 self,
67 parser,
68 section=None, date=None, source=None, manual=None,
69 short_desc=None, synopsis=None, long_desc=None,
70 files=None, authors=None, see_also=None,
72 self.parser = parser
73 self.section = section
74 self.date = date
75 self.source = source
76 self.manual = manual
77 self.short_desc = short_desc
78 self.synopsis = synopsis
79 self.long_desc = long_desc
80 self.files = files
81 self.authors = authors
82 self.see_also = see_also
84 def write_title(self, f):
85 f.write('.\\" Process this file with\n')
86 f.write(
87 '.\\" groff -man -Tascii %s.%s\n' % (
88 self.parser.get_prog_name(),
89 self.section,
92 f.write(
93 '.TH %s "%s" "%s" "%s" "%s"\n' % (
94 self.parser.get_prog_name().upper(),
95 self.section,
96 self.date.strftime('%b %d, %Y'),
97 self.source,
98 self.manual,
102 def write_name(self, f):
103 f.write('.SH "NAME"\n')
104 f.write(
105 '%s \- %s\n' % (
106 self.parser.get_prog_name(),
107 self.short_desc,
111 def write_synopsis(self, f):
112 f.write('.SH "SYNOPSIS"\n')
113 f.write(self.synopsis)
115 def write_description(self, f):
116 f.write('.SH "DESCRIPTION"\n')
117 f.write(self.long_desc)
119 def _get_option_strings(self, option):
120 """Return a list of option strings formatted with their metavariables.
122 This method is very similar to
123 optparse.HelpFormatter.format_option_strings().
127 if option.takes_value():
128 metavar = (option.metavar or option.dest).lower()
129 short_opts = [
130 '\\fB%s\\fR \\fI%s\\fR' % (opt, metavar)
131 for opt in option._short_opts
133 long_opts = [
134 '\\fB%s\\fR=\\fI%s\\fR' % (opt, metavar)
135 for opt in option._long_opts
137 else:
138 short_opts = [
139 '\\fB%s\\fR' % (opt,)
140 for opt in option._short_opts
142 long_opts = [
143 '\\fB%s\\fR' % (opt,)
144 for opt in option._long_opts
147 return short_opts + long_opts
149 def _write_option(self, f, option):
150 man_help = getattr(option, 'man_help', option.help)
152 if man_help is not optparse.SUPPRESS_HELP:
153 man_help = wrap(man_help)
154 f.write('.IP "%s"\n' % (', '.join(self._get_option_strings(option)),))
155 f.write('%s\n' % (man_help,))
157 def _write_container_help(self, f, container):
158 for option in container.option_list:
159 if option.help is not optparse.SUPPRESS_HELP:
160 self._write_option(f, option)
162 def write_options(self, f):
163 f.write('.SH "OPTIONS"\n')
164 if self.parser.option_list:
165 (self._write_container_help(f, self.parser))
166 for group in self.parser.option_groups:
167 f.write('.SH "%s"\n' % (group.title.upper(),))
168 if group.description:
169 f.write(self.format_description(group.description) + '\n')
170 self._write_container_help(f, group)
172 def write_files(self, f):
173 f.write('.SH "FILES"\n')
174 f.write(self.files)
176 def write_authors(self, f):
177 f.write('.SH "AUTHORS"\n')
178 f.write("Main authors are:\n")
179 for author in self.authors:
180 f.write(".br\n")
181 f.write(author + "\n")
182 f.write(".PP\n")
183 f.write(
184 "Manpage was written for the Debian GNU/Linux system by\n"
185 "Laszlo 'GCS' Boszormenyi <gcs@lsc.hu> (but may be used by others).\n")
187 def write_see_also(self, f):
188 f.write('.SH "SEE ALSO"\n')
189 f.write(', '.join([
190 '%s(%s)' % (name, section,)
191 for (name, section,) in self.see_also
192 ]) + '\n')
194 def write_manpage(self, f):
195 self.write_title(f)
196 self.write_name(f)
197 self.write_synopsis(f)
198 self.write_description(f)
199 self.write_options(f)
200 self.write_files(f)
201 self.write_authors(f)
202 self.write_see_also(f)