summaryrefslogtreecommitdiff
path: root/build_manpage.py
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--build_manpage.py131
1 files changed, 131 insertions, 0 deletions
diff --git a/build_manpage.py b/build_manpage.py
new file mode 100644
index 0000000..8bdbf2f
--- /dev/null
+++ b/build_manpage.py
@@ -0,0 +1,131 @@
+# -*- coding: utf-8 -*-
+
+#
+# This file is copied from http://andialbrecht.wordpress.com/2009/03/17/creating-a-man-page-with-distutils-and-optparse/
+#
+
+"""build_manpage command -- Generate man page from setup()"""
+
+import datetime
+from distutils.command.build import build
+from distutils.core import Command
+from distutils.errors import DistutilsOptionError
+import optparse
+
+class build_manpage(Command):
+
+ description = 'Generate man page from setup().'
+
+ user_options = [
+ ('output=', 'O', 'output file'),
+ ('parser=', None, 'module path to optparser (e.g. mymod:func)'),
+ ]
+
+ def initialize_options(self):
+ self.output = None
+ self.parser = None
+
+ def finalize_options(self):
+ if self.output is None:
+ raise DistutilsOptionError('\'output\' option is required')
+ if self.parser is None:
+ raise DistutilsOptionError('\'parser\' option is required')
+ mod_name, func_name = self.parser.split(':')
+ fromlist = mod_name.split('.')
+ try:
+ mod = __import__(mod_name, fromlist=fromlist)
+ self._parser = getattr(mod, func_name)()
+ except ImportError, err:
+ raise
+ self._parser.formatter = ManPageFormatter()
+ self._parser.formatter.set_parser(self._parser)
+ self.announce('Writing man page %s' % self.output)
+ self._today = datetime.date.today()
+
+ def _markup(self, txt):
+ return txt.replace('-', '\\-')
+
+ def _write_header(self):
+ appname = self.distribution.get_name()
+ ret = []
+ ret.append('.TH %s 1 %s\n' % (self._markup(appname),
+ self._today.strftime('%Y\\-%m\\-%d')))
+ description = self.distribution.get_description()
+ if description:
+ name = self._markup('%s - %s' % (self._markup(appname),
+ description.splitlines()[0]))
+ else:
+ name = self._markup(appname)
+ ret.append('.SH NAME\n%s\n' % name)
+ synopsis = self._parser.get_usage()
+ if synopsis:
+ synopsis = synopsis.replace('%s ' % appname, '')
+ ret.append('.SH SYNOPSIS\n.B %s\n%s\n' % (self._markup(appname),
+ synopsis))
+ long_desc = self.distribution.get_long_description()
+ if long_desc:
+ ret.append('.SH DESCRIPTION\n%s\n' % self._markup(long_desc))
+ return ''.join(ret)
+
+ def _write_options(self):
+ ret = ['.SH OPTIONS\n']
+ ret.append(self._parser.format_option_help())
+ return ''.join(ret)
+
+ def _write_footer(self):
+ ret = []
+ appname = self.distribution.get_name()
+ author = '%s <%s>' % (self.distribution.get_author(),
+ self.distribution.get_author_email())
+ ret.append(('.SH AUTHORS\n.B %s\nwas written by %s.\n'
+ % (self._markup(appname), self._markup(author))))
+ homepage = self.distribution.get_url()
+ ret.append(('.SH DISTRIBUTION\nThe latest version of %s may '
+ 'be downloaded from\n'
+ '.UR %s\n.UE\n'
+ % (self._markup(appname), self._markup(homepage),)))
+ return ''.join(ret)
+
+ def run(self):
+ manpage = []
+ manpage.append(self._write_header())
+ manpage.append(self._write_options())
+ manpage.append(self._write_footer())
+ stream = open(self.output, 'w')
+ stream.write(''.join(manpage))
+ stream.close()
+
+
+class ManPageFormatter(optparse.HelpFormatter):
+
+ def __init__(self,
+ indent_increment=2,
+ max_help_position=24,
+ width=None,
+ short_first=1):
+ optparse.HelpFormatter.__init__(self, indent_increment,
+ max_help_position, width, short_first)
+
+ def _markup(self, txt):
+ return txt.replace('-', '\\-')
+
+ def format_usage(self, usage):
+ return self._markup(usage)
+
+ def format_heading(self, heading):
+ if self.level == 0:
+ return ''
+ return '.TP\n%s\n' % self._markup(heading.upper())
+
+ def format_option(self, option):
+ result = []
+ opts = self.option_strings[option]
+ result.append('.TP\n.B %s\n' % self._markup(opts))
+ if option.help:
+ help_text = '%s\n' % self._markup(self.expand_default(option))
+ result.append(help_text)
+ return ''.join(result)
+
+
+build.sub_commands.append(('build_manpage', None))
+