1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9  """ 
 10  Plaintext output generation. 
 11  """ 
 12  __docformat__ = 'epytext en' 
 13   
 14  from epydoc.apidoc import * 
 15  import re 
 16   
 18 -    def write(self, api_doc): 
  19          result = [] 
 20          out = result.append 
 21   
 22          try: 
 23              if isinstance(api_doc, ModuleDoc): 
 24                  self.write_module(out, api_doc) 
 25              elif isinstance(api_doc, ClassDoc): 
 26                  self.write_class(out, api_doc) 
 27              elif isinstance(api_doc, RoutineDoc): 
 28                  self.write_function(out, api_doc) 
 29              else: 
 30                  assert 0, ('%s not handled yet' % api_doc.__class__) 
 31          except Exception, e: 
 32              print '\n\n' 
 33              print ''.join(result) 
 34              raise 
 35   
 36          return ''.join(result) 
  37   
 38 -    def write_module(self, out, mod_doc): 
  39           
 40           
 41           
 42           
 43          out(self.section('Module Name')) 
 44          out('    %s\n\n' % mod_doc.canonical_name) 
 45   
 46           
 47          if mod_doc.descr not in (None, '', UNKNOWN): 
 48              out(self.section('Description')) 
 49              out(mod_doc.descr.to_plaintext(None, indent=4)) 
 50   
 51           
 52   
 53          self.write_list(out, 'Classes', mod_doc, value_type='class') 
 54          self.write_list(out, 'Functions', mod_doc, value_type='function') 
 55          self.write_list(out, 'Variables', mod_doc, value_type='other') 
  56           
 57           
 58   
 59 -    def baselist(self, class_doc): 
  60          if class_doc.bases is UNKNOWN: 
 61              return '(unknown bases)' 
 62          if len(class_doc.bases) == 0: return '' 
 63          s = '(' 
 64          class_parent = class_doc.canonical_name.container() 
 65          for i, base in enumerate(class_doc.bases): 
 66              if base.canonical_name.container() == class_parent: 
 67                  s += str(base.canonical_name[-1]) 
 68              else: 
 69                  s += str(base.canonical_name) 
 70              if i < len(class_doc.bases)-1: out(', ') 
 71          return s+')' 
  72   
 73 -    def write_class(self, out, class_doc, name=None, prefix='', verbose=True): 
  74          baselist = self.baselist(class_doc) 
 75           
 76           
 77           
 78           
 79          if prefix == '': 
 80              out(self.section('Class Name')) 
 81              out('    %s%s\n\n' % (class_doc.canonical_name, baselist)) 
 82          else: 
 83              out(prefix + 'class %s' % self.bold(str(name)) + baselist+'\n') 
 84   
 85          if not verbose: return 
 86   
 87           
 88          if prefix != '': 
 89              prefix += ' |  ' 
 90   
 91           
 92          if class_doc.descr not in (None, '', UNKNOWN): 
 93              if prefix == '': 
 94                  out(self.section('Description', prefix)) 
 95                  out(self._descr(class_doc.descr, '    ')) 
 96              else: 
 97                  out(self._descr(class_doc.descr, prefix)) 
 98   
 99           
100          self.write_list(out, 'Methods', class_doc, 
101                          value_type='instancemethod', prefix=prefix, 
102                          noindent=len(prefix)>4) 
103          self.write_list(out, 'Class Methods', class_doc, 
104                          value_type='classmethod', prefix=prefix) 
105          self.write_list(out, 'Static Methods', class_doc, 
106                          value_type='staticmethod', prefix=prefix) 
107          self.write_list(out, 'Nested Classes', class_doc, 
108                          value_type='class', prefix=prefix) 
109          self.write_list(out, 'Instance Variables', class_doc, 
110                          value_type='instancevariable', prefix=prefix) 
111          self.write_list(out, 'Class Variables', class_doc, 
112                          value_type='classvariable', prefix=prefix) 
113           
114          self.write_list(out, 'Inherited Methods', class_doc, 
115                          value_type='method', prefix=prefix, 
116                          inherited=True, verbose=False) 
117          self.write_list(out, 'Inherited Instance Variables', class_doc, 
118                          value_type='instancevariable', prefix=prefix, 
119                          inherited=True, verbose=False) 
120          self.write_list(out, 'Inherited Class Variables', class_doc, 
121                          value_type='classvariable', prefix=prefix, 
122                          inherited=True, verbose=False) 
123          self.write_list(out, 'Inherited Nested Classes', class_doc, 
124                          value_type='class', prefix=prefix, 
125                          inherited=True, verbose=False) 
 126                           
