document.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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. def asStructuredText(I, munge=0, rst=False):
  20. """ Output structured text format. Note, this will whack any existing
  21. 'structured' format of the text.
  22. If `rst=True`, then the output will quote all code as inline literals in
  23. accordance with 'reStructuredText' markup principles.
  24. """
  25. if rst:
  26. inline_literal = lambda s: "``%s``" % (s,)
  27. else:
  28. inline_literal = lambda s: s
  29. r = [inline_literal(I.getName())]
  30. outp = r.append
  31. level = 1
  32. if I.getDoc():
  33. outp(_justify_and_indent(_trim_doc_string(I.getDoc()), level))
  34. bases = [base
  35. for base in I.__bases__
  36. if base is not zope.interface.Interface
  37. ]
  38. if bases:
  39. outp(_justify_and_indent("This interface extends:", level, munge))
  40. level += 1
  41. for b in bases:
  42. item = "o %s" % inline_literal(b.getName())
  43. outp(_justify_and_indent(_trim_doc_string(item), level, munge))
  44. level -= 1
  45. namesAndDescriptions = sorted(I.namesAndDescriptions())
  46. outp(_justify_and_indent("Attributes:", level, munge))
  47. level += 1
  48. for name, desc in namesAndDescriptions:
  49. if not hasattr(desc, 'getSignatureString'): # ugh...
  50. item = "%s -- %s" % (inline_literal(desc.getName()),
  51. desc.getDoc() or 'no documentation')
  52. outp(_justify_and_indent(_trim_doc_string(item), level, munge))
  53. level -= 1
  54. outp(_justify_and_indent("Methods:", level, munge))
  55. level += 1
  56. for name, desc in namesAndDescriptions:
  57. if hasattr(desc, 'getSignatureString'): # ugh...
  58. _call = "%s%s" % (desc.getName(), desc.getSignatureString())
  59. item = "%s -- %s" % (inline_literal(_call),
  60. desc.getDoc() or 'no documentation')
  61. outp(_justify_and_indent(_trim_doc_string(item), level, munge))
  62. return "\n\n".join(r) + "\n\n"
  63. def asReStructuredText(I, munge=0):
  64. """ Output reStructuredText format. Note, this will whack any existing
  65. 'structured' format of the text."""
  66. return asStructuredText(I, munge=munge, rst=True)
  67. def _trim_doc_string(text):
  68. """ Trims a doc string to make it format
  69. correctly with structured text. """
  70. lines = text.replace('\r\n', '\n').split('\n')
  71. nlines = [lines.pop(0)]
  72. if lines:
  73. min_indent = min([len(line) - len(line.lstrip())
  74. for line in lines])
  75. for line in lines:
  76. nlines.append(line[min_indent:])
  77. return '\n'.join(nlines)
  78. def _justify_and_indent(text, level, munge=0, width=72):
  79. """ indent and justify text, rejustify (munge) if specified """
  80. indent = " " * level
  81. if munge:
  82. lines = []
  83. line = indent
  84. text = text.split()
  85. for word in text:
  86. line = ' '.join([line, word])
  87. if len(line) > width:
  88. lines.append(line)
  89. line = indent
  90. else:
  91. lines.append(line)
  92. return '\n'.join(lines)
  93. else:
  94. return indent + \
  95. text.strip().replace("\r\n", "\n") .replace("\n", "\n" + indent)