Exemple #1
0
    def parse(self, parser):
        token = next(parser.stream)
        lineno = token.lineno
        filename = parser.name
        error = parser.parse_expression()

        args = [error, nodes.Const(filename), nodes.Const(lineno)]
        try:
            body = parser.parse_statements(["name:endtry"], drop_needle=True)
            node = nodes.CallBlock(
                self.call_method("_handle_body", args), [], [], body
            ).set_lineno(lineno)
        except Exception as e:
            # that was expected
            self._logger.exception("Caught exception while parsing template")
            node = nodes.CallBlock(
                self.call_method(
                    "_handle_error",
                    [nodes.Const(self._format_error(error, e, filename, lineno))],
                ),
                [],
                [],
                [],
            ).set_lineno(lineno)

        return node
Exemple #2
0
    def parse(self, parser):
        """
        Parse the referred template and the namespace.
        """
        token = next(parser.stream)
        lineno = token.lineno
        parser.stream.expect('name:to')
        template = parser.parse_expression()
        parser.stream.expect('name:as')
        namespace = next(parser.stream).value
        includeNode = nodes.Include(lineno=lineno)
        includeNode.with_context = True
        includeNode.ignore_missing = False
        includeNode.template = template

        temp = parser.free_identifier(lineno)

        return [
            nodes.Assign(
                nodes.Name(temp.name, 'store'),
                nodes.Name(MARKINGS, 'load')
            ).set_lineno(lineno),
            nodes.Assign(
                nodes.Name(MARKINGS, 'store'),
                nodes.Const({})).set_lineno(lineno),
            nodes.Assign(
                nodes.Name(namespace, 'store'),
                nodes.Const({})).set_lineno(lineno),
            nodes.CallBlock(
                self.call_method('_push_resource',
                                 args=[
                                     nodes.Name(namespace, 'load'),
                                     nodes.Name('site', 'load'),
                                     nodes.Name('resource', 'load'),
                                     template]),
                [], [], []).set_lineno(lineno),
            nodes.Assign(
                nodes.Name('resource', 'store'),
                nodes.Getitem(nodes.Name(namespace, 'load'),
                              nodes.Const('resource'), 'load')
            ).set_lineno(lineno),
            nodes.CallBlock(
                self.call_method('_assign_reference',
                                 args=[
                                     nodes.Name(MARKINGS, 'load'),
                                     nodes.Name(namespace, 'load')]),
                [], [], [includeNode]).set_lineno(lineno),
            nodes.Assign(nodes.Name('resource', 'store'),
                         nodes.Getitem(nodes.Name(namespace, 'load'),
                                       nodes.Const('parent_resource'), 'load')
                         ).set_lineno(lineno),
            nodes.Assign(
                nodes.Name(MARKINGS, 'store'),
                nodes.Name(temp.name, 'load')
            ).set_lineno(lineno),
        ]
Exemple #3
0
    def parse(self, parser):
        tag = next(parser.stream)

        package_name = parser.parse_expression()
        if not package_name:
            raise TemplateSyntaxError("Bad package name", tag.lineno)

        args = [package_name]
        if tag.value == "stylesheet":
            return nodes.CallBlock(self.call_method('package_css', args), [], [], []).set_lineno(tag.lineno)

        if tag.value == "javascript":
            return nodes.CallBlock(self.call_method('package_js', args), [], [], []).set_lineno(tag.lineno)

        return []
Exemple #4
0
    def parse(self, parser):
        # the first token is the token that started the tag.  In our case
        # we only listen to ``'csi'`` so this will be a name token with
        # `csi` 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 a single expression that is used as the URL we're going
        # to include
        args = [parser.parse_expression()]

        # if there is a comma, the user provided a tag type.  If not use
        # 'div' as second parameter.
        if parser.stream.skip_if("comma"):
            args.append(parser.parse_expression())
        else:
            args.append(nodes.Const("div"))

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

        # Now return a `CallBlock` node that calls our _csi helper method on
        # this extension.
        n = nodes.CallBlock(self.call_method("_csi", args), [], [], body)
        n = n.set_lineno(lineno)
        return n
