Beispiel #1
0
    def parse(self, parser):
        '''parse content of extension'''
        # line number of token that started the tag
        lineno = next(parser.stream).lineno

        # template context
        context = nodes.ContextReference()

        # parse keyword arguments
        kwargs = []

        while parser.stream.look().type == lexer.TOKEN_ASSIGN:
            key = parser.stream.expect(lexer.TOKEN_NAME)
            next(parser.stream)
            kwargs.append(nodes.Keyword(key.value,
                                        parser.parse_expression()), )
            parser.stream.skip_if('comma')
        # parse content of the activeurl block up to endactiveurl
        body = parser.parse_statements(['name:endactiveurl'], drop_needle=True)

        args = [context]

        call_method = self.call_method(
            'render_tag',
            args=args,
            kwargs=kwargs,
        )

        return nodes.CallBlock(call_method, [], [], body).set_lineno(lineno)
Beispiel #2
0
 def parse(self, parser):
     return nodes.Output([self.call_method('_dump', [
         nodes.EnvironmentAttribute('sandboxed'),
         self.attr('ext_attr'),
         nodes.ImportedName(__name__ + '.importable_object'),
         nodes.ContextReference()
     ])]).set_lineno(next(parser.stream).lineno)
Beispiel #3
0
 def make_call_node(*kw):
     return self.call_method('_reverse', args=[
         viewname,
         nodes.List(args),
         nodes.Dict(kwargs),
         nodes.ContextReference(),
     ], kwargs=kw)
    def parse(self, parser):
        # the first token is the token that started the tag.  In our case
        # we only listen to ``'script'`` so this will be a name token with
        # `script` as value.  We get the line number so that we can give
        # that line number to the nodes we create by hand.
        lineno = next(parser.stream).lineno

        # Get the current context and pass along
        kwargs = [nodes.Keyword('ctx', nodes.ContextReference())]

        # Parse until we are done with optional script tag attributes
        while parser.stream.current.value in SCRIPT_ATTRS:
            attr_name = parser.stream.current.value
            parser.stream.skip(2)
            kwargs.append(
                nodes.Keyword(attr_name, parser.parse_expression()))

        # now we parse the body of the script block up to `endscript` and
        # drop the needle (which would always be `endscript` in that case)
        body = parser.parse_statements(['name:endscript'], drop_needle=True)

        # now return a `CallBlock` node that calls our _render_script
        # helper method on this extension.
        return nodes.CallBlock(
            self.call_method('_render_script', kwargs=kwargs),
            [], [], body).set_lineno(lineno)
Beispiel #5
0
    def parse(self, parser):
        lineno = next(parser.stream).lineno

        # get the context
        context = nodes.ContextReference()

        # get the arguments
        args = [context]
        try:
            while True:
                args.append(parser.parse_expression())
        except TemplateSyntaxError:
            pass  # no more arguments

        # get the tag_name for use in looking up callable
        self.active_tag = parser._tag_stack[-1]
        args.insert(0, nodes.Const(self.active_tag))

        # create the node
        node = self.call_method('_invoke_tag', args=args, lineno=lineno)

        return nodes.Output(
            [node],
            lineno=lineno
        )
Beispiel #6
0
 def parse_experiments_confirm_human(self, parser):
     """Parse {% experiments_confirm_human %} tags"""
     lineno = parser.stream.current.lineno
     args = [nodes.ContextReference()]
     node = self.call_method(
         'render_experiments_confirm_human', args, lineno=lineno)
     return nodes.CallBlock(node, [], [], []).set_lineno(lineno)
    def parse(self, parser):
        # the first token is the token that started the tag.  In our case
        # we only listen to ``'webpack'`` so this will be a name token with
        # `webpack` as value.  We get the line number so that we can give
        # that line number to the nodes we create by hand.
        lineno = six.next(parser.stream).lineno
        ctx_ref = nodes.ContextReference()

        # Parse a single expression that is the 'bundle' or 'config:bundle'
        args = [ctx_ref, parser.parse_expression()]

        # if there is a comma, the user provided an 'extensions' arg
        if parser.stream.skip_if('comma'):
            args.append(parser.parse_expression())
        else:
            args.append(nodes.Const(None))

        # now we parse the body of the cache block up to `endwebpack` and
        # drop the needle (which would always be `endwebpack` in that case)
        body = parser.parse_statements(['name:endwebpack'], drop_needle=True)

        call_args = [nodes.Name('ASSET', 'store')]

        return nodes.CallBlock(self.call_method('_get_graph', args), call_args,
                               [], body).set_lineno(lineno)
