Exemplo n.º 1
0
    def __call__(self, stream, directives, ctxt, **vars):
        ctxt.push({'_i18n.choose.params': self.params,
                   '_i18n.choose.SingularDirective': None,
                   '_i18n.choose.PluralDirective': None})

        new_stream = []
        singular_stream = None
        singular_msgbuf = None
        plural_stream = None
        plural_msgbuf = None

        ngettext = ctxt.get('_i18n.ungettext')
        assert hasattr(ngettext, '__call__'), 'No ngettext function available'
        dngettext = ctxt.get('_i18n.dngettext')
        if not dngettext:
            dngettext = lambda d, s, p, n: ngettext(s, p, n)

        for kind, event, pos in stream:
            if kind is SUB:
                subdirectives, substream = event
                if isinstance(subdirectives[0],
                              SingularDirective) and not singular_stream:
                    # Apply directives to update context
                    singular_stream = list(_apply_directives(substream,
                                                             subdirectives,
                                                             ctxt, vars))
                    new_stream.append((MSGBUF, (), ('', -1))) # msgbuf place holder
                    singular_msgbuf = ctxt.get('_i18n.choose.SingularDirective')
                elif isinstance(subdirectives[0],
                                PluralDirective) and not plural_stream:
                    # Apply directives to update context
                    plural_stream = list(_apply_directives(substream,
                                                           subdirectives,
                                                           ctxt, vars))
                    plural_msgbuf = ctxt.get('_i18n.choose.PluralDirective')
                else:
                    new_stream.append((kind, event, pos))
            else:
                new_stream.append((kind, event, pos))

        if ctxt.get('_i18n.domain'):
            ngettext = lambda s, p, n: dngettext(ctxt.get('_i18n.domain'),
                                                 s, p, n)

        for kind, data, pos in new_stream:
            if kind is MSGBUF:
                for skind, sdata, spos in singular_stream:
                    if skind is MSGBUF:
                        translation = ngettext(singular_msgbuf.format(),
                                               plural_msgbuf.format(),
                                               self.numeral.evaluate(ctxt))
                        for event in singular_msgbuf.translate(translation):
                            yield event
                    else:
                        yield skind, sdata, spos
            else:
                yield kind, data, pos

        ctxt.pop()
Exemplo n.º 2
0
    def __call__(self, stream, directives, ctxt, **vars):
        ctxt.push({"_i18n.choose.params": self.params, "_i18n.choose.singular": None, "_i18n.choose.plural": None})

        ngettext = ctxt.get("_i18n.ngettext")
        assert hasattr(ngettext, "__call__"), "No ngettext function available"
        dngettext = ctxt.get("_i18n.dngettext")
        if not dngettext:
            dngettext = lambda d, s, p, n: ngettext(s, p, n)

        new_stream = []
        singular_stream = None
        singular_msgbuf = None
        plural_stream = None
        plural_msgbuf = None

        numeral = self.numeral.evaluate(ctxt)
        is_plural = self._is_plural(numeral, ngettext)

        for event in stream:
            if event[0] is SUB and any(isinstance(d, ChooseBranchDirective) for d in event[1][0]):
                subdirectives, substream = event[1]

                if isinstance(subdirectives[0], SingularDirective):
                    singular_stream = list(_apply_directives(substream, subdirectives, ctxt, vars))
                    new_stream.append((MSGBUF, None, (None, -1, -1)))

                elif isinstance(subdirectives[0], PluralDirective):
                    if is_plural:
                        plural_stream = list(_apply_directives(substream, subdirectives, ctxt, vars))

            else:
                new_stream.append(event)

        if ctxt.get("_i18n.domain"):
            ngettext = lambda s, p, n: dngettext(ctxt.get("_i18n.domain"), s, p, n)

        singular_msgbuf = ctxt.get("_i18n.choose.singular")
        if is_plural:
            plural_msgbuf = ctxt.get("_i18n.choose.plural")
            msgbuf, choice = plural_msgbuf, plural_stream
        else:
            msgbuf, choice = singular_msgbuf, singular_stream
            plural_msgbuf = MessageBuffer(self)

        for kind, data, pos in new_stream:
            if kind is MSGBUF:
                for event in choice:
                    if event[0] is MSGBUF:
                        translation = ngettext(singular_msgbuf.format(), plural_msgbuf.format(), numeral)
                        for subevent in msgbuf.translate(translation):
                            yield subevent
                    else:
                        yield event
            else:
                yield kind, data, pos

        ctxt.pop()
