Index: markup.py
===================================================================
--- markup.py	(Revision 47)
+++ markup.py	(Arbeitskopie)
@@ -18,12 +18,12 @@
 from genshi.core import Attrs, Markup, Namespace, Stream, StreamEventKind
 from genshi.core import START, END, START_NS, END_NS, TEXT, PI, COMMENT
 from genshi.input import XMLParser
-from genshi.template.base import BadDirectiveError, Template, \
-                                 TemplateSyntaxError, _apply_directives, \
-                                 EXEC, INCLUDE, SUB
+from genshi.template.base import Template, TemplateSyntaxError, \
+                                 _apply_directives, EXEC, INCLUDE, SUB
 from genshi.template.eval import Suite
+from genshi.template.directives import DirectivesLibraryManager, \
+                                       UnknownDirectiveError
 from genshi.template.interpolation import interpolate
-from genshi.template.directives import *
 from genshi.template.text import NewTextTemplate
 
 __all__ = ['MarkupTemplate']
@@ -42,30 +42,19 @@
     </ul>
     """
 
-    DIRECTIVE_NAMESPACE = 'http://genshi.edgewall.org/'
     XINCLUDE_NAMESPACE = 'http://www.w3.org/2001/XInclude'
 
-    directives = [('def', DefDirective),
-                  ('match', MatchDirective),
-                  ('when', WhenDirective),
-                  ('otherwise', OtherwiseDirective),
-                  ('for', ForDirective),
-                  ('if', IfDirective),
-                  ('choose', ChooseDirective),
-                  ('with', WithDirective),
-                  ('replace', ReplaceDirective),
-                  ('content', ContentDirective),
-                  ('attrs', AttrsDirective),
-                  ('strip', StripDirective)]
     serializer = 'xml'
     _number_conv = Markup
 
     def __init__(self, source, filepath=None, filename=None, loader=None,
-                 encoding=None, lookup='strict', allow_exec=True):
+                 encoding=None, lookup='strict', allow_exec=True,
+                 directives_library_manager=None):
         Template.__init__(self, source, filepath=filepath, filename=filename,
                           loader=loader, encoding=encoding, lookup=lookup,
-                          allow_exec=allow_exec)
-        self.add_directives(self.DIRECTIVE_NAMESPACE, self)
+                          allow_exec=allow_exec, directives_library_manager= \
+                          directives_library_manager)
+        self._stream = self._extract_directives(self._stream)
 
     def _init_filters(self):
         Template._init_filters(self)
@@ -111,12 +100,14 @@
 
         return stream
 
-    def _extract_directives(self, stream, namespace, factory):
+    def _extract_directives(self, stream):
         depth = 0
         dirmap = {} # temporary mapping of directives to elements
         new_stream = []
         ns_prefix = {} # namespace prefixes in use
 
+        library = self.directives_library
+
         for kind, data, pos in stream:
 
             if kind is START:
@@ -124,34 +115,51 @@
                 directives = []
                 strip = False
 
-                if tag.namespace == namespace:
-                    cls = factory.get_directive(tag.localname)
+                if library.defines_namespace(tag.namespace):
+                    cls = library.get_directive(tag.localname, 
+                                                namespace=tag.namespace)
                     if cls is None:
-                        raise BadDirectiveError(tag.localname,
-                                                self.filepath, pos[1])
+                        raise UnknownDirectiveError(tag.localname,
+                                                    self.filepath, pos[1])
+# FIXME:axn arguments to directives should be in the namespace of
+# the directive, alternatively one may use no namespace at all
+# for when using namespaces, must make sure that no directive of that
+# namespace is being defined in the library 
                     args = dict([(name.localname, value) for name, value
                                  in attrs if not name.namespace])
-                    directives.append((factory.get_directive_index(cls), cls,
-                                       args, ns_prefix.copy(), pos))
+
+                    directives.append((
+                        library.get_directive_priority(tag.localname, 
+                                                       namespace=
+                                                       tag.namespace),
+                                                       cls, args, 
+                                                       ns_prefix.copy(),
+                                                       pos))
                     strip = True
 
                 new_attrs = []
                 for name, value in attrs:
-                    if name.namespace == namespace:
-                        cls = factory.get_directive(name.localname)
+                    if library.defines_namespace(name.namespace):
+                        cls = library.get_directive(name.localname, 
+                                                    namespace=name.namespace)
                         if cls is None:
-                            raise BadDirectiveError(name.localname,
-                                                    self.filepath, pos[1])
+                            raise UnknownDirectiveError(name.localname,
+                                                        self.filepath, pos[1])
                         if type(value) is list and len(value) == 1:
                             value = value[0][1]
-                        directives.append((factory.get_directive_index(cls),
-                                           cls, value, ns_prefix.copy(), pos))
+                        directives.append((
+                            library.get_directive_priority(name.localname, 
+                                                           namespace=
+                                                           name.namespace),
+                                                           cls, value, 
+                                                           ns_prefix.copy(),
+                                                           pos))
                     else:
                         new_attrs.append((name, value))
                 new_attrs = Attrs(new_attrs)
 
                 if directives:
-                    directives.sort()
+                    #directives.sort()
                     dirmap[(depth, tag)] = (directives, len(new_stream),
                                             strip)
 
@@ -176,8 +184,7 @@
 
             elif kind is SUB:
                 directives, substream = data
-                substream = self._extract_directives(substream, namespace,
-                                                     factory)
+                substream = self._extract_directives(substream)
 
                 if len(substream) == 1 and substream[0][0] is SUB:
                     added_directives, substream = substream[0][1]
@@ -190,12 +197,12 @@
                 # directives
                 prefix, uri = data
                 ns_prefix[prefix] = uri
-                if uri != namespace:
+                if not library.defines_namespace(uri):
                     new_stream.append((kind, data, pos))
 
             elif kind is END_NS:
                 uri = ns_prefix.pop(data, None)
-                if uri and uri != namespace:
+                if uri and not library.defines_namespace(uri):
                     new_stream.append((kind, data, pos))
 
             else:
@@ -291,20 +298,6 @@
             self._extract_includes(self._interpolate_attrs(stream))
         )
 
-    def add_directives(self, namespace, factory):
-        """Register a custom `DirectiveFactory` for a given namespace.
-        
-        :param namespace: the namespace URI
-        :type namespace: `basestring`
-        :param factory: the directive factory to register
-        :type factory: `DirectiveFactory`
-        :since: version 0.6
-        """
-        assert not self._prepared, 'Too late for adding directives, ' \
-                                   'template already prepared'
-        self._stream = self._extract_directives(self._stream, namespace,
-                                                factory)
-
     def _match(self, stream, ctxt, start=0, end=None, **vars):
         """Internal stream filter that applies any defined match templates
         to the stream.
@@ -327,6 +320,14 @@
                     append(event)
                     break
 
+        # Make the select() function available in the body of the
+        # match template
+        selected = [False]
+        def select(path):
+            selected[0] = True
+            return content.select(path, namespaces, ctxt)
+        vars['select'] = select
+
         for event in stream:
 
             # We (currently) only care about start and end events for matching
@@ -365,14 +366,6 @@
                         content = list(content)
                     content = Stream(content)
 
-                    # Make the select() function available in the body of the
-                    # match template
-                    selected = [False]
-                    def select(path):
-                        selected[0] = True
-                        return content.select(path, namespaces, ctxt)
-                    vars = dict(select=select)
-
                     # Recursively process the output
                     template = _apply_directives(template, directives, ctxt,
                                                  vars)