Exemple #5
0
 def parse(self, parser):
     lineno = next(parser.stream).lineno
     message_node = parser.parse_expression()
     return nodes.CallBlock(self.call_method(name='_raise',
                                             args=[message_node],
                                             lineno=lineno), [], [], [],
                            lineno=lineno)
Exemple #6
0
 def parse(self, parser):
     lineno = next(parser.stream).lineno
     context = jinja2.nodes.ContextReference()
     return nodes.CallBlock(
         self.call_method('render',
                          [context, parser.parse_expression()]), [], [],
         "").set_lineno(lineno)
Exemple #7
0
    def parse(self, parser):
        # parse chart name
        chart_tag = parser.stream.next()

        args = [parser.parse_expression()]

        # parse 'with' statement
        if parser.stream.current.type != 'block_end':
            token = parser.stream.next()
            if token.value != 'with':
                parser.fail("expected 'with' statement", token.lineno)

        # parse options
        while parser.stream.current.type != 'block_end':
            lineno = parser.stream.current.lineno

            target = parser.parse_assign_target()
            parser.stream.expect('assign')
            expr = parser.parse_expression()

            args.append(nodes.Assign(target, expr, lineno=lineno))

        self.environment.options['name'] = self._chart_name(chart_tag.value)
        self.environment.options['id'] = self._chart_id()

        return nodes.CallBlock(self.call_method('_render', args), [], [],
                               []).set_lineno(chart_tag.lineno)
Exemple #8
0
 def output(text):
     return nodes.CallBlock(
         self.call_method('_block',
                          args=[
                              nodes.Name(EXTENDS_DJANGO, 'load'),
                              nodes.Const(text),
                          ]), [], [], []).set_lineno(lineno)
Exemple #9
0
    def parse(self, parser):
        """
        Parses the statements and defers to the callback for pygments processing.
        """
        lineno = parser.stream.next().lineno
        lex = nodes.Const(None)
        filename = nodes.Const(None)

        if not parser.stream.current.test('block_end'):
            if parser.stream.look().test('assign'):
                name = value = value1 = None
                (name, value) = parse_kwargs(parser)
                if parser.stream.skip_if('comma'):
                    (_, value1) = parse_kwargs(parser)

                (lex, filename) = (value, value1) \
                                        if name == 'lex' \
                                            else (value1, value)
            else:
                lex = nodes.Const(parser.stream.next().value)
                if parser.stream.skip_if('comma'):
                    filename = parser.parse_expression()

        body = parser.parse_statements(['name:endsyntax'], drop_needle=True)
        return nodes.CallBlock(
            self.call_method('_render_syntax', args=[lex, filename]), [], [],
            body).set_lineno(lineno)
Exemple #10
0
    def parse(self, parser):
        lineno = next(parser.stream).lineno

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

        return nodes.CallBlock(self.call_method('_parse_markdown'), [], [],
                               body).set_lineno(lineno)
Exemple #11
0
    def parse(self, parser):
        # the first token is the token that started the tag.  In our case
        # we only listen to ``'click'`` so this will be a name token with
        # `click` as value.  We get the line number so that we can give
        # that line number to the nodes we create by hand.
        lineno = parser.stream.next().lineno
        ctx_ref = jinja2.nodes.ContextReference()

        # # now we parse a single expression that is used as cache key.
        # args = [parser.parse_expression()]
        #
        # # if there is a comma, the user provided a timeout.  If not use
        # # None as second parameter.
        # 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 `endclick` and
        # drop the needle (which would always be `endclick` in that case)
        body = parser.parse_statements(['name:endclick'], drop_needle=True)

        # now return a `CallBlock` node that calls our _cache_support
        # helper method on this extension.
        return nodes.CallBlock(self.call_method('_click_support', [ctx_ref]),
                               [], [], body).set_lineno(lineno)
    def parse(self, parser):
        parser_token = next(parser.stream)
        parser_lineno = parser_token.lineno

        node = nodes.Scope(lineno=parser_lineno)
        assignments = []
        widget_args = []

        while parser.stream.current.type != 'block_end':
            lineno = parser.stream.current.lineno
            if assignments:
                parser.stream.expect('comma')

            widget_target = parser.parse_assign_target()
            parser.stream.expect('assign')
            widget_config = parser.parse_expression()
            widget_name = widget_target.name
            widget_target, widget_node = self._widget_uuid(
                widget_target, widget_config)
            widget_args = [
                nodes.Name('widgets', 'load'),
                nodes.Const(widget_name), widget_config, widget_node
            ]
            assignments.append(
                nodes.Assign(widget_target, widget_node, lineno=lineno))
        node.body = assignments + list(
            parser.parse_statements(('name:endwidget', ), drop_needle=True))

        output = [
            nodes.CallBlock(
                self.call_method('_widget_onload', args=widget_args), [], [],
                '').set_lineno(parser_lineno), node
        ]

        return output
