docs: def plantuml(desc):
      """Generate plantuml class diagram
  
      :param desc: result of sadisplay.describe function
  
      Return plantuml class diagram string
      """
  
      classes, relations, inherits = desc
  
      result = [
          '@startuml',
          'skinparam defaultFontName Courier',
      ]
  
      for cls in classes:
          # issue #11 - tabular output of class members (attrs)
          # http://stackoverflow.com/a/8356620/258194
  
          # build table
          class_desc = []
          # table columns
          class_desc += [(i[1], i[0]) for i in cls['cols']]
          # class properties
          class_desc += [('+', i) for i in cls['props']]
          # methods
          class_desc += [('%s()' % i, '') for i in cls['methods']]
  
          result.append(
              'Class %(name)s {\n%(desc)s\n}' % {
                  'name': cls['name'],
                  'desc': '\n'.join(tabular_output(class_desc)),
              }
          )
  
      for item in inherits:
          result.append("%(parent)s <|-- %(child)s" % item)
  
      for item in relations:
          result.append("%(from)s <--o %(to)s: %(by)s" % item)
  
      result += [
          'right footer generated by sadisplay v%s' % __version__,
          '@enduml',
      ]
  
      return '\n\n'.join(result)