# HG changeset patch # User zzzeek # Date 1162947313 0 # Node ID 2fdf34945dfd499ddab90ec09a9db7014e602a2f # Parent d8fc236ca3d8ce32b89430c46208dbc320f7421e got a few more unit tests working. need to figure out path.select() better diff --git a/genshi/codegen/adapters.py b/genshi/codegen/adapters.py --- a/genshi/codegen/adapters.py +++ b/genshi/codegen/adapters.py @@ -63,7 +63,10 @@ class InlineQName(unicode): """creates a QName-like object from a START event""" def __new__(cls, event): - self = unicode.__new__(cls, u'{%s}%s' % (event[1][0], event[1][1])) + if event[1][0] is not None: + self = unicode.__new__(cls, u'{%s}%s' % (event[1][0], event[1][1])) + else: + self = unicode.__new__(cls, u'%s' % (event[1][1])) self.namespace = event[1][0] self.localname = event[1][1] return self diff --git a/genshi/codegen/generator.py b/genshi/codegen/generator.py --- a/genshi/codegen/generator.py +++ b/genshi/codegen/generator.py @@ -112,7 +112,7 @@ class Generator(object): """given a Template, generates Python modules (as strings or code objects) optimized to a particular Serializer.""" - def __init__(self, template, method='html', serializer=None, strip_whitespace=False, filters=None): + def __init__(self, template, method='html', serializer=None, strip_whitespace=False, compress_empty=False, filters=None): self.template = template self.serializer = serializer or ({ 'xml': serialize.XMLSerializeFilter, @@ -122,6 +122,8 @@ self.code = self._generate_module() self.filters = filters or [] + if compress_empty: + self.filters.append(output.EmptyTagFilter()) if strip_whitespace: self.filters.append(output.PostWhitespaceFilter()) def generate(self, *args, **kwargs): @@ -164,7 +166,8 @@ expr = parse(expr, "eval") visitor.walk(expr, self) def visitName(self, node, *args, **kwargs): - self.identifiers.add(node.name) + if node.name not in __builtins__: + self.identifiers.add(node.name) class PythonGenerator(object): def __init__(self, stream, serializer): diff --git a/genshi/codegen/interp.py b/genshi/codegen/interp.py --- a/genshi/codegen/interp.py +++ b/genshi/codegen/interp.py @@ -56,7 +56,7 @@ #for filter_ in self.filters[3:]: # content = filter_(content, ctxt) content = list(content) - + for test in [mt[0] for mt in match_templates]: test(tail[0][0:3], namespaces, ctxt, updateonly=True) @@ -70,12 +70,24 @@ else: yield event +# TODO: this adds too much overhead +def _ensure(stream): + """Ensure that every item on the stream is actually an inline event.""" + for event in stream: + if type(event) is not tuple: + if hasattr(event, 'totuple'): + event = event.totuple() + else: + event = TEXT, unicode(event), (None, -1, -1), unicode(event) + yield event + def evaluate(result, pos): if result is not None: if isinstance(result, basestring): yield TEXT, result, pos, result elif hasattr(result, '__iter__'): - for event in result: + substream = _ensure(result) + for event in substream: yield event else: yield TEXT, unicode(result), pos, result diff --git a/genshi/codegen/output.py b/genshi/codegen/output.py --- a/genshi/codegen/output.py +++ b/genshi/codegen/output.py @@ -12,6 +12,27 @@ END_CDATA, PI, COMMENT, XML_NAMESPACE +class EmptyTagFilter(object): + """Combines `START` and `STOP` events into `EMPTY` events for elements that + have no contents. + """ + EMPTY = StreamEventKind('EMPTY') + + def __call__(self, stream): + prev = (None, None, None, None) + for kind, data, pos, literal in stream: + if prev[0] is START: + if kind is END: + prev = EMPTY, prev[1], prev[2], prev[3][:-1] + '/>' + yield prev + continue + else: + yield prev + if kind is not START: + yield kind, data, pos, literal + prev = kind, data, pos, literal +EMPTY = EmptyTagFilter.EMPTY + class PostWhitespaceFilter(object): """A filter that removes extraneous ignorable white space from the stream.""" diff --git a/genshi/codegen/tests/template.py b/genshi/codegen/tests/template.py --- a/genshi/codegen/tests/template.py +++ b/genshi/codegen/tests/template.py @@ -12,8 +12,8 @@ class MarkupTemplateAdapter(object): def __init__(self, text): - self.generator = Generator(RealMarkupTemplate(text), strip_whitespace=True) - print u''.join(self.generator._generate_code_events()) + self.generator = Generator(RealMarkupTemplate(text), strip_whitespace=True, compress_empty=True) + #print u''.join(self.generator._generate_code_events()) def generate(self, *args, **kwargs): return self.generator.generate(*args, **kwargs)