--- /dev/null
+#!/usr/bin/python
+#---------------------------------------------------------------------------
+#
+# Like simplify.xsl but using Python so a few non-standard conversions can
+# also be done. (Currently it is still about the same as simplify.xsl...)
+#
+#---------------------------------------------------------------------------
+
+import sys
+import os
+import libxml2
+
+
+DEST="docs/xml/wxPython-metadata.xml"
+SRC="docs/xml-raw"
+
+
+
+def getModuleNames():
+ """
+ Get the list of extension modules from setup.py
+ """
+ import setup
+ names = [e.name[1:] for e in setup.wxpExtensions]
+ return names
+
+
+
+def getAttr(node, name):
+ """
+ Get a value by name from the <attribute> elements in the SWIG XML output
+ """
+ path = "./attributelist/attribute[@name='%s']/@value" % name
+ n = node.xpathEval2(path)
+ if len(n):
+ return n[0].content
+ else:
+ return None
+
+
+
+
+
+def processModule(newDocNode, modulename):
+ """
+ Start processing a new XML file, create a module element and then
+ find the include elements
+ """
+ filename = os.path.join(SRC, "%s_swig.xml" % modulename)
+ print filename
+
+ doc = libxml2.parseFile(filename)
+ topNode = doc.getRootElement()
+
+ # make a module element
+ name = getAttr(topNode, "module")
+ assert name == modulename # sanity check
+
+ moduleNode = libxml2.newNode("module")
+ moduleNode.setProp("name", name)
+ newDocNode.addChild(moduleNode)
+
+ node = topNode.children
+ while node is not None:
+ if node.name == "include":
+ processInclude(moduleNode, node, 0)
+ node = node.next
+
+ doc.freeDoc()
+
+
+
+def processInclude(moduleNode, includeNode, level):
+ """
+ Almost everything we are interested in is inside an <include>,
+ which may also be nested.
+ """
+
+ # check first for imports
+ for node in includeNode.xpathEval2("import"):
+ try:
+ modNode = node.xpathEval2("module")[0]
+ name = getAttr(modNode, "name")
+ impNode = libxml2.newNode("import")
+ impNode.setProp("name", name)
+ moduleNode.addChild(impNode)
+ except IndexError:
+ pass
+
+ # then look through the child nodes for other things we need
+ node = includeNode.children
+ while node is not None:
+ if node.name == "insert":
+ processInsert(moduleNode, node, level)
+
+ elif node.name == "class":
+ processClass(moduleNode, node, level)
+
+ elif node.name == "cdecl" and getAttr(node, "view") == "globalfunctionHandler":
+ func = libxml2.newNode("method")
+ func.setProp("name", getAttr(node, "sym_name"))
+ func.setProp("oldname", getAttr(node, "name"))
+ func.setProp("type", getAttr(node, "type"))
+ doCheckOverloaded(func, node)
+ doDocStrings(func, node)
+ doParamList(func, node)
+ moduleNode.addChild(func)
+
+
+ elif node.name == "include":
+ processInclude(moduleNode, node, level+1)
+
+ node = node.next
+
+
+
+def processInsert(parentNode, insertNode, level):
+ """
+ Check for pythoncode
+ """
+ if getAttr(insertNode, "section") == "python":
+ code = getAttr(insertNode, "code")
+ node = libxml2.newNode("pythoncode")
+ node.addChild(libxml2.newText(code))
+ parentNode.addChild(node)
+
+
+
+def processClass(parentNode, classNode, level):
+ """
+ Handle classes, constructors, methods, etc.
+ """
+ # make class element
+ klass = libxml2.newNode("class")
+ klass.setProp("name", getAttr(classNode, "sym_name"))
+ klass.setProp("oldname", getAttr(classNode, "name"))
+ klass.setProp("module", getAttr(classNode, "module"))
+ doDocStrings(klass, classNode)
+ parentNode.addChild(klass)
+
+ # check for baseclass(es)
+ for node in classNode.xpathEval2("attributelist/baselist/base"):
+ baseclass = libxml2.newNode("baseclass")
+ baseclass.setProp("name", node.prop("name"))
+ klass.addChild(baseclass)
+
+ # check for constructors/destructors
+ for type in ["constructor", "destructor"]:
+ for node in classNode.xpathEval2("%s | extend/%s" % (type, type)):
+ func = libxml2.newNode(type)
+ func.setProp("name", getAttr(node, "sym_name"))
+ if parentNode.name != "destructor":
+ doCheckOverloaded(func, node)
+ doDocStrings(func, node)
+ doParamList(func, node)
+ klass.addChild(func)
+
+ # check for cdecl's. In class scope we are interested in methods,
+ # static methods, or properties
+ for node in classNode.xpathEval2("cdecl | extend/cdecl"):
+ view = getAttr(node, "view")
+ if view == "memberfunctionHandler":
+ func = libxml2.newNode("method")
+ func.setProp("name", getAttr(node, "sym_name"))
+ func.setProp("type", getAttr(node, "type"))
+ doCheckOverloaded(func, node)
+ doDocStrings(func, node)
+ doParamList(func, node)
+ klass.addChild(func)
+
+ elif view == "staticmemberfunctionHandler":
+ func = libxml2.newNode("staticmethod")
+ func.setProp("name", getAttr(node, "sym_name"))
+ func.setProp("type", getAttr(node, "type"))
+ doCheckOverloaded(func, node)
+ doDocStrings(func, node)
+ doParamList(func, node)
+ klass.addChild(func)
+
+ elif view == "variableHandler":
+ prop = libxml2.newNode("property")
+ prop.setProp("name", getAttr(node, "sym_name"))
+ prop.setProp("type", getAttr(node, "type"))
+ if getAttr(node, "feature_immutable"):
+ prop.setProp("readonly", "yes")
+ else:
+ prop.setProp("readonly", "no")
+ doDocStrings(prop, node)
+ klass.addChild(prop)
+
+
+
+def doParamList(parentNode, srcNode):
+ """
+ Convert the parameter list
+ """
+ params = srcNode.xpathEval2("attributelist/parmlist/parm")
+ if params:
+ plist = libxml2.newNode("paramlist")
+ for p in params:
+ pnode = libxml2.newNode("param")
+ pnode.setProp("name", getAttr(p, "name"))
+ pnode.setProp("type", getAttr(p, "type"))
+ pnode.setProp("default", getAttr(p, "value"))
+ plist.addChild(pnode)
+ parentNode.addChild(plist)
+
+
+
+def doCheckOverloaded(parentNode, srcNode):
+ """
+ Set an attribute indicating if the srcNode is tagged as being overloaded
+ """
+ if srcNode.xpathEval2("./attributelist/attribute[@name='sym_overloaded']"):
+ parentNode.setProp("overloaded", "yes")
+ else:
+ parentNode.setProp("overloaded", "no")
+
+
+
+def doDocStrings(parentNode, srcNode):
+ """
+ Check for the various possible docstring attributes, and attach
+ coresponding child nodes if found.
+ """
+ def makeDocElement(name, content):
+ node = libxml2.newNode(name)
+ node.addChild(libxml2.newText(content))
+ return node
+
+ autodoc = getAttr(srcNode, "python_autodoc")
+ docstr = getAttr(srcNode, "feature_docstring")
+ refdoc = getAttr(srcNode, "feature_refdoc")
+ if autodoc:
+ parentNode.addChild(makeDocElement("autodoc", autodoc))
+ if docstr:
+ parentNode.addChild(makeDocElement("docstring", docstr))
+ if refdoc:
+ parentNode.addChild(makeDocElement("refdoc", refdoc))
+
+
+
+
+
+def main():
+ if not os.path.exists(SRC):
+ print "Unable to find %s, please run this script from the root wxPython directory." % SRC
+ sys.exit(1)
+
+ newDoc = libxml2.newDoc("1.0")
+ newTopNode = libxml2.newNode("wxPython-metadata")
+ newDoc.addChild(newTopNode)
+
+ for m in getModuleNames():
+ processModule(newTopNode, m)
+
+ newDoc.saveFormatFile(DEST, True)
+
+
+#---------------------------------------------------------------------------
+
+if __name__ == "__main__":
+ main()
--- /dev/null
+<?xml version="1.0"?>
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:strip-space elements="*" />
+<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />
+
+
+<!-- Stuff to ignore (ignored because the rules don't do anything) -->
+<xsl:template match="/top/attributelist" />
+<xsl:template match="include/attributelist" />
+<xsl:template match="namespace" />
+<xsl:template match="typemap" />
+<xsl:template match="typemapcopy" />
+<xsl:template match="insert" />
+<xsl:template match="fragment" />
+<xsl:template match="constant" />
+<xsl:template match="import" />
+
+
+<!-- Wrap the whole thing in a top level element -->
+<xsl:template match="/">
+ <xsl:element name="module">
+ <xsl:attribute name="name"><xsl:value-of select="top/attributelist/attribute[@name='module']/@value"/></xsl:attribute>
+ <xsl:apply-templates />
+ </xsl:element>
+</xsl:template>
+
+
+
+<xsl:template match="/top/include/import/module">
+ <xsl:element name="import">
+ <xsl:attribute name="name"><xsl:value-of select="./attributelist/attribute[@name='name']/@value"/></xsl:attribute>
+ </xsl:element>
+</xsl:template>
+
+
+<!-- A callable template that outputs the various docstrings for the current node -->
+<xsl:template name="DoDocstrings">
+ <xsl:if test="./attributelist/attribute[@name='python_autodoc' and @value!='']">
+ <xsl:element name="autodoc"><xsl:value-of select="./attributelist/attribute[@name='python_autodoc']/@value"/></xsl:element>
+ </xsl:if>
+ <xsl:if test="./attributelist/attribute[@name='feature_docstring' and @value!='']">
+ <xsl:element name="docstring"><xsl:value-of select="./attributelist/attribute[@name='feature_docstring']/@value"/></xsl:element>
+ </xsl:if>
+ <xsl:if test="./attributelist/attribute[@name='feature_refdoc' and @value!='']">
+ <xsl:element name="refdoc"><xsl:value-of select="./attributelist/attribute[@name='feature_refdoc']/@value"/></xsl:element>
+ </xsl:if>
+</xsl:template>
+
+
+<!-- A callable template that handles parameter lists -->
+<xsl:template name="DoParamList">
+ <xsl:if test="attributelist/parmlist">
+ <xsl:element name="paramlist">
+ <xsl:for-each select="attributelist/parmlist/parm">
+ <xsl:element name="param">
+ <xsl:attribute name="name"><xsl:value-of select="./attributelist/attribute[@name='name']/@value"/></xsl:attribute>
+ <xsl:attribute name="type"><xsl:value-of select="./attributelist/attribute[@name='type']/@value"/></xsl:attribute>
+ <xsl:attribute name="default"><xsl:value-of select="./attributelist/attribute[@name='value']/@value"/></xsl:attribute>
+ </xsl:element>
+ </xsl:for-each>
+ </xsl:element>
+ </xsl:if>
+</xsl:template>
+
+
+<!-- Check for overloaded methods -->
+<xsl:template name="CheckOverloaded">
+ <xsl:choose>
+ <xsl:when test="./attributelist/attribute[@name='sym_overloaded']">
+ <xsl:attribute name="overloaded">yes</xsl:attribute>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:attribute name="overloaded">no</xsl:attribute>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+
+<!-- A callable template that handles functions, methods, etc. -->
+<xsl:template name="DoFunction">
+ <xsl:attribute name="name"><xsl:value-of select="./attributelist/attribute[@name='sym_name']/@value"/></xsl:attribute>
+ <!-- <xsl:attribute name="returntype"><xsl:value-of select="./attributelist/attribute[@name='type']/@value"/></xsl:attribute> -->
+ <xsl:call-template name="CheckOverloaded" />
+ <xsl:call-template name="DoDocstrings" />
+ <xsl:call-template name="DoParamList" />
+</xsl:template>
+
+
+
+
+<!-- Create a class element with doc sub elements taken from the attributelist -->
+<xsl:template match="class">
+ <xsl:element name="class">
+
+ <xsl:attribute name="name">
+ <xsl:value-of select="./attributelist/attribute[@name='sym_name']/@value"/>
+ </xsl:attribute>
+ <xsl:attribute name="oldname">
+ <xsl:value-of select="./attributelist/attribute[@name='name']/@value"/>
+ </xsl:attribute>
+
+ <xsl:attribute name="module">
+ <xsl:value-of select="./attributelist/attribute[@name='module']/@value"/>
+ </xsl:attribute>
+
+ <xsl:call-template name="DoDocstrings" />
+ <xsl:apply-templates />
+
+ </xsl:element>
+</xsl:template>
+
+<xsl:template match="base">
+ <xsl:element name="baseclass">
+ <xsl:attribute name="name">
+ <xsl:value-of select="@name"/>
+ </xsl:attribute>
+ </xsl:element>
+</xsl:template>
+
+
+<!-- constructor -->
+<xsl:template match="constructor">
+ <xsl:element name="constructor">
+ <xsl:attribute name="name">
+ <xsl:value-of select="./attributelist/attribute[@name='sym_name']/@value"/>
+ </xsl:attribute>
+ <xsl:call-template name="CheckOverloaded" />
+
+ <xsl:call-template name="DoDocstrings" />
+ <xsl:call-template name="DoParamList" />
+
+ </xsl:element>
+</xsl:template>
+
+
+<!-- destructor -->
+<xsl:template match="destructor">
+ <xsl:element name="destructor">
+
+ <xsl:attribute name="name">
+ <xsl:value-of select="./attributelist/attribute[@name='sym_name']/@value"/>
+ </xsl:attribute>
+
+ <xsl:call-template name="DoDocstrings" />
+ <xsl:call-template name="DoParamList" />
+
+ </xsl:element>
+</xsl:template>
+
+
+<!-- cdecls: can be functions, methods, properties, etc. -->
+<xsl:template match="cdecl">
+ <xsl:choose>
+ <!-- method -->
+ <xsl:when test="./attributelist/attribute[@name='view' and @value='memberfunctionHandler']">
+ <xsl:element name="method">
+ <xsl:call-template name="DoFunction" />
+ </xsl:element>
+ </xsl:when>
+
+ <!-- staticmethod -->
+ <xsl:when test="./attributelist/attribute[@name='view' and @value='staticmemberfunctionHandler']">
+ <xsl:element name="staticmethod">
+ <xsl:call-template name="DoFunction" />
+ </xsl:element>
+ </xsl:when>
+
+ <!-- property -->
+ <xsl:when test="./attributelist/attribute[@name='view' and @value='variableHandler']">
+ <xsl:element name="property">
+ <xsl:attribute name="name">
+ <xsl:value-of select="./attributelist/attribute[@name='sym_name']/@value"/>
+ </xsl:attribute>
+ <xsl:attribute name="type">
+ <xsl:value-of select="./attributelist/attribute[@name='type']/@value"/>
+ </xsl:attribute>
+ <xsl:choose>
+ <xsl:when test="./attributelist/attribute[@name='feature_immutable']">
+ <xsl:attribute name="readonly">yes</xsl:attribute>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:attribute name="readonly">no</xsl:attribute>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:call-template name="DoDocstrings" />
+ </xsl:element>
+ </xsl:when>
+
+ <!-- global function -->
+ <xsl:when test="./attributelist/attribute[@name='view' and @value='globalfunctionHandler']">
+ <xsl:element name="function">
+ <xsl:attribute name="oldname">
+ <xsl:value-of select="./attributelist/attribute[@name='name']/@value"/>
+ </xsl:attribute>
+ <xsl:call-template name="DoFunction" />
+ </xsl:element>
+ </xsl:when>
+
+ </xsl:choose>
+</xsl:template>
+
+
+<!-- %pythoncode directives -->
+<xsl:template match="insert">
+ <xsl:if test="./attributelist/attribute[@name='section' and @value='python']">
+ <xsl:element name="pythoncode">
+ <xsl:value-of select="./attributelist/attribute[@name='code']/@value"/>
+ </xsl:element>
+ </xsl:if>
+</xsl:template>
+
+
+</xsl:stylesheet>
+