Beispiel #8
0
 def parse_experiment_goal(self, parser):
     """Parse {% experiment_goal ... %} tags"""
     lineno = parser.stream.current.lineno
     args = [nodes.ContextReference()]
     goal_name = parser.stream.current
     args.append(self._name_or_const(goal_name))
     next(parser.stream)
     node = self.call_method('render_experiment_goal', args, lineno=lineno)
     return nodes.CallBlock(node, [], [], []).set_lineno(lineno)
Beispiel #9
0
    def parse(self, parser):
        lineno = next(parser.stream).lineno
        # token = parser.stream.expect(lexer.TOKEN_STRING)
        context = nodes.ContextReference()

        call = self.call_method('_load_shared_session', [context],
                                lineno=lineno)
        final = nodes.Output([call], lineno=lineno)
        return final
Beispiel #10
0
    def parse(self, parser):
        # the first token is the token that started the tag.  In our case
        # we only listen to ``'copyright'`` so this will be a name token with
        # `copyright` as value.  We get the line number so that we can give
        # that line number to the nodes we create by hand.
        lineno = next(parser.stream).lineno

        callmethod = self.call_method('_copyright', [nodes.ContextReference()],
                                      lineno=lineno)
        return nodes.Output([callmethod], lineno=lineno)
Beispiel #11
0
 def parse_experiments_prepare_conditionals(self, parser):
     """Parse {% experiments_prepare_conditionals %} tags"""
     lineno = parser.stream.current.lineno
     # list of nodes that will be used when calling the callback:
     args = []
     args.append(nodes.ContextReference())
     # Jinja2 callbacky nodey magic:
     call_node = self.call_method(
         'render_experiments_prepare_conditionals', args, lineno=lineno)
     return nodes.CallBlock(call_node, [], [], []).set_lineno(lineno)
Beispiel #12
0
    def parse_attrs(self, parser, add_id=True, with_context=False):
        attrs = {}
        while parser.stream.current.type != 'block_end':
            node = parser.parse_assign_target(with_tuple=False)

            if parser.stream.skip_if('assign'):
                attrs[node.name] = parser.parse_expression()
            else:
                attrs[node.name] = nodes.Const(node.name)
        if with_context:
            attrs['ctx'] = nodes.ContextReference()
        return nodes.Dict(
            [nodes.Pair(nodes.Const(k), v) for k, v in attrs.items()])
Beispiel #13
0
    def parse(self, parser):
        token = next(parser.stream)
        if token.value == 'pushtemplatepath':
            lineno = token.lineno # parser.stream.next().lineno

            # now we parse a single expression, which needs to resolve to the schema file
            template_path = parser.parse_expression()

            args = [template_path, nodes.ContextReference(), nodes.Const(parser.filename)]

            # now return a `CallBlock` node that calls our _push_tamplate_path
            # helper method on this extension.
            return nodes.CallBlock(self.call_method('_push_template_path', args),
                                   [], [], []).set_lineno(lineno)
        elif token.value == 'poptemplatepath':
            lineno = token.lineno # parser.stream.next().lineno

            args = [nodes.ContextReference()]

            # now return a `CallBlock` node that calls our _pop_template_path
            # helper method on this extension.
            return nodes.CallBlock(self.call_method('_pop_template_path', args),
                                   [], [], []).set_lineno(lineno)
