⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 doxproc.py

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 PY
📖 第 1 页 / 共 3 页
字号:
#!/usr/bin/python# Copyright 2006 Rene Rivera# Distributed under the Boost Software License, Version 1.0.# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)'''Processing of Doxygen generated XML.'''import osimport os.pathimport sysimport timeimport stringimport getoptimport globimport reimport xml.dom.minidom    def usage():    print '''Usage:    %s optionsOptions:    --xmldir        Directory with the Doxygen xml result files.    --output        Write the output BoostBook to the given location.    --id            The ID of the top level BoostBook section.    --title         The title of the top level BoostBook section.    --enable-index  Generate additional index sections for classes and                    types.''' % ( sys.argv[0] )def get_args( argv = sys.argv[1:] ):    spec = [        'xmldir=',        'output=',        'id=',        'title=',        'enable-index',        'help' ]    options = {        '--xmldir' : 'xml',        '--output' : None,        '--id' : 'dox',        '--title' : 'Doxygen'        }    ( option_pairs, other ) = getopt.getopt( argv, '', spec )    map( lambda x: options.__setitem__( x[0], x[1] ), option_pairs )        if options.has_key( '--help' ):        usage()        sys.exit(1)        return {        'xmldir' : options['--xmldir'],        'output' : options['--output'],        'id' : options['--id'],        'title' : options['--title'],        'index' : options.has_key('--enable-index')        }def if_attribute(node, attribute, true_value, false_value=None):    if node.getAttribute(attribute) == 'yes':        return true_value    else:        return false_valueclass Doxygen2BoostBook:        def __init__( self, **kwargs ):        ##        self.args = kwargs        self.args.setdefault('id','')        self.args.setdefault('title','')        self.args.setdefault('last_revision', time.asctime())        self.args.setdefault('index', False)        self.id = '%(id)s.reference' % self.args        self.args['id'] = self.id        #~ This is our template BoostBook document we insert the generated content into.        self.boostbook = xml.dom.minidom.parseString('''<?xml version="1.0" encoding="UTF-8"?><section id="%(id)s" name="%(title)s" last-revision="%(last_revision)s">    <title>%(title)s</title>    <library-reference id="%(id)s.headers">        <title>Headers</title>    </library-reference>    <index id="%(id)s.classes">        <title>Classes</title>    </index>    <index id="%(id)s.index">        <title>Index</title>    </index></section>''' % self.args )        self.section = {            'headers' : self._getChild('library-reference',id='%(id)s.headers' % self.args),            'classes' : self._getChild('index',id='%(id)s.classes' % self.args),            'index' : self._getChild('index',id='%(id)s.index' % self.args)            }        #~ Remove the index sections if we aren't generating it.        if not self.args['index']:            self.section['classes'].parentNode.removeChild(self.section['classes'])            self.section['classes'].unlink()            del self.section['classes']            self.section['index'].parentNode.removeChild(self.section['index'])            self.section['index'].unlink()            del self.section['index']        #~ The symbols, per Doxygen notion, that we translated.        self.symbols = {}        #~ Map of Doxygen IDs and BoostBook IDs, so we can translate as needed.        self.idmap = {}        #~ Marks generation, to prevent redoing it.        self.generated = False        #~ Add an Doxygen generated XML document to the content we are translating.    def addDox( self, document ):        self._translateNode(document.documentElement)        #~ Turns the internal XML tree into an output UTF-8 string.    def tostring( self ):        self._generate()        #~ return self.boostbook.toprettyxml('  ')        return self.boostbook.toxml('utf-8')        #~ Does post-processing on the partial generated content to generate additional info    #~ now that we have the complete source documents.    def _generate( self ):        if not self.generated:            self.generated = True            symbols = self.symbols.keys()            symbols.sort()            #~ Populate the header section.            for symbol in symbols:                if self.symbols[symbol]['kind'] in ('header'):                    self.section['headers'].appendChild(self.symbols[symbol]['dom'])            for symbol in symbols:                if self.symbols[symbol]['kind'] not in ('namespace', 'header'):                    container = self._resolveContainer(self.symbols[symbol],                        self.symbols[self.symbols[symbol]['header']]['dom'])                    if container.nodeName != 'namespace':                        ## The current BoostBook to Docbook translation doesn't                        ## respect, nor assign, IDs to inner types of any kind.                        ## So nuke the ID entry so as not create bogus links.                        del self.idmap[self.symbols[symbol]['id']]                    container.appendChild(self.symbols[symbol]['dom'])            self._rewriteIDs(self.boostbook.documentElement)        #~ Rewrite the various IDs from Doxygen references to the newly created    #~ BoostBook references.    def _rewriteIDs( self, node ):        if node.nodeName in ('link'):            if (self.idmap.has_key(node.getAttribute('linkend'))):                #~ A link, and we have someplace to repoint it at.                node.setAttribute('linkend',self.idmap[node.getAttribute('linkend')])            else:                #~ A link, but we don't have a generated target for it.                node.removeAttribute('linkend')        elif hasattr(node,'hasAttribute') and node.hasAttribute('id') and self.idmap.has_key(node.getAttribute('id')):            #~ Simple ID, and we have a translation.            node.setAttribute('id',self.idmap[node.getAttribute('id')])        #~ Recurse, and iterate, depth-first traversal which turns out to be        #~ left-to-right and top-to-bottom for the document.        if node.firstChild:            self._rewriteIDs(node.firstChild)        if node.nextSibling:            self._rewriteIDs(node.nextSibling)        def _resolveContainer( self, cpp, root ):        container = root        for ns in cpp['namespace']:            node = self._getChild('namespace',name=ns,root=container)            if not node:                node = container.appendChild(                    self._createNode('namespace',name=ns))            container = node        for inner in cpp['name'].split('::'):            node = self._getChild(name=inner,root=container)            if not node:                break            container = node        return container        def _setID( self, id, name ):        self.idmap[id] = name.replace('::','.').replace('/','.')        #~ print '--| setID:',id,'::',self.idmap[id]        #~ Translate a given node within a given context.    #~ The translation dispatches to a local method of the form    #~ "_translate[_context0,...,_contextN]", and the keyword args are    #~ passed along. If there is no translation handling method we    #~ return None.    def _translateNode( self, *context, **kwargs ):        node = None        names = [ ]        for c in context:            if c:                if not isinstance(c,xml.dom.Node):                    suffix = '_'+c.replace('-','_')                else:                    suffix = '_'+c.nodeName.replace('-','_')                    node = c                names.append('_translate')                names = map(lambda x: x+suffix,names)        if node:            for name in names:                if hasattr(self,name):                    return getattr(self,name)(node,**kwargs)        return None        #~ Translates the children of the given parent node, appending the results    #~ to the indicated target. For nodes not translated by the translation method    #~ it copies the child over and recurses on that child to translate any    #~ possible interior nodes. Hence this will translate the entire subtree.    def _translateChildren( self, parent, **kwargs ):        target = kwargs['target']        for n in parent.childNodes:            child = self._translateNode(n,target=target)            if child:                target.appendChild(child)            else:                child = n.cloneNode(False)                if hasattr(child,'data'):                    child.data = re.sub(r'\s+',' ',child.data)                target.appendChild(child)                self._translateChildren(n,target=child)        #~ Translate the given node as a description, into the description subnode    #~ of the target. If no description subnode is present in the target it    #~ is created.    def _translateDescription( self, node, target=None, tag='description', **kwargs ):        description = self._getChild(tag,root=target)        if not description:            description = target.appendChild(self._createNode(tag))        self._translateChildren(node,target=description)        return description        #~ Top level translation of: <doxygen ...>...</doxygen>,    #~ translates the children.    def _translate_doxygen( self, node ):        #~ print '_translate_doxygen:', node.nodeName        result = []        for n in node.childNodes:            newNode = self._translateNode(n)            if newNode:                result.append(newNode)        return result        #~ Top level translation of:    #~ <doxygenindex ...>    #~   <compound ...>    #~     <member ...>    #~       <name>...</name>    #~     </member>    #~     ...    #~   </compound>    #~   ...    #~ </doxygenindex>    #~ builds the class and symbol sections, if requested.    def _translate_doxygenindex( self, node ):        #~ print '_translate_doxygenindex:', node.nodeName        if self.args['index']:            entries = []            classes = []            #~ Accumulate all the index entries we care about.            for n in node.childNodes:                if n.nodeName == 'compound':                    if n.getAttribute('kind') not in ('file','dir','define'):                        cpp = self._cppName(self._getChildData('name',root=n))                        entry = {                            'name' : cpp['name'],                            'compoundname' : cpp['compoundname'],                            'id' : n.getAttribute('refid')                            }                        if n.getAttribute('kind') in ('class','struct'):                            classes.append(entry)                        entries.append(entry)                        for m in n.childNodes:                            if m.nodeName == 'member':                                cpp = self._cppName(self._getChildData('name',root=m))                                entry = {                                    'name' : cpp['name'],                                    'compoundname' : cpp['compoundname'],                                    'id' : n.getAttribute('refid')                                    }                                if hasattr(m,'getAttribute') and m.getAttribute('kind') in ('class','struct'):

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -