comparison markup/builder.py @ 133:79f445396cd7 trunk

Minor cleanup and performance improvement for the builder module.
author cmlenz
date Sun, 06 Aug 2006 17:10:47 +0000
parents cc2aee07f53b
children 2f30ce3fb85e
comparison
equal deleted inserted replaced
132:dc42cb3c02dc 133:79f445396cd7
9 # 9 #
10 # This software consists of voluntary contributions made by many 10 # This software consists of voluntary contributions made by many
11 # individuals. For the exact contribution history, see the revision 11 # individuals. For the exact contribution history, see the revision
12 # history and logs, available at http://markup.edgewall.org/log/. 12 # history and logs, available at http://markup.edgewall.org/log/.
13 13
14 from markup.core import Attributes, Namespace, QName, Stream, escape 14 from markup.core import Attributes, Namespace, QName, Stream, START, END, TEXT
15 15
16 __all__ = ['Fragment', 'Element', 'tag'] 16 __all__ = ['Fragment', 'Element', 'tag']
17 17
18 18
19 class Fragment(object): 19 class Fragment(object):
27 27
28 def __add__(self, other): 28 def __add__(self, other):
29 return Fragment()(self, other) 29 return Fragment()(self, other)
30 30
31 def __call__(self, *args): 31 def __call__(self, *args):
32 for arg in args: 32 map(self.append, args)
33 self.append(arg)
34 return self 33 return self
35 34
36 def __iter__(self): 35 def __iter__(self):
37 return self._generate() 36 return self._generate()
38 37
50 if isinstance(node, (Element, basestring, int, float, long)): 49 if isinstance(node, (Element, basestring, int, float, long)):
51 # For objects of a known/primitive type, we avoid the check for 50 # For objects of a known/primitive type, we avoid the check for
52 # whether it is iterable for better performance 51 # whether it is iterable for better performance
53 self.children.append(node) 52 self.children.append(node)
54 elif isinstance(node, Fragment): 53 elif isinstance(node, Fragment):
55 self.children += node.children 54 self.children.extend(node.children)
56 elif node is not None: 55 elif node is not None:
57 try: 56 try:
58 children = iter(node) 57 map(self.append, iter(node))
59 except TypeError: 58 except TypeError:
60 self.children.append(node) 59 self.children.append(node)
61 else:
62 for child in children:
63 self.append(child)
64 60
65 def _generate(self): 61 def _generate(self):
66 for child in self.children: 62 for child in self.children:
67 if isinstance(child, Fragment): 63 if isinstance(child, Fragment):
68 for event in child._generate(): 64 for event in child._generate():
69 yield event 65 yield event
70 else: 66 else:
71 if not isinstance(child, basestring): 67 if not isinstance(child, basestring):
72 child = unicode(child) 68 child = unicode(child)
73 yield Stream.TEXT, child, (None, -1, -1) 69 yield TEXT, child, (None, -1, -1)
74 70
75 def generate(self): 71 def generate(self):
76 """Return a markup event stream for the fragment.""" 72 """Return a markup event stream for the fragment."""
77 return Stream(self._generate()) 73 return Stream(self._generate())
78 74
160 156
161 def __init__(self, tag_, **attrib): 157 def __init__(self, tag_, **attrib):
162 Fragment.__init__(self) 158 Fragment.__init__(self)
163 self.tag = QName(tag_) 159 self.tag = QName(tag_)
164 self.attrib = Attributes() 160 self.attrib = Attributes()
165 self(**attrib) 161 for attr, value in attrib.items():
162 if value is not None:
163 if not isinstance(value, basestring):
164 value = unicode(value)
165 self.attrib.append((QName(attr.rstrip('_').replace('_', '-')),
166 value))
166 167
167 def __call__(self, *args, **kwargs): 168 def __call__(self, *args, **kwargs):
168 for attr, value in kwargs.items(): 169 for attr, value in kwargs.items():
169 if value is None: 170 if value is not None:
170 continue 171 if not isinstance(value, basestring):
171 attr = attr.rstrip('_').replace('_', '-') 172 value = unicode(value)
172 self.attrib.set(attr, escape(value)) 173 self.attrib.set(attr.rstrip('_').replace('_', '-'), value)
173 Fragment.__call__(self, *args) 174 Fragment.__call__(self, *args)
174 return self 175 return self
175 176
176 def __repr__(self): 177 def __repr__(self):
177 return '<%s "%s">' % (self.__class__.__name__, self.tag) 178 return '<%s "%s">' % (self.__class__.__name__, self.tag)
178 179
179 def _generate(self): 180 def _generate(self):
180 attrib = Attributes() 181 yield START, (self.tag, self.attrib), (None, -1, -1)
181 for attr, value in self.attrib:
182 if not isinstance(value, basestring):
183 value = unicode(value)
184 attrib.append((attr, value))
185 yield Stream.START, (self.tag, attrib), (None, -1, -1)
186 for kind, data, pos in Fragment._generate(self): 182 for kind, data, pos in Fragment._generate(self):
187 yield kind, data, pos 183 yield kind, data, pos
188 yield Stream.END, self.tag, (None, -1, -1) 184 yield END, self.tag, (None, -1, -1)
189 185
190 def generate(self): 186 def generate(self):
191 """Return a markup event stream for the fragment.""" 187 """Return a markup event stream for the fragment."""
192 return Stream(self._generate()) 188 return Stream(self._generate())
193 189
Copyright (C) 2012-2017 Edgewall Software