Beispiel #14
0
 def parse(self, parser):
     lineno = next(parser.stream).lineno
     args = []
     if parser.stream.current.type != 'block_end':
         lineno = parser.stream.current.lineno
         args.append ( parser.parse_expression() )
     else:
         args.append( nodes.Const(None) )
     
     body = parser.parse_statements(['name:endmatplotlib', 'name:endplot', 'name:end_matplotlib', 'name:end_plot'], drop_needle=True )
     args.append( nodes.ContextReference() )
     args.append( nodes.Name('i', 'load') )
     return nodes.CallBlock(self.call_method('_execute_matplotlib', args ),
                            [], [], body).set_lineno(lineno)
Beispiel #15
0
    def parse(self, parser):
        token = next(parser.stream)
        if token.value == 'save_compound':
            lineno = token.lineno #parser.stream.next().lineno

            compound = parser.parse_expression()
            system_name = parser.parse_expression()
            forcefield = parser.parse_expression()

            args = [compound, system_name, forcefield, nodes.ContextReference()]

            # now return a `CallBlock` node that calls our _param_check
            # helper method on this extension.
            return nodes.CallBlock(self.call_method('_save_compound', args),
                                   [], [], []).set_lineno(lineno)
Beispiel #16
0
    def parse(self, parser):
        lineno = parser.stream.next().lineno

        ctx_ref = nodes.ContextReference()

        body = parser.parse_statements(['name:endscript'], drop_needle=True)

        # TODO: Check we've an output node
        # if this is not 'unsafe' and we have dangerous children, bail out
        if len(body[0].nodes) > 1 or type(body[0].nodes[0])\
                != nodes.TemplateData:
            raise Exception('{% script %} tag has an unsafe body')

        node = self.call_method('_render_script', [ctx_ref], lineno=lineno)
        return nodes.CallBlock(node, [], [], body).set_lineno(lineno)
Beispiel #17
0
    def parse(self, parser):
        lineno = parser.stream.next().lineno

        viewlet_args = []
        name = None
        first = True
        while parser.stream.current.type != 'block_end':
            if not first:
                parser.stream.expect('comma')
                viewlet_args.append(parser.parse_expression())
            else:
                name = parser.parse_expression()
            first = False
        context = nodes.ContextReference()
        return nodes.CallBlock(self.call_method('_call_viewlet', args=[name, context, nodes.List(viewlet_args)]),
                               [], [], []).set_lineno(lineno)
Beispiel #18
0
    def parse_experiment_enroll(self, parser):
        """Parse {% experiment_enroll ... %} tags"""

        lineno = parser.stream.current.lineno

        # list of nodes that will be used when calling the callback:
        args = []

        # parsing first parameter:
        experiment_name = parser.stream.current
        args.append(self._name_or_const(experiment_name))
        next(parser.stream)

        # parsing remaining parameters (the "alternatives"):
        alternatives = []
        while parser.stream.current.type != 'block_end':
            if self._token_as(parser):
                break
            alternatives.append(self._name_or_const(parser.stream.current))
            next(parser.stream)
        args.append(nodes.List(alternatives))

        # expecting `as` after the alternatives:
        if not self._token_as(parser):
            raise TemplateSyntaxError(
                'Syntax should be like: '
                '{% experiment_enroll "experiment_name"'
                ' "alternative1" "alternative2" ... as some_variable %}',
                lineno,
            )
        next(parser.stream)

        # parse what comes after `as`:
        target = parser.parse_assign_target()

        # We're done with parsing the tag.

        # we will also need the context in the callback:
        args.append(nodes.ContextReference())

        # create a callback node that will be executed on render:
        call_node = self.call_method('render_experiment_enroll',
                                     args,
                                     lineno=lineno)

        # return an assignment node that will trigger the callback:
        return nodes.Assign(target, call_node, lineno=lineno)
