DocumentationTools/ModuleDocumentor.py

changeset 945
8cd4d08fa9f6
parent 791
9ec2ac20e54e
child 1227
c5db073a124f
equal deleted inserted replaced
944:1b59c4ba121e 945:8cd4d08fa9f6
19 19
20 from Utilities import html_uencode 20 from Utilities import html_uencode
21 from Utilities.ModuleParser import RB_SOURCE 21 from Utilities.ModuleParser import RB_SOURCE
22 22
23 _signal = re.compile(r""" 23 _signal = re.compile(r"""
24 ^@signal [ \t]+ 24 ^@signal [ \t]+
25 (?P<SignalName1> 25 (?P<SignalName1>
26 [a-zA-Z_] \w* [ \t]* \( [^)]* \) 26 [a-zA-Z_] \w* [ \t]* \( [^)]* \)
27 ) 27 )
28 [ \t]* (?P<SignalDescription1> .*) 28 [ \t]* (?P<SignalDescription1> .*)
29 | 29 |
30 ^@signal [ \t]+ 30 ^@signal [ \t]+
31 (?P<SignalName2> 31 (?P<SignalName2>
32 [a-zA-Z_] \w* 32 [a-zA-Z_] \w*
33 ) 33 )
34 [ \t]+ (?P<SignalDescription2> .*) 34 [ \t]+ (?P<SignalDescription2> .*)
35 """, re.VERBOSE | re.DOTALL | re.MULTILINE).search 35 """, re.VERBOSE | re.DOTALL | re.MULTILINE).search
36 36
37 _event = re.compile(r""" 37 _event = re.compile(r"""
38 ^@event [ \t]+ 38 ^@event [ \t]+
39 (?P<EventName1> 39 (?P<EventName1>
40 [a-zA-Z_] \w* [ \t]* \( [^)]* \) 40 [a-zA-Z_] \w* [ \t]* \( [^)]* \)
41 ) 41 )
42 [ \t]* (?P<EventDescription1> .*) 42 [ \t]* (?P<EventDescription1> .*)
43 | 43 |
44 ^@event [ \t]+ 44 ^@event [ \t]+
45 (?P<EventName2> 45 (?P<EventName2>
46 [a-zA-Z_] \w* 46 [a-zA-Z_] \w*
47 ) 47 )
48 [ \t]+ (?P<EventDescription2> .*) 48 [ \t]+ (?P<EventDescription2> .*)
49 """, re.VERBOSE | re.DOTALL | re.MULTILINE).search 49 """, re.VERBOSE | re.DOTALL | re.MULTILINE).search
50 50
51
51 class TagError(Exception): 52 class TagError(Exception):
52 """ 53 """
53 Exception class raised, if an invalid documentation tag was found. 54 Exception class raised, if an invalid documentation tag was found.
54 """ 55 """
55 56
57
56 class ModuleDocument(object): 58 class ModuleDocument(object):
57 """ 59 """
58 Class implementing the builtin documentation generator. 60 Class implementing the builtin documentation generator.
59 """ 61 """
60 def __init__(self, module, colors, stylesheet = None): 62 def __init__(self, module, colors, stylesheet=None):
61 """ 63 """
62 Constructor 64 Constructor
63 65
64 @param module the information of the parsed Python file 66 @param module the information of the parsed Python file
65 @param colors dictionary specifying the various colors for the output 67 @param colors dictionary specifying the various colors for the output
157 TemplatesListsStyle.seeListEntryTemplate.format(**colors) 159 TemplatesListsStyle.seeListEntryTemplate.format(**colors)
158 self.seeLinkTemplate = TemplatesListsStyle.seeLinkTemplate.format(**colors) 160 self.seeLinkTemplate = TemplatesListsStyle.seeLinkTemplate.format(**colors)
159 self.sinceInfoTemplate = \ 161 self.sinceInfoTemplate = \
160 TemplatesListsStyle.sinceInfoTemplate.format(**colors) 162 TemplatesListsStyle.sinceInfoTemplate.format(**colors)
161 163
162 self.keywords = [] # list of tuples containing the name (string) and 164 self.keywords = [] # list of tuples containing the name (string) and
163 # the ref (string). The ref is without the filename part. 165 # the ref (string). The ref is without the filename part.
164 self.generated = False 166 self.generated = False
165 167
166 def isEmpty(self): 168 def isEmpty(self):
167 """ 169 """
204 Public method to generate the source code documentation. 206 Public method to generate the source code documentation.
205 207
206 @return The source code documentation. (string) 208 @return The source code documentation. (string)
207 """ 209 """
208 doc = self.headerTemplate.format(**{ \ 210 doc = self.headerTemplate.format(**{ \
209 'Title' : self.module.name, 211 'Title': self.module.name,
210 'Style' : self.stylesheet}) + \ 212 'Style': self.stylesheet}) + \
211 self.__genModuleSection() + \ 213 self.__genModuleSection() + \
212 self.footerTemplate 214 self.footerTemplate
213 self.generated = True 215 self.generated = True
214 return doc 216 return doc
215 217
224 functionList = self.__genFunctionListSection() 226 functionList = self.__genFunctionListSection()
225 try: 227 try:
226 if self.module.type == RB_SOURCE: 228 if self.module.type == RB_SOURCE:
227 rbModulesList = self.__genRbModulesListSection() 229 rbModulesList = self.__genRbModulesListSection()
228 modBody = self.rbFileTemplate.format(**{ \ 230 modBody = self.rbFileTemplate.format(**{ \
229 'Module' : self.module.name, 231 'Module': self.module.name,
230 'ModuleDescription' : \ 232 'ModuleDescription': \
231 self.__formatDescription(self.module.description), 233 self.__formatDescription(self.module.description),
232 'GlobalsList' : globalsList, 234 'GlobalsList': globalsList,
233 'ClassList' : classList, 235 'ClassList': classList,
234 'RbModulesList' : rbModulesList, 236 'RbModulesList': rbModulesList,
235 'FunctionList' : functionList, 237 'FunctionList': functionList,
236 }) 238 })
237 else: 239 else:
238 modBody = self.moduleTemplate.format(**{ \ 240 modBody = self.moduleTemplate.format(**{ \
239 'Module' : self.module.name, 241 'Module': self.module.name,
240 'ModuleDescription' : \ 242 'ModuleDescription': \
241 self.__formatDescription(self.module.description), 243 self.__formatDescription(self.module.description),
242 'GlobalsList' : globalsList, 244 'GlobalsList': globalsList,
243 'ClassList' : classList, 245 'ClassList': classList,
244 'FunctionList' : functionList, 246 'FunctionList': functionList,
245 }) 247 })
246 except TagError as e: 248 except TagError as e:
247 sys.stderr.write("Error in tags of description of module {0}.\n".format( 249 sys.stderr.write("Error in tags of description of module {0}.\n".format(
248 self.module.name)) 250 self.module.name))
249 sys.stderr.write("{0}\n".format(e)) 251 sys.stderr.write("{0}\n".format(e))
256 else: 258 else:
257 rbModulesSection = "" 259 rbModulesSection = ""
258 return "{0}{1}{2}{3}".format( 260 return "{0}{1}{2}{3}".format(
259 modBody, classesSection, rbModulesSection, functionsSection) 261 modBody, classesSection, rbModulesSection, functionsSection)
260 262
261 def __genListSection(self, names, dict, kwSuffix = ""): 263 def __genListSection(self, names, dict, kwSuffix=""):
262 """ 264 """
263 Private method to generate a list section of the document. 265 Private method to generate a list section of the document.
264 266
265 @param names The names to appear in the list. (list of strings) 267 @param names The names to appear in the list. (list of strings)
266 @param dict A dictionary containing all relevant information. 268 @param dict A dictionary containing all relevant information.
268 @return The list section. (string) 270 @return The list section. (string)
269 """ 271 """
270 lst = [] 272 lst = []
271 for name in names: 273 for name in names:
272 lst.append(self.listEntryTemplate.format(**{ \ 274 lst.append(self.listEntryTemplate.format(**{ \
273 'Link' : "{0}".format(name), 275 'Link': "{0}".format(name),
274 'Name' : dict[name].name, 276 'Name': dict[name].name,
275 'Description' : self.__getShortDescription(dict[name].description), 277 'Description': self.__getShortDescription(dict[name].description),
276 'Deprecated' : self.__checkDeprecated(dict[name].description) and \ 278 'Deprecated': self.__checkDeprecated(dict[name].description) and \
277 self.listEntryDeprecatedTemplate or "", 279 self.listEntryDeprecatedTemplate or "",
278 })) 280 }))
279 if kwSuffix: 281 if kwSuffix:
280 n = "{0} ({1})".format(name, kwSuffix) 282 n = "{0} ({1})".format(name, kwSuffix)
281 else: 283 else:
282 n = "{0}".format(name) 284 n = "{0}".format(name)
283 self.keywords.append((n, "#{0}".format(name))) 285 self.keywords.append((n, "#{0}".format(name)))
284 return ''.join(lst) 286 return ''.join(lst)
285 287
286 def __genGlobalsListSection(self, class_ = None): 288 def __genGlobalsListSection(self, class_=None):
287 """ 289 """
288 Private method to generate the section listing all global attributes of 290 Private method to generate the section listing all global attributes of
289 the module. 291 the module.
290 292
291 @param class_ reference to a class object (Class) 293 @param class_ reference to a class object (Class)
294 attrNames = [] 296 attrNames = []
295 if class_ is not None: 297 if class_ is not None:
296 scope = class_ 298 scope = class_
297 else: 299 else:
298 scope = self.module 300 scope = self.module
299 attrNames = sorted([attr for attr in scope.globals.keys() 301 attrNames = sorted([attr for attr in scope.globals.keys()
300 if not scope.globals[attr].isSignal]) 302 if not scope.globals[attr].isSignal])
301 if attrNames: 303 if attrNames:
302 s = ''.join( 304 s = ''.join(
303 [self.listEntrySimpleTemplate.format(**{'Name' : name}) \ 305 [self.listEntrySimpleTemplate.format(**{'Name': name}) \
304 for name in attrNames]) 306 for name in attrNames])
305 else: 307 else:
306 s = self.listEntryNoneTemplate 308 s = self.listEntryNoneTemplate
307 return self.listTemplate.format(**{ \ 309 return self.listTemplate.format(**{ \
308 'Entries' : s, 310 'Entries': s,
309 }) 311 })
310 312
311 def __genClassListSection(self): 313 def __genClassListSection(self):
312 """ 314 """
313 Private method to generate the section listing all classes of the module. 315 Private method to generate the section listing all classes of the module.
319 self.empty = False 321 self.empty = False
320 s = self.__genListSection(names, self.module.classes) 322 s = self.__genListSection(names, self.module.classes)
321 else: 323 else:
322 s = self.listEntryNoneTemplate 324 s = self.listEntryNoneTemplate
323 return self.listTemplate.format(**{ \ 325 return self.listTemplate.format(**{ \
324 'Entries' : s, 326 'Entries': s,
325 }) 327 })
326 328
327 def __genRbModulesListSection(self): 329 def __genRbModulesListSection(self):
328 """ 330 """
329 Private method to generate the section listing all modules of the file 331 Private method to generate the section listing all modules of the file
330 (Ruby only). 332 (Ruby only).
331 333
332 @return The modules list section. (string) 334 @return The modules list section. (string)
333 """ 335 """
334 names = sorted(list(self.module.modules.keys())) 336 names = sorted(list(self.module.modules.keys()))
336 self.empty = False 338 self.empty = False
337 s = self.__genListSection(names, self.module.modules) 339 s = self.__genListSection(names, self.module.modules)
338 else: 340 else:
339 s = self.listEntryNoneTemplate 341 s = self.listEntryNoneTemplate
340 return self.listTemplate.format(**{ \ 342 return self.listTemplate.format(**{ \
341 'Entries' : s, 343 'Entries': s,
342 }) 344 })
343 345
344 def __genFunctionListSection(self): 346 def __genFunctionListSection(self):
345 """ 347 """
346 Private method to generate the section listing all functions of the module. 348 Private method to generate the section listing all functions of the module.
352 self.empty = False 354 self.empty = False
353 s = self.__genListSection(names, self.module.functions) 355 s = self.__genListSection(names, self.module.functions)
354 else: 356 else:
355 s = self.listEntryNoneTemplate 357 s = self.listEntryNoneTemplate
356 return self.listTemplate.format(**{ \ 358 return self.listTemplate.format(**{ \
357 'Entries' : s, 359 'Entries': s,
358 }) 360 })
359 361
360 def __genClassesSection(self): 362 def __genClassesSection(self):
361 """ 363 """
362 Private method to generate the document section with details about classes. 364 Private method to generate the document section with details about classes.
376 globalsList = self.__genGlobalsListSection(_class) 378 globalsList = self.__genGlobalsListSection(_class)
377 methList, methBodies = self.__genMethodSection(_class, className) 379 methList, methBodies = self.__genMethodSection(_class, className)
378 380
379 try: 381 try:
380 clsBody = self.classTemplate.format(**{ \ 382 clsBody = self.classTemplate.format(**{ \
381 'Anchor' : className, 383 'Anchor': className,
382 'Class' : _class.name, 384 'Class': _class.name,
383 'ClassSuper' : supers, 385 'ClassSuper': supers,
384 'ClassDescription' : self.__formatDescription(_class.description), 386 'ClassDescription': self.__formatDescription(_class.description),
385 'GlobalsList' : globalsList, 387 'GlobalsList': globalsList,
386 'MethodList' : methList, 388 'MethodList': methList,
387 'MethodDetails' : methBodies, 389 'MethodDetails': methBodies,
388 }) 390 })
389 except TagError as e: 391 except TagError as e:
390 sys.stderr.write("Error in tags of description of class {0}.\n".format( 392 sys.stderr.write("Error in tags of description of class {0}.\n".format(
391 className)) 393 className))
392 sys.stderr.write("{0}\n".format(e)) 394 sys.stderr.write("{0}\n".format(e))
407 @return The list section. (string) 409 @return The list section. (string)
408 """ 410 """
409 lst = [] 411 lst = []
410 try: 412 try:
411 lst.append(self.listEntryTemplate.format(**{ \ 413 lst.append(self.listEntryTemplate.format(**{ \
412 'Link' : "{0}.{1}".format(className, '__init__'), 414 'Link': "{0}.{1}".format(className, '__init__'),
413 'Name' : clsName, 415 'Name': clsName,
414 'Description' : self.__getShortDescription(dict['__init__'].description), 416 'Description': self.__getShortDescription(dict['__init__'].description),
415 'Deprecated' : self.__checkDeprecated(dict['__init__'].description) and \ 417 'Deprecated': self.__checkDeprecated(dict['__init__'].description) and \
416 self.listEntryDeprecatedTemplate or "", 418 self.listEntryDeprecatedTemplate or "",
417 })) 419 }))
418 self.keywords.append(("{0} (Constructor)".format(className), 420 self.keywords.append(("{0} (Constructor)".format(className),
419 "#{0}.{1}".format(className, '__init__'))) 421 "#{0}.{1}".format(className, '__init__')))
420 except KeyError: 422 except KeyError:
421 pass 423 pass
422 424
423 for name in names: 425 for name in names:
424 lst.append(self.listEntryTemplate.format(**{ \ 426 lst.append(self.listEntryTemplate.format(**{ \
425 'Link' : "{0}.{1}".format(className, name), 427 'Link': "{0}.{1}".format(className, name),
426 'Name' : dict[name].name, 428 'Name': dict[name].name,
427 'Description' : self.__getShortDescription(dict[name].description), 429 'Description': self.__getShortDescription(dict[name].description),
428 'Deprecated' : self.__checkDeprecated(dict[name].description) and \ 430 'Deprecated': self.__checkDeprecated(dict[name].description) and \
429 self.listEntryDeprecatedTemplate or "", 431 self.listEntryDeprecatedTemplate or "",
430 })) 432 }))
431 self.keywords.append(("{0}.{1}".format(className, name), 433 self.keywords.append(("{0}.{1}".format(className, name),
432 "#{0}.{1}".format(className, name))) 434 "#{0}.{1}".format(className, name)))
433 return ''.join(lst) 435 return ''.join(lst)
434 436
435 def __genMethodSection(self, obj, className): 437 def __genMethodSection(self, obj, className):
436 """ 438 """
445 methods = sorted(list(obj.methods.keys())) 447 methods = sorted(list(obj.methods.keys()))
446 if '__init__' in methods: 448 if '__init__' in methods:
447 methods.remove('__init__') 449 methods.remove('__init__')
448 try: 450 try:
449 methBody = self.constructorTemplate.format(**{ \ 451 methBody = self.constructorTemplate.format(**{ \
450 'Anchor' : className, 452 'Anchor': className,
451 'Class' : obj.name, 453 'Class': obj.name,
452 'Method' : '__init__', 454 'Method': '__init__',
453 'MethodDescription' : \ 455 'MethodDescription': \
454 self.__formatDescription(obj.methods['__init__'].description), 456 self.__formatDescription(obj.methods['__init__'].description),
455 'Params' : ', '.join(obj.methods['__init__'].parameters[1:]), 457 'Params': ', '.join(obj.methods['__init__'].parameters[1:]),
456 }) 458 })
457 except TagError as e: 459 except TagError as e:
458 sys.stderr.write( 460 sys.stderr.write(
459 "Error in tags of description of method {0}.{1}.\n".format( 461 "Error in tags of description of method {0}.{1}.\n".format(
460 className, '__init__')) 462 className, '__init__'))
463 methBodies.append(methBody) 465 methBodies.append(methBody)
464 466
465 for method in methods: 467 for method in methods:
466 try: 468 try:
467 methBody = self.methodTemplate.format(**{ \ 469 methBody = self.methodTemplate.format(**{ \
468 'Anchor' : className, 470 'Anchor': className,
469 'Class' : obj.name, 471 'Class': obj.name,
470 'Method' : obj.methods[method].name, 472 'Method': obj.methods[method].name,
471 'MethodDescription' : \ 473 'MethodDescription': \
472 self.__formatDescription(obj.methods[method].description), 474 self.__formatDescription(obj.methods[method].description),
473 'Params' : ', '.join(obj.methods[method].parameters[1:]), 475 'Params': ', '.join(obj.methods[method].parameters[1:]),
474 }) 476 })
475 except TagError as e: 477 except TagError as e:
476 sys.stderr.write( 478 sys.stderr.write(
477 "Error in tags of description of method {0}.{1}.\n".format( 479 "Error in tags of description of method {0}.{1}.\n".format(
478 className, method)) 480 className, method))
483 methList = self.__genMethodsListSection(methods, obj.methods, className, obj.name) 485 methList = self.__genMethodsListSection(methods, obj.methods, className, obj.name)
484 486
485 if not methList: 487 if not methList:
486 methList = self.listEntryNoneTemplate 488 methList = self.listEntryNoneTemplate
487 return self.listTemplate.format(**{ \ 489 return self.listTemplate.format(**{ \
488 'Entries' : methList, 490 'Entries': methList,
489 }), ''.join(methBodies) 491 }), ''.join(methBodies)
490 492
491 def __genRbModulesSection(self): 493 def __genRbModulesSection(self):
492 """ 494 """
493 Private method to generate the document section with details about Ruby modules. 495 Private method to generate the document section with details about Ruby modules.
503 classList, classBodies = \ 505 classList, classBodies = \
504 self.__genRbModulesClassesSection(rbModule, rbModuleName) 506 self.__genRbModulesClassesSection(rbModule, rbModuleName)
505 507
506 try: 508 try:
507 rbmBody = self.rbModuleTemplate.format(**{ \ 509 rbmBody = self.rbModuleTemplate.format(**{ \
508 'Anchor' : rbModuleName, 510 'Anchor': rbModuleName,
509 'Module' : rbModule.name, 511 'Module': rbModule.name,
510 'ModuleDescription' : self.__formatDescription(rbModule.description), 512 'ModuleDescription': self.__formatDescription(rbModule.description),
511 'GlobalsList' : globalsList, 513 'GlobalsList': globalsList,
512 'ClassesList' : classList, 514 'ClassesList': classList,
513 'ClassesDetails' : classBodies, 515 'ClassesDetails': classBodies,
514 'FunctionsList' : methList, 516 'FunctionsList': methList,
515 'FunctionsDetails' : methBodies, 517 'FunctionsDetails': methBodies,
516 }) 518 })
517 except TagError as e: 519 except TagError as e:
518 sys.stderr.write( 520 sys.stderr.write(
519 "Error in tags of description of Ruby module {0}.\n".format( 521 "Error in tags of description of Ruby module {0}.\n".format(
520 rbModuleName)) 522 rbModuleName))
545 547
546 methList, methBodies = self.__genMethodSection(_class, className) 548 methList, methBodies = self.__genMethodSection(_class, className)
547 549
548 try: 550 try:
549 clsBody = self.rbModulesClassTemplate.format(**{ \ 551 clsBody = self.rbModulesClassTemplate.format(**{ \
550 'Anchor' : className, 552 'Anchor': className,
551 'Class' : _class.name, 553 'Class': _class.name,
552 'ClassSuper' : supers, 554 'ClassSuper': supers,
553 'ClassDescription' : self.__formatDescription(_class.description), 555 'ClassDescription': self.__formatDescription(_class.description),
554 'MethodList' : methList, 556 'MethodList': methList,
555 'MethodDetails' : methBodies, 557 'MethodDetails': methBodies,
556 }) 558 })
557 except TagError as e: 559 except TagError as e:
558 sys.stderr.write("Error in tags of description of class {0}.\n".format( 560 sys.stderr.write("Error in tags of description of class {0}.\n".format(
559 className)) 561 className))
560 sys.stderr.write("{0}\n".format(e)) 562 sys.stderr.write("{0}\n".format(e))
561 clsBody = "" 563 clsBody = ""
562 564
563 classes.append(clsBody) 565 classes.append(clsBody)
564 566
565
566 classesList = \ 567 classesList = \
567 self.__genRbModulesClassesListSection(classNames, obj.classes, modName) 568 self.__genRbModulesClassesListSection(classNames, obj.classes, modName)
568 569
569 if not classesList: 570 if not classesList:
570 classesList = self.listEntryNoneTemplate 571 classesList = self.listEntryNoneTemplate
571 return self.listTemplate.format(**{ \ 572 return self.listTemplate.format(**{ \
572 'Entries' : classesList, 573 'Entries': classesList,
573 }), ''.join(classes) 574 }), ''.join(classes)
574 575
575 def __genRbModulesClassesListSection(self, names, dict, moduleName): 576 def __genRbModulesClassesListSection(self, names, dict, moduleName):
576 """ 577 """
577 Private method to generate the classes list section of a Ruby module. 578 Private method to generate the classes list section of a Ruby module.
582 @return The list section. (string) 583 @return The list section. (string)
583 """ 584 """
584 lst = [] 585 lst = []
585 for name in names: 586 for name in names:
586 lst.append(self.listEntryTemplate.format(**{ \ 587 lst.append(self.listEntryTemplate.format(**{ \
587 'Link' : "{0}.{1}".format(moduleName, name), 588 'Link': "{0}.{1}".format(moduleName, name),
588 'Name' : dict[name].name, 589 'Name': dict[name].name,
589 'Description' : self.__getShortDescription(dict[name].description), 590 'Description': self.__getShortDescription(dict[name].description),
590 'Deprecated' : self.__checkDeprecated(dict[name].description) and \ 591 'Deprecated': self.__checkDeprecated(dict[name].description) and \
591 self.listEntryDeprecatedTemplate or "", 592 self.listEntryDeprecatedTemplate or "",
592 })) 593 }))
593 self.keywords.append(("{0}.{1}".format(moduleName, name), 594 self.keywords.append(("{0}.{1}".format(moduleName, name),
594 "#{0}.{1}".format(moduleName, name))) 595 "#{0}.{1}".format(moduleName, name)))
595 return ''.join(lst) 596 return ''.join(lst)
596 597
597 def __genFunctionsSection(self): 598 def __genFunctionsSection(self):
598 """ 599 """
603 funcBodies = [] 604 funcBodies = []
604 funcNames = sorted(list(self.module.functions.keys())) 605 funcNames = sorted(list(self.module.functions.keys()))
605 for funcName in funcNames: 606 for funcName in funcNames:
606 try: 607 try:
607 funcBody = self.functionTemplate.format(**{ \ 608 funcBody = self.functionTemplate.format(**{ \
608 'Anchor' : funcName, 609 'Anchor': funcName,
609 'Function' : self.module.functions[funcName].name, 610 'Function': self.module.functions[funcName].name,
610 'FunctionDescription' : self.__formatDescription( 611 'FunctionDescription': self.__formatDescription(
611 self.module.functions[funcName].description), 612 self.module.functions[funcName].description),
612 'Params' : ', '.join(self.module.functions[funcName].parameters), 613 'Params': ', '.join(self.module.functions[funcName].parameters),
613 }) 614 })
614 except TagError as e: 615 except TagError as e:
615 sys.stderr.write("Error in tags of description of function {0}.\n".format( 616 sys.stderr.write("Error in tags of description of function {0}.\n".format(
616 funcName)) 617 funcName))
617 sys.stderr.write("{0}\n".format(e)) 618 sys.stderr.write("{0}\n".format(e))
640 descfound = 1 641 descfound = 1
641 dotpos = desc.find('.') 642 dotpos = desc.find('.')
642 if dotpos == -1: 643 if dotpos == -1:
643 sdlist.append(desc.strip()) 644 sdlist.append(desc.strip())
644 else: 645 else:
645 while dotpos+1 < len(desc) and not desc[dotpos+1].isspace(): 646 while dotpos + 1 < len(desc) and not desc[dotpos + 1].isspace():
646 # don't recognize '.' inside a number or word as stop condition 647 # don't recognize '.' inside a number or word as stop condition
647 dotpos = desc.find('.', dotpos+1) 648 dotpos = desc.find('.', dotpos + 1)
648 if dotpos == -1: 649 if dotpos == -1:
649 break 650 break
650 if dotpos == -1: 651 if dotpos == -1:
651 sdlist.append(desc.strip()) 652 sdlist.append(desc.strip())
652 else: 653 else:
653 sdlist.append(desc[:dotpos+1].strip()) 654 sdlist.append(desc[:dotpos + 1].strip())
654 break # break if a '.' is found 655 break # break if a '.' is found
655 else: 656 else:
656 if descfound: 657 if descfound:
657 break # break if an empty line is found 658 break # break if an empty line is found
658 if sdlist: 659 if sdlist:
660 else: 661 else:
661 return '' 662 return ''
662 663
663 def __checkDeprecated(self, descr): 664 def __checkDeprecated(self, descr):
664 """ 665 """
665 Private method to check, if the object to be documented contains a 666 Private method to check, if the object to be documented contains a
666 deprecated flag. 667 deprecated flag.
667 668
668 @param desc The documentation string. (string) 669 @param desc The documentation string. (string)
669 @return Flag indicating the deprecation status. (boolean) 670 @return Flag indicating the deprecation status. (boolean)
670 """ 671 """
694 linelist.append("") 695 linelist.append("")
695 else: 696 else:
696 linelist.append(html_uencode(line)) 697 linelist.append(html_uencode(line))
697 else: 698 else:
698 lst.append(self.paragraphTemplate.format(**{ \ 699 lst.append(self.paragraphTemplate.format(**{ \
699 'Lines' : '\n'.join(linelist) 700 'Lines': '\n'.join(linelist)
700 })) 701 }))
701 linelist = [] 702 linelist = []
702 if linelist: 703 if linelist:
703 lst.append(self.paragraphTemplate.format(**{ \ 704 lst.append(self.paragraphTemplate.format(**{ \
704 'Lines' : '\n'.join(linelist) 705 'Lines': '\n'.join(linelist)
705 })) 706 }))
706 return ''.join(lst) 707 return ''.join(lst)
707 708
708 def __genDescriptionListSection(self, dictionary, template): 709 def __genDescriptionListSection(self, dictionary, template):
709 """ 710 """
716 """ 717 """
717 lst = [] 718 lst = []
718 keys = sorted(list(dictionary.keys())) 719 keys = sorted(list(dictionary.keys()))
719 for key in keys: 720 for key in keys:
720 lst.append(template.format(**{ \ 721 lst.append(template.format(**{ \
721 'Name' : key, 722 'Name': key,
722 'Description' : html_uencode('\n'.join(dictionary[key])), 723 'Description': html_uencode('\n'.join(dictionary[key])),
723 })) 724 }))
724 return ''.join(lst) 725 return ''.join(lst)
725 726
726 def __genParamDescriptionListSection(self, _list, template): 727 def __genParamDescriptionListSection(self, _list, template):
727 """ 728 """
733 @return The list section. (string) 734 @return The list section. (string)
734 """ 735 """
735 lst = [] 736 lst = []
736 for name, lines in _list: 737 for name, lines in _list:
737 lst.append(template.format(**{ \ 738 lst.append(template.format(**{ \
738 'Name' : name, 739 'Name': name,
739 'Description' : html_uencode('\n'.join(lines)), 740 'Description': html_uencode('\n'.join(lines)),
740 })) 741 }))
741 return ''.join(lst) 742 return ''.join(lst)
742 743
743 def __formatCrossReferenceEntry(self, entry): 744 def __formatCrossReferenceEntry(self, entry):
744 """ 745 """
768 if anchor: 769 if anchor:
769 reference = "{0}#{1}".format(reference, anchor) 770 reference = "{0}#{1}".format(reference, anchor)
770 entry = 'href="{0}">{1}</a>'.format(reference, label) 771 entry = 'href="{0}">{1}</a>'.format(reference, label)
771 772
772 return self.seeLinkTemplate.format(**{ \ 773 return self.seeLinkTemplate.format(**{ \
773 'Link' : entry, 774 'Link': entry,
774 }) 775 })
775 776
776 def __genSeeListSection(self, _list, template): 777 def __genSeeListSection(self, _list, template):
777 """ 778 """
778 Private method to generate the "see also" list section of a description. 779 Private method to generate the "see also" list section of a description.
783 """ 784 """
784 lst = [] 785 lst = []
785 for seeEntry in _list: 786 for seeEntry in _list:
786 seeEntryString = ''.join(seeEntry) 787 seeEntryString = ''.join(seeEntry)
787 lst.append(template.format(**{ \ 788 lst.append(template.format(**{ \
788 'Link' : html_uencode(self.__formatCrossReferenceEntry(seeEntryString)), 789 'Link': html_uencode(self.__formatCrossReferenceEntry(seeEntryString)),
789 })) 790 }))
790 return '\n'.join(lst) 791 return '\n'.join(lst)
791 792
792 def __processInlineTags(self, desc): 793 def __processInlineTags(self, desc):
793 """ 794 """
885 except IndexError: 886 except IndexError:
886 exceptionDict[excName] = [] 887 exceptionDict[excName] = []
887 lastItem = exceptionDict[excName] 888 lastItem = exceptionDict[excName]
888 elif desc.startswith("@signal"): 889 elif desc.startswith("@signal"):
889 inTagSection = True 890 inTagSection = True
890 m = _signal(desc,0) 891 m = _signal(desc, 0)
891 if m is None: 892 if m is None:
892 raise TagError("Wrong format in {0} line.\n".format(parts[0])) 893 raise TagError("Wrong format in {0} line.\n".format(parts[0]))
893 signalName = 1 and m.group("SignalName1") \ 894 signalName = 1 and m.group("SignalName1") \
894 or m.group("SignalName2") 895 or m.group("SignalName2")
895 signalDesc = 1 and m.group("SignalDescription1") \ 896 signalDesc = 1 and m.group("SignalDescription1") \
898 if signalDesc is not None: 899 if signalDesc is not None:
899 signalDict[signalName].append(signalDesc) 900 signalDict[signalName].append(signalDesc)
900 lastItem = signalDict[signalName] 901 lastItem = signalDict[signalName]
901 elif desc.startswith("@event"): 902 elif desc.startswith("@event"):
902 inTagSection = True 903 inTagSection = True
903 m = _event(desc,0) 904 m = _event(desc, 0)
904 if m is None: 905 if m is None:
905 raise TagError("Wrong format in {0} line.\n".format(parts[0])) 906 raise TagError("Wrong format in {0} line.\n".format(parts[0]))
906 eventName = 1 and m.group("EventName1") \ 907 eventName = 1 and m.group("EventName1") \
907 or m.group("EventName2") 908 or m.group("EventName2")
908 eventDesc = 1 and m.group("EventDescription1") \ 909 eventDesc = 1 and m.group("EventDescription1") \
954 else: 955 else:
955 description = "" 956 description = ""
956 957
957 if paramList: 958 if paramList:
958 parameterSect = self.parametersListTemplate.format(**{ \ 959 parameterSect = self.parametersListTemplate.format(**{ \
959 'Parameters' : self.__genParamDescriptionListSection(paramList, 960 'Parameters': self.__genParamDescriptionListSection(paramList,
960 self.parametersListEntryTemplate) 961 self.parametersListEntryTemplate)
961 }) 962 })
962 else: 963 else:
963 parameterSect = "" 964 parameterSect = ""
964 965
967 else: 968 else:
968 returnSect = "" 969 returnSect = ""
969 970
970 if exceptionDict: 971 if exceptionDict:
971 exceptionSect = self.exceptionsListTemplate.format(**{ \ 972 exceptionSect = self.exceptionsListTemplate.format(**{ \
972 'Exceptions' : self.__genDescriptionListSection(exceptionDict, 973 'Exceptions': self.__genDescriptionListSection(exceptionDict,
973 self.exceptionsListEntryTemplate) 974 self.exceptionsListEntryTemplate)
974 }) 975 })
975 else: 976 else:
976 exceptionSect = "" 977 exceptionSect = ""
977 978
978 if signalDict: 979 if signalDict:
979 signalSect = self.signalsListTemplate.format(**{ \ 980 signalSect = self.signalsListTemplate.format(**{ \
980 'Signals' : self.__genDescriptionListSection(signalDict, 981 'Signals': self.__genDescriptionListSection(signalDict,
981 self.signalsListEntryTemplate) 982 self.signalsListEntryTemplate)
982 }) 983 })
983 else: 984 else:
984 signalSect = "" 985 signalSect = ""
985 986
986 if eventDict: 987 if eventDict:
987 eventSect = self.eventsListTemplate.format(**{ \ 988 eventSect = self.eventsListTemplate.format(**{ \
988 'Events' : self.__genDescriptionListSection(eventDict, 989 'Events': self.__genDescriptionListSection(eventDict,
989 self.eventsListEntryTemplate) 990 self.eventsListEntryTemplate)
990 }) 991 })
991 else: 992 else:
992 eventSect = "" 993 eventSect = ""
993 994
994 if deprecated: 995 if deprecated:
995 deprecatedSect = self.deprecatedTemplate.format(**{ \ 996 deprecatedSect = self.deprecatedTemplate.format(**{ \
996 'Lines' : html_uencode('\n'.join(deprecated)), 997 'Lines': html_uencode('\n'.join(deprecated)),
997 }) 998 })
998 else: 999 else:
999 deprecatedSect = "" 1000 deprecatedSect = ""
1000 1001
1001 if authorInfo: 1002 if authorInfo:
1002 authorInfoSect = self.authorInfoTemplate.format(**{ \ 1003 authorInfoSect = self.authorInfoTemplate.format(**{ \
1003 'Authors' : html_uencode('\n'.join(authorInfo)), 1004 'Authors': html_uencode('\n'.join(authorInfo)),
1004 }) 1005 })
1005 else: 1006 else:
1006 authorInfoSect = "" 1007 authorInfoSect = ""
1007 1008
1008 if sinceInfo: 1009 if sinceInfo:
1009 sinceInfoSect = self.sinceInfoTemplate.format(**{ \ 1010 sinceInfoSect = self.sinceInfoTemplate.format(**{ \
1010 'Info' : html_uencode(sinceInfo[0]), 1011 'Info': html_uencode(sinceInfo[0]),
1011 }) 1012 })
1012 else: 1013 else:
1013 sinceInfoSect = "" 1014 sinceInfoSect = ""
1014 1015
1015 if seeList: 1016 if seeList:
1016 seeSect = self.seeListTemplate.format(**{ \ 1017 seeSect = self.seeListTemplate.format(**{ \
1017 'Links' : self.__genSeeListSection(seeList, self.seeListEntryTemplate), 1018 'Links': self.__genSeeListSection(seeList, self.seeListEntryTemplate),
1018 }) 1019 })
1019 else: 1020 else:
1020 seeSect = '' 1021 seeSect = ''
1021 1022
1022 return "{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}".format( 1023 return "{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}".format(

eric ide

mercurial