Exemple #13
0
    def parse(self, parser):
        lineno = parser.stream.next().lineno

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

        return nodes.CallBlock(self.call_method('_lang'), [], [],
                               body).set_lineno(lineno)
Exemple #14
0
  def parse(self, parser):
    lineno = next(parser.stream).lineno

    github_path = ''
    tag = None
    last_token_type = None
    for token in parser.stream:
      if last_token_type == lexer.TOKEN_NAME and token.value == 'tag':
        parser.stream.expect(lexer.TOKEN_COLON)
        tag = parser.stream.expect(lexer.TOKEN_NAME).value
        break
      github_path += token.value
      last_token_type = token.type

    m = self.github_path_re.match(github_path)
    if not m:
      raise TemplateSyntaxError(
          'Github file path must be in the format '
          '/<owner>/<repo>/blob/<branch>/<path>, '
          'found {}'.format(repr(github_path)),
          lineno, parser.name, parser.filename)

    owner, repo, branch, path = m.groups()
    call = self.call_method('_github_sample', [
        nodes.Const(owner),
        nodes.Const(repo),
        nodes.Const(branch),
        nodes.Const(path),
        nodes.Const(tag),
    ])
    return nodes.CallBlock(call, [], [], []).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)
Exemple #16
0
 def parse(self, parser):
     lineno = parser.stream.next().lineno
     body = parser.parse_statements(['name:endspaceless'], drop_needle=True)
     return nodes.CallBlock(
         self.call_method('_strip_spaces', [], [], None, None),
         [], [], body,
     ).set_lineno(lineno)
Exemple #17
0
    def parse(self, parser):
        # 进入此函数,即表示 {% uri %} 标签被找到了
        # 下面的代码,会获取当前 {% uri %} 语句所在模板的行号
        lineno = next(parser.stream).lineno

        # 获取 {% uri %} 语句中的参数,比如我们调用是 {% uri 'python' %},
        # 这里就会返回一个 jinja2.nodes.Const 类型的对象,其值是 'python'
        lang_type = parser.parse_expression()

        # 将参数封装为列表
        args = []
        if lang_type is not None:
            args.append(lang_type)

            # 下面代码,可以支持两个参数,参数之间,用逗号隔开,不过本例用不到
            # 这里先检查当前处理流的位置,是不是个逗号,是的话,再获取下一个参数
            # 不是的话,就在参数列表的最后,加一个空对象
            # if parser.stream.skip_if('comma'):
            #   args.append(parser.parser_expression())
            # else:
            #   args.append(nodes.Const(None))

        # 解析从 {% uri %} 标志开始,到 {% enduri %} 为止的中间所有语句
        # 将解析完的内容,帮到 body 里,并且将当前流的位置,移动到 {% enduri %} 后面
        # 因为我们这里,是单结束标签,所以不需要获取 body
        # body = parser.parse_statements(['name:enduri'], drop_needle=True)
        body = ''

        # 返回一个 CallBlock类型的节点,并将其之前取得的行号,设置在该节点中
        # 初始化 CallBlock 节点时,传入我们自定义的 _do_query_resource 方法的调用,两个空列表,以及刚才解析后的语句内容 body
        return nodes.CallBlock(self.call_method('_do_query_resource', args),
                               [], [], body).set_lineno(lineno)
