示例#1
0
def make_doc_function(node):
    """ Makes the doc of the node node"""

    # first case : it is a dict function
    # FIXME : to be improved, what do we want ?
    if util.use_parameter_class(node):
        member_list = CL.get_members(util.get_decl_param_class(node), True)
        member_list2 = treat_member_list(member_list)
        h = ['Parameter Name','Type','Default', 'Documentation']
        l = [(m.spelling,m.ctype, m.initializer.replace("res.",""), m.doc) for m in member_list2]
        table =  make_table(h, l)
        doc = doc + '\n' + table
        return doc
    
    # General case
    p = ProcessedDoc(node) # general treatment and analysis, common with cpp2rst

    doc = "%s\n\n%s\n"%(p.brief_doc, p.doc)
   
    params = p.elements['params'] # parameters of the function
    if params:
        doc += "Parameters\n----------\n"
       for p in params:
           name, comment = (p + '  ').split(' ',1)
           doc += "%s \n%s\n"%(name, decal(comment))

    if p.elements['return']:
        _type = '' # FIXME : deduce the type ?
        doc += "Returns\n-------\n%s\n%s"(_type, decal(comment))
    
    return doc
示例#2
0
    def generate_desc_file(self, output_filename, verbose=True):
        """ Makes the desc file"""

        # First treat the parameter class if any (classes passed by dictionnary that MUST be converted)
        param_cls_list = list(self.get_all_param_classes())

        # Precompute
        self.all_enums = list(self.all_enums_gen())
        self.all_classes = list(self.all_classes_gen())
        self.all_functions = list(self.all_functions_gen())
        self.param_cls_list = param_cls_list

        # checks
        for c in param_cls_list:
            for m in CL.get_members(c, True):
                assert CL.is_public(
                    m
                ), "Parameter class : all members must be public. %s::%s is not" % (
                    c.spelling, m.spelling)

        # analyse the modules and converters that need to be added
        print "Analysing dependencies"
        types_being_wrapped_or_converted = param_cls_list + self.all_classes + self.all_enums
        import_list, converters_list = self.DE(
            self.get_all_params_ret_type(param_cls_list),
            types_being_wrapped_or_converted)

        # Reporting
        if self.all_classes:
            print "Wrapping classes:"
            for c in self.all_classes:
                print "   ", c.spelling
        if self.all_enums:
            print "Wrapping enums:"
            for c in self.all_enums:
                print "   ", c.spelling
        if self.all_functions:
            print "Wrapping functions:"
            for c in self.all_functions:
                print "   ", c.spelling
        if param_cls_list:
            print "Generating converters for :"
            for c in param_cls_list:
                print "   ", c.spelling

        # Render mako
        print "Generating " + output_filename
        tpl = Template(filename=util.script_path() + '/mako/desc.py',
                       strict_undefined=True)
        rendered = tpl.render(W=self,
                              CL=CL,
                              doc=doc,
                              util=util,
                              import_list=import_list,
                              converters_list=converters_list,
                              using_list=list(self.namespaces) +
                              list(self.namespace_to_factor))
        open(output_filename,
             "w").write(util.clean_end_and_while_char(rendered))
示例#3
0
文件: doc.py 项目: tschaefer87/cpp2py
def make_doc(node):
    """ process doc of node"""

    doc = process_doc(node.raw_comment)
    if util.use_parameter_class(node):
        doc = doc + '\n' + doc_format_param(
            CL.get_members(util.get_decl_param_class(node), True))

    return replace_latex(replace_cpp_keywords_by_py_keywords(doc))