Beispiel #19
0
    def parse(self, parser):
        lineno = parser.stream.next().lineno
        token = next(parser.stream)

        if token.value not in self.allowed_languages:
            raise TemplateSyntaxError(
                'Expected language token from set: %s' %
                ', '.join(self.allowed_languages), lineno)

        body = parser.parse_statements(['name:endshow'], drop_needle=True)
        call_method = self.call_method(
            '_show_support',
            [nodes.ContextReference(),
             nodes.Const(token.value)],
        )
        node = nodes.CallBlock(call_method, [], [], body).set_lineno(lineno)
        return node
 def parse(self, parser):
     lineno = parser.stream.current.lineno
     tag_name = parser.stream.current.value
     additional_params = [
         nodes.Keyword('_context', nodes.ContextReference()),
         nodes.Keyword('_template', nodes.Const(parser.name)),
         nodes.Keyword('_lineno', nodes.Const(lineno)),
         nodes.Keyword('_tag_name', nodes.Const(tag_name)),
     ]
     self.init_parser(parser)
     args, kwargs, target = self.parse_args(parser)
     kwargs.extend(additional_params)
     block_call = self.call_method('render_wrapper', args, kwargs)
     return self.output(parser,
                        block_call,
                        target,
                        tag_name=tag_name,
                        lineno=lineno)
Beispiel #21
0
    def parse(self, parser):
        token = next(parser.stream)
        if token.value == 'redirect':
            lineno = token.lineno

            # now we parse a single expression, which needs to resolve to the file name
            file_name = parser.parse_expression()

            args = [file_name, nodes.ContextReference()]

            # now we parse the body of the redirect block up to `endrediret` and
            # drop the needle (which would always be `endredirect` in that case)
            body = parser.parse_statements(['name:endredirect'], drop_needle=True)

            # now return a `CallBlock` node that calls our _redirector
            # helper method on this extension.
            return nodes.CallBlock(self.call_method('_redirector', args),
                                   [], [], body).set_lineno(lineno)
Beispiel #22
0
    def parse(self, parser):
        # the first token is the token that started the tag.  In our case
        # we only listen to ``'typograph'`` so this will be a name token with
        # `typograph` as value.  We get the line number so that we can give
        # that line number to the nodes we create by hand.
        lineno = next(parser.stream).lineno

        # now we parse the body of the block up to `endtypograph` and
        # drop the needle (which would always be `endtypograph` in that case)
        body = parser.parse_statements(['name:endtypograph'], drop_needle=True)

        # pass the context as an argument to called method
        ctx_ref = nodes.ContextReference()

        # now return a `CallBlock` node that calls our _typograph_support
        # helper method on this extension.
        node = self.call_method('_typograph_support', [ctx_ref], lineno=lineno)
        return nodes.CallBlock(node, [], [], body, lineno=lineno)
Beispiel #23
0
    def parse_experiment(self, parser):
        """Parse {% experiment ... %} tags"""

        lineno = parser.stream.current.lineno

        # list of nodes that will be used when calling the callback:
        args = []

        # get tag parameters:
        while parser.stream.current.type != 'block_end':
            if parser.stream.skip_if('comma'):
                continue  # just ignore commas
            # {% experiment %} tag only accepts strings, i.e. Const:
            args.append(nodes.Const(parser.stream.current.value))
            next(parser.stream)

        # verify tag syntax:
        tokens = [nodes.Const('experiment')] + args
        try:
            _parse_token_contents(list(map(attrgetter('value'), tokens)))
        except ValueError:
            raise TemplateSyntaxError(
                "Syntax should be like: "
                "{% experiment experiment_name"
                " alternative [weight=val] [user=val] %}",
                lineno,
            )

        # fill in default values:
        while len(args) < 4:
            args.append(nodes.Const(None))

        # additional args:
        args.append(nodes.ContextReference())

        # parse the body of the block up to `endexperiment` and
        # drop the needle (which will always be `endexperiment`):
        body = parser.parse_statements(['name:endexperiment'],
                                       drop_needle=True)

        # Jinja2 callbacky nodey magic:
        call_node = self.call_method('render_experiment', args, lineno=lineno)
        return nodes.CallBlock(call_node, [], [], body).set_lineno(lineno)