127 -    def write_variable(self, out, var_doc, name=None, prefix='', verbose=True): 
 128          if name is None: name = var_doc.name 
129          out(prefix+self.bold(str(name))) 
130          if (var_doc.value not in (UNKNOWN, None) and 
131              var_doc.is_alias is True and 
132              var_doc.value.canonical_name not in (None, UNKNOWN)): 
133              out(' = %s' % var_doc.value.canonical_name) 
134          elif var_doc.value not in (UNKNOWN, None): 
135              pyval_repr = var_doc.value.pyval_repr() 
136              if pyval_repr is not UNKNOWN: 
137                  val_repr = pyval_repr.expandtabs() 
138              else: 
139                  var_repr = var_doc.value.parse_repr 
140              if var_repr is not UNKNOWN: 
141                  if len(val_repr)+len(name) > 75: 
142                      val_repr = '%s...' % val_repr[:75-len(name)-3] 
143                  if '\n' in val_repr: val_repr = '%s...' % (val_repr.split()[0]) 
144                  out(' = %s' % val_repr) 
145          out('\n') 
146          if not verbose: return 
147          prefix += '    '  
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 += '    '  
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 += '    '  
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       
201 -    def fmt_arg(self, name, default): 
 202          if default is None: 
203              return '%s' % name 
204          elif default.parse_repr is not UNKNOWN: 
205              return '%s=%s' % (name, default.parse_repr) 
206          else: 
207              pyval_repr = default.pyval_repr() 
208              if pyval_repr is not UNKNOWN: 
209                  return '%s=%s' % (name, pyval_repr) 
210              else: 
211                  return '%s=??' % name 
 212   
213 -    def write_list(self, out, heading, doc, value_type=None, imported=False, 
214                     inherited=False, prefix='', noindent=False, 
215                     verbose=True): 
 216           
217          if isinstance(doc, ClassDoc): 
218              var_docs = doc.select_variables(value_type=value_type, 
219                                              imported=imported, 
220                                              inherited=inherited) 
221          else: 
222              var_docs = doc.select_variables(value_type=value_type, 
223                                              imported=imported) 
224          if not var_docs: return 
225   
226          out(prefix+'\n') 
227          if not noindent: 
228              out(self.section(heading, prefix)) 
229              prefix += '    ' 
230   
231          for i, var_doc in enumerate(var_docs): 
232              val_doc, name = var_doc.value, var_doc.name 
233   
234              if verbose: 
235                  out(prefix+'\n') 
236   
237               
238              if not verbose: 
239                  if isinstance(doc, ClassDoc): 
240                      name = var_doc.canonical_name 
241                  elif val_doc not in (None, UNKNOWN): 
242                      name = val_doc.canonical_name 
243                       
244              if isinstance(val_doc, RoutineDoc): 
245                  self.write_function(out, val_doc, name, prefix, verbose) 
246              elif isinstance(val_doc, PropertyDoc): 
247                  self.write_property(out, val_doc, name, prefix, verbose) 
248              elif isinstance(val_doc, ClassDoc): 
249                  self.write_class(out, val_doc, name, prefix, verbose) 
250              else: 
251                  self.write_variable(out, var_doc, name, prefix, verbose) 
 252   
253 -    def _descr(self, descr, prefix): 
 254          s = descr.to_plaintext(None, indent=len(prefix)).rstrip() 
255          s = '\n'.join([(prefix+l[len(prefix):]) for l in s.split('\n')]) 
256          return s+'\n' 
 257                                  
258   
259   
260   
261   
262   
263           
264       
265       
266       
267       
268 -    def bold(self, text): 
 269          """Write a string in bold by overstriking.""" 
270          return ''.join([ch+'\b'+ch for ch in text]) 
271   
272 -    def title(self, text, indent): 
 273          return ' '*indent + self.bold(text.capitalize()) + '\n\n' 
 274   
275 -    def section(self, text, indent=''): 
 276          if indent == '': 
277              return indent + self.bold(text.upper()) + '\n' 
278          else: 
279              return indent + self.bold(text.capitalize()) + '\n' 
  280