示例#4
0
文件: cpp2desc.py 项目: TRIQS/triqs
    def generate_desc_file(self, output_filename, verbose  = True):
        """ Makes the desc file"""
         
        # First treat the parameter class if any (classes passed by dictionnary that MUST be converted)
        param_cls_list = list(self.get_all_param_classes())
        for c in param_cls_list : 
            open('parameters_%s.rst'%c.spelling, 'w').write(doc.doc_param_dict_format(CL.get_members(c, True)))

        # Precompute
        self.all_enums     = list(self.all_enums_gen())
        self.all_classes   = list(self.all_classes_gen())
        self.all_functions = list(self.all_functions_gen())
        self.param_cls_list = param_cls_list
       
        # checks
        for c in param_cls_list:
            for m in CL.get_members(c, True):
                assert CL.is_public(m), "Parameter class : all members must be public. %s::%s is not"%(c.spelling, m.spelling) 

        # analyse the modules and converters that need to be added
        print "Analysing dependencies"
        types_being_wrapped_or_converted = param_cls_list + self.all_classes + self.all_enums 
        import_list, converters_list = self.DE(self.get_all_params_ret_type(param_cls_list), types_being_wrapped_or_converted)
        if any(map(self.has_hdf5_scheme, self.all_classes)):
            converters_list.append("triqs/cpp2py_converters/h5.hpp")
   
        # Reporting 
        if self.all_classes:
            print "Wrapping classes:"
            for c in self.all_classes: 
                print "   ", c.spelling
        if self.all_enums:
            print "Wrapping enums:"
            for c in self.all_enums: 
                print "   ", c.spelling
        if self.all_functions:
            print "Wrapping functions:"
            for c in self.all_functions: 
                print "   ", c.spelling
        if param_cls_list:
            print "Generating converters for :"
            for c in param_cls_list: 
                print "   ", c.spelling

        # Render mako
        print "Generating " + output_filename
        tpl = Template(filename= util.script_path() + '/mako/desc.py', strict_undefined = True)
        rendered = tpl.render(W = self, CL = CL, doc = doc, util = util,  
                              import_list = import_list, converters_list = converters_list, using_list = list(self.namespaces) + list(self.namespace_to_factor))
        open(output_filename, "w").write(util.clean_end_and_while_char(rendered))
示例#5
0
    def get_all_params_ret_type(self, param_cls_list):
        """Yields every parameters and return type of every methods and functions"""

        for f in self.all_functions_gen():
            yield getattr(f, 'result_type', None)
            for p in CL.get_params(f):
                yield p.type

        for x in itertools.chain(param_cls_list, self.all_classes_gen()):
            for m in CL.get_members(x, False):  # False : no inherited
                yield m.type
            for m in itertools.chain(CL.get_constructors(x),
                                     CL.get_methods(x)):
                yield getattr(m, 'result_type', None)
                for p in CL.get_params(m):
                    yield p.type
示例#6
0
文件: cpp2desc.py 项目: TRIQS/triqs
    def get_all_params_ret_type(self, param_cls_list):
        """Yields every parameters and return type of every methods and functions"""
       
        for f in self.all_functions_gen():
            yield getattr(f, 'result_type', None)
            for p in CL.get_params(f) : 
                yield p.type

        for x in itertools.chain(param_cls_list, self.all_classes_gen()): 
            for m in CL.get_members(x, False): # False : no inherited
                yield m.type
            for m in itertools.chain(CL.get_constructors(x), CL.get_methods(x)):
                # A minimal filter, do not reuse self.keep_fnt here, because the namespace is N1::N2:...::ClassName
                if CL.is_template(m) or ("ignore_in_python" in CL.get_annotations(m)): continue
                yield getattr(m, 'result_type', None)
                for p in CL.get_params(m) : 
                    yield p.type
示例#7
0
    def make_h5(self, cls):

        print CL.get_annotations(cls)
        """cls : AST node for a class. Returns the h5_read/write code"""
        # FIXME : treat template !
        h5w = '\n'.join('h5_write(gr, "%s", %s);'%(x.spelling, x.spelling) for x in CL.get_members(cls, False))
        h5 = """
void h5_write(triqs::h5::group h5group, std::string const & subgroup_name, {cls_name} const &x) {{
auto gr = h5group.create_group(subgroup_name);
{h5w}
}}

void h5_read(triqs::h5::group h5group, std::string const & subgroup_name,{cls_name} &x) {{
auto gr = h5group.open_group(subgroup_name);
{h5r}
}}
        """.format(cls_name = cls.spelling, h5w = h5w, h5r = h5w.replace('write', 'read'))
        ns = ':'.join(CL.get_namespace_list(cls))
        r = "namespace %s {{\n {H5} \n}}"%ns if ns else '' "{H5}"  
        return r.format(H5 = h5)