Exemplo n.º 3
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.º 4
0
    def __call__(self, stream, directives, ctxt, **vars):
        self.params = ctxt.get('_i18n.choose.params', [])[:]
        msgbuf = MessageBuffer(self)
        stream = _apply_directives(stream, directives, ctxt, vars)

        previous = stream.next()
        if previous[0] is START:
            yield previous
        else:
            msgbuf.append(*previous)

        try:
            previous = stream.next()
        except StopIteration:
            # For example <i18n:singular> or <i18n:plural> directives
            yield MSGBUF, (), -1  # the place holder for msgbuf output
            ctxt['_i18n.choose.%s' % self.tagname] = msgbuf
            return

        for event in stream:
            msgbuf.append(*previous)
            previous = event
        yield MSGBUF, (), -1  # the place holder for msgbuf output

        if previous[0] is END:
            yield previous  # the outer end tag
        else:
            msgbuf.append(*previous)
        ctxt['_i18n.choose.%s' % self.tagname] = msgbuf
Exemplo n.º 5
0
    def __call__(self, stream, directives, ctxt, **vars):
        info = ctxt._choice_stack and ctxt._choice_stack[-1]
        if not info:
            raise TemplateRuntimeError('"when" directives can only be used '
                                       'inside a "choose" directive',
                                       self.filename, *(next(stream))[2][1:])
        if info[0]:
            return []
        if not self.expr and not info[1]:
            raise TemplateRuntimeError('either "choose" or "when" directive '
                                       'must have a test expression',
                                       self.filename, *(next(stream))[2][1:])
        if info[1]:
            value = info[2]
            if self.expr:
                matched = value == _eval_expr(self.expr, ctxt, vars)
            else:
                matched = bool(value)
        else:
            matched = bool(_eval_expr(self.expr, ctxt, vars))
        info[0] = matched
        if not matched:
            return []

        return _apply_directives(stream, directives, ctxt, vars)
Exemplo n.º 6
0
    def __call__(self, stream, directives, ctxt, **vars):
        self.params = ctxt.get('_i18n.choose.params', [])[:]
        msgbuf = MessageBuffer(self)
        stream = _apply_directives(stream, directives, ctxt, vars)

        previous = stream.next()
        if previous[0] is START:
            yield previous
        else:
            msgbuf.append(*previous)

        try:
            previous = stream.next()
        except StopIteration:
            # For example <i18n:singular> or <i18n:plural> directives
            yield MSGBUF, (), -1 # the place holder for msgbuf output
            ctxt['_i18n.choose.%s' % self.tagname] = msgbuf
            return

        for event in stream:
            msgbuf.append(*previous)
            previous = event
        yield MSGBUF, (), -1 # the place holder for msgbuf output

        if previous[0] is END:
            yield previous # the outer end tag
        else:
            msgbuf.append(*previous)
        ctxt['_i18n.choose.%s' % self.tagname] = msgbuf
Exemplo n.º 7
0
    def __call__(self, stream, directives, ctxt, **vars):
        gettext = ctxt.get('_i18n.gettext')
        if ctxt.get('_i18n.domain'):
            dgettext = ctxt.get('_i18n.dgettext')
            assert hasattr(dgettext, '__call__'), \
                'No domain gettext function passed'
            gettext = lambda msg: dgettext(ctxt.get('_i18n.domain'), msg)

        def _generate():
            msgbuf = MessageBuffer(self)
            previous = stream.next()
            if previous[0] is START:
                yield previous
            else:
                msgbuf.append(*previous)
            previous = stream.next()
            for kind, data, pos in stream:
                msgbuf.append(*previous)
                previous = kind, data, pos
            if previous[0] is not END:
                msgbuf.append(*previous)
                previous = None
            for event in msgbuf.translate(gettext(msgbuf.format())):
                yield event
            if previous:
                yield previous

        return _apply_directives(_generate(), directives, ctxt, vars)
