Пример #1
0
    def static_attributes(self):
        result = {}
        element_ns = self.element.nsmap.get(self.element.prefix)

        nsmap = self.element.nsmap.copy()
        nsmap.update(config.DEFAULT_NS_MAP)

        root = self.element.getroottree().getroot()
        omit_default_prefix = root.meta_omit_default_prefix

        for prefix, ns in nsmap.items():
            if ns not in self.ns_omit:
                attrs = utils.get_attributes_from_namespace(self.element, ns)
                if prefix is None or ns == element_ns:
                    attrs.update(
                        utils.get_attributes_from_namespace(self.element, None))

                for tag, value in attrs.items():
                    name = tag.split('}')[-1]

                    if prefix and (ns != element_ns or not omit_default_prefix):
                        result["%s:%s" % (prefix, name)] = value
                    elif omit_default_prefix:
                        result[name] = value

        if self.element.prefix is None:
            result.update(
                utils.get_attributes_from_namespace(self.element, None))

        return result
Пример #2
0
    def static_attributes(self):
        result = {}
        element_ns = self.element.nsmap.get(self.element.prefix)

        nsmap = self.element.nsmap.copy()
        nsmap.update(config.DEFAULT_NS_MAP)

        root = self.element.getroottree().getroot()
        omit_default_prefix = root.meta_omit_default_prefix

        for prefix, ns in nsmap.items():
            if ns not in self.ns_omit:
                attrs = utils.get_attributes_from_namespace(self.element, ns)
                if prefix is None or ns == element_ns:
                    attrs.update(
                        utils.get_attributes_from_namespace(
                            self.element, None))

                for tag, value in attrs.items():
                    name = tag.split('}')[-1]

                    if prefix and (ns != element_ns
                                   or not omit_default_prefix):
                        result["%s:%s" % (prefix, name)] = value
                    elif omit_default_prefix:
                        result[name] = value

        if self.element.prefix is None:
            result.update(
                utils.get_attributes_from_namespace(self.element, None))

        return result