示例#8
0
    def get_all_params_ret_type(self, param_cls_list):
        """Yields every parameters and return type of every methods and functions"""

        for f in self.all_functions_gen():
            yield getattr(f, 'result_type', None)
            for p in CL.get_params(f):
                yield p.type

        for x in itertools.chain(param_cls_list, self.all_classes_gen()):
            for m in CL.get_members(x, False):  # False : no inherited
                yield m.type
            for m in itertools.chain(CL.get_constructors(x),
                                     CL.get_methods(x)):
                # A minimal filter, do not reuse self.keep_fnt here, because the namespace is N1::N2:...::ClassName
                if CL.is_template(m) or ("ignore_in_python"
                                         in CL.get_annotations(m)):
                    continue
                yield getattr(m, 'result_type', None)
                for p in CL.get_params(m):
                    yield p.type
示例#9
0
文件: doc.py 项目: richtma93/triqs
def make_doc_function(node):
    """ Makes the doc of the node node"""
    pdoc = ProcessedDoc(
        node)  # general treatment and analysis, common with cpp2rst

    # first case : it is a dict function
    # FIXME : to be improved, what do we want ?
    if util.use_parameter_class(node):
        member_list = CL.get_members(util.get_decl_param_class(node), True)
        table = doc_param_dict_format(member_list)
        return "%s\n\n%s\n\n%s\n" % (pdoc.brief_doc, pdoc.doc, table)

        # member_list2 = treat_member_list(member_list)
        # h = ['Parameter Name','Type','Default', 'Documentation']
        # l = [(m.spelling,m.ctype, m.initializer.replace("res.",""), m.doc) for m in member_list2]
        # table =  make_table(h, *l)
        # doc = clean_doc_string(node.raw_comment) + '\n' + table
        # return doc

    # General case

    doc = "\n%s\n%s" % (pdoc.brief_doc, pdoc.doc)
    doc = doc.strip() + "\n"

    params = pdoc.elements.pop('param', None)  # parameters of the function
    if params:
        doc += "\nParameters\n----------\n"
        for p in params:
            name, comment = (p + '  ').split(' ', 1)
            doc += "%s \n%s\n\n" % (name, decal(comment))

    ret = pdoc.elements.pop('return', None)
    if ret:
        _type = ''  # FIXME : deduce the type ?
        doc += "Returns\n-------\nout  %s\n%s\n\n" % (_type, decal(ret))

    return doc.strip()
示例#10
0
文件: doc.py 项目: TRIQS/triqs
def make_doc_function(node):
    """ Makes the doc of the node node"""
    pdoc = ProcessedDoc(node) # general treatment and analysis, common with cpp2rst

    # first case : it is a dict function
    # FIXME : to be improved, what do we want ?
    if util.use_parameter_class(node):
        member_list = CL.get_members(util.get_decl_param_class(node), True)
        table = doc_param_dict_format(member_list)
        return "%s\n\n%s\n\n%s\n"%( pdoc.brief_doc, pdoc.doc, table) 

        # member_list2 = treat_member_list(member_list)
        # h = ['Parameter Name','Type','Default', 'Documentation']
        # l = [(m.spelling,m.ctype, m.initializer.replace("res.",""), m.doc) for m in member_list2]
        # table =  make_table(h, *l)
        # doc = clean_doc_string(node.raw_comment) + '\n' + table
        # return doc
    
    # General case

    doc = "\n%s\n%s"%(pdoc.brief_doc, pdoc.doc)
    doc = doc.strip() + "\n"
   
    params = pdoc.elements.pop('param', None) # parameters of the function
    if params:
       doc += "\nParameters\n----------\n"
       for p in params:
           name, comment = (p + '  ').split(' ',1)
           doc += "%s \n%s\n\n"%(name, decal(comment))

    ret = pdoc.elements.pop('return', None)
    if ret:
        _type = '' # FIXME : deduce the type ?
        doc += "Returns\n-------\nout  %s\n%s\n\n"%(_type, decal(ret))
   
    return doc.strip()
