style
[librarian.git] / librarian / xmlutils.py
index 9e921a2..ae3512a 100644 (file)
@@ -12,24 +12,34 @@ class Xmill(object):
     Used instead of XSLT which is difficult and cumbersome.
 
     """
     Used instead of XSLT which is difficult and cumbersome.
 
     """
-    def __init__(self, options=None):
+    def __init__(self, options=None, state=None):
         self._options = []
         self._options = []
+        self.state = state or {}
         if options:
             self._options.append(options)
         self.text_filters = []
         if options:
             self._options.append(options)
         self.text_filters = []
+        self.escaped_text_filters = []
 
     def register_text_filter(self, fun):
         self.text_filters.append(fun)
 
 
     def register_text_filter(self, fun):
         self.text_filters.append(fun)
 
+    def register_escaped_text_filter(self, fun):
+        self.escaped_text_filters.append(fun)
+
     def filter_text(self, text):
         for flt in self.text_filters:
             if text is None:
                 return None
     def filter_text(self, text):
         for flt in self.text_filters:
             if text is None:
                 return None
-            text = flt(text)
+            else:
+                text = flt(text)
         # TODO: just work on the tree and let lxml handle escaping.
         e = etree.Element("x")
         e.text = text
         # TODO: just work on the tree and let lxml handle escaping.
         e = etree.Element("x")
         e.text = text
-        return etree.tostring(e, encoding=unicode)[3:-4]
+        # This whole mixing text with ML is so wrong.
+        output = etree.tostring(e, encoding=unicode)[3:-4]
+        for flt in self.escaped_text_filters:
+            output = flt(output)
+        return output
 
     def generate(self, document):
         """Generate text from node using handlers defined in class."""
 
     def generate(self, document):
         """Generate text from node using handlers defined in class."""
@@ -50,18 +60,17 @@ class Xmill(object):
         """
         self._options.append(opts)
 
         """
         self._options.append(opts)
 
-
     def _handle_for_element(self, element):
         ns = None
         tagname = None
     def _handle_for_element(self, element):
         ns = None
         tagname = None
-#        from nose.tools import set_trace
+        # from nose.tools import set_trace
 
         if element.tag[0] == '{':
             for nshort, nhref in element.nsmap.items():
                 try:
                     if element.tag.index('{%s}' % nhref) == 0:
                         ns = nshort
 
         if element.tag[0] == '{':
             for nshort, nhref in element.nsmap.items():
                 try:
                     if element.tag.index('{%s}' % nhref) == 0:
                         ns = nshort
-                        tagname  = element.tag[len('{%s}' % nhref):]
+                        tagname = element.tag[len('{%s}' % nhref):]
                         break
                 except ValueError:
                     pass
                         break
                 except ValueError:
                     pass
@@ -85,18 +94,22 @@ class Xmill(object):
 
         while True:
             sibling = element.getnext()
 
         while True:
             sibling = element.getnext()
-            if sibling is not None: return sibling  # found a new branch to dig into
+            if sibling is not None:
+                return sibling  # found a new branch to dig into
             element = element.getparent()
             element = element.getparent()
-            if element is None: return None  # end of tree
+            if element is None:
+                return None  # end of tree
 
     def _handle_element(self, element):
 
     def _handle_element(self, element):
-        if isinstance(element, etree._Comment): return None
-        
+        if isinstance(element, etree._Comment):
+            return None
+
         handler = self._handle_for_element(element)
         handler = self._handle_for_element(element)
+        if self.state.get('mute') and not getattr(handler, 'unmuter', False):
+            return None
         # How many scopes
         # How many scopes
+        options_scopes = len(self._options)
         try:
         try:
-            options_scopes = len(self._options)
-
             if handler is None:
                 pre = [self.filter_text(element.text)]
                 post = [self.filter_text(element.tail)]
             if handler is None:
                 pre = [self.filter_text(element.text)]
                 post = [self.filter_text(element.tail)]
@@ -117,18 +130,20 @@ class Xmill(object):
         finally:
             # clean up option scopes if necessary
             self._options = self._options[0:options_scopes]
         finally:
             # clean up option scopes if necessary
             self._options = self._options[0:options_scopes]
+
         return out
 
 
 def tag_open_close(name_, classes_=None, **attrs):
     u"""Creates tag beginning and end.
         return out
 
 
 def tag_open_close(name_, classes_=None, **attrs):
     u"""Creates tag beginning and end.
-    
+
     >>> tag_open_close("a", "klass", x=u"ą<")
     (u'<a x="\\u0105&lt;" class="klass">', u'</a>')
 
     """
     if classes_:
     >>> tag_open_close("a", "klass", x=u"ą<")
     (u'<a x="\\u0105&lt;" class="klass">', u'</a>')
 
     """
     if classes_:
-        if isinstance(classes_, (tuple, list)): classes_ = ' '.join(classes_)
+        if isinstance(classes_, (tuple, list)):
+            classes_ = ' '.join(classes_)
         attrs['class'] = classes_
 
     e = etree.Element(name_)
         attrs['class'] = classes_
 
     e = etree.Element(name_)
@@ -138,6 +153,7 @@ def tag_open_close(name_, classes_=None, **attrs):
     pre, post = etree.tostring(e, encoding=unicode).split(u"> <")
     return pre + u">", u"<" + post
 
     pre, post = etree.tostring(e, encoding=unicode).split(u"> <")
     return pre + u">", u"<" + post
 
+
 def tag(name_, classes_=None, **attrs):
     """Returns a handler which wraps node contents in tag `name', with class attribute
     set to `classes' and other attributes according to keyword paramters
 def tag(name_, classes_=None, **attrs):
     """Returns a handler which wraps node contents in tag `name', with class attribute
     set to `classes' and other attributes according to keyword paramters
@@ -152,13 +168,16 @@ def tagged(name, classes=None, **attrs):
     set to `classes' and other attributes according to keyword paramters
     """
     if classes:
     set to `classes' and other attributes according to keyword paramters
     """
     if classes:
-        if isinstance(classes, (tuple,list)): classes = ' '.join(classes)
+        if isinstance(classes, (tuple, list)):
+            classes = ' '.join(classes)
         attrs['class'] = classes
         attrs['class'] = classes
-    a = ''.join([' %s="%s"' % (k,v) for (k,v) in attrs.items()])
+    a = ''.join([' %s="%s"' % (k, v) for (k, v) in attrs.items()])
+
     def _decor(f):
         def _wrap(self, element):
             r = f(self, element)
     def _decor(f):
         def _wrap(self, element):
             r = f(self, element)
-            if r is None: return
+            if r is None:
+                return
 
             prepend = "<%s%s>" % (name, a)
             append = "</%s>" % name
 
             prepend = "<%s%s>" % (name, a)
             append = "</%s>" % name
@@ -183,6 +202,7 @@ def ifoption(**options):
         return _handler
     return _decor
 
         return _handler
     return _decor
 
+
 def flatten(l, ltypes=(list, tuple)):
     """flatten function from BasicPropery/BasicTypes package
     """
 def flatten(l, ltypes=(list, tuple)):
     """flatten function from BasicPropery/BasicTypes package
     """