📄 generate_docstrings.py
字号:
#!/usr/bin/env python__author__ = "Johan Hake & Prabhu Ramachandran"__license__ = "bsd style"import osfrom xml.dom import minidomimport reimport textwrapimport sysimport typesdef my_open_read(source): if hasattr(source, "read"): return source else: return open(source)def my_open_write(dest): if hasattr(dest, "write"): return dest else: return open(dest, 'w')class Doxy2SWIG: """Converts Doxygen generated XML files into a file containing docstrings that can be used by SWIG-1.3.x that have support for feature("docstring"). Once the data is parsed it is stored in self.pieces. """ __author__ = "Prabhu Ramachandran" __license__ = "BSD style" # This code is implemented using Mark Pilgrim's code as a guideline: # http://www.faqs.org/docs/diveintopython/kgp_divein.html def __init__(self, src): """Initialize the instance given a source object (file or filename). """ f = my_open_read(src) self.my_dir = os.path.dirname(f.name) self.xmldoc = minidom.parse(f).documentElement f.close() self.pieces = [] self.pieces.append('\n// File: %s\n'%\ os.path.basename(f.name)) self.space_re = re.compile(r'\s+') self.lead_spc = re.compile(r'^(%feature\S+\s+\S+\s*?)"\s+(\S)') self.multi = 0 self.ignores = ('inheritancegraph', 'param', 'listofallmembers', 'innerclass', 'name', 'declname', 'incdepgraph', 'invincdepgraph', 'programlisting', 'type', 'references', 'referencedby', 'location', 'collaborationgraph', 'reimplements', 'reimplementedby', 'derivedcompoundref', 'basecompoundref', 'argsstring') #self.generics = [] self.include_function_definition = False def generate(self): """Parses the file set in the initialization. The resulting data is stored in `self.pieces`. """ self.parse(self.xmldoc) def parse(self, node): """Parse a given node. This function in turn calls the `parse_<nodeType>` functions which handle the respective nodes. """ pm = getattr(self, "parse_%s"%node.__class__.__name__) pm(node) def parse_Document(self, node): self.parse(node.documentElement) def parse_Text(self, node): txt = node.data txt = txt.replace('\\', r'\\\\') txt = txt.replace('"', r'\"') # ignore pure whitespace m = self.space_re.match(txt) if m and len(m.group()) == len(txt): pass else: self.add_text(textwrap.fill(txt)) def parse_Element(self, node): """Parse an `ELEMENT_NODE`. This calls specific `do_<tagName>` handers for different elements. If no handler is available the `generic_parse` method is called. All tagNames specified in `self.ignores` are simply ignored. """ name = node.tagName ignores = self.ignores if name in ignores: return attr = "do_%s" % name if hasattr(self, attr): handlerMethod = getattr(self, attr) handlerMethod(node) else: self.generic_parse(node) #if name not in self.generics: self.generics.append(name) def parse_Comment(self, node): return def add_text(self, value): """Adds text corresponding to `value` into `self.pieces`.""" if type(value) in (types.ListType, types.TupleType): self.pieces.extend(value) else: self.pieces.append(value) def get_specific_nodes(self, node, names): """Given a node and a sequence of strings in `names`, return a dictionary containing the names as keys and child `ELEMENT_NODEs`, that have a `tagName` equal to the name. """ nodes = [(x.tagName, x) for x in node.childNodes \ if x.nodeType == x.ELEMENT_NODE and \ x.tagName in names] return dict(nodes) def generic_parse(self, node, pad=0): """A Generic parser for arbitrary tags in a node. Parameters: - node: A node in the DOM. - pad: `int` (default: 0) If 0 the node data is not padded with newlines. If 1 it appends a newline after parsing the childNodes. If 2 it pads before and after the nodes are processed. Defaults to 0. """ npiece = 0 if pad: npiece = len(self.pieces) if pad == 2: self.add_text('\n') for n in node.childNodes: self.parse(n) if pad: if len(self.pieces) > npiece: self.add_text('\n') def space_parse(self, node): self.add_text(' ') self.generic_parse(node) do_ref = space_parse do_emphasis = space_parse do_bold = space_parse do_computeroutput = space_parse do_formula = space_parse def do_compoundname(self, node): self.add_text('\n\n') data = node.firstChild.data self.add_text('%%feature("docstring") %s "\n'%data) def do_compounddef(self, node): kind = node.attributes['kind'].value if kind in ('class', 'struct'): prot = node.attributes['prot'].value if prot <> 'public': return names = ('compoundname', 'briefdescription', 'detaileddescription', 'includes') first = self.get_specific_nodes(node, names) for n in names: if first.has_key(n): self.parse(first[n]) self.add_text(['";','\n']) for n in node.childNodes: if n not in first.values(): self.parse(n) elif kind in ('file', 'namespace'): nodes = node.getElementsByTagName('sectiondef') for n in nodes: self.parse(n) def do_includes(self, node): self.add_text('C++ includes: ') self.generic_parse(node, pad=1) def do_parameterlist(self, node): self.add_text(['\n', '\n', 'Parameters:', '\n']) self.generic_parse(node, pad=1) def do_para(self, node): self.add_text('\n') self.generic_parse(node, pad=1) def do_parametername(self, node): self.add_text('\n') self.add_text("%s: "%node.firstChild.data) def do_parameterdefinition(self, node): self.generic_parse(node, pad=1) def do_detaileddescription(self, node): self.generic_parse(node, pad=1) def do_briefdescription(self, node): self.generic_parse(node, pad=1) def do_memberdef(self, node): prot = node.attributes['prot'].value id = node.attributes['id'].value kind = node.attributes['kind'].value tmp = node.parentNode.parentNode.parentNode compdef = tmp.getElementsByTagName('compounddef')[0] cdef_kind = compdef.attributes['kind'].value if prot == 'public': first = self.get_specific_nodes(node, ('definition', 'name'))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -