Mercurial > genshi > mirror
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 |