Mercurial > genshi > mirror
comparison markup/template.py @ 77:f5ec6d4a61e4 trunk
* Simplify implementation of the individual XPath tests (use closures instead of callable classes)
* Add support for using `select("@*")` in `py:attrs` directives (#10).
author | cmlenz |
---|---|
date | Thu, 13 Jul 2006 12:32:11 +0000 |
parents | 3722696d0343 |
children | 46fed54f23cd |
comparison
equal
deleted
inserted
replaced
76:85f70ec37112 | 77:f5ec6d4a61e4 |
---|---|
222 def _generate(): | 222 def _generate(): |
223 kind, (tag, attrib), pos = stream.next() | 223 kind, (tag, attrib), pos = stream.next() |
224 attrs = self.expr.evaluate(ctxt) | 224 attrs = self.expr.evaluate(ctxt) |
225 if attrs: | 225 if attrs: |
226 attrib = Attributes(attrib[:]) | 226 attrib = Attributes(attrib[:]) |
227 if not isinstance(attrs, list): # assume it's a dict | 227 if isinstance(attrs, Stream): |
228 try: | |
229 attrs = iter(attrs).next() | |
230 except StopIteration: | |
231 attrs = [] | |
232 elif not isinstance(attrs, list): # assume it's a dict | |
228 attrs = attrs.items() | 233 attrs = attrs.items() |
229 for name, value in attrs: | 234 for name, value in attrs: |
230 if value is None: | 235 if value is None: |
231 attrib.remove(name) | 236 attrib.remove(name) |
232 else: | 237 else: |
233 attrib.set(name, unicode(value).strip()) | 238 attrib.set(name, unicode(value).strip()) |
234 yield kind, (tag, attrib), pos | 239 yield kind, (tag, attrib), pos |
235 for event in stream: | 240 for event in stream: |
236 yield event | 241 yield event |
242 | |
237 return self._apply_directives(_generate(), ctxt, directives) | 243 return self._apply_directives(_generate(), ctxt, directives) |
238 | 244 |
239 | 245 |
240 class ContentDirective(Directive): | 246 class ContentDirective(Directive): |
241 """Implementation of the `py:content` template directive. | 247 """Implementation of the `py:content` template directive. |
797 stream = self.stream | 803 stream = self.stream |
798 for filter_ in [self._eval, self._match, self._flatten] + self.filters: | 804 for filter_ in [self._eval, self._match, self._flatten] + self.filters: |
799 stream = filter_(iter(stream), ctxt) | 805 stream = filter_(iter(stream), ctxt) |
800 return Stream(stream) | 806 return Stream(stream) |
801 | 807 |
808 def _ensure(self, stream, ctxt=None): | |
809 """Ensure that every item on the stream is actually a markup event.""" | |
810 for event in stream: | |
811 try: | |
812 kind, data, pos = event | |
813 except ValueError: | |
814 kind, data, pos = event.totuple() | |
815 yield kind, data, pos | |
816 | |
802 def _eval(self, stream, ctxt=None): | 817 def _eval(self, stream, ctxt=None): |
803 """Internal stream filter that evaluates any expressions in `START` and | 818 """Internal stream filter that evaluates any expressions in `START` and |
804 `TEXT` events. | 819 `TEXT` events. |
805 """ | 820 """ |
806 for kind, data, pos in stream: | 821 for kind, data, pos in stream: |
838 yield TEXT, result, pos | 853 yield TEXT, result, pos |
839 else: | 854 else: |
840 # Test if the expression evaluated to an iterable, in which | 855 # Test if the expression evaluated to an iterable, in which |
841 # case we yield the individual items | 856 # case we yield the individual items |
842 try: | 857 try: |
843 for event in self._match(self._eval(iter(result), ctxt), | 858 substream = iter(result) |
844 ctxt): | 859 for filter_ in [self._ensure, self._eval, self._match]: |
860 substream = filter_(substream, ctxt) | |
861 for event in substream: | |
845 yield event | 862 yield event |
846 except TypeError: | 863 except TypeError: |
847 # Neither a string nor an iterable, so just pass it | 864 # Neither a string nor an iterable, so just pass it |
848 # through | 865 # through |
849 yield TEXT, unicode(result), pos | 866 yield TEXT, unicode(result), pos |