Exemplo n.º 8
0
    def __call__(self, stream, directives, ctxt, **vars):
        info = ctxt._choice_stack and ctxt._choice_stack[-1]
        if not info:
            raise TemplateRuntimeError('"when" directives can only be used '
                                       'inside a "choose" directive',
                                       self.filename, *stream.next()[2][1:])
        if info[0]:
            return []
        if not self.expr and not info[1]:
            raise TemplateRuntimeError('either "choose" or "when" directive '
                                       'must have a test expression',
                                       self.filename, *stream.next()[2][1:])
        if info[1]:
            value = info[2]
            if self.expr:
                matched = value == _eval_expr(self.expr, ctxt, vars)
            else:
                matched = bool(value)
        else:
            matched = bool(_eval_expr(self.expr, ctxt, vars))
        info[0] = matched
        if not matched:
            return []

        return _apply_directives(stream, directives, ctxt, vars)
Exemplo n.º 9
0
    def __call__(self, stream, directives, ctxt, **vars):
        gettext = ctxt.get('_i18n.gettext')
        if ctxt.get('_i18n.domain'):
            dgettext = ctxt.get('_i18n.dgettext')
            assert hasattr(dgettext, '__call__'), \
                'No domain gettext function passed'
            gettext = lambda msg: dgettext(ctxt.get('_i18n.domain'), msg)

        def _generate():
            msgbuf = MessageBuffer(self)
            previous = stream.next()
            if previous[0] is START:
                yield previous
            else:
                msgbuf.append(*previous)
            previous = stream.next()
            for kind, data, pos in stream:
                msgbuf.append(*previous)
                previous = kind, data, pos
            if previous[0] is not END:
                msgbuf.append(*previous)
                previous = None
            for event in msgbuf.translate(gettext(msgbuf.format())):
                yield event
            if previous:
                yield previous

        return _apply_directives(_generate(), directives, ctxt, vars)
Exemplo n.º 10
0
 def __call__(self, stream, directives, ctxt, **vars):
     info = [False, bool(self.expr), None]
     if self.expr:
         info[2] = _eval_expr(self.expr, ctxt, vars)
     ctxt._choice_stack.append(info)
     for event in _apply_directives(stream, directives, ctxt, vars):
         yield event
     ctxt._choice_stack.pop()
Exemplo n.º 11
0
 def __call__(self, stream, directives, ctxt, **vars):
     info = [False, bool(self.expr), None]
     if self.expr:
         info[2] = _eval_expr(self.expr, ctxt, vars)
     ctxt._choice_stack.append(info)
     for event in _apply_directives(stream, directives, ctxt, vars):
         yield event
     ctxt._choice_stack.pop()
Exemplo n.º 12
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.º 13
0
 def __call__(self, stream, directives, ctxt, **vars):
     frame = {}
     ctxt.push(frame)
     for targets, expr in self.vars:
         value = _eval_expr(expr, ctxt, vars)
         for assign in targets:
             assign(frame, value)
     for event in _apply_directives(stream, directives, ctxt, vars):
         yield event
     ctxt.pop()
Exemplo n.º 14
0
 def __call__(self, stream, directives, ctxt, **vars):
     frame = {}
     ctxt.push(frame)
     for targets, expr in self.vars:
         value = _eval_expr(expr, ctxt, vars)
         for assign in targets:
             assign(frame, value)
     for event in _apply_directives(stream, directives, ctxt, vars):
         yield event
     ctxt.pop()
