示例#1
0
 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', self.lineno)
示例#2
0
 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", self.lineno)
示例#3
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),
        ]
示例#4
0
    def buffer_node(self, parser, uri, default):
        node_id = self.create_node_id(uri.value, default.value)
        for node in self._node_storage:
            if node.items[0].value == node_id:
                break
        else:
            self._node_storage.append(self.create_tuple(node_id, uri, default))

        return nodes.Getitem(nodes.Name(DJEDI_NODE_STORAGE, 'load'),
                             nodes.Const(node_id), None)
示例#5
0
    def parse(self, parser):
        # Get the component for the tag name that we matched on
        tag_name = parser.stream.current[2]
        component_class = self.environment.components[tag_name]
        field_names = [f.name for f in dataclasses.fields(component_class)]
        has_children = CHILDREN_FIELD_NAME in field_names

        lineno = next(parser.stream).lineno

        node = nodes.Scope(lineno=lineno)

        # list of `Pair` nodes for tag properties to update "component" dictionary
        component_dict_update_items = []

        while parser.stream.current.type != 'block_end':
            lineno = parser.stream.current.lineno
            if component_dict_update_items:
                parser.stream.expect('comma')
            name = parser.stream.expect('name')
            parser.stream.expect('assign')
            value = parser.parse_expression()
            component_dict_update_items.append(
                nodes.Pair(nodes.Const(name.value), value))

        # dictionary initialization in the "component" name
        prepare_component_dict = [
            self._initialize_component_dict(component_class, lineno)
        ]

        if component_dict_update_items:
            component_dict_delta = nodes.Dict(component_dict_update_items)
            # `Getattr` for "update" function of the dictionary "component"
            update_component_dict_fun = nodes.Getattr(
                nodes.Name(TMP_COMPONENT_DICT_NAME, 'load'), 'update', 'load')
            # `Call` for `component.update(<prop name>, <prop value>)`
            call_component_dict_update = nodes.Call(update_component_dict_fun,
                                                    [component_dict_delta], [],
                                                    None, None)
            prepare_component_dict.append(
                nodes.ExprStmt(call_component_dict_update))

        # assign `component = __component` and `__component = None`
        prepare_component_dict.extend([
            nodes.Assign(nodes.Name(COMPONENT_DICT_NAME,
                                    'store',
                                    lineno=lineno),
                         nodes.Name(TMP_COMPONENT_DICT_NAME,
                                    'load',
                                    lineno=lineno),
                         lineno=lineno),
            nodes.Assign(nodes.Name(TMP_COMPONENT_DICT_NAME,
                                    'store',
                                    lineno=lineno),
                         nodes.Const(None, lineno=lineno),
                         lineno=lineno)
        ])

        if has_children:
            inner_block = list(
                parser.parse_statements(('name:end' + tag_name, ),
                                        drop_needle=True))
            # create children() macro
            children_macro = nodes.Macro()
            children_macro.name = CHILDREN_MACRO_NAME
            children_macro.args = []
            children_macro.defaults = []
            children_macro.body = inner_block
            children_macro_nodes = [children_macro]
        else:
            children_macro_nodes = []

        # include tag template
        include_tag = nodes.Include()
        # use `template` item of the "component" dictionary for template path
        include_tag.template = nodes.Getitem(nodes.Name(COMPONENT_DICT_NAME,
                                                        'load',
                                                        lineno=lineno),
                                             nodes.Const(TEMPLATE_FIELD_NAME,
                                                         lineno=lineno),
                                             'load',
                                             lineno=lineno)
        include_tag.ignore_missing = False
        include_tag.with_context = True

        node.body = prepare_component_dict + children_macro_nodes + [
            include_tag,
        ]

        return node
示例#6
0
def tablerow(
    token: "Token", parser: "Parser"
) -> Union[nodes.Node, List[nodes.Node]]:
    """The tablerow tag {% tablerow ... %} ... {% endtablerow %}

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

    Returns:
        The parsed node
    """
    target = parser.parse_assign_target(extra_end_rules=("name:in", ))
    parser.stream.expect("name:in")
    iter_ = parser.parse_tuple(
        with_condexpr=False,
        extra_end_rules=("name:cols", "name:limit", "name:offset"),
    )

    cols = parse_tag_args(parser.stream, "cols", token.lineno)
    limit = parse_tag_args(parser.stream, "limit", token.lineno)
    offset = parse_tag_args(parser.stream, "offset", token.lineno)

    if limit and offset:
        limit = nodes.Add(offset, limit)
    if limit or offset:
        iter_ = nodes.Getitem(iter_, nodes.Slice(offset, limit, None), "load")

    if cols:
        slice_start = nodes.Mul(nodes.Name("_tablerow_i", "load"), cols)
        inner_iter = nodes.Getitem(
            iter_,
            nodes.Slice(
                slice_start,
                nodes.Add(slice_start, cols),
                None,
            ),
            "load",
        )
    else:
        inner_iter: nodes.Getitem = iter_

    inner_body = [
        nodes.Output(
            [
                nodes.Const('<td class="col'),
                nodes.Getattr(nodes.Name("loop", "load"), "index", "load"),
                nodes.Const('">'),
            ]
        ),
        *parser.parse_statements(("name:endtablerow",), drop_needle=True),
        nodes.Output([nodes.Const("</td>")]),
    ]
    tr_begin = nodes.Output(
        [
            nodes.Const('<tr class="row'),
            nodes.CondExpr(
                nodes.Name("loop", "load"),
                nodes.Getattr(nodes.Name("loop", "load"), "index", "load"),
                nodes.Const(1),
            ),
            nodes.Const('">'),
        ]
    )
    tr_end = nodes.Output([nodes.Const("</tr>")])
    inner_loop = nodes.For(
        target, inner_iter, inner_body, [], None, False, lineno=token.lineno
    )
    if not cols:
        return [tr_begin, inner_loop, tr_end]

    # (iter_ | length) / cols
    iter_length = nodes.Div(
        nodes.Filter(iter_, "length", [], [], None, None),
        cols,
    )  # float
    # int(iter_length)
    iter_length_int = nodes.Filter(iter_length, "int", [], [], None, None)

    # implement ceil, as jinja's ceil is implemented as round(..., "ceil")
    # while liquid has a ceil filter
    # iter_length_int if iter_length == iter_length_int
    # else iter_length_int + 1
    iter_length = nodes.CondExpr(
        nodes.Compare(iter_length, [nodes.Operand("eq", iter_length_int)]),
        iter_length_int,
        nodes.Add(iter_length_int, nodes.Const(1)),
    )

    return nodes.For(
        nodes.Name("_tablerow_i", "store"),
        nodes.Call(nodes.Name("range", "load"), [iter_length], [], None, None),
        [tr_begin, inner_loop, tr_end],
        [],
        None,
        False,
        lineno=token.lineno,
    )