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 from epydoc.util import TerminalController
16 import re
17
19 - def __init__(self, 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
47 out(self.section('Module Name'))
48 out(' %s\n\n' % mod_doc.canonical_name)
49
50
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
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
61
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
86
87
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
96
97 if not verbose: return
98
99
100 if prefix != '':
101 prefix += ' | '
102
103
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
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 += ' '
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 += ' '
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 += ' '
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
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
206 if x > left and x+arglen > 75:
207 out('\n'+prefix + ' '*len(name) + ' ')
208 x = left
209
210
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
217 x += arglen
218
219
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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254 - def write_list(self, out, heading, doc, value_type=None, imported=False,
255 inherited=False, prefix='', noindent=False,
256 verbose=True):
257
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
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'
301
302
303
304
305
306
307
308
309
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
329
330
331 - def color(self, text, style):
332 colors = self.STYLE.get(style, '').split()
333 text = '%s' % text
334
335 if 'bold' in colors and not self.term.BOLD:
336 text = ''.join([ch+'\b'+ch for ch in text])
337
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
345 h1 = 'bold',
346 h2 = 'bold',
347
348 class_name = 'bold cyan',
349
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