Exemplo n.º 15
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.º 16
0
    def __call__(self, stream, directives, ctxt, **vars):
        info = ctxt._choice_stack and ctxt._choice_stack[-1]
        if not info:
            raise TemplateRuntimeError('an "otherwise" directive can only be '
                                       'used inside a "choose" directive',
                                       self.filename, *stream.next()[2][1:])
        if info[0]:
            return []
        info[0] = True

        return _apply_directives(stream, directives, ctxt, vars)
Exemplo n.º 17
0
    def __call__(self, stream, directives, ctxt, **vars):
        info = ctxt._choice_stack and ctxt._choice_stack[-1]
        if not info:
            raise TemplateRuntimeError('an "otherwise" directive can only be '
                                       'used inside a "choose" directive',
                                       self.filename, *(next(stream))[2][1:])
        if info[0]:
            return []
        info[0] = True

        return _apply_directives(stream, directives, ctxt, vars)
Exemplo n.º 18
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.º 19
0
 def __call__(self, stream, directives, ctxt, **vars):
     def _generate():
         if not self.expr or _eval_expr(self.expr, ctxt, vars):
             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(), directives, ctxt, vars)
Exemplo n.º 20
0
 def __call__(self, stream, directives, ctxt, **vars):
     def _generate():
         if not self.expr or _eval_expr(self.expr, ctxt, vars):
             next(stream) # skip start tag
             previous = next(stream)
             for event in stream:
                 yield previous
                 previous = event
         else:
             for event in stream:
                 yield event
     return _apply_directives(_generate(), directives, ctxt, vars)
Exemplo n.º 21
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.º 22
0
    def __call__(self, stream, directives, ctxt, **vars):
        self.params = ctxt.get('_i18n.choose.params', [])[:]
        msgbuf = MessageBuffer(self)

        stream = iter(_apply_directives(stream, directives, ctxt, vars))
        yield stream.next()  # the outer start tag
        previous = stream.next()
        for kind, data, pos in stream:
            msgbuf.append(*previous)
            previous = kind, data, pos
        yield MSGBUF, (), -1  # the place holder for msgbuf output
        yield previous  # the outer end tag
        ctxt['_i18n.choose.%s' % type(self).__name__] = msgbuf
Exemplo n.º 23
0
    def __call__(self, stream, directives, ctxt, **vars):
        self.params = ctxt.get('_i18n.choose.params', [])[:]
        msgbuf = MessageBuffer(self)

        stream = iter(_apply_directives(stream, directives, ctxt, vars))
        yield stream.next() # the outer start tag
        previous = stream.next()
        for kind, data, pos in stream:
            msgbuf.append(*previous)
            previous = kind, data, pos
        yield MSGBUF, (), -1 # the place holder for msgbuf output
        yield previous # the outer end tag
        ctxt['_i18n.choose.%s' % type(self).__name__] = msgbuf
Exemplo n.º 24
0
    def __call__(self, stream, directives, ctxt, **vars):
        iterable = _eval_expr(self.expr, ctxt, vars)
        if iterable is None:
            return

        assign = self.assign
        scope = {}
        stream = list(stream)
        for item in iterable:
            assign(scope, item)
            ctxt.push(scope)
            for event in _apply_directives(stream, directives, ctxt, vars):
                yield event
            ctxt.pop()
Exemplo n.º 25
0
    def __call__(self, stream, directives, ctxt, **vars):
        iterable = _eval_expr(self.expr, ctxt, vars)
        if iterable is None:
            return

        assign = self.assign
        scope = {}
        stream = list(stream)
        for item in iterable:
            assign(scope, item)
            ctxt.push(scope)
            for event in _apply_directives(stream, directives, ctxt, vars):
                yield event
            ctxt.pop()
Exemplo n.º 26
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
     ctxt.push(scope)
     for event in _apply_directives(stream, ctxt, directives):
         yield event
     ctxt.pop()