示例#11
0
def render_cls(cls, all_methods, all_friend_functions):
    """
       Generate the rst page for a class
        
        * cls : node for the classf_name : name of the function
        * doc_methods : ??
    """

    cls_doc = cls.processed_doc
    doc_elem = cls_doc.elements
    R = rst_start

    # include
    incl = doc_elem.pop('include', '')

    # class header
    cls_name_fully_qualified = CL.fully_qualified_name(cls)
    R += """
.. _{cls.spelling}:

{cls_name_fully_qualified}
{separator}

Defined in header <*{incl}*>

.. code-block:: c

    {templ_synop}class {cls.spelling};

{cls_doc.brief_doc}

{cls_doc.doc}
    """.format(cls=cls,
               incl=incl.strip(),
               separator='=' * (len(cls_name_fully_qualified)),
               templ_synop=make_synopsis_template_decl(cls),
               cls_doc=cls_doc,
               cls_name_fully_qualified=cls_name_fully_qualified)

    #
    R += cls_doc.doc
    if 'tparam' in doc_elem:
        R += render_list(doc_elem.pop('tparam'), 'Template parameters')
    if 'note' in doc_elem: R += render_note(doc_elem.pop('note'))
    if 'warning' in doc_elem: R += render_warning(doc_elem.pop('warning'))
    if 'figure' in doc_elem: R += render_fig(doc_elem.pop('figure'))

    # Members
    c_members = list(CL.get_members(cls, True))
    if len(c_members) > 0:
        R += make_header('Public members')
        R += render_table([(t.spelling, t.type.spelling,
                            replace_latex(clean_doc_string(t.raw_comment))
                            if t.raw_comment else '') for t in c_members])

    # Using : TODO : KEEP THIS ?
    c_usings = list(CL.get_usings(cls))
    for t in c_usings:
        t.my_tag = t.spelling

    if len(c_usings) > 0:
        R += make_header('Member types')
        R += render_table([(t.spelling,
                            replace_latex(clean_doc_string(t.raw_comment))
                            if t.raw_comment else '') for t in c_usings])

    # A table for all member functions and all friend functions
    def group_of_overload(f_list):
        s = set(f.processed_doc.elements['group'] for f in f_list
                if 'group' in f.processed_doc.elements)
        assert len(s) < 2, "Can not have different group for various overload"
        return s.pop if s else ''

    def make_func_list(all_f, header_name):
        R = ''
        if len(all_f) > 0:
            R += make_header(header_name)
            R += render_table([
                (":ref:`%s <%s_%s>`" %
                 (name, escape_lg(cls.spelling), escape_lg(name)),
                 f_list[0].processed_doc.brief_doc)
                for (name, f_list) in all_f.items()
            ])
            R += toctree_hidden
            for f_name in all_f:
                R += "    {cls.spelling}/{f_name}\n".format(cls=cls,
                                                            f_name=f_name)
        return R

    R += make_func_list(all_methods, 'Member functions')
    R += make_func_list(all_friend_functions, 'Non Member functions')

    # Example
    if 'example' in doc_elem: R += render_example(doc_elem.pop('example'))

    return R