Exemple #18
0
    def parse(self, parser):
        lineno = next(parser.stream).lineno

        body = parser.parse_statements(["name:endb64encode"], drop_needle=True)

        return nodes.CallBlock(self.call_method("_b64encode", None), [], [],
                               body).set_lineno(lineno)
Exemple #19
0
    def parse(self, parser):
        # 进入此函数时,即表示{% code %}标签被找到了
        # 下面的代码会获取当前{% code %}语句在模板文件中的行号
        lineno = next(parser.stream).lineno

        # 获取{% code %}语句中的参数,比如我们调用{% code 'python' %},
        # 这里就会返回一个jinja2.nodes.Const类型的对象,值为'python'
        lang_type = parser.parse_expression()

        # 将参数封装为列表
        args = []
        if lang_type is not None:
            args.append(lang_type)

            # 下面的代码可以支持两个参数,参数之间用逗号分隔,不过本例中用不到
            # 这里先检查当前处理流的位置是不是个逗号,是的话就再获取一个参数
            # 不是的话,就在参数列表最后加个空值对象
            # if parser.stream.skip_if('comma'):
            #     args.append(parser.parse_expression())
            # else:
            #     args.append(nodes.Const(None))

        # 解析从{% code %}标志开始,到{% endcode %}为止中间的所有语句
        # 将解析完后的内容存在body里,并将当前流位置移到{% endcode %}之后
        body = parser.parse_statements(['name:endcode'], drop_needle=True)

        # 返回一个CallBlock类型的节点,并将其之前取得的行号设置在该节点中
        # 初始化CallBlock节点时,传入我们自定义的"_pygmentize"方法的调用,
        # 两个空列表,还有刚才解析后的语句内容body
        return nodes.CallBlock(self.call_method('_pygmentize', args), [], [],
                               body).set_lineno(lineno)
Exemple #20
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)
Exemple #21
0
 def parse(self, parser):
     """
     Delegates all the parsing to the native include node.
     """
     node = parser.parse_include()
     return nodes.CallBlock(self.call_method('_render_include_text'), [],
                            [], [node]).set_lineno(node.lineno)
    def parse(self, parser):
        lineno = next(parser.stream).lineno

        options = dict()

        # Parse the arguments
        source = parser.parse_expression()

        if parser.stream.skip_if('comma'):
            first = True
            while parser.stream.current.type != 'block_end':
                if not first:
                    parser.stream.expect('comma')
                first = False

                # Lookahead to see if this is an assignment (an option)
                if parser.stream.current.test('name') and parser.stream.look().test('assign'):
                    name = next(parser.stream).value
                    parser.stream.skip()
                    value = parser.parse_expression()

                    options[nodes.Const(name)] = value

        node_options = []
        for k, v in options.items():
            node_options.append(nodes.Pair(k, v))

        node_options = nodes.Dict(node_options)

        call = self.call_method('render', [source, node_options], lineno=lineno)
        output = nodes.CallBlock(call, [], [], [])
        output.set_lineno(lineno)

        return output
    def parse(self, parser):
        lineno = next(parser.stream).lineno

        #: Parse timeout
        args = [parser.parse_expression()]

        #: Parse fragment name
        #: Grab the fragment name if it exists
        #: otherwise, default to the old method of using the templates
        #: lineno to maintain backwards compatibility.
        if parser.stream.skip_if('comma'):
            args.append(parser.parse_expression())
        else:
            args.append(nodes.Const("%s%s" % (parser.filename, lineno)))

        #: Parse vary_on parameters
        vary_on = []
        while parser.stream.skip_if('comma'):
            vary_on.append(parser.parse_expression())

        if vary_on:
            args.append(nodes.List(vary_on))
        else:
            args.append(nodes.Const([]))

        body = parser.parse_statements(['name:endcache'], drop_needle=True)
        return nodes.CallBlock(self.call_method('_cache', args),
                               [], [], body).set_lineno(lineno)
    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)
    def parse(self, parser):
        # the first token is the token that started the tag.  In our case
        # we only listen to ``'cache'`` so this will be a name token with
        # `cache` 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

        # Use the filename + line number and first object for the cache key.
        name = '%s+%s' % (self.name, lineno)
        args = [nodes.Const(name), parser.parse_expression()]

        # If there is a comma, the user provided a timeout.  If not, use
        # None as second parameter.
        timeout = nodes.Const(None)
        extra = nodes.Const([])
        while parser.stream.skip_if('comma'):
            x = parser.parse_expression()
            if parser.stream.current.type == 'assign':
                next(parser.stream)
                extra = parser.parse_expression()
            else:
                timeout = x
        args.extend([timeout, extra])

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

        self.process_cache_arguments(args)

        # now return a `CallBlock` node that calls our _cache_support
        # helper method on this extension.
        return nodes.CallBlock(self.call_method('_cache_support', args), [],
                               [], body).set_lineno(lineno)
