Commits

Luke Plant committed c18928a

Moved generic elementtree utils into separate module

Comments (0)

Files changed (3)

semanticeditor/utils/__init__.py

 from semanticeditor.utils.presentation import *
+from semanticeditor.utils.etree import *

semanticeditor/utils/etree.py

+"""
+ElementTree utils
+"""
+
+from elementtree import ElementTree as ET
+from xml.parsers import expat
+
+# ElementTree utilities
+
+def textjoin(a, b):
+    a = a or ''
+    b = b or ''
+    return a + b
+
+def cleanup(elem, filter):
+    """
+    Removes start and stop tags for any element for which the filter
+    function returns false.  If you want to remove the entire element,
+    including all subelements, use the 'clear' method inside the
+    filter callable.
+
+    Note that this function modifies the tree in place.
+    @param elem An element tree.
+    @param filter An filter function.  This should be a callable that
+    takes an element as its single argument.
+    """
+
+    out = []
+    for e in elem:
+        cleanup(e, filter)
+        if not filter(e):
+            if e.text:
+                if out:
+                    out[-1].tail = textjoin(out[-1].tail, e.text)
+                else:
+                    elem.text = textjoin(elem.text, e.text)
+            out.extend(e)
+            if e.tail:
+                if out:
+                    out[-1].tail = textjoin(out[-1].tail, e.tail)
+                else:
+                    elem.text = textjoin(elem.text, e.tail)
+        else:
+            out.append(e)
+    elem[:] = out
+
+def flatten(elem):
+    text = elem.text or ""
+    for e in elem:
+        text += flatten(e)
+        if e.tail:
+            text += e.tail
+    return text
+
+def get_parent(topnode, elem):
+    """
+    Return the parent of 'elem'.
+
+    topnode is the node to start searching from
+    """
+    for n in topnode.getiterator():
+        if elem in n.getchildren():
+            return n
+    return None
+
+def get_index(parent, elem):
+    """
+    Return the index of elem in parent's children
+    """
+    return list(parent.getchildren()).index(elem)
+
+def wrap_elements_in_tag(parent, start_idx, stop_idx, tag):
+    """
+    Wrap elements in parent at indices [start_idx:stop_idx] with
+    a new element
+    """
+    newelem = ET.Element(tag)
+    group = parent[start_idx:stop_idx]
+    newelem[:] = group
+    parent[start_idx:stop_idx] = [newelem]
+    return newelem
+

semanticeditor/utils/presentation.py

 """
 
 from elementtree import ElementTree as ET
+from semanticeditor.utils.etree import cleanup, flatten, get_parent, get_index, wrap_elements_in_tag
 from xml.parsers import expat
 
+### Errors ###
+
 class InvalidHtml(ValueError):
     pass
 
 class TooManyColumns(BadStructure):
     pass
 
+### Definitions ###
+
 headingdef = ['h1','h2','h3','h4','h5','h6']
 NEWROW = 'command:newrow'
 NEWCOL = 'command:newcolumn'
                      name="New column",
                      description="TODO")
 
-
 MAXCOLS = 4
 COLUMNCLASS = 'col'
 
-# Parsing
+### Parsing ###
 
 def parse(content):
     try:
         raise InvalidHtml("HTML content is not well formed.")
     return tree
 
-# ElementTree utilities
-
-def textjoin(a, b):
-    a = a or ''
-    b = b or ''
-    return a + b
-
-def cleanup(elem, filter):
-    """
-    Removes start and stop tags for any element for which the filter
-    function returns false.  If you want to remove the entire element,
-    including all subelements, use the 'clear' method inside the
-    filter callable.
-
-    Note that this function modifies the tree in place.
-    @param elem An element tree.
-    @param filter An filter function.  This should be a callable that
-    takes an element as its single argument.
-    """
-
-    out = []
-    for e in elem:
-        cleanup(e, filter)
-        if not filter(e):
-            if e.text:
-                if out:
-                    out[-1].tail = textjoin(out[-1].tail, e.text)
-                else:
-                    elem.text = textjoin(elem.text, e.text)
-            out.extend(e)
-            if e.tail:
-                if out:
-                    out[-1].tail = textjoin(out[-1].tail, e.tail)
-                else:
-                    elem.text = textjoin(elem.text, e.tail)
-        else:
-            out.append(e)
-    elem[:] = out
-
-def flatten(elem):
-    text = elem.text or ""
-    for e in elem:
-        text += flatten(e)
-        if e.tail:
-            text += e.tail
-    return text
-
-def get_parent(topnode, elem):
-    """
-    Return the parent of 'elem'.
-
-    topnode is the node to start searching from
-    """
-    for n in topnode.getiterator():
-        if elem in n.getchildren():
-            return n
-    return None
-
-def get_index(parent, elem):
-    """
-    Return the index of elem in parent's children
-    """
-    return list(parent.getchildren()).index(elem)
-
-def wrap_elements_in_tag(parent, start_idx, stop_idx, tag):
-    """
-    Wrap elements in parent at indices [start_idx:stop_idx] with
-    a new element
-    """
-    newelem = ET.Element(tag)
-    group = parent[start_idx:stop_idx]
-    newelem[:] = group
-    parent[start_idx:stop_idx] = [newelem]
-    return newelem
-
 ### Semantic editor functionality ###
 
 ## Presentation dictionary utilities