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
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), ]
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 []
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
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)
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)
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)
def output(text): return nodes.CallBlock( self.call_method('_block', args=[ nodes.Name(EXTENDS_DJANGO, 'load'), nodes.Const(text), ]), [], [], []).set_lineno(lineno)
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)
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)
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
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)
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)
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)
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)
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)
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)
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)
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)
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 ``'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)
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)
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)