Beispiel #24
0
def _empty_extension_parse(self, open_token_condition, parser):
    args = [
        nodes.ContextReference(),
        nodes.Const(parser.filename),
        nodes.Const(parser.stream.current.lineno)
    ]
    kwargs = {}
    name_token = parser.stream.expect(open_token_condition)
    automata_state = AutomataState.Expect_Name

    while parser.stream.current.type != TOKEN_BLOCK_END:
        if automata_state == AutomataState.Expect_Name:
            name_token = parser.stream.expect(TOKEN_NAME)
            automata_state = AutomataState.Expect_Assign
        elif automata_state == AutomataState.Expect_Assign:
            parser.stream.skip_if(TOKEN_ASSIGN)
            automata_state = AutomataState.Expect_Value
        elif automata_state == AutomataState.Expect_Value:
            value_token = parser.stream.next_if(TOKEN_FLOAT)

            if value_token:
                kwargs[name_token.value] = value_token.value
            else:
                value_token = parser.stream.next_if(TOKEN_INTEGER)

                if value_token:
                    kwargs[name_token.value] = value_token.value
                else:
                    value_token = parser.stream.expect(TOKEN_STRING)
                    kwargs[name_token.value] = value_token.value

            automata_state = AutomataState.Expect_Comma
        elif automata_state == AutomataState.Expect_Comma:
            parser.stream.skip_if(TOKEN_COMMA)
            automata_state = AutomataState.Expect_Name

    lineno = parser.stream.current.lineno

    return nodes.CallBlock(
        self.call_method('_process_markup', args, [
            nodes.Keyword(name, nodes.Const(value))
            for name, value in kwargs.items()
        ]), [], [], []).set_lineno(lineno)
Beispiel #25
0
    def parse(self, parser):
        """
        Parse {% py %} blocks in templates.

        Inserts an appropriate CallBlock into the parse tree where a {% py %}
        block is found, so it can be executed when the template is rendered.

        No actual code execution happens here.
        """
        lineno = next(parser.stream).lineno
        # Get contents until an {% endpy %} declaration
        # drop_needle drops the {% endpy %} at the end
        body = parser.parse_statements(['name:endpy'], drop_needle=True)

        # Insert a CallBlock that'll call our `_exec_python` method with
        # the body of {% py %} when rendering
        return nodes.CallBlock(
            self.call_method('_exec_python', [
                nodes.ContextReference(),
                nodes.Const(lineno),
                nodes.Const(parser.filename)
            ]), [], [], body).set_lineno(lineno)
Beispiel #26
0
    def parse_experiment_enrolled_alternative(self, parser):
        """
        Parse {% experiment_enrolled_alternative <experiment_name> %} tags
        """

        lineno = parser.stream.current.lineno

        # list of nodes that will be used when calling the callback:
        args = []

        # get experiment name from token
        experiment_name = parser.stream.current
        args.append(self._name_or_const(experiment_name))
        next(parser.stream)

        # we will also need the context in the callback:
        args.append(nodes.ContextReference())

        # expecting `as` after the alternatives:
        if not self._token_as(parser):
            raise TemplateSyntaxError(
                'Syntax should be like: '
                '{% experiment_enrolled_alternative "experiment_name"'
                ' as some_variable %}',
                lineno,
            )
        next(parser.stream)

        # parse what comes after `as`:
        target = parser.parse_assign_target()

        # create a callback node that will be executed on render:
        call_node = self.call_method('render_experiment_enrolled_alternative',
                                     args,
                                     lineno=lineno)

        # return an assignment node that will trigger the callback:
        return nodes.Assign(target, call_node, lineno=lineno)