示例#12
0
    def analyse_one_ns(self, namespace):

        print "*** Namespace %s ***" % namespace

        # ----------------------
        #      Filters
        # ----------------------
        def keep_ns(n):
            """Given a namespace node n, shall we keep it ?"""
            ns = CL.fully_qualified(n)
            return ns in namespace

        def keep_cls(c):
            """ Given a class node, shall we keep it ? 

               Reject if no raw_comment.
               Keeps if its namespace is EXACTLY in self.namespaces
               e.g. A::B::cls will be kept iif A::B is in self.namespaces, not it A is.

               The filter to keep a class/struct or an enum :
                 it must have a raw comment
                 if we a namespace list, it must be in it.
                 if target_file_only it has to be in the file given to c++2py
            """
            if c.spelling.startswith('_'): return False
            # FIXME : Commented for debug
            if not c.raw_comment: return False
            if namespace:
                qualified_ns = CL.get_namespace(c)
                if qualified_ns != namespace: return False
            return (c.location.file.name
                    == self.filename) if self.target_file_only else True

        def keep_fnt(f):
            #print "RAW", f.spelling, f.raw_comment
            if not f.raw_comment: return False
            if f.spelling.startswith('operator') or f.spelling in [
                    'begin', 'end'
            ]:
                return False
            return keep_cls(f)

        def keep_using(c):
            #if not c.raw_comment : return False
            if namespace:
                qualified_ns = CL.get_namespace(c)
                if qualified_ns != namespace: return False
            return (c.location.file.name
                    == self.filename) if self.target_file_only else True

        # ----------------------

        # A list of AST nodes for classes
        classes = CL.get_classes(self.root,
                                 keep_cls,
                                 traverse_namespaces=True,
                                 keep_ns=keep_ns)
        classes = list(
            classes)  # make a list to avoid exhaustion of the generator

        D = OrderedDict()
        for cls in classes:
            cls.namespace = CL.get_namespace(cls)
            cls.name = CL.get_name_with_template_specialization(
                cls) or cls.spelling
            cls.fully_qualified_name = '::'.join([cls.namespace, cls.name])
            cls.name_for_label = synopsis.make_label(cls.fully_qualified_name)
            D[cls.fully_qualified_name] = cls
            # print "CLASS", cls.name
            # print "CLASS", cls.fully_qualified_name
            # print "CLASS", cls.name_for_label
            # print "CLASS", "----------------------"

            print " ... class :  %s" % cls.fully_qualified_name, cls.location
            #assert ',' not in cls.fully_qualified_name, "Not implemented"

            # process the doc of the class and add it to the node
            cls.processed_doc = ProcessedDoc(cls)

            # all methods and constructors
            # we build a OrderedDict of the constructors (first) and the methods, in order of declaration
            constructors = list(CL.get_constructors(cls))
            for f in constructors:
                f.is_constructor = True  # tag them for later use
            methods = OrderedDict()
            if constructors: methods['constructor'] = constructors
            methods.update(
                self.regroup_func_by_names(CL.get_methods(
                    cls, True)))  # True : with inherited
            #methods.update(self.regroup_func_by_names(CL.get_methods(cls, True, keep = keep_fnt))) # True : with inherited

            # all non member functions
            friend_functions = self.regroup_func_by_names(
                CL.get_friend_functions(cls))
            #friend_functions = self.regroup_func_by_names(CL.get_friend_functions(cls, keep = keep_fnt))

            # Analyse the doc string for all methods and functions, and store the result in the node itself
            for (n, f_list) in (methods.items() + friend_functions.items()):
                for f in f_list:
                    f.processed_doc = ProcessedDoc(f)

            # attach to the node
            cls.methods, cls.friend_functions = methods, friend_functions

            # members
            cls.members = list(CL.get_members(cls, True))

            # using
            cls.usings = list(CL.get_usings(cls))  # , keep_using))

        # Eliminate doublons, like forward declarations
        classes = D.values()

        # A list of AST nodes for the methods and functions
        functions = CL.get_functions(self.root,
                                     keep_fnt,
                                     traverse_namespaces=True,
                                     keep_ns=keep_ns)
        functions = list(
            functions)  # make a to avoid exhaustion of the generator

        # Analyse the doc strings
        for f in functions:
            f.processed_doc = ProcessedDoc(f)

        # Find the using of this namespace, and make the list unique based on the fully_qualified_name
        usings = list(
            CL.get_usings(self.root,
                          keep_using,
                          traverse_namespaces=True,
                          keep_ns=keep_ns))
        D = OrderedDict()
        for c in usings:
            c.namespace = CL.get_namespace(c)
            c.fully_qualified_name = '::'.join([c.namespace, c.spelling])
            D[c.fully_qualified_name] = c
        usings = D.values()

        return classes, functions, usings