Пример #3
0
    def __call__(self, macro, global_scope=True, debug=False):
        root = copy.deepcopy(self.tree).getroot()

        if not isinstance(root, Element):
            raise ValueError(
                "Must define valid namespace for tag: '%s.'" % root.tag)

        # if macro is non-trivial, start compilation at the element
        # where the macro is defined
        if macro:
            for element in root.walk():
                node = element.node
                if node is not None and node.define_macro == macro:
                    element.meta_translator = root.meta_translator

                    # if element is the document root, render as a normal
                    # template, e.g. unset the `macro` mode
                    if root is element:
                        macro = None
                    else:
                        root = element

                    break
            else:
                raise KeyError(macro)

        # initialize code stream object
        stream = generation.CodeIO(
            root.node.symbols, encoding=self.encoding,
            indentation=0, indentation_string="\t")

        # transient symbols are added to the primary scope to exclude
        # them from being carried over when using macros
        for name, value in stream.symbols.as_dict().items():
            if value is config.TRANSIENT_SYMBOL:
                stream.scope[0].add(name)

        # initialize variable scope
        stream.scope.append(set(
            (stream.symbols.out,
             stream.symbols.write,
             stream.symbols.scope,
             stream.symbols.domain,
             stream.symbols.language)))

        if global_scope is False:
            stream.scope[-1].add(stream.symbols.remote_scope)

        # set up initialization code
        stream.symbol_mapping['_init_stream'] = generation.initialize_stream
        stream.symbol_mapping['_init_scope'] = generation.initialize_scope
        stream.symbol_mapping['_init_tal'] = generation.initialize_tal
        stream.symbol_mapping['_init_default'] = generation.initialize_default

        # add code-generation lookup globals
        if debug:
            lookup = codegen.lookup_attr_debug
        else:
            lookup = codegen.lookup_attr
        stream.symbol_mapping['_lookup_attr'] = lookup

        if global_scope:
            assignments = (
                clauses.Assign(
                    types.value("_init_stream()"), ("%(out)s", "%(write)s")),
                clauses.Assign(
                     types.value("_init_tal()"), ("%(attributes)s", "%(repeat)s")),
                clauses.Assign(
                    types.value("_init_default()"), '%(default_marker_symbol)s'),
                clauses.Assign(
                    types.value(repr(None)), '%(default)s'),
                clauses.Assign(
                     types.template("None"), "%(domain)s"))
        else:
            assignments = (
                clauses.Assign(
                    types.template(
                        "%(scope)s['%(out)s'], %(scope)s['%(write)s']"),
                    ("%(out)s", "%(write)s")),
                clauses.Assign(
                    types.value("_init_tal()"), ("%(attributes)s", "%(repeat)s")),
                clauses.Assign(
                    types.value("_init_default()"), '%(default_marker_symbol)s'),
                clauses.Assign(
                    types.value(repr(None)), '%(default)s'),
                clauses.Assign(
                     types.template("None"), "%(domain)s"))

        for clause in assignments:
            clause.begin(stream)
            clause.end(stream)

        if macro is not None:
            nsmap = {}
            namespaces = set()

            for tag in root.attrib:
                if '}' not in tag:
                    continue

                namespace = tag[1:].split('}')[0]
                namespaces.add(namespace)

            for prefix, namespace in root.nsmap.items():
                if namespace in namespaces:
                    nsmap[prefix] = namespace

            wrapper = self.tree.parser.makeelement(
                utils.meta_attr('wrapper'),
                utils.get_attributes_from_namespace(root, config.META_NS),
                nsmap=nsmap)
            wrapper.append(root)
            root = wrapper

        # output XML headers, if applicable
        if global_scope is True or macro is "":
            header = ""
            if self.xml_declaration is not None:
                header += self.xml_declaration + '\n'
            if self.doctype:
                doctype = self.doctype + '\n'
                if self.encoding:
                    doctype = doctype.encode(self.encoding)
                header += doctype
            if header:
                out = clauses.Out(header)
                stream.scope.append(set())
                stream.begin([out])
                stream.end([out])
                stream.scope.pop()

        # add meta settings
        root.meta_omit_default_prefix = self.omit_default_prefix

        # start generation
        root.start(stream)
        body = stream.getvalue()

        # symbols dictionary
        __dict__ = stream.symbols.as_dict()

        # prepare globals
        _globals = ["from cPickle import loads as _loads"]
        for symbol, value in stream.symbol_mapping.items():
            _globals.append(
                "%s = _loads(%s)" % (symbol, repr(dumps(value))))

        transient = []
        for name, value in stream.symbols.as_dict().items():
            if value is config.TRANSIENT_SYMBOL:
                transient.append("%s = econtext.get('%s')" % (name, name))
        transient = "; ".join(transient)

        # wrap generated Python-code in function definition
        if global_scope:
            source = generation.function_wrap(
                'render', _globals, body, transient,
                "%(out)s.getvalue()" % __dict__)
        else:
            source = generation.function_wrap(
                'render', _globals, body, transient)

        suite = codegen.Suite(source)
        return suite.source