Beispiel #27
0
 def parse(self, parser):
     lineno = parser.stream.next().lineno
     kindarg = parser.parse_expression()
     # Allow kind to be defined as jinja2 name node
     if isinstance(kindarg, nodes.Name):
         kindarg = nodes.Const(kindarg.name)
     args = [kindarg]
     if args[0].value not in self.compressors:
         raise TemplateSyntaxError('compress kind may be one of: %s' %
                                   (', '.join(self.compressors.keys())),
                                   lineno)
     if parser.stream.skip_if('comma'):
         modearg = parser.parse_expression()
         # Allow mode to be defined as jinja2 name node
         if isinstance(modearg, nodes.Name):
             modearg = nodes.Const(modearg.name)
             args.append(modearg)
     else:
         args.append(nodes.Const('file'))
     args.append(nodes.ContextReference())
     body = parser.parse_statements(['name:endcompress'], drop_needle=True)
     return nodes.CallBlock(self.call_method('_compress', args), [], [], 
         body).set_lineno(lineno)
Beispiel #28
0
 def process_cache_arguments(self, args):
     args.append(nodes.Getattr(nodes.ContextReference(), 'request', 'load'))
Beispiel #29
0
 def parse(self, parser):
     lineno = next(parser.stream).lineno
     body = parser.parse_statements(['name:endpy'], drop_needle=True)
     return nodes.CallBlock(self.call_method('_exec_python',
                                             [nodes.ContextReference(), nodes.Const(lineno), nodes.Const(parser.filename)]),
                            [], [], body).set_lineno(lineno)
Beispiel #30
0
def _embed_extension_parse(self, open_token_condition, close_token_condition,
                           parser):
    args = [
        nodes.ContextReference(),
        nodes.Const(parser.filename),
        nodes.Const(parser.stream.current.lineno)
    ]
    kwargs = {}
    name_token = parser.stream.expect(open_token_condition)
    automata_state = AutomataState.Expect_Name
    content_path = None

    while parser.stream.current.type != TOKEN_BLOCK_END:
        if automata_state == AutomataState.Expect_Name:
            name_token = parser.stream.expect(TOKEN_NAME)
            automata_state = AutomataState.Expect_Assign
        elif automata_state == AutomataState.Expect_Assign:
            parser.stream.skip_if(TOKEN_ASSIGN)
            automata_state = AutomataState.Expect_Value
        elif automata_state == AutomataState.Expect_Value:
            value_token = parser.stream.next_if(TOKEN_FLOAT)

            if value_token:
                kwargs[name_token.value] = value_token.value
            else:
                value_token = parser.stream.next_if(TOKEN_INTEGER)

                if value_token:
                    kwargs[name_token.value] = value_token.value
                else:
                    value_token = parser.stream.expect(TOKEN_STRING)

                    if name_token.value == 'absolute_path':
                        content_path = normpath(
                            abspath(
                                join(parser.environment.globals['source_path'],
                                     value_token.value)))
                    elif name_token.value == 'relative_path':
                        content_path = normpath(
                            abspath(
                                join(dirname(parser.filename),
                                     value_token.value)))
                    else:
                        kwargs[name_token.value] = value_token.value

            automata_state = AutomataState.Expect_Comma
        elif automata_state == AutomataState.Expect_Comma:
            parser.stream.skip_if(TOKEN_COMMA)
            automata_state = AutomataState.Expect_Name

    lineno = parser.stream.current.lineno

    if content_path is not None:
        if not isfile(content_path):
            raise TemplateSyntaxError(
                f'Cannot find content file "{content_path}".', lineno,
                parser.filename)

        kwargs['content_path'] = content_path
        body = []
    else:
        body = parser.parse_statements([close_token_condition],
                                       drop_needle=True)

    return nodes.CallBlock(
        self.call_method('_process_markup', args, [
            nodes.Keyword(name, nodes.Const(value))
            for name, value in kwargs.items()
        ]), [], [], body).set_lineno(lineno)