sources for visit.py [rev. unknown]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# 
# a generic conversion serializer 
#
from py.xml import escape 
class SimpleUnicodeVisitor(object):
    """ recursive visitor to write unicode. """
    def __init__(self, write, indent=0, curindent=0, shortempty=True): 
        self.write = write
        self.cache = {}
        self.visited = {} # for detection of recursion
        self.indent = indent 
        self.curindent = curindent
        self.parents = []
        self.shortempty = shortempty  # short empty tags or not 
    def visit(self, node): 
        """ dispatcher on node's class/bases name. """
        cls = node.__class__
        try:
            visitmethod = self.cache[cls]   
        except KeyError:
            for subclass in cls.__mro__: 
                visitmethod = getattr(self, subclass.__name__, None)
                if visitmethod is not None:
                    break
            else:
                visitmethod = self.object 
            self.cache[cls] = visitmethod
        visitmethod(node) 
    def object(self, obj):
        #self.write(obj) 
        self.write(escape(unicode(obj)))
    def raw(self, obj):
        self.write(obj.uniobj) 
    def list(self, obj):  
        assert id(obj) not in self.visited
        self.visited[id(obj)] = 1
        map(self.visit, obj) 
    def Tag(self, tag):
        assert id(tag) not in self.visited
        try: 
            tag.parent = self.parents[-1]
        except IndexError: 
            tag.parent = None 
        self.visited[id(tag)] = 1
        tagname = getattr(tag, 'xmlname', tag.__class__.__name__)
        if self.curindent and not self._isinline(tagname):
            self.write("\n" + u' ' * self.curindent) 
        if tag:
            self.curindent += self.indent 
            self.write(u'<%s%s>' % (tagname, self.attributes(tag)))
            self.parents.append(tag) 
            map(self.visit, tag)
            self.parents.pop() 
            self.write(u'</%s>' % tagname) 
            self.curindent -= self.indent 
        else:
            nameattr = tagname+self.attributes(tag) 
            if self._issingleton(tagname): 
                self.write(u'<%s/>' % (nameattr,))
            else: 
                self.write(u'<%s></%s>' % (nameattr, tagname))
    def attributes(self, tag):
        # serialize attributes
        attrlist = dir(tag.attr) 
        attrlist.sort() 
        l = []
        for name in attrlist: 
            res = self.repr_attribute(tag.attr, name)
            if res is not None: 
                l.append(res) 
        l.extend(self.getstyle(tag))
        return u"".join(l)
    def repr_attribute(self, attrs, name): 
        if name[:2] != '__': 
            value = getattr(attrs, name) 
            if name.endswith('_'): 
                name = name[:-1]
            return u' %s="%s"' % (name, escape(unicode(value)))
    def getstyle(self, tag): 
        """ return attribute list suitable for styling. """ 
        try: 
            styledict = tag.style.__dict__
        except AttributeError: 
            return [] 
        else: 
            stylelist = [x+': ' + y for x,y in styledict.items()]
            return [u' style="%s"' % u'; '.join(stylelist)]
    def _issingleton(self, tagname):
        """can (and will) be overridden in subclasses"""
        return self.shortempty
    def _isinline(self, tagname):
        """can (and will) be overridden in subclasses"""
        return False