1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/libxml2dom/macrolib.py Fri Jan 14 15:39:03 2005 +0000
1.3 @@ -0,0 +1,116 @@
1.4 +#!/usr/bin/env python
1.5 +
1.6 +"""
1.7 +DOM macros for libxml2.
1.8 +"""
1.9 +
1.10 +__version__ = "0.1.2"
1.11 +
1.12 +import xml.dom
1.13 +import libxml2
1.14 +import sys
1.15 +
1.16 +# NOTE: libxml2 seems to use UTF-8 throughout.
1.17 +
1.18 +def from_unicode(s):
1.19 + if type(s) == type(u""):
1.20 + return s.encode("utf-8")
1.21 + else:
1.22 + return s
1.23 +
1.24 +def to_unicode(s):
1.25 + if type(s) == type(""):
1.26 + return unicode(s, encoding="utf-8")
1.27 + else:
1.28 + return s
1.29 +
1.30 +_nodeTypes = {
1.31 + "attribute" : xml.dom.Node.ATTRIBUTE_NODE,
1.32 + "comment" : xml.dom.Node.COMMENT_NODE,
1.33 + "document_xml" : xml.dom.Node.DOCUMENT_NODE,
1.34 + "doctype" : xml.dom.Node.DOCUMENT_TYPE_NODE,
1.35 + "dtd" : xml.dom.Node.DOCUMENT_TYPE_NODE, # NOTE: Needs verifying.
1.36 + "element" : xml.dom.Node.ELEMENT_NODE,
1.37 + "entity" : xml.dom.Node.ENTITY_NODE,
1.38 + "entity_ref" : xml.dom.Node.ENTITY_REFERENCE_NODE,
1.39 + "notation" : xml.dom.Node.NOTATION_NODE,
1.40 + "pi" : xml.dom.Node.PROCESSING_INSTRUCTION_NODE,
1.41 + "text" : xml.dom.Node.TEXT_NODE
1.42 + }
1.43 +
1.44 +def Node_nodeType(node):
1.45 + global _nodesTypes
1.46 + return _nodeTypes[node.type]
1.47 +
1.48 +def Node_childNodes(node):
1.49 +
1.50 + # NOTE: Consider a generator instead.
1.51 +
1.52 + child_nodes = []
1.53 + node = node.children
1.54 + while node is not None:
1.55 + child_nodes.append(node)
1.56 + node = node.next
1.57 + return child_nodes
1.58 +
1.59 +def _getNs(node):
1.60 +
1.61 + "Internal namespace information retrieval."
1.62 +
1.63 + try:
1.64 + return node.ns()
1.65 + except libxml2.treeError:
1.66 + return None
1.67 +
1.68 +def Node_namespaceURI(node):
1.69 + ns = _getNs(node)
1.70 + if ns is not None:
1.71 + return to_unicode(ns.content)
1.72 + else:
1.73 + return None
1.74 +
1.75 +def Node_nodeValue(node):
1.76 + return to_unicode(node.content)
1.77 +
1.78 +def Node_prefix(node):
1.79 + ns = _getNs(node)
1.80 + if ns is not None:
1.81 + return to_unicode(ns.name)
1.82 + else:
1.83 + return None
1.84 +
1.85 +def Node_nodeName(node):
1.86 + prefix = Node_prefix(node)
1.87 + if prefix is not None:
1.88 + return prefix + ":" + Node_localName(node)
1.89 + else:
1.90 + return Node_localName(node)
1.91 +
1.92 +def Node_tagName(node):
1.93 + if node.type == "element":
1.94 + return Node_nodeName(node)
1.95 + else:
1.96 + return None
1.97 +
1.98 +def Node_localName(node):
1.99 + return to_unicode(node.name)
1.100 +
1.101 +def Node_parentNode(node):
1.102 + if node.type == "document_xml":
1.103 + return None
1.104 + else:
1.105 + return node.parent
1.106 +
1.107 +def Node_previousSibling(node):
1.108 + if node.prev is not None:
1.109 + return node.prev
1.110 + else:
1.111 + return None
1.112 +
1.113 +def Node_nextSibling(node):
1.114 + if node.next is not None:
1.115 + return node.next
1.116 + else:
1.117 + return None
1.118 +
1.119 +# vim: tabstop=4 expandtab shiftwidth=4
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/libxml2macro.py Fri Jan 14 15:39:03 2005 +0000
2.3 @@ -0,0 +1,78 @@
2.4 +#!/usr/bin/env python
2.5 +
2.6 +import compiler
2.7 +
2.8 +def process_nodes(root_node, prefix):
2.9 +
2.10 + """
2.11 + Under the 'root_node', process all suitable expression nodes which employ
2.12 + Name nodes using the given 'prefix'.
2.13 + """
2.14 +
2.15 + for node in root_node.getChildNodes():
2.16 + # Identify suitable names and add such nodes
2.17 + if isinstance(node, compiler.ast.CallFunc):
2.18 + process_callfunc(node, prefix)
2.19 + elif isinstance(node, compiler.ast.Getattr):
2.20 + process_getattr(node, prefix, root_node)
2.21 + else:
2.22 + process_nodes(node, prefix)
2.23 +
2.24 +def process_callfunc(node, prefix):
2.25 + # Check the target.
2.26 + target = node.node
2.27 + if isinstance(target, compiler.ast.Getattr):
2.28 + process_getattr(target, prefix, node)
2.29 + else:
2.30 + process_nodes(node, prefix)
2.31 +
2.32 +def process_getattr(node, prefix, parent):
2.33 + # Check the target.
2.34 + target = node.expr
2.35 + if isinstance(target, compiler.ast.Name) and target.name.startswith(prefix):
2.36 +
2.37 + # Replace CallFunc plus Getattr occurrences:
2.38 + # node.attr(args) -> Node_attr(node, args)
2.39 +
2.40 + if isinstance(parent, compiler.ast.CallFunc):
2.41 + parent.node = compiler.ast.Name("Node_%s" % node.attrname)
2.42 + parent.args.insert(0, compiler.ast.Name(target.name))
2.43 +
2.44 + # Replace plain Getattr nodes:
2.45 + # node.attr -> Node_attr(node)
2.46 + # NOTE: Nasty but necessary rewiring of the parent node required.
2.47 +
2.48 + else:
2.49 + replacement = compiler.ast.CallFunc(
2.50 + compiler.ast.Name("Node_%s" % node.attrname),
2.51 + [node.expr]
2.52 + )
2.53 + for key, value in parent.__dict__.items():
2.54 + # Detect lists.
2.55 + try:
2.56 + if node in value:
2.57 + index = value.index(node)
2.58 + value[index] = replacement
2.59 + except TypeError:
2.60 + if value is node:
2.61 + parent.__dict__[key] = replacement
2.62 + else:
2.63 + process_nodes(node, prefix)
2.64 +
2.65 +def process_file(filename, prefix="x2_"):
2.66 +
2.67 + """
2.68 + Process the module given by the specified 'filename'. The optional special
2.69 + 'prefix' marks those variables to be processed.
2.70 + """
2.71 +
2.72 + # Open the module as an AST.
2.73 +
2.74 + module = compiler.parseFile(filename)
2.75 +
2.76 + # Find references to special variables.
2.77 +
2.78 + process_nodes(module, prefix)
2.79 + return module
2.80 +
2.81 +# vim: tabstop=4 expandtab shiftwidth=4
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/macrotest.py Fri Jan 14 15:39:03 2005 +0000
3.3 @@ -0,0 +1,19 @@
3.4 +#!/usr/bin/env python
3.5 +
3.6 +"A test of macros."
3.7 +
3.8 +from libxml2dom.macrolib import *
3.9 +import libxml2
3.10 +import xml.dom
3.11 +import sys
3.12 +
3.13 +x2_d = libxml2.parseFile(sys.argv[1])
3.14 +x2_root = None
3.15 +for x2_n in x2_d.childNodes:
3.16 + if x2_n.nodeType == xml.dom.Node.ELEMENT_NODE:
3.17 + x2_root = x2_n
3.18 + break
3.19 +
3.20 +print x2_root.localName, x2_root.namespaceURI, x2_root.getAttributeNS(None, "xmlns")
3.21 +
3.22 +# vim: tabstop=4 expandtab shiftwidth=4