From 685d898512944add00640b6e37da89159ee4d9b5 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Tue, 23 Dec 2003 17:45:54 +0000 Subject: [PATCH] Added XML simplification scripts for generating the wxPython metadata xml. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@24980 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- wxPython/docs/.cvsignore | 1 + wxPython/docs/bin/simplify | 35 +++++ wxPython/docs/bin/simplify.py | 263 +++++++++++++++++++++++++++++++++ wxPython/docs/bin/simplify.xsl | 217 +++++++++++++++++++++++++++ 4 files changed, 516 insertions(+) create mode 100644 wxPython/docs/.cvsignore create mode 100755 wxPython/docs/bin/simplify create mode 100755 wxPython/docs/bin/simplify.py create mode 100644 wxPython/docs/bin/simplify.xsl diff --git a/wxPython/docs/.cvsignore b/wxPython/docs/.cvsignore new file mode 100644 index 0000000000..6f2a9b09da --- /dev/null +++ b/wxPython/docs/.cvsignore @@ -0,0 +1 @@ +xml-raw diff --git a/wxPython/docs/bin/simplify b/wxPython/docs/bin/simplify new file mode 100755 index 0000000000..663d0b6549 --- /dev/null +++ b/wxPython/docs/bin/simplify @@ -0,0 +1,35 @@ +#!/bin/bash +#---------------------------------------------------------------------- +# Uses simplify.xsl to convert the XML files output by SWIG to a +# simpler XML format that contains only the metadata that we are +# interested in. Converts all input files into a single output file. +#---------------------------------------------------------------------- + +if [ ! -d wxPython ]; then + echo "Please run this script from the root wxPython directory." + exit 1 +fi + + +XSLT=docs/bin/simplify.xsl +MODULES=`python -c "import sys,setup; [sys.stdout.write(e.name[1:]+' ') for e in setup.wxpExtensions]"` +DEST=docs/xml/wxPython-metadata.xml +SRC=docs/xml-raw + + +echo "Using: " $XSLT +echo "Writing to: " $DEST +echo "Modules: " $MODULES + + + +echo "" > $DEST +echo "" >> $DEST + +for m in $MODULES; do + F=$SRC/${m}_swig.xml + echo $F + xsltproc $XSLT $F >> $DEST +done + +echo "" >> $DEST diff --git a/wxPython/docs/bin/simplify.py b/wxPython/docs/bin/simplify.py new file mode 100755 index 0000000000..4997cdcae1 --- /dev/null +++ b/wxPython/docs/bin/simplify.py @@ -0,0 +1,263 @@ +#!/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 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 , + 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() diff --git a/wxPython/docs/bin/simplify.xsl b/wxPython/docs/bin/simplify.xsl new file mode 100644 index 0000000000..2084d4cb77 --- /dev/null +++ b/wxPython/docs/bin/simplify.xsl @@ -0,0 +1,217 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + yes + + + no + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + yes + + + no + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 2.45.2