From d48d93c09747c130e6e2ccd5ebefe23281c4e917 Mon Sep 17 00:00:00 2001 From: Christopher Lenz Date: Tue, 13 Oct 2009 18:12:55 +0000 Subject: [PATCH] Backported a couple of templating core changes from the advanced-i18n branch, in particular considering the determination of directive ordering../set --- genshi/template/base.py | 28 ++++++++++++++++------------ genshi/template/directives.py | 11 ++--------- genshi/template/markup.py | 11 ++++++----- genshi/template/text.py | 6 +++--- 4 files changed, 27 insertions(+), 29 deletions(-) diff --git a/genshi/template/base.py b/genshi/template/base.py index 92e0f22e..317b9336 100644 --- a/genshi/template/base.py +++ b/genshi/template/base.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright (C) 2006-2008 Edgewall Software +# Copyright (C) 2006-2009 Edgewall Software # All rights reserved. # # This software is licensed as described in the file COPYING, which @@ -321,16 +321,6 @@ class DirectiveFactory(object): provided by this factory. """ - def compare_directives(self): - """Return a function that takes two directive classes and compares - them to determine their relative ordering. - """ - def _get_index(cls): - if cls in self._dir_order: - return self._dir_order.index(cls) - return 0 - return lambda a, b: cmp(_get_index(a[0]), _get_index(b[0])) - def get_directive(self, name): """Return the directive class for the given name. @@ -340,6 +330,20 @@ def get_directive(self, name): """ return self._dir_by_name.get(name) + def get_directive_index(self, dir_cls): + """Return a key for the given directive class that should be used to + sort it among other directives on the same `SUB` event. + + The default implementation simply returns the index of the directive in + the `directives` list. + + :param dir_cls: the directive class + :return: the sort key + """ + if dir_cls in self._dir_order: + return self._dir_order.index(dir_cls) + return len(self._dir_order) + class Template(DirectiveFactory): """Abstract template base class. @@ -451,7 +455,7 @@ def _prepare(self, stream): if kind is SUB: directives = [] substream = data[1] - for cls, value, namespaces, pos in data[0]: + for _, cls, value, namespaces, pos in sorted(data[0]): directive, substream = cls.attach(self, substream, value, namespaces, pos) if directive: diff --git a/genshi/template/directives.py b/genshi/template/directives.py index 8b56fe4d..29f31181 100644 --- a/genshi/template/directives.py +++ b/genshi/template/directives.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright (C) 2006-2008 Edgewall Software +# Copyright (C) 2006-2009 Edgewall Software # All rights reserved. # # This software is licensed as described in the file COPYING, which @@ -527,7 +527,7 @@ class StripDirective(Directive): def __call__(self, stream, directives, ctxt, **vars): def _generate(): - if _eval_expr(self.expr, ctxt, vars): + if not self.expr or _eval_expr(self.expr, ctxt, vars): stream.next() # skip start tag previous = stream.next() for event in stream: @@ -538,13 +538,6 @@ def _generate(): yield event return _apply_directives(_generate(), directives, ctxt, vars) - @classmethod - def attach(cls, template, stream, value, namespaces, pos): - if not value: - return None, stream[1:-1] - return super(StripDirective, cls).attach(template, stream, value, - namespaces, pos) - class ChooseDirective(Directive): """Implementation of the ``py:choose`` directive for conditionally selecting diff --git a/genshi/template/markup.py b/genshi/template/markup.py index 1049c0b8..e7af0546 100644 --- a/genshi/template/markup.py +++ b/genshi/template/markup.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright (C) 2006-2008 Edgewall Software +# Copyright (C) 2006-2009 Edgewall Software # All rights reserved. # # This software is licensed as described in the file COPYING, which @@ -131,7 +131,8 @@ def _extract_directives(self, stream, namespace, factory): self.filepath, pos[1]) args = dict([(name.localname, value) for name, value in attrs if not name.namespace]) - directives.append((cls, args, ns_prefix.copy(), pos)) + directives.append((factory.get_directive_index(cls), cls, + args, ns_prefix.copy(), pos)) strip = True new_attrs = [] @@ -143,14 +144,14 @@ def _extract_directives(self, stream, namespace, factory): self.filepath, pos[1]) if type(value) is list and len(value) == 1: value = value[0][1] - directives.append((cls, value, ns_prefix.copy(), - pos)) + directives.append((factory.get_directive_index(cls), + cls, value, ns_prefix.copy(), pos)) else: new_attrs.append((name, value)) new_attrs = Attrs(new_attrs) if directives: - directives.sort(self.compare_directives()) + directives.sort() dirmap[(depth, tag)] = (directives, len(new_stream), strip) diff --git a/genshi/template/text.py b/genshi/template/text.py index 87471a55..b3063b68 100644 --- a/genshi/template/text.py +++ b/genshi/template/text.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright (C) 2006-2008 Edgewall Software +# Copyright (C) 2006-2009 Edgewall Software # All rights reserved. # # This software is licensed as described in the file COPYING, which @@ -219,7 +219,7 @@ def _escape_repl(mo): cls = self.get_directive(command) if cls is None: raise BadDirectiveError(command) - directive = cls, value, None, (self.filepath, lineno, 0) + directive = 0, cls, value, None, (self.filepath, lineno, 0) dirmap[depth] = (directive, len(stream)) depth += 1 @@ -315,7 +315,7 @@ def _parse(self, source, encoding): cls = self.get_directive(command) if cls is None: raise BadDirectiveError(command) - directive = cls, value, None, (self.filepath, lineno, 0) + directive = 0, cls, value, None, (self.filepath, lineno, 0) dirmap[depth] = (directive, len(stream)) depth += 1