Exemplo n.º 27
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.º 28
0
    def __call__(self, stream, directives, ctxt, **vars):
        def _generate():
            kind, (tag, attrib), pos = stream.next()
            attrs = _eval_expr(self.expr, ctxt, vars)
            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 |= [(QName(n), v is not None and unicode(v).strip()
                            or None) for n, v in attrs]
            yield kind, (tag, attrib), pos
            for event in stream:
                yield event

        return _apply_directives(_generate(), directives, ctxt, vars)
Exemplo n.º 29
0
    def __call__(self, stream, directives, ctxt, **vars):
        def _generate():
            kind, (tag, attrib), pos  = stream.next()
            attrs = _eval_expr(self.expr, ctxt, vars)
            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(), directives, ctxt, vars)
Exemplo n.º 30
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 = _eval_expr(self.defaults.get(name), ctxt, vars)
             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, directives, ctxt, vars):
         yield event
     ctxt.pop()
Exemplo n.º 31
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 = _eval_expr(self.defaults.get(name), ctxt, vars)
             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, directives, ctxt, vars):
         yield event
     ctxt.pop()
Exemplo n.º 32
0
    def __call__(self, stream, directives, ctxt, **vars):
        def _generate():
            kind, (tag, attrib), pos  = next(stream)
            attrs = _eval_expr(self.expr, ctxt, vars)
            if attrs:
                if isinstance(attrs, Stream):
                    try:
                        attrs = next(iter(attrs))
                    except StopIteration:
                        attrs = []
                elif not isinstance(attrs, list): # assume it's a dict
                    attrs = list(attrs.items())
                attrib |= [
                    (QName(n), v is not None and str(v).strip() or None)
                    for n, v in attrs
                ]
            yield kind, (tag, attrib), pos
            for event in stream:
                yield event

        return _apply_directives(_generate(), directives, ctxt, vars)
Exemplo n.º 33
0
    def _match(self, stream, ctxt, start=0, end=None, **vars):
        """Internal stream filter that applies any defined match templates
        to the stream.
        """
        match_templates = ctxt._match_templates

        def _strip(stream, append):
            depth = 1
            next = stream.next
            while 1:
                event = next()
                if event[0] is START:
                    depth += 1
                elif event[0] is END:
                    depth -= 1
                if depth > 0:
                    yield event
                else:
                    append(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, hints, namespaces, directives) \
                    in enumerate(match_templates):
                if idx < start or end is not None and idx >= end:
                    continue

                if test(event, namespaces, ctxt) is True:
                    if 'match_once' in hints:
                        del match_templates[idx]
                        idx -= 1

                    # 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
                    pre_end = idx + 1
                    if 'match_once' not in hints and 'not_recursive' in hints:
                        pre_end -= 1
                    tail = []
                    inner = _strip(stream, tail.append)
                    if pre_end > 0:
                        inner = self._match(inner,
                                            ctxt,
                                            start=start,
                                            end=pre_end,
                                            **vars)
                    content = self._include(chain([event], inner, tail), ctxt)
                    if 'not_buffered' not in hints:
                        content = list(content)
                    content = Stream(content)

                    # Make the select() function available in the body of the
                    # match template
                    selected = [False]

                    def select(path):
                        selected[0] = True
                        return content.select(path, namespaces, ctxt)

                    vars = dict(select=select)

                    # Recursively process the output
                    template = _apply_directives(template, directives, ctxt,
                                                 vars)
                    for event in self._match(self._flatten(
                            template, ctxt, **vars),
                                             ctxt,
                                             start=idx + 1,
                                             **vars):
                        yield event

                    # If the match template did not actually call select to
                    # consume the matched stream, the original events need to
                    # be consumed here or they'll get appended to the output
                    if not selected[0]:
                        for event in content:
                            pass

                    # Let this match template and the remaining match
                    # templates know about the last event in the
                    # matched content, so they can update their
                    # internal state accordingly
                    for test in [mt[0] for mt in match_templates[idx:]]:
                        test(tail[0], namespaces, ctxt, updateonly=True)

                    break

            else:  # no matches
                yield event
