示例#1
0
 def parse_test(self, node):
     token = next(self.stream)
     if self.stream.current.test('name:not'):
         next(self.stream)
         negated = True
     else:
         negated = False
     name = self.stream.expect('name').value
     while self.stream.current.type == 'dot':
         next(self.stream)
         name += '.' + self.stream.expect('name').value
     dyn_args = dyn_kwargs = None
     kwargs = []
     if self.stream.current.type == 'lparen':
         args, kwargs, dyn_args, dyn_kwargs = self.parse_call(None)
     elif (self.stream.current.type
           in ('name', 'string', 'integer', 'float', 'lparen', 'lbracket',
               'lbrace') and not self.stream.current.test_any(
                   'name:else', 'name:or', 'name:and')):
         if self.stream.current.test('name:is'):
             self.fail('You cannot chain multiple tests with is')
         args = [self.parse_primary()]
     else:
         args = []
     node = nodes.Test(node,
                       name,
                       args,
                       kwargs,
                       dyn_args,
                       dyn_kwargs,
                       lineno=token.lineno)
     if negated:
         node = nodes.Not(node, lineno=token.lineno)
     return node
示例#2
0
def decrement(token: "Token", parser: "Parser") -> List[nodes.Node]:
    """The decrement tag {% decrement x %}

    Args:
        token: The token matches tag name
        parser: The parser

    Returns:
        The parsed node
    """
    variable = parser.stream.expect("name")
    varname = f"_liquid_xcrement_{variable.value}"
    varnode = nodes.Name(varname, "load")

    return [
        nodes.Assign(
            nodes.Name(varname, "store"),
            nodes.CondExpr(
                nodes.Test(varnode, "defined", [], [], None, None),
                nodes.Sub(varnode, nodes.Const(1)),
                nodes.Const(-1),
            ),
            lineno=token.lineno,
        ),
        nodes.Output([varnode], lineno=token.lineno),
    ]
示例#3
0
    def parse(self, parser):
        lineno = next(parser.stream).lineno

        # Get the block selection from the tag argument.
        block_selection = parser.parse_expression()

        # Make "Name" node for "For" node target.
        block_name = nodes.Name('_ext_ob_blknm', 'store')

        # For each block, add an "If" node checking if it matches the target.
        # Also record the original "default" ordering of the blocks.
        blocks = []
        block_names = []
        for node in parser.parse_statements(['name:endorderblocks'],
                                            drop_needle=True):
            if isinstance(node, nodes.Block):
                blocks.append(nodes.If(
                    nodes.Compare(
                        block_name,
                        [nodes.Operand('eq', nodes.Const(node.name))]),
                    [node], []))

                block_names.append(node.name)

        # Make a "For" node iterating over the given block selection.  If the
        # block selection is undefined or None then use the original ordering.
        return nodes.For(
            block_name,
            nodes.CondExpr(
                nodes.And(
                    nodes.Test(block_selection, 'defined',
                               [], [], None, None),
                    nodes.Not(
                        nodes.Test(block_selection, 'none',
                                   [], [], None, None)),
                ),
                block_selection,
                nodes.Tuple([nodes.Const(x) for x in block_names], 'store')),
            blocks, [], None, False)
示例#4
0
 def parse_test(self, node):
     token = next(self.stream)
     if self.stream.current.test("name:not"):
         next(self.stream)
         negated = True
     else:
         negated = False
     name = self.stream.expect("name").value
     while self.stream.current.type == "dot":
         next(self.stream)
         name += "." + self.stream.expect("name").value
     dyn_args = dyn_kwargs = None
     kwargs = []
     if self.stream.current.type == "lparen":
         args, kwargs, dyn_args, dyn_kwargs = self.parse_call(None)
     elif self.stream.current.type in (
             "name",
             "string",
             "integer",
             "float",
             "lparen",
             "lbracket",
             "lbrace",
     ) and not self.stream.current.test_any("name:else", "name:or",
                                            "name:and"):
         if self.stream.current.test("name:is"):
             self.fail("You cannot chain multiple tests with is")
         args = [self.parse_primary()]
     else:
         args = []
     node = nodes.Test(node,
                       name,
                       args,
                       kwargs,
                       dyn_args,
                       dyn_kwargs,
                       lineno=token.lineno)
     if negated:
         node = nodes.Not(node, lineno=token.lineno)
     return node