示例#13
0
文件: cpp2rst.py 项目: TRIQS/triqs
    def analyse_one_ns(self, namespace):

        print "*** Namespace %s ***"%namespace

        # ----------------------
        #      Filters
        # ----------------------
        def keep_ns(n):
            """Given a namespace node n, shall we keep it ?"""
            ns = CL.fully_qualified(n) 
            return ns in namespace
        
        def keep_cls(c):
            """ Given a class node, shall we keep it ? 

               Reject if no raw_comment.
               Keeps if its namespace is EXACTLY in self.namespaces
               e.g. A::B::cls will be kept iif A::B is in self.namespaces, not it A is.

               The filter to keep a class/struct or an enum :
                 it must have a raw comment
                 if we a namespace list, it must be in it.
                 if target_file_only it has to be in the file given to c++2py
            """
            if c.spelling.startswith('_') : return False
            # FIXME : Commented for debug
            if not c.raw_comment : return False
            if namespace:
                qualified_ns = CL.get_namespace(c) 
                if qualified_ns != namespace : return False
            return (c.location.file.name == self.filename) if self.target_file_only else True
        
        def keep_fnt(f):
            #print "RAW", f.spelling, f.raw_comment
            if not f.raw_comment : return False
            if  f.spelling.startswith('operator') or f.spelling in ['begin','end'] : return False
            return keep_cls(f) 

        def keep_using(c):
            #if not c.raw_comment : return False
            if namespace:
                qualified_ns = CL.get_namespace(c) 
                if qualified_ns != namespace : return False
            return (c.location.file.name == self.filename) if self.target_file_only else True

        # ----------------------

        # A list of AST nodes for classes
        classes = CL.get_classes(self.root, keep_cls, traverse_namespaces = True, keep_ns = keep_ns)
        classes = list(classes) # make a list to avoid exhaustion of the generator
  
        D = OrderedDict()
        for cls in classes: 
            cls.namespace = CL.get_namespace(cls)
            cls.name = CL.get_name_with_template_specialization(cls) or cls.spelling 
            cls.fully_qualified_name = '::'.join([cls.namespace, cls.name])
            cls.name_for_label = synopsis.make_label(cls.fully_qualified_name)
            D[cls.fully_qualified_name] = cls
            # print "CLASS", cls.name
            # print "CLASS", cls.fully_qualified_name 
            # print "CLASS", cls.name_for_label
            # print "CLASS", "----------------------"
       
            print " ... class :  %s"%cls.fully_qualified_name, cls.location
            #assert ',' not in cls.fully_qualified_name, "Not implemented"

            # process the doc of the class and add it to the node
            cls.processed_doc = ProcessedDoc(cls)

            # all methods and constructors
            # we build a OrderedDict of the constructors (first) and the methods, in order of declaration 
            constructors = list(CL.get_constructors(cls))
            for f in constructors : f.is_constructor = True # tag them for later use
            methods = OrderedDict()
            if constructors: methods['constructor'] = constructors
            methods.update(self.regroup_func_by_names(CL.get_methods(cls, True))) # True : with inherited 
            #methods.update(self.regroup_func_by_names(CL.get_methods(cls, True, keep = keep_fnt))) # True : with inherited 

            # all non member functions
            friend_functions = self.regroup_func_by_names(CL.get_friend_functions(cls))
            #friend_functions = self.regroup_func_by_names(CL.get_friend_functions(cls, keep = keep_fnt))

            # Analyse the doc string for all methods and functions, and store the result in the node itself
            for (n,f_list) in (methods.items() + friend_functions.items()):
                for f in f_list:
                    f.processed_doc = ProcessedDoc(f)

            # attach to the node
            cls.methods, cls.friend_functions = methods, friend_functions

            # members 
            cls.members = list(CL.get_members(cls, True)) 
            
            # using 
            cls.usings = list(CL.get_usings(cls)) # , keep_using)) 
             
        # Eliminate doublons, like forward declarations
        classes = D.values()

        # A list of AST nodes for the methods and functions
        functions = CL.get_functions(self.root, keep_fnt, traverse_namespaces = True, keep_ns = keep_ns)
        functions = list(functions) # make a to avoid exhaustion of the generator

        # Analyse the doc strings 
        for f in functions:
            f.processed_doc = ProcessedDoc(f)
        
        # Find the using of this namespace, and make the list unique based on the fully_qualified_name 
        usings = list(CL.get_usings(self.root, keep_using, traverse_namespaces = True, keep_ns = keep_ns)) 
        D = OrderedDict()
        for c in usings:
            c.namespace = CL.get_namespace(c)
            c.fully_qualified_name = '::'.join([c.namespace, c.spelling])
            D[c.fully_qualified_name] = c
        usings = D.values()

        return classes, functions, usings
