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 1701 2008-01-31 06:49:44Z edloper $ 
  8   
  9  """ 
 10  Plaintext output generation. 
 11  """ 
 12  __docformat__ = 'epytext en' 
 13   
 14  from epydoc.apidoc import * 
 15  from epydoc.util import TerminalController 
 16  import re 
 17   
18 -class PlaintextWriter:
19 - def __init__(self, term):
20 self.term = term
21
22 - def write(self, api_doc, **options):
23 result = [] 24 out = result.append 25 26 self._show_private = options.get('show_private', True) 27 self._cols = options.get('cols', 75) 28 29 try: 30 if isinstance(api_doc, ModuleDoc): 31 self.write_module(out, api_doc) 32 elif isinstance(api_doc, ClassDoc): 33 self.write_class(out, api_doc) 34 elif isinstance(api_doc, RoutineDoc): 35 self.write_function(out, api_doc) 36 else: 37 assert 0, ('%s not handled yet' % api_doc.__class__) 38 except Exception, e: 39 print '\n\n' 40 print ''.join(result) 41 raise 42 43 return ''.join(result)
44
45 - def write_module(self, out, mod_doc):
46 # The cannonical name of the module. 47 out(self.section('Module Name')) 48 out(' %s\n\n' % mod_doc.canonical_name) 49 50 # The module's description. 51 if mod_doc.descr not in (None, '', UNKNOWN): 52 out(self.section('Description')) 53 out(mod_doc.descr.to_plaintext(None, indent=4)) 54 55 #out('metadata: %s\n\n' % mod_doc.metadata) # [xx] testing 56 57 self.write_list(out, 'Classes', mod_doc, value_type='class') 58 self.write_list(out, 'Functions', mod_doc, value_type='function') 59 self.write_list(out, 'Variables', mod_doc, value_type='other')
60 # hmm.. do this as just a flat list?? 61 #self.write_list(out, 'Imports', mod_doc, imported=True, verbose=False) 62
63 - def baselist(self, class_doc):
64 if class_doc.bases is UNKNOWN: 65 return '(unknown bases)' 66 if len(class_doc.bases) == 0: return '' 67 s = '(' 68 class_parent = class_doc.canonical_name.container() 69 for i, base in enumerate(class_doc.bases): 70 if base.canonical_name is None: 71 if base.parse_repr is not UNKNOWN: 72 s += base.parse_repr 73 else: 74 s += '??' 75 elif base.canonical_name.container() == class_parent: 76 s += str(base.canonical_name[-1]) 77 else: 78 s += str(base.canonical_name) 79 if i < len(class_doc.bases)-1: out(', ') 80 return s+')'
81
82 - def write_class(self, out, class_doc, name=None, prefix='', verbose=True):
83 baselist = self.baselist(class_doc) 84 85 # If we're at the top level, then list the cannonical name of 86 # the class; otherwise, our parent will have already printed 87 # the name of the variable containing the class. 88 if prefix == '': 89 out(self.section('Class Name')) 90 out(' %s%s\n\n' % ( 91 self.color(class_doc.canonical_name, 'class_name'), baselist)) 92 else: 93 out(prefix + self.color('class %s' % name, 'class_name') 94 + baselist + '\n') 95 #out(prefix + 'class %s' % self.bold(str(name)) + baselist+'\n') 96 97 if not verbose: return 98 99 # Indent the body 100 if prefix != '': 101 prefix += ' | ' 102 103 # The class's description. 104 if class_doc.descr not in (None, '', UNKNOWN): 105 if prefix == '': 106 out(self.section('Description', prefix)) 107 out(self._descr(class_doc.descr, ' ')) 108 else: 109 out(self._descr(class_doc.descr, prefix)) 110 111 # List of nested classes in this class. 112 self.write_list(out, 'Methods', class_doc, 113 value_type='instancemethod', prefix=prefix, 114 noindent=len(prefix)>4) 115 self.write_list(out, 'Class Methods', class_doc, 116 value_type='classmethod', prefix=prefix) 117 self.write_list(out, 'Static Methods', class_doc, 118 value_type='staticmethod', prefix=prefix) 119 self.write_list(out, 'Nested Classes', class_doc, 120 value_type='class', prefix=prefix) 121 self.write_list(out, 'Instance Variables', class_doc, 122 value_type='instancevariable', prefix=prefix) 123 self.write_list(out, 'Class Variables', class_doc, 124 value_type='classvariable', prefix=prefix) 125 126 self.write_list(out, 'Inherited Methods', class_doc, 127 value_type='method', prefix=prefix, 128 inherited=True, verbose=False) 129 self.write_list(out, 'Inherited Instance Variables', class_doc, 130 value_type='instancevariable', prefix=prefix, 131 inherited=True, verbose=False) 132 self.write_list(out, 'Inherited Class Variables', class_doc, 133 value_type='classvariable', prefix=prefix, 134 inherited=True, verbose=False) 135 self.write_list(out, 'Inherited Nested Classes', class_doc, 136 value_type='class', prefix=prefix, 137 inherited=True, verbose=False)
138
139 - def write_variable(self, out, var_doc, name=None, prefix='', verbose=True):
140 if name is None: name = var_doc.name 141 out(prefix+self.bold(str(name))) 142 if (var_doc.value not in (UNKNOWN, None) and 143 var_doc.is_alias is True and 144 var_doc.value.canonical_name not in (None, UNKNOWN)): 145 out(' = %s' % var_doc.value.canonical_name) 146 elif var_doc.value not in (UNKNOWN, None): 147 val_repr = var_doc.value.summary_pyval_repr( 148 max_len=self._cols-len(name)-len(prefix)-3) 149 out(' = %s' % val_repr.to_plaintext(None)) 150 out('\n') 151 if not verbose: return 152 prefix += ' ' # indent the body. 153 if var_doc.descr not in (None, '', UNKNOWN): 154 out(self._descr(var_doc.descr, prefix))
155
156 - def write_property(self, out, prop_doc, name=None, prefix='', 157 verbose=True):
158 if name is None: name = prop_doc.canonical_name 159 out(prefix+self.bold(str(name))) 160 if not verbose: return 161 prefix += ' ' # indent the body. 162 163 if prop_doc.descr not in (None, '', UNKNOWN): 164 out(self._descr(prop_doc.descr, prefix))
165 166
167 - def write_function(self, out, func_doc, name=None, prefix='', 168 verbose=True):
169 if name is None: name = func_doc.canonical_name 170 self.write_signature(out, func_doc, name, prefix, verbose) 171 if not verbose: return 172 173 prefix += ' ' # indent the body. 174 175 if func_doc.descr not in (None, '', UNKNOWN): 176 out(self._descr(func_doc.descr, prefix)) 177 178 if func_doc.return_descr not in (None, '', UNKNOWN): 179 out(self.section('Returns:', prefix)) 180 out(self._descr(func_doc.return_descr, prefix+' ')) 181 182 if func_doc.return_type not in (None, '', UNKNOWN): 183 out(self.section('Return Type:', prefix)) 184 out(self._descr(func_doc.return_type, prefix+' '))
185
186 - def write_signature(self, out, func_doc, name, prefix, verbose):
187 args = zip(func_doc.posargs, func_doc.posarg_defaults) 188 if func_doc.vararg: args.append( ('*'+func_doc.vararg, None) ) 189 if func_doc.kwarg: args.append( ('**'+func_doc.kwarg, None) ) 190 191 if verbose: style='sig_' 192 else: style='inhsig_' 193 194 out(prefix) 195 out(self.color(name, style+'name')) 196 out(self.color('(', style+'punct')) 197 x = left = len(prefix) + len(name) + 1 198 for i, (argname, default) in enumerate(args): 199 # Figure out how big this argument is. 200 arglen = len(argname) 201 if default is not None: 202 default_repr = default.summary_pyval_repr().to_plaintext(None) 203 arglen += 1+len(default_repr) 204 205 # Wrap to the next line, if necessary. 206 if x > left and x+arglen > 75: 207 out('\n'+prefix + ' '*len(name) + ' ') 208 x = left 209 210 # Display the argument. 211 out(self.color(argname, style+'arg')) 212 if default: 213 out(self.color('=', style+'punct')) 214 out(self.color(default_repr, style+'default')) 215 216 # Update our position 217 x += arglen 218 219 # Display a comma, unless this is the last arg 220 if i < len(args)-1: 221 out(self.color(', ', style+'punct')) 222 x += 2 223 224 out(self.color(')', style+'punct') + '\n') 225 return
226 227 228 229 230 # out(prefix + self.color(name, 'sig_name') + 231 # self.color('(', 'sig_punct')) 232 # x = left = len(prefix) + len(name) + 1 233 # for i, arg in enumerate(args): 234 # if x > left and x+len(arg) > 75: 235 # out('\n'+prefix + ' '*len(name) + ' ') 236 # x = left 237 # out(arg) 238 # x += len(arg) 239 # if i < len(args)-1: 240 # out(self.color(', ', 'sig_punct')) 241 # x += 2 242 # out(self.color(')', 'sig_punct') + '\n') 243 244 # # [xx] tuple args! 245 # def fmt_arg(self, name, default): 246 # if default is None: 247 # return self.color(name, 'sig_arg') 248 # else: 249 # default_repr = default.summary_pyval_repr().to_plaintext(None) 250 # return (self.color(name, 'sig_arg') + 251 # self.color('=', 'sig_punct') + 252 # self.color(default_repr, 'sig_default')) 253
254 - def write_list(self, out, heading, doc, value_type=None, imported=False, 255 inherited=False, prefix='', noindent=False, 256 verbose=True):
257 # Get a list of the VarDocs we should describe. 258 if isinstance(doc, ClassDoc): 259 var_docs = doc.select_variables(value_type=value_type, 260 imported=imported, 261 inherited=inherited) 262 else: 263 var_docs = doc.select_variables(value_type=value_type, 264 imported=imported) 265 if not var_docs: return 266 267 out(prefix+'\n') 268 if not noindent: 269 out(self.section(heading, prefix)) 270 prefix += ' ' 271 272 for i, var_doc in enumerate(var_docs): 273 val_doc, name = var_doc.value, var_doc.name 274 275 if not var_doc.is_public and not self._show_private: 276 continue 277 278 if verbose: 279 out(prefix+'\n') 280 281 # hmm: 282 if not verbose: 283 if isinstance(doc, ClassDoc): 284 name = var_doc.canonical_name 285 elif val_doc not in (None, UNKNOWN): 286 name = val_doc.canonical_name 287 288 if isinstance(val_doc, RoutineDoc): 289 self.write_function(out, val_doc, name, prefix, verbose) 290 elif isinstance(val_doc, PropertyDoc): 291 self.write_property(out, val_doc, name, prefix, verbose) 292 elif isinstance(val_doc, ClassDoc): 293 self.write_class(out, val_doc, name, prefix, verbose) 294 else: 295 self.write_variable(out, var_doc, name, prefix, verbose)
296
297 - def _descr(self, descr, prefix):
298 s = descr.to_plaintext(None, indent=len(prefix)).rstrip() 299 s = '\n'.join([(prefix+l[len(prefix):]) for l in s.split('\n')]) 300 return s+'\n'#+prefix+'\n'
301 302 303 # def drawline(self, s, x): 304 # s = re.sub(r'(?m)^(.{%s}) ' % x, r'\1|', s) 305 # return re.sub(r'(?m)^( {,%s})$(?=\n)' % x, x*' '+'|', s) 306 307 308 #//////////////////////////////////////////////////////////// 309 # Helpers 310 #//////////////////////////////////////////////////////////// 311
312 - def bold(self, text):
313 """Write a string in bold by overstriking.""" 314 return ''.join([ch+'\b'+ch for ch in text])
315
316 - def title(self, text, indent):
317 return ' '*indent + self.bold(text.capitalize()) + '\n\n'
318
319 - def section(self, text, indent=''):
320 if indent == '': 321 text = text.upper() 322 return indent + self.color(text, 'h1') + '\n' 323 else: 324 text = text.capitalize() 325 return indent + self.color(text, 'h2') + '\n'
326 327 #//////////////////////////////////////////////////////////// 328 # Terminal Control 329 #//////////////////////////////////////////////////////////// 330
331 - def color(self, text, style):
332 colors = self.STYLE.get(style, '').split() 333 text = '%s' % text 334 # Use poor-man's bold if necessary: 335 if 'bold' in colors and not self.term.BOLD: 336 text = ''.join([ch+'\b'+ch for ch in text]) 337 # Use color if we have it: 338 s = '' 339 for color in colors: 340 s += getattr(self.term, color.upper()) 341 return '%s%s%s' % (s, text, self.term.NORMAL)
342 343 STYLE = dict( 344 # Section headings 345 h1 = 'bold', 346 h2 = 'bold', 347 # Class names 348 class_name = 'bold cyan', 349 # Function Signatures 350 sig_name = 'green', 351 sig_punct = '', 352 sig_arg = 'cyan', 353 sig_default='yellow', 354 inhsig_name = 'green', 355 inhsig_punct = '', 356 inhsig_arg = 'cyan', 357 inhsig_default='yellow', 358 )
359