comparison markup/template.py @ 23:d88358f719fa trunk

Separate match and eval filters from the include and user-supplied filters.
author cmlenz
date Tue, 20 Jun 2006 17:31:32 +0000
parents 2483fe549959
children b4f78c05e5c9
comparison
equal deleted inserted replaced
22:2483fe549959 23:d88358f719fa
585 if basedir and filename: 585 if basedir and filename:
586 self.filepath = os.path.join(basedir, filename) 586 self.filepath = os.path.join(basedir, filename)
587 else: 587 else:
588 self.filepath = '<string>' 588 self.filepath = '<string>'
589 589
590 self.filters = [self._eval, self._match] 590 self.filters = []
591 self.parse() 591 self.parse()
592 592
593 def __repr__(self): 593 def __repr__(self):
594 return '<%s "%s">' % (self.__class__.__name__, self.filename) 594 return '<%s "%s">' % (self.__class__.__name__, self.filename)
595 595
690 if patterns: 690 if patterns:
691 for result in _interpolate(group): 691 for result in _interpolate(group):
692 yield result 692 yield result
693 else: 693 else:
694 yield Stream.TEXT, group.replace('$$', '$'), \ 694 yield Stream.TEXT, group.replace('$$', '$'), \
695 (lineno, offset) 695 (filename, lineno, offset)
696 return _interpolate(text) 696 return _interpolate(text)
697 _interpolate = classmethod(_interpolate) 697 _interpolate = classmethod(_interpolate)
698 698
699 def generate(self, ctxt=None): 699 def generate(self, ctxt=None):
700 """Transform the template based on the given context data.""" 700 """Transform the template based on the given context data."""
701 if ctxt is None: 701 if ctxt is None:
702 ctxt = Context() 702 ctxt = Context()
703 if not hasattr(ctxt, '_match_templates'): 703 if not hasattr(ctxt, '_match_templates'):
704 ctxt._match_templates = [] 704 ctxt._match_templates = []
705 705
706 return Stream(self._flatten(self.stream, ctxt)) 706 stream = self._match(self._eval(self.stream, ctxt), ctxt)
707 return Stream(self._flatten(stream, ctxt))
707 708
708 def _eval(self, stream, ctxt=None): 709 def _eval(self, stream, ctxt=None):
709 for kind, data, pos in stream: 710 for kind, data, pos in stream:
710 711
711 if kind is Stream.START: 712 if kind is Stream.START:
724 else: 725 else:
725 values.append(subdata) 726 values.append(subdata)
726 value = filter(lambda x: x is not None, values) 727 value = filter(lambda x: x is not None, values)
727 if not value: 728 if not value:
728 continue 729 continue
729 new_attrib.append((name, ''.join(value))) 730 new_attrib.append((name, u''.join(value)))
730 yield kind, (tag, Attributes(new_attrib)), pos 731 yield kind, (tag, Attributes(new_attrib)), pos
731 732
732 elif kind is Template.EXPR: 733 elif kind is Template.EXPR:
733 result = data.evaluate(ctxt) 734 result = data.evaluate(ctxt)
734 if result is None: 735 if result is None:
736 737
737 # First check for a string, otherwise the iterable test below 738 # First check for a string, otherwise the iterable test below
738 # succeeds, and the string will be chopped up into individual 739 # succeeds, and the string will be chopped up into individual
739 # characters 740 # characters
740 if isinstance(result, basestring): 741 if isinstance(result, basestring):
741 yield Stream.TEXT, result, pos 742 yield Stream.TEXT, unicode(result), pos
742 else: 743 else:
743 # Test if the expression evaluated to an iterable, in which 744 # Test if the expression evaluated to an iterable, in which
744 # case we yield the individual items 745 # case we yield the individual items
745 try: 746 try:
746 yield (Template.SUB, ([], iter(result)), pos) 747 yield (Template.SUB, ([], iter(result)), pos)
750 yield Stream.TEXT, unicode(result), pos 751 yield Stream.TEXT, unicode(result), pos
751 752
752 else: 753 else:
753 yield kind, data, pos 754 yield kind, data, pos
754 755
755 def _flatten(self, stream, ctxt=None, apply_filters=True): 756 def _flatten(self, stream, ctxt=None):
756 if apply_filters: 757 for filter_ in self.filters:
757 for filter_ in self.filters: 758 stream = filter_(iter(stream), ctxt)
758 stream = filter_(iter(stream), ctxt)
759 try: 759 try:
760 for kind, data, pos in stream: 760 for kind, data, pos in stream:
761 if kind is Template.SUB: 761 if kind is Template.SUB:
762 # This event is a list of directives and a list of 762 # This event is a list of directives and a list of
763 # nested events to which those directives should be 763 # nested events to which those directives should be
764 # applied 764 # applied
765 directives, substream = data 765 directives, substream = data
766 directives.reverse() 766 directives.reverse()
767 for directive in directives: 767 for directive in directives:
768 substream = directive(iter(substream), ctxt) 768 substream = directive(iter(substream), ctxt)
769 substream = self._match(self._eval(substream, ctxt), ctxt)
769 for event in self._flatten(substream, ctxt): 770 for event in self._flatten(substream, ctxt):
770 yield event 771 yield event
771 continue 772 continue
772 else: 773 else:
773 yield kind, data, pos 774 yield kind, data, pos
806 content.append(event) 807 content.append(event)
807 808
808 # enable the path to keep track of the stream state 809 # enable the path to keep track of the stream state
809 test(*event) 810 test(*event)
810 811
811 content = list(self._flatten(content, ctxt, False)) 812 content = list(self._flatten(content, ctxt))
812 813
813 def _apply(stream, ctxt): 814 def _apply(stream, ctxt):
814 stream = list(stream)
815 ctxt.push(select=lambda path: Stream(stream).select(path)) 815 ctxt.push(select=lambda path: Stream(stream).select(path))
816 for event in template: 816 for event in template:
817 yield event 817 yield event
818 ctxt.pop() 818 ctxt.pop()
819 819
Copyright (C) 2012-2017 Edgewall Software