comparison markup/template.py @ 208:835203f3b8fd

Cleanup the application of template processing steps (flatten, eval, match) so that they are only performed when necessary. Results in a small performance boost, and also fixes #35.
author cmlenz
date Tue, 29 Aug 2006 15:44:54 +0000
parents d122ff386411
children c0c70dc5bf95
comparison
equal deleted inserted replaced
207:0619a27f5e67 208:835203f3b8fd
913 assert isinstance(ctxt, Context) 913 assert isinstance(ctxt, Context)
914 else: 914 else:
915 ctxt = Context(**kwargs) 915 ctxt = Context(**kwargs)
916 916
917 stream = self.stream 917 stream = self.stream
918 for filter_ in [self._eval, self._match, self._flatten] + self.filters: 918 for filter_ in [self._flatten, self._eval, self._match] + self.filters:
919 stream = filter_(iter(stream), ctxt) 919 stream = filter_(iter(stream), ctxt)
920 return Stream(stream) 920 return Stream(stream)
921 921
922 def _eval(self, stream, ctxt=None): 922 def _eval(self, stream, ctxt=None):
923 """Internal stream filter that evaluates any expressions in `START` and 923 """Internal stream filter that evaluates any expressions in `START` and
924 `TEXT` events. 924 `TEXT` events.
925 """ 925 """
926 filters = (self._eval, self._match, self._flatten) 926 filters = (self._flatten, self._eval)
927 927
928 for kind, data, pos in stream: 928 for kind, data, pos in stream:
929 929
930 if kind is START and data[1]: 930 if kind is START and data[1]:
931 # Attributes may still contain expressions in start tags at 931 # Attributes may still contain expressions in start tags at
981 if kind is SUB: 981 if kind is SUB:
982 # This event is a list of directives and a list of nested 982 # This event is a list of directives and a list of nested
983 # events to which those directives should be applied 983 # events to which those directives should be applied
984 directives, substream = data 984 directives, substream = data
985 substream = _apply_directives(substream, ctxt, directives) 985 substream = _apply_directives(substream, ctxt, directives)
986 for filter_ in (self._eval, self._match, self._flatten): 986 for event in self._flatten(substream, ctxt):
987 substream = filter_(substream, ctxt)
988 for event in substream:
989 yield event 987 yield event
990 else: 988 else:
991 yield kind, data, pos 989 yield kind, data, pos
992 990
993 def _match(self, stream, ctxt=None, match_templates=None): 991 def _match(self, stream, ctxt=None, match_templates=None):
1007 1005
1008 for idx, (test, path, template, directives) in \ 1006 for idx, (test, path, template, directives) in \
1009 enumerate(match_templates): 1007 enumerate(match_templates):
1010 1008
1011 if test(kind, data, pos, ctxt) is True: 1009 if test(kind, data, pos, ctxt) is True:
1010
1011 # Let the remaining match templates know about the event so
1012 # they get a chance to update their internal state
1013 for test in [mt[0] for mt in match_templates[idx + 1:]]:
1014 test(kind, data, pos, ctxt)
1015
1012 # Consume and store all events until an end event 1016 # Consume and store all events until an end event
1013 # corresponding to this start event is encountered 1017 # corresponding to this start event is encountered
1014 content = [(kind, data, pos)] 1018 content = [(kind, data, pos)]
1015 depth = 1 1019 depth = 1
1020 stream = self._match(stream, ctxt)
1016 while depth > 0: 1021 while depth > 0:
1017 kind, data, pos = stream.next() 1022 kind, data, pos = stream.next()
1018 if kind is START: 1023 if kind is START:
1019 depth += 1 1024 depth += 1
1020 elif kind is END: 1025 elif kind is END:
1021 depth -= 1 1026 depth -= 1
1022 content.append((kind, data, pos)) 1027 content.append((kind, data, pos))
1023 test(kind, data, pos, ctxt) 1028
1024 1029 # Make the select() function available in the body of the
1025 content = list(self._flatten(content, ctxt)) 1030 # match template
1026 select = lambda path: Stream(content).select(path) 1031 def select(path):
1032 return Stream(content).select(path)
1027 ctxt.push(dict(select=select)) 1033 ctxt.push(dict(select=select))
1028 1034
1035 # Recursively process the output
1029 template = _apply_directives(template, ctxt, directives) 1036 template = _apply_directives(template, ctxt, directives)
1030 for event in self._match(self._eval(template, ctxt), 1037 for event in self._match(self._eval(template, ctxt),
1031 ctxt, match_templates[:idx] + 1038 ctxt, match_templates[:idx] +
1032 match_templates[idx + 1:]): 1039 match_templates[idx + 1:]):
1033 yield event 1040 yield event
Copyright (C) 2012-2017 Edgewall Software