Exemplo n.º 34
0
 def __call__(self, stream, directives, ctxt, **vars):
     ctxt.push({'_i18n.domain': self.domain})
     for event in _apply_directives(stream, directives, ctxt, vars):
         yield event
     ctxt.pop()
Exemplo n.º 35
0
 def __call__(self, stream, directives, ctxt, **vars):
     return _apply_directives(stream, directives, ctxt, vars)
Exemplo n.º 36
0
 def __call__(self, stream, ctxt, directives):
     if self.expr.evaluate(ctxt):
         return _apply_directives(stream, ctxt, directives)
     return []
Exemplo n.º 37
0
    def _match(self, stream, ctxt, start=0, end=None, **vars):
        """Internal stream filter that applies any defined match templates
        to the stream.
        """
        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 events for matching
            # We might care about namespace events in the future, though
            if not match_templates or event[0] is not START:
                yield event
                continue

            for idx, (test, path, template, hints, namespaces, directives) \
                    in enumerate(match_templates):
                if idx < start or end is not None and idx >= end:
                    continue

                if test(event, namespaces, ctxt) is True:
                    if 'match_once' in hints:
                        del match_templates[idx]
                        idx -= 1

                    # 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
                    pre_end = idx + 1
                    if 'match_once' not in hints and 'not_recursive' in hints:
                        pre_end -= 1
                    inner = _strip(stream)
                    if pre_end > 0:
                        inner = self._match(inner, ctxt, end=pre_end)
                    content = self._include(chain([event], inner, tail), ctxt)
                    if 'not_buffered' not in hints:
                        content = list(content)

                    # Make the select() function available in the body of the
                    # match template
                    selected = [False]
                    def select(path):
                        selected[0] = True
                        return Stream(content).select(path, namespaces, ctxt)
                    vars = dict(select=select)

                    # Recursively process the output
                    template = _apply_directives(template, directives, ctxt,
                                                 **vars)
                    for event in self._match(
                            self._exec(
                                self._eval(
                                    self._flatten(template, ctxt, **vars),
                                    ctxt, **vars),
                                ctxt, **vars),
                            ctxt, start=idx + 1, **vars):
                        yield event

                    # If the match template did not actually call select to
                    # consume the matched stream, the original events need to
                    # be consumed here or they'll get appended to the output
                    if not selected[0]:
                        for event in content:
                            pass

                    # Let the remaining match templates know about the last
                    # event in the matched content, so they can update their
                    # internal state accordingly
                    for test in [mt[0] for mt in match_templates]:
                        test(tail[0], namespaces, ctxt, updateonly=True)

                    break

            else: # no matches
                yield event
Exemplo n.º 38
0
 def __call__(self, stream, directives, ctxt, **vars):
     value = _eval_expr(self.expr, ctxt, vars)
     if value:
         return _apply_directives(stream, directives, ctxt, vars)
     return []
Exemplo n.º 39
0
    def __call__(self, stream, directives, ctxt, **vars):
        ctxt.push({
            '_i18n.choose.params': self.params,
            '_i18n.choose.SingularDirective': None,
            '_i18n.choose.PluralDirective': None
        })

        new_stream = []
        singular_stream = None
        singular_msgbuf = None
        plural_stream = None
        plural_msgbuf = None

        ngettext = ctxt.get('_i18n.ungettext')
        assert hasattr(ngettext, '__call__'), 'No ngettext function available'
        dngettext = ctxt.get('_i18n.dngettext')
        if not dngettext:
            dngettext = lambda d, s, p, n: ngettext(s, p, n)

        for kind, event, pos in stream:
            if kind is SUB:
                subdirectives, substream = event
                if isinstance(subdirectives[0],
                              SingularDirective) and not singular_stream:
                    # Apply directives to update context
                    singular_stream = list(
                        _apply_directives(substream, subdirectives, ctxt,
                                          vars))
                    new_stream.append(
                        (MSGBUF, (), ('', -1)))  # msgbuf place holder
                    singular_msgbuf = ctxt.get(
                        '_i18n.choose.SingularDirective')
                elif isinstance(subdirectives[0],
                                PluralDirective) and not plural_stream:
                    # Apply directives to update context
                    plural_stream = list(
                        _apply_directives(substream, subdirectives, ctxt,
                                          vars))
                    plural_msgbuf = ctxt.get('_i18n.choose.PluralDirective')
                else:
                    new_stream.append((kind, event, pos))
            else:
                new_stream.append((kind, event, pos))

        if ctxt.get('_i18n.domain'):
            ngettext = lambda s, p, n: dngettext(ctxt.get('_i18n.domain'), s,
                                                 p, n)

        for kind, data, pos in new_stream:
            if kind is MSGBUF:
                for skind, sdata, spos in singular_stream:
                    if skind is MSGBUF:
                        translation = ngettext(singular_msgbuf.format(),
                                               plural_msgbuf.format(),
                                               self.numeral.evaluate(ctxt))
                        for event in singular_msgbuf.translate(translation):
                            yield event
                    else:
                        yield skind, sdata, spos
            else:
                yield kind, data, pos

        ctxt.pop()