Exemple #26
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)
Exemple #27
0
    def parse(self, parser):
        # the first token is the token that started the tag.  In our case
        # we only listen to ``'cache'`` so this will be a name token with
        # `cache` 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 a single expression that is used as cache key.
        args = [parser.parse_expression()]

        # if there is a comma, the user provided a timeout.  If not use
        # None as second parameter.
        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 `endcache` and
        # drop the needle (which would always be `endcache` in that case)
        body = parser.parse_statements(["name:endcache"], drop_needle=True)

        # now return a `CallBlock` node that calls our _cache_support
        # helper method on this extension.
        return nodes.CallBlock(self.call_method("_cache_support", args), [],
                               [], body).set_lineno(lineno)
    def parse(self, parser):
        lineno = next(parser.stream).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"))

        body = parser.parse_statements(["name:endcompress"], drop_needle=True)

        # Skip the kind if used in the endblock, by using the kind in the
        # endblock the templates are slightly more readable.
        parser.stream.skip_if("name:" + kindarg.value)
        return nodes.CallBlock(self.call_method("_compress_normal", args), [],
                               [], body).set_lineno(lineno)
Exemple #29
0
    def parse(self, parser):
        # parse chart name
        chart_tag = next(parser.stream)

        args = [parser.parse_expression()]

        # parse 'with' statement
        if parser.stream.current.type != 'block_end':
            token = next(parser.stream)
            if token.value != 'with':
                parser.fail("expected 'with' statement", token.lineno)

        # parse options
        while parser.stream.current.type != 'block_end':
            lineno = parser.stream.current.lineno

            target = parser.parse_assign_target()
            parser.stream.expect('assign')
            expr = parser.parse_expression()

            args.append(nodes.Assign(target, expr, lineno=lineno))

        support_func = chart_tag.value + '_support'

        return nodes.CallBlock(self.call_method(support_func, args), [], [],
                               []).set_lineno(chart_tag.lineno)
Exemple #30
0
    def parse(self, parser):
        lineno = next(parser.stream).lineno
        expr = parser.parse_expression()
        args = [expr]
        kwargs = [nodes.Keyword('func', expr)]
        if parser.stream.skip_if('comma'):
            # Optional 'note' for function docstring
            if (parser.stream.current.type == 'name'
                    and parser.stream.current.value
                    in ('note', 'cond_for', 'depends_on')):
                stream_type = parser.stream.current.value
                next(parser.stream)
                parser.stream.expect('assign')
                # Depends meta is always a list
                if stream_type == 'depends_on':
                    c_expr = parser.parse_list()
                else:
                    c_expr = parser.parse_expression()
                args.append(c_expr)
                kwargs.append(nodes.Keyword(stream_type, c_expr))

        body = parser.parse_statements(['name:endsql', 'name:endquery'],
                                       drop_needle=True)
        raw_template = self.environment.sql_params['raws'][parser.name]

        # Lines range of original raw template
        raw_lines = slice(lineno, parser.stream.current.lineno - 1)
        self.environment.sql_params.setdefault('funcs', {}).update(
            {expr.value: {
                'raw_sql': '\n '.join(raw_template[raw_lines])
            }})
        call_node = nodes.Call(self.attr('_sql_process', lineno=lineno), args,
                               kwargs, None, None)
        return nodes.CallBlock(call_node, [], [], body)