document.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. ##############################################################################
  2. #
  3. # Copyright (c) 2001, 2002 Zope Foundation and Contributors.
  4. # All Rights Reserved.
  5. #
  6. # This software is subject to the provisions of the Zope Public License,
  7. # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
  8. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
  9. # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  10. # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
  11. # FOR A PARTICULAR PURPOSE.
  12. #
  13. ##############################################################################
  14. """ Pretty-Print an Interface object as structured text (Yum)
  15. This module provides a function, asStructuredText, for rendering an
  16. interface as structured text.
  17. """
  18. import zope.interface
  19. __all__ = [
  20. 'asReStructuredText',
  21. 'asStructuredText',
  22. ]
  23. def asStructuredText(I, munge=0, rst=False):
  24. """ Output structured text format. Note, this will whack any existing
  25. 'structured' format of the text.
  26. If `rst=True`, then the output will quote all code as inline literals in
  27. accordance with 'reStructuredText' markup principles.
  28. """
  29. if rst:
  30. inline_literal = lambda s: "``%s``" % (s,)
  31. else:
  32. inline_literal = lambda s: s
  33. r = [inline_literal(I.getName())]
  34. outp = r.append
  35. level = 1
  36. if I.getDoc():
  37. outp(_justify_and_indent(_trim_doc_string(I.getDoc()), level))
  38. bases = [base
  39. for base in I.__bases__
  40. if base is not zope.interface.Interface
  41. ]
  42. if bases:
  43. outp(_justify_and_indent("This interface extends:", level, munge))
  44. level += 1
  45. for b in bases:
  46. item = "o %s" % inline_literal(b.getName())
  47. outp(_justify_and_indent(_trim_doc_string(item), level, munge))
  48. level -= 1
  49. namesAndDescriptions = sorted(I.namesAndDescriptions())
  50. outp(_justify_and_indent("Attributes:", level, munge))
  51. level += 1
  52. for name, desc in namesAndDescriptions:
  53. if not hasattr(desc, 'getSignatureString'): # ugh...
  54. item = "%s -- %s" % (inline_literal(desc.getName()),
  55. desc.getDoc() or 'no documentation')
  56. outp(_justify_and_indent(_trim_doc_string(item), level, munge))
  57. level -= 1
  58. outp(_justify_and_indent("Methods:", level, munge))
  59. level += 1
  60. for name, desc in namesAndDescriptions:
  61. if hasattr(desc, 'getSignatureString'): # ugh...
  62. _call = "%s%s" % (desc.getName(), desc.getSignatureString())
  63. item = "%s -- %s" % (inline_literal(_call),
  64. desc.getDoc() or 'no documentation')
  65. outp(_justify_and_indent(_trim_doc_string(item), level, munge))
  66. return "\n\n".join(r) + "\n\n"
  67. def asReStructuredText(I, munge=0):
  68. """ Output reStructuredText format. Note, this will whack any existing
  69. 'structured' format of the text."""
  70. return asStructuredText(I, munge=munge, rst=True)
  71. def _trim_doc_string(text):
  72. """ Trims a doc string to make it format
  73. correctly with structured text. """
  74. lines = text.replace('\r\n', '\n').split('\n')
  75. nlines = [lines.pop(0)]
  76. if lines:
  77. min_indent = min([len(line) - len(line.lstrip())
  78. for line in lines])
  79. for line in lines:
  80. nlines.append(line[min_indent:])
  81. return '\n'.join(nlines)
  82. def _justify_and_indent(text, level, munge=0, width=72):
  83. """ indent and justify text, rejustify (munge) if specified """
  84. indent = " " * level
  85. if munge:
  86. lines = []
  87. line = indent
  88. text = text.split()
  89. for word in text:
  90. line = ' '.join([line, word])
  91. if len(line) > width:
  92. lines.append(line)
  93. line = indent
  94. else:
  95. lines.append(line)
  96. return '\n'.join(lines)
  97. else:
  98. return indent + \
  99. text.strip().replace("\r\n", "\n") .replace("\n", "\n" + indent)