blob: 910b507944ebeb1f69bd16fdd92eb129d7c050b2 [file] [log] [blame]
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
"""
Useful transforms for dom objects.
"""
from __future__ import absolute_import
from . import dom
try:
from io import StringIO
except ImportError:
from cStringIO import StringIO
class Visitor:
def descend(self, node):
for child in node.children:
child.dispatch(self)
def node(self, node):
self.descend(node)
def leaf(self, leaf):
pass
class Identity:
def descend(self, node):
result = []
for child in node.children:
result.append(child.dispatch(self))
return result
def default(self, tag):
result = dom.Tag(tag.name, *tag.attrs)
result.extend(self.descend(tag))
return result
def tree(self, tree):
result = dom.Tree()
result.extend(self.descend(tree))
return result
def tag(self, tag):
return self.default(tag)
def leaf(self, leaf):
return leaf.__class__(leaf.data)
class Sexp(Identity):
def __init__(self):
self.stack = []
self.level = 0
self.out = ""
def open(self, s):
self.out += "(%s" % s
self.level += len(s) + 1
self.stack.append(s)
def line(self, s = ""):
self.out = self.out.rstrip()
self.out += "\n" + " "*self.level + s
def close(self):
s = self.stack.pop()
self.level -= len(s) + 1
self.out = self.out.rstrip()
self.out += ")"
def tree(self, tree):
self.open("+ ")
for child in tree.children:
self.line(); child.dispatch(self)
self.close()
def tag(self, tag):
self.open("Node(%s) " % tag.name)
for child in tag.children:
self.line(); child.dispatch(self)
self.close()
def leaf(self, leaf):
self.line("%s(%s)" % (leaf.__class__.__name__, leaf.data))
class Output:
def descend(self, node):
out = StringIO()
for child in node.children:
out.write(child.dispatch(self))
return out.getvalue()
def default(self, tag):
out = StringIO()
out.write("<%s" % tag.name)
for k, v in tag.attrs:
out.write(' %s="%s"' % (k, v))
out.write(">")
out.write(self.descend(tag))
if not tag.singleton:
out.write("</%s>" % tag.name)
return out.getvalue()
def tree(self, tree):
return self.descend(tree)
def tag(self, tag):
return self.default(tag)
def data(self, leaf):
return leaf.data
def entity(self, leaf):
return "&%s;" % leaf.data
def character(self, leaf):
raise Exception("TODO")
def comment(self, leaf):
return "<!-- %s -->" % leaf.data
class Empty(Output):
def tag(self, tag):
return self.descend(tag)
def data(self, leaf):
return ""
def entity(self, leaf):
return ""
def character(self, leaf):
return ""
def comment(self, leaf):
return ""
class Text(Empty):
def data(self, leaf):
return leaf.data
def entity(self, leaf):
return "&%s;" % leaf.data
def character(self, leaf):
# XXX: is this right?
return "&#%s;" % leaf.data