Пример #4
0
    def __call__(self, macro, global_scope=True, debug=False):
        root = copy.deepcopy(self.tree).getroot()

        if not isinstance(root, Element):
            raise ValueError("Must define valid namespace for tag: '%s.'" %
                             root.tag)

        # if macro is non-trivial, start compilation at the element
        # where the macro is defined
        if macro:
            for element in root.walk():
                node = element.node
                if node is not None and node.define_macro == macro:
                    element.meta_translator = root.meta_translator

                    # if element is the document root, render as a normal
                    # template, e.g. unset the `macro` mode
                    if root is element:
                        macro = None
                    else:
                        root = element

                    break
            else:
                raise KeyError(macro)

        # initialize code stream object
        stream = generation.CodeIO(root.node.symbols,
                                   encoding=self.encoding,
                                   indentation=0,
                                   indentation_string="\t")

        # transient symbols are added to the primary scope to exclude
        # them from being carried over when using macros
        for name, value in stream.symbols.as_dict().items():
            if value is config.TRANSIENT_SYMBOL:
                stream.scope[0].add(name)

        # initialize variable scope
        stream.scope.append(
            set((stream.symbols.out, stream.symbols.write,
                 stream.symbols.scope, stream.symbols.domain,
                 stream.symbols.language)))

        if global_scope is False:
            stream.scope[-1].add(stream.symbols.remote_scope)

        # set up initialization code
        stream.symbol_mapping['_init_stream'] = generation.initialize_stream
        stream.symbol_mapping['_init_scope'] = generation.initialize_scope
        stream.symbol_mapping['_init_tal'] = generation.initialize_tal
        stream.symbol_mapping['_init_default'] = generation.initialize_default

        # add code-generation lookup globals
        if debug:
            lookup = codegen.lookup_attr_debug
        else:
            lookup = codegen.lookup_attr
        stream.symbol_mapping['_lookup_attr'] = lookup

        if global_scope:
            assignments = (clauses.Assign(types.value("_init_stream()"),
                                          ("%(out)s", "%(write)s")),
                           clauses.Assign(types.value("_init_tal()"),
                                          ("%(attributes)s", "%(repeat)s")),
                           clauses.Assign(types.value("_init_default()"),
                                          '%(default_marker_symbol)s'),
                           clauses.Assign(types.value(repr(None)),
                                          '%(default)s'),
                           clauses.Assign(types.template("None"),
                                          "%(domain)s"))
        else:
            assignments = (clauses.Assign(
                types.template("%(scope)s['%(out)s'], %(scope)s['%(write)s']"),
                ("%(out)s", "%(write)s")),
                           clauses.Assign(types.value("_init_tal()"),
                                          ("%(attributes)s", "%(repeat)s")),
                           clauses.Assign(types.value("_init_default()"),
                                          '%(default_marker_symbol)s'),
                           clauses.Assign(types.value(repr(None)),
                                          '%(default)s'),
                           clauses.Assign(types.template("None"),
                                          "%(domain)s"))

        for clause in assignments:
            clause.begin(stream)
            clause.end(stream)

        if macro is not None:
            nsmap = {}
            namespaces = set()

            for tag in root.attrib:
                if '}' not in tag:
                    continue

                namespace = tag[1:].split('}')[0]
                namespaces.add(namespace)

            for prefix, namespace in root.nsmap.items():
                if namespace in namespaces:
                    nsmap[prefix] = namespace

            wrapper = self.tree.parser.makeelement(
                utils.meta_attr('wrapper'),
                utils.get_attributes_from_namespace(root, config.META_NS),
                nsmap=nsmap)
            wrapper.append(root)
            root = wrapper

        # output XML headers, if applicable
        if global_scope is True or macro is "":
            header = ""
            if self.xml_declaration is not None:
                header += self.xml_declaration + '\n'
            if self.doctype:
                doctype = self.doctype + '\n'
                if self.encoding:
                    doctype = doctype.encode(self.encoding)
                header += doctype
            if header:
                out = clauses.Out(header)
                stream.scope.append(set())
                stream.begin([out])
                stream.end([out])
                stream.scope.pop()

        # add meta settings
        root.meta_omit_default_prefix = self.omit_default_prefix

        # start generation
        root.start(stream)
        body = stream.getvalue()

        # symbols dictionary
        __dict__ = stream.symbols.as_dict()

        # prepare globals
        _globals = ["from cPickle import loads as _loads"]
        for symbol, value in stream.symbol_mapping.items():
            _globals.append("%s = _loads(%s)" % (symbol, repr(dumps(value))))

        transient = []
        for name, value in stream.symbols.as_dict().items():
            if value is config.TRANSIENT_SYMBOL:
                transient.append("%s = econtext.get('%s')" % (name, name))
        transient = "; ".join(transient)

        # wrap generated Python-code in function definition
        if global_scope:
            source = generation.function_wrap('render', _globals, body,
                                              transient,
                                              "%(out)s.getvalue()" % __dict__)
        else:
            source = generation.function_wrap('render', _globals, body,
                                              transient)

        suite = codegen.Suite(source)
        return suite.source