def parse_primary(self): token = self.stream.current if token.type == 'name': if token.value in ('true', 'false', 'True', 'False'): node = nodes.Const(token.value in ('true', 'True'), lineno=token.lineno) elif token.value in ('none', 'None'): node = nodes.Const(None, lineno=token.lineno) else: node = nodes.Name(token.value, 'load', lineno=token.lineno) next(self.stream) elif token.type == 'string': next(self.stream) buf = [token.value] lineno = token.lineno while self.stream.current.type == 'string': buf.append(self.stream.current.value) next(self.stream) node = nodes.Const(''.join(buf), lineno=lineno) elif token.type in ('integer', 'float'): next(self.stream) node = nodes.Const(token.value, lineno=token.lineno) elif token.type == 'lparen': next(self.stream) node = self.parse_tuple(explicit_parentheses=True) self.stream.expect('rparen') elif token.type == 'lbracket': node = self.parse_list() elif token.type == 'lbrace': node = self.parse_dict() else: self.fail("unexpected '%s'" % describe_token(token), token.lineno) return node
def parse(self, parser: Parser) -> nodes.Node: """ See http://jinja.pocoo.org/docs/2.10/extensions/ for help writing extensions. """ if parser.stream.current.test("name:ifnuses"): negate = True ifname = "name:ifnuses" else: negate = False ifname = "name:ifuses" node = result = nodes.If(lineno=parser.stream.expect(ifname).lineno) while 1: args = [ parser.parse_expression(), nodes.Const(parser.stream.current.lineno), nodes.Const(parser.name), nodes.Const(parser.filename), ] test_name = "_use_query" if not negate else "_use_nquery" node.test = self.call_method(test_name, args) node.body = parser.parse_statements( ("name:elifuses", "name:elifnuses", "name:else", "name:endifuses", "name:endifnuses")) node.elif_ = [] node.else_ = [] token = next(parser.stream) if token.test("name:elifuses"): negate = False node = nodes.If(lineno=parser.stream.current.lineno) result.elif_.append(node) continue elif token.test("name:elifnuses"): negate = True node = nodes.If(lineno=parser.stream.current.lineno) result.elif_.append(node) continue elif token.test("name:else"): result.else_ = parser.parse_statements( ( "name:endifuses", "name:endifnuses", ), drop_needle=True, ) break return result
def parse_subscript(self, node): token = next(self.stream) if token.type == 'dot': attr_token = self.stream.current next(self.stream) if attr_token.type == 'name': return nodes.Getattr(node, attr_token.value, 'load', lineno=token.lineno) elif attr_token.type != 'integer': self.fail('expected name or number', attr_token.lineno) arg = nodes.Const(attr_token.value, lineno=attr_token.lineno) return nodes.Getitem(node, arg, 'load', lineno=token.lineno) if token.type == 'lbracket': args = [] while self.stream.current.type != 'rbracket': if args: self.stream.expect('comma') args.append(self.parse_subscribed()) self.stream.expect('rbracket') if len(args) == 1: arg = args[0] else: arg = nodes.Tuple(args, 'load', lineno=token.lineno) return nodes.Getitem(node, arg, 'load', lineno=token.lineno) self.fail('expected subscript expression', token.lineno)
def _make_node(self, singular, plural, variables, plural_expr, vars_referenced, num_called_num): """Generates a useful node from the data provided.""" # no variables referenced? no need to escape for old style # gettext invocations only if there are vars. if not vars_referenced and not self.environment.newstyle_gettext: singular = singular.replace('%%', '%') if plural: plural = plural.replace('%%', '%') # singular only: if plural_expr is None: gettext = nodes.Name('gettext', 'load') node = nodes.Call(gettext, [nodes.Const(singular)], [], None, None) # singular and plural else: ngettext = nodes.Name('ngettext', 'load') node = nodes.Call( ngettext, [nodes.Const(singular), nodes.Const(plural), plural_expr], [], None, None) # in case newstyle gettext is used, the method is powerful # enough to handle the variable expansion and autoescape # handling itself if self.environment.newstyle_gettext: for key, value in iteritems(variables): # the function adds that later anyways in case num was # called num, so just skip it. if num_called_num and key == 'num': continue node.kwargs.append(nodes.Keyword(key, value)) # otherwise do that here else: # mark the return value as safe if we are in an # environment with autoescaping turned on node = nodes.MarkSafeIfAutoescape(node) if variables: node = nodes.Mod( node, nodes.Dict([ nodes.Pair(nodes.Const(key), value) for key, value in variables.items() ])) return nodes.Output([node])
def autoindent(rv, token): prefix = token.value[:-3] if isinstance(rv, list): node = nodes.FilterBlock(lineno=token.lineno) node.filter = nodes.Filter(None, 'lineprefix', [nodes.Const(prefix)], [], None, None, lineno=token.lineno) node.body = rv else: node = nodes.Filter(rv, 'lineprefix', [nodes.Const(prefix)], [], None, None, lineno=token.lineno) return node
def parse(self, parser: Parser) -> nodes.Node: """ See http://jinja.pocoo.org/docs/2.10/extensions/ for help writing extensions. """ # This will be the macro name "assert" token = next(parser.stream) # now we parse a single expression that must evalute to True args = [ parser.parse_expression(), nodes.Const(token.lineno), nodes.Const(parser.name), nodes.Const(parser.filename) ] if parser.stream.skip_if('comma'): args.append(parser.parse_expression()) else: args.append(nodes.Const("Template assertion failed.")) return nodes.CallBlock(self.call_method('_do_assert', args), [], [], "").set_lineno(token.lineno)