示例#14
0
def render_cls(cls, all_m, all_friend_functions, doc_methods, doc_class,
               cls_doc):
    doc_elem = doc_class.elements
    R = rst_start

    # include
    incl = doc_elem['include']
    if incl:
        R += """
.. code-block:: c

    #include <{incl}>
        """.format(incl=incl.strip())

    # class header
    R += """
.. _{cls.spelling}:

{cls.spelling}
{separator}

{cls_doc.brief_doc}

{cls_doc.processed_doc}

**Synopsis**:

.. code-block:: c

    {templ_synop}class {cls.spelling};
    """.format(cls=cls,
               separator='=' * (len(cls.spelling) + 2),
               templ_synop=make_synopsis_template_decl(cls),
               cls_doc=cls_doc)

    # doc, note, warning, figure
    R += replace_latex(doc_class.processed_doc)
    R += replace_latex(render_note('note', doc_elem))
    R += replace_latex(render_note('warning', doc_elem))
    R += render_fig(doc_elem)
    R += render_list(doc_elem['tparam'], 'Template parameters')

    c_members = list(CL.get_members(cls, True))
    if len(c_members) > 0:
        R += head('Public members')
        R += make_table(
            ['Member', 'Type', 'Comment'],
            [(t.spelling, t.type.spelling,
              replace_latex(t.raw_comment) if t.raw_comment else '')
             for t in c_members])

    c_usings = list(CL.get_usings(cls))
    if len(c_usings) > 0:
        R += head('Member types')
        R += make_table(['Member type', 'Comment'], [
            (t.spelling, replace_latex(t.raw_comment) if t.raw_comment else '')
            for t in c_usings
        ])

    if len(all_m) > 0:
        R += head('Member functions')
        R += make_table(['Member function', 'Comment'],
                        [(":ref:`%s <%s_%s>`" %
                          (name, escape_lg(cls.spelling), escape_lg(name)),
                          replace_latex(doc_methods[name][0].brief_doc))
                         for name in all_m])

        R += toctree_hidden
        for m_name in all_m:
            R += "    {cls.spelling}/{m_name}\n".format(cls=cls, m_name=m_name)

    if len(all_friend_functions) > 0:
        R += head('Non Member functions')
        R += make_table(['Non member function', 'Comment'],
                        [(":ref:`%s <%s_%s>`" %
                          (name, escape_lg(cls.spelling), escape_lg(name)),
                          replace_latex(doc_methods[name][0].brief_doc))
                         for name in all_friend_functions])

        R += toctree_hidden
        for f_name in all_friend_functions:
            R += "    {cls.spelling}/{f_name}\n".format(cls=cls, f_name=f_name)

    code, d1, d2, s, e = prepare_example(cls.spelling, 4)
    if code is not None:
        R += """
Example
---------

{d1}

.. triqs_example::

    linenos:{s},{e}

{code}

{d2}
        """.format(d1=d1, d2=d2, s=s, e=e, code=code)
    return R