Exemplo n.º 40
0
 def __call__(self, stream, directives, ctxt, **vars):
     ctxt.push({'_i18n.domain': self.domain})
     for event in _apply_directives(stream, directives, ctxt, vars):
         yield event
     ctxt.pop()
Exemplo n.º 41
0
 def __call__(self, stream, directives, ctxt, **vars):
     return _apply_directives(stream, directives, ctxt, vars)
Exemplo n.º 42
0
    def __call__(self, stream, directives, ctxt, **vars):
        ctxt.push({
            '_i18n.choose.params': self.params,
            '_i18n.choose.singular': None,
            '_i18n.choose.plural': None
        })

        ngettext = ctxt.get('_i18n.ngettext')
        assert hasattr(ngettext, '__call__'), 'No ngettext function available'
        dngettext = ctxt.get('_i18n.dngettext')
        if not dngettext:
            dngettext = lambda d, s, p, n: ngettext(s, p, n)

        new_stream = []
        singular_stream = None
        singular_msgbuf = None
        plural_stream = None
        plural_msgbuf = None

        numeral = self.numeral.evaluate(ctxt)
        is_plural = self._is_plural(numeral, ngettext)

        for event in stream:
            if event[0] is SUB and any(
                    isinstance(d, ChooseBranchDirective) for d in event[1][0]):
                subdirectives, substream = event[1]

                if isinstance(subdirectives[0], SingularDirective):
                    singular_stream = list(
                        _apply_directives(substream, subdirectives, ctxt,
                                          vars))
                    new_stream.append((MSGBUF, None, (None, -1, -1)))

                elif isinstance(subdirectives[0], PluralDirective):
                    if is_plural:
                        plural_stream = list(
                            _apply_directives(substream, subdirectives, ctxt,
                                              vars))

            else:
                new_stream.append(event)

        if ctxt.get('_i18n.domain'):
            ngettext = lambda s, p, n: dngettext(ctxt.get('_i18n.domain'), s,
                                                 p, n)

        singular_msgbuf = ctxt.get('_i18n.choose.singular')
        if is_plural:
            plural_msgbuf = ctxt.get('_i18n.choose.plural')
            msgbuf, choice = plural_msgbuf, plural_stream
        else:
            msgbuf, choice = singular_msgbuf, singular_stream
            plural_msgbuf = MessageBuffer(self)

        for kind, data, pos in new_stream:
            if kind is MSGBUF:
                for event in choice:
                    if event[0] is MSGBUF:
                        translation = ngettext(singular_msgbuf.format(),
                                               plural_msgbuf.format(), numeral)
                        for subevent in msgbuf.translate(translation):
                            yield subevent
                    else:
                        yield event
            else:
                yield kind, data, pos

        ctxt.pop()
Exemplo n.º 43
0
 def __call__(self, stream, directives, ctxt, **vars):
     value = _eval_expr(self.expr, ctxt, vars)
     if value:
         return _apply_directives(stream, directives, ctxt, vars)
     return []