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
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
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
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