فهرست منبع

Add script to build man page from argparse

oz123 10 سال پیش
والد
کامیت
6ee7e6580f
3فایلهای تغییر یافته به همراه149 افزوده شده و 3 حذف شده
  1. 145 0
      build_manpage.py
  2. 1 1
      pwman/__init__.py
  3. 3 2
      setup.py

+ 145 - 0
build_manpage.py

@@ -0,0 +1,145 @@
+# -*- coding: utf-8 -*-
+
+"""build_manpage command -- Generate man page from setup()"""
+
+"""python setup.py build_manpage --output=bla.txt
+   --parser=scripts.pwman3:parser_optios
+"""
+
+import datetime
+from distutils.command.build import build
+from distutils.core import Command
+from distutils.errors import DistutilsOptionError
+import optparse
+import argparse
+
+class build_manpage(Command):
+    """-O bla.1 --parser pwman:parser_options"""
+    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)
+
+        if isinstance(self._parser, argparse.ArgumentParser):
+            self._parser.prog = 'pwman3'
+            synopsis = self._parser.format_usage().split(':',1)[1]
+        else:
+            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 ManPageArgFormatter(argparse.HelpFormatter):
+    pass
+
+class ManPageFormatter(optparse.HelpFormatter):
+
+    def __init__(self,
+                 indent_increment=2,
+                 max_help_position=24,
+                 width=None,
+                 short_first=1):
+
+        # should be replace with super ?
+        optparse.HelpFormatter.__init__(self, indent_increment,
+                                        max_help_position, width, short_first)
+
+        # argparse.HelpFormatter(indent_increment, max_help_position, width,)
+        # no such option in argparse?                         short_first=1)
+
+    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))
+

+ 1 - 1
pwman/__init__.py

@@ -26,7 +26,7 @@ import sys
 import re
 import data.factory
 
-appname = "Pwman3"
+appname = "pwman3"
 try:
     version = pkg_resources.get_distribution('pwman3').version
 except pkg_resources.DistributionNotFound:  # pragma: no cover

+ 3 - 2
setup.py

@@ -9,7 +9,7 @@ import sys
 from setuptools.command.install import install
 import os
 from subprocess import Popen,  PIPE
-
+from build_manpage import build_manpage
 
 def describe():
     des = Popen('git describe', shell=True, stdout=PIPE)
@@ -74,6 +74,7 @@ setup(name=pwman.appname,
       ],
       test_suite='pwman.tests.suite',
       cmdclass={
-                'install_pycrypto': PyCryptoInstallCommand},
+                'install_pycrypto': PyCryptoInstallCommand,
+                'build_manpage': build_manpage},
 
       )