Exemplo n.º 1
0
    def __call__(self, stream, ctxt, directives):
        matched, frame = ctxt._find('_choose.matched')
        if not frame:
            raise TemplateRuntimeError(
                '"when" directives can only be used '
                'inside a "choose" directive', self.filename,
                *stream.next()[2][1:])
        if matched:
            return []
        if not self.expr and '_choose.value' not in frame:
            raise TemplateRuntimeError(
                'either "choose" or "when" directive '
                'must have a test expression', self.filename,
                *stream.next()[2][1:])
        if '_choose.value' in frame:
            value = frame['_choose.value']
            if self.expr:
                matched = value == self.expr.evaluate(ctxt)
            else:
                matched = bool(value)
        else:
            matched = bool(self.expr.evaluate(ctxt))
        frame['_choose.matched'] = matched
        if not matched:
            return []

        return _apply_directives(stream, ctxt, directives)
Exemplo n.º 2
0
 def __call__(self, stream, ctxt, directives):
     frame = dict({'_choose.matched': False})
     if self.expr:
         frame['_choose.value'] = self.expr.evaluate(ctxt)
     ctxt.push(frame)
     for event in _apply_directives(stream, ctxt, directives):
         yield event
     ctxt.pop()
Exemplo n.º 3
0
 def __call__(self, stream, ctxt, directives):
     frame = {}
     ctxt.push(frame)
     for targets, expr in self.vars:
         value = expr.evaluate(ctxt)
         for assign in targets:
             assign(frame, value)
     for event in _apply_directives(stream, ctxt, directives):
         yield event
     ctxt.pop()
Exemplo n.º 4
0
    def __call__(self, stream, ctxt, directives):
        matched, frame = ctxt._find('_choose.matched')
        if not frame:
            raise TemplateRuntimeError(
                'an "otherwise" directive can only be '
                'used inside a "choose" directive', self.filename,
                *stream.next()[2][1:])
        if matched:
            return []
        frame['_choose.matched'] = True

        return _apply_directives(stream, ctxt, directives)
Exemplo n.º 5
0
    def __call__(self, stream, ctxt, directives):
        def _generate():
            if self.expr.evaluate(ctxt):
                stream.next()  # skip start tag
                previous = stream.next()
                for event in stream:
                    yield previous
                    previous = event
            else:
                for event in stream:
                    yield event

        return _apply_directives(_generate(), ctxt, directives)
Exemplo n.º 6
0
    def __call__(self, stream, ctxt, directives):
        iterable = self.expr.evaluate(ctxt)
        if iterable is None:
            return

        assign = self.assign
        scope = {}
        stream = list(stream)
        try:
            iterator = iter(iterable)
            for item in iterator:
                assign(scope, item)
                ctxt.push(scope)
                for event in _apply_directives(stream, ctxt, directives):
                    yield event
                ctxt.pop()
        except TypeError, e:
            raise TemplateRuntimeError(str(e), self.filename,
                                       *stream[0][2][1:])
Exemplo n.º 7
0
 def function(*args, **kwargs):
     scope = {}
     args = list(args)  # make mutable
     for name in self.args:
         if args:
             scope[name] = args.pop(0)
         else:
             if name in kwargs:
                 val = kwargs.pop(name)
             else:
                 val = self.defaults.get(name).evaluate(ctxt)
             scope[name] = val
     if not self.star_args is None:
         scope[self.star_args] = args
     if not self.dstar_args is None:
         scope[self.dstar_args] = kwargs
     ctxt.push(scope)
     for event in _apply_directives(stream, ctxt, directives):
         yield event
     ctxt.pop()
Exemplo n.º 8
0
    def __call__(self, stream, ctxt, directives):
        def _generate():
            kind, (tag, attrib), pos = stream.next()
            attrs = self.expr.evaluate(ctxt)
            if attrs:
                if isinstance(attrs, Stream):
                    try:
                        attrs = iter(attrs).next()
                    except StopIteration:
                        attrs = []
                elif not isinstance(attrs, list):  # assume it's a dict
                    attrs = attrs.items()
                attrib -= [name for name, val in attrs if val is None]
                attrib |= [(QName(name), unicode(val).strip())
                           for name, val in attrs if val is not None]
            yield kind, (tag, attrib), pos
            for event in stream:
                yield event

        return _apply_directives(_generate(), ctxt, directives)
Exemplo n.º 9
0
 def __call__(self, stream, ctxt, directives):
     if self.expr.evaluate(ctxt):
         return _apply_directives(stream, ctxt, directives)
     return []
Exemplo n.º 10
0
    def _match(self, stream, ctxt, match_templates=None):
        """Internal stream filter that applies any defined match templates
        to the stream.
        """
        if match_templates is None:
            match_templates = ctxt._match_templates

        tail = []

        def _strip(stream):
            depth = 1
            while 1:
                event = stream.next()
                if event[0] is START:
                    depth += 1
                elif event[0] is END:
                    depth -= 1
                if depth > 0:
                    yield event
                else:
                    tail[:] = [event]
                    break

        for event in stream:

            # We (currently) only care about start and end events for matching
            # We might care about namespace events in the future, though
            if not match_templates or (event[0] is not START
                                       and event[0] is not END):
                yield event
                continue

            for idx, (test, path, template, namespaces, directives) in \
                    enumerate(match_templates):

                if test(event, namespaces, ctxt) is True:

                    # Let the remaining match templates know about the event so
                    # they get a chance to update their internal state
                    for test in [mt[0] for mt in match_templates[idx + 1:]]:
                        test(event, namespaces, ctxt, updateonly=True)

                    # Consume and store all events until an end event
                    # corresponding to this start event is encountered
                    content = chain([event],
                                    self._match(_strip(stream), ctxt,
                                                [match_templates[idx]]), tail)
                    content = list(self._include(content, ctxt))

                    for test in [mt[0] for mt in match_templates]:
                        test(tail[0], namespaces, ctxt, updateonly=True)

                    # Make the select() function available in the body of the
                    # match template
                    def select(path):
                        return Stream(content).select(path, namespaces, ctxt)

                    ctxt.push(dict(select=select))

                    # Recursively process the output
                    template = _apply_directives(template, ctxt, directives)
                    for event in self._match(
                            self._eval(self._flatten(template, ctxt),
                                       ctxt), ctxt,
                            match_templates[:idx] + match_templates[idx + 1:]):
                        yield event

                    ctxt.pop()
                    break

            else:  # no matches
                yield event