Generate plantuml class diagram

    :param desc: result of sadisplay.describe function

    Return plantuml class diagram string

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)