Package epydoc :: Package docwriter :: Module plaintext |
[hide private]
[frames] | no frames]

# Source Code for Module epydoc.docwriter.plaintext

      1  # epydoc -- Plaintext output generation
      2  #
      3  # Copyright (C) 2005 Edward Loper
      4  # Author: Edward Loper <edloper@loper.org>
      5  # URL: <http://epydoc.sf.net>
      6  #
      7  # $Id: plaintext.py 1473 2007-02-13 19:46:05Z edloper $
      8
      9  """
     10  Plaintext output generation.
     11  """
     12  __docformat__ = 'epytext en'
     13
     14  from epydoc.apidoc import *
     15  import re
     16
     17 -class PlaintextWriter:
     18 -    def write(self, api_doc, **options):
     19          result = []
     20          out = result.append
     21
     22          self._cols = options.get('cols', 75)
     23
     24          try:
     25              if isinstance(api_doc, ModuleDoc):
     26                  self.write_module(out, api_doc)
     27              elif isinstance(api_doc, ClassDoc):
     28                  self.write_class(out, api_doc)
     29              elif isinstance(api_doc, RoutineDoc):
     30                  self.write_function(out, api_doc)
     31              else:
     32                  assert 0, ('%s not handled yet' % api_doc.__class__)
     33          except Exception, e:
     34              print '\n\n'
     35              print ''.join(result)
     36              raise
     37
     38          return ''.join(result)
     39
     40 -    def write_module(self, out, mod_doc):
     41          #for n,v in mod_doc.variables.items():
     42          #    print n, `v.value`, `v.value.value`
     43
     44          # The cannonical name of the module.
     45          out(self.section('Module Name'))
     46          out('    %s\n\n' % mod_doc.canonical_name)
     47
     48          # The module's description.
     49          if mod_doc.descr not in (None, '', UNKNOWN):
     50              out(self.section('Description'))
     51              out(mod_doc.descr.to_plaintext(None, indent=4))
     52
     53          #out('metadata: %s\n\n' % mod_doc.metadata) # [xx] testing
     54
     55          self.write_list(out, 'Classes', mod_doc, value_type='class')
     56          self.write_list(out, 'Functions', mod_doc, value_type='function')
     57          self.write_list(out, 'Variables', mod_doc, value_type='other')
     58          # hmm.. do this as just a flat list??
     59          #self.write_list(out, 'Imports', mod_doc, imported=True, verbose=False)
     60
     61 -    def baselist(self, class_doc):
     62          if class_doc.bases is UNKNOWN:
     63              return '(unknown bases)'
     64          if len(class_doc.bases) == 0: return ''
     65          s = '('
     66          class_parent = class_doc.canonical_name.container()
     67          for i, base in enumerate(class_doc.bases):
     68              if base.canonical_name is None:
     69                  if base.parse_repr is not UNKNOWN:
     70                      s += base.parse_repr
     71                  else:
     72                      s += '??'
     73              elif base.canonical_name.container() == class_parent:
     74                  s += str(base.canonical_name[-1])
     75              else:
     76                  s += str(base.canonical_name)
     77              if i < len(class_doc.bases)-1: out(', ')
     78          return s+')'
     79
     80 -    def write_class(self, out, class_doc, name=None, prefix='', verbose=True):
     81          baselist = self.baselist(class_doc)
     82
     83          # If we're at the top level, then list the cannonical name of
     84          # the class; otherwise, our parent will have already printed
     85          # the name of the variable containing the class.
     86          if prefix == '':
     87              out(self.section('Class Name'))
     88              out('    %s%s\n\n' % (class_doc.canonical_name, baselist))
     89          else:
     90              out(prefix + 'class %s' % self.bold(str(name)) + baselist+'\n')
     91
     92          if not verbose: return
     93
     94          # Indent the body
     95          if prefix != '':
     96              prefix += ' |  '
     97
     98          # The class's description.
     99          if class_doc.descr not in (None, '', UNKNOWN):
    100              if prefix == '':
    101                  out(self.section('Description', prefix))
    102                  out(self._descr(class_doc.descr, '    '))
    103              else:
    104                  out(self._descr(class_doc.descr, prefix))
    105
    106          # List of nested classes in this class.
    107          self.write_list(out, 'Methods', class_doc,
    108                          value_type='instancemethod', prefix=prefix,
    109                          noindent=len(prefix)>4)
    110          self.write_list(out, 'Class Methods', class_doc,
    111                          value_type='classmethod', prefix=prefix)
    112          self.write_list(out, 'Static Methods', class_doc,
    113                          value_type='staticmethod', prefix=prefix)
    114          self.write_list(out, 'Nested Classes', class_doc,
    115                          value_type='class', prefix=prefix)
    116          self.write_list(out, 'Instance Variables', class_doc,
    117                          value_type='instancevariable', prefix=prefix)
    118          self.write_list(out, 'Class Variables', class_doc,
    119                          value_type='classvariable', prefix=prefix)
    120
    121          self.write_list(out, 'Inherited Methods', class_doc,
    122                          value_type='method', prefix=prefix,
    123                          inherited=True, verbose=False)
    124          self.write_list(out, 'Inherited Instance Variables', class_doc,
    125                          value_type='instancevariable', prefix=prefix,
    126                          inherited=True, verbose=False)
    127          self.write_list(out, 'Inherited Class Variables', class_doc,
    128                          value_type='classvariable', prefix=prefix,
    129                          inherited=True, verbose=False)
    130          self.write_list(out, 'Inherited Nested Classes', class_doc,
    131                          value_type='class', prefix=prefix,
    132                          inherited=True, verbose=False)
    133
    134 -    def write_variable(self, out, var_doc, name=None, prefix='', verbose=True):
    135          if name is None: name = var_doc.name
    136          out(prefix+self.bold(str(name)))
    137          if (var_doc.value not in (UNKNOWN, None) and
    138              var_doc.is_alias is True and
    139              var_doc.value.canonical_name not in (None, UNKNOWN)):
    140              out(' = %s' % var_doc.value.canonical_name)
    141          elif var_doc.value not in (UNKNOWN, None):
    142              val_repr = var_doc.value.summary_pyval_repr(
    143                  max_len=self._cols-len(name)-len(prefix)-3)
    144              out(' = %s' % val_repr.to_plaintext(None))
    145          out('\n')
    146          if not verbose: return
    147          prefix += '    ' # indent the body.
    148          if var_doc.descr not in (None, '', UNKNOWN):
    149              out(self._descr(var_doc.descr, prefix))
    150
    151 -    def write_property(self, out, prop_doc, name=None, prefix='',
    152                         verbose=True):
    153          if name is None: name = prop_doc.canonical_name
    154          out(prefix+self.bold(str(name)))
    155          if not verbose: return
    156          prefix += '    ' # indent the body.
    157
    158          if prop_doc.descr not in (None, '', UNKNOWN):
    159              out(self._descr(prop_doc.descr, prefix))
    160
    161
    162 -    def write_function(self, out, func_doc, name=None, prefix='',
    163                         verbose=True):
    164          if name is None: name = func_doc.canonical_name
    165          self.write_signature(out, func_doc, name, prefix)
    166          if not verbose: return
    167
    168          prefix += '    ' # indent the body.
    169
    170          if func_doc.descr not in (None, '', UNKNOWN):
    171              out(self._descr(func_doc.descr, prefix))
    172
    173          if func_doc.return_descr not in (None, '', UNKNOWN):
    174              out(self.section('Returns:', prefix))
    175              out(self._descr(func_doc.return_descr, prefix+'    '))
    176
    177          if func_doc.return_type not in (None, '', UNKNOWN):
    178              out(self.section('Return Type:', prefix))
    179              out(self._descr(func_doc.return_type, prefix+'    '))
    180
    181 -    def write_signature(self, out, func_doc, name, prefix):
    182          args = [self.fmt_arg(argname, default) for (argname, default)
    183                  in zip(func_doc.posargs, func_doc.posarg_defaults)]
    184          if func_doc.vararg: args.append('*'+func_doc.vararg)
    185          if func_doc.kwarg: args.append('**'+func_doc.kwarg)
    186
    187          out(prefix+self.bold(str(name))+'(')
    188          x = left = len(prefix) + len(name) + 1
    189          for i, arg in enumerate(args):
    190              if x > left and x+len(arg) > 75:
    191                  out('\n'+prefix + ' '*len(name) + ' ')
    192                  x = left
    193              out(arg)
    194              x += len(arg)
    195              if i < len(args)-1:
    196                  out(', ')
    197                  x += 2
    198          out(')\n')
    199
    200      # [xx] tuple args!
    201 -    def fmt_arg(self, name, default):
    202          if default is None:
    203              return '%s' % name
    204          else:
    205              default_repr = default.summary_pyval_repr()
    206              return '%s=%s' % (name, default_repr.to_plaintext(None))
    207
    208 -    def write_list(self, out, heading, doc, value_type=None, imported=False,
    209                     inherited=False, prefix='', noindent=False,
    210                     verbose=True):
    211          # Get a list of the VarDocs we should describe.
    212          if isinstance(doc, ClassDoc):
    213              var_docs = doc.select_variables(value_type=value_type,
    214                                              imported=imported,
    215                                              inherited=inherited)
    216          else:
    217              var_docs = doc.select_variables(value_type=value_type,
    218                                              imported=imported)
    219          if not var_docs: return
    220
    221          out(prefix+'\n')
    222          if not noindent:
    223              out(self.section(heading, prefix))
    224              prefix += '    '
    225
    226          for i, var_doc in enumerate(var_docs):
    227              val_doc, name = var_doc.value, var_doc.name
    228
    229              if verbose:
    230                  out(prefix+'\n')
    231
    232              # hmm:
    233              if not verbose:
    234                  if isinstance(doc, ClassDoc):
    235                      name = var_doc.canonical_name
    236                  elif val_doc not in (None, UNKNOWN):
    237                      name = val_doc.canonical_name
    238
    239              if isinstance(val_doc, RoutineDoc):
    240                  self.write_function(out, val_doc, name, prefix, verbose)
    241              elif isinstance(val_doc, PropertyDoc):
    242                  self.write_property(out, val_doc, name, prefix, verbose)
    243              elif isinstance(val_doc, ClassDoc):
    244                  self.write_class(out, val_doc, name, prefix, verbose)
    245              else:
    246                  self.write_variable(out, var_doc, name, prefix, verbose)
    247
    248 -    def _descr(self, descr, prefix):
    249          s = descr.to_plaintext(None, indent=len(prefix)).rstrip()
    250          s = '\n'.join([(prefix+l[len(prefix):]) for l in s.split('\n')])
    251          return s+'\n'#+prefix+'\n'
    252
    253
    254  #    def drawline(self, s, x):
    255  #        s = re.sub(r'(?m)^(.{%s}) ' % x, r'\1|', s)
    256  #        return re.sub(r'(?m)^( {,%s})$(?=\n)' % x, x*' '+'|', s)
    257
    258
    259      #////////////////////////////////////////////////////////////
    260      # Helpers
    261      #////////////////////////////////////////////////////////////
    262
    263 -    def bold(self, text):
    264          """Write a string in bold by overstriking."""
    265          return ''.join([ch+'\b'+ch for ch in text])
    266
    267 -    def title(self, text, indent):
    268          return ' '*indent + self.bold(text.capitalize()) + '\n\n'
    269
    270 -    def section(self, text, indent=''):
    271          if indent == '':
    272              return indent + self.bold(text.upper()) + '\n'
    273          else:
    274              return indent + self.bold(text.capitalize()) + '\n'
    275