bsx avatar bsx committed 922d650

first hackish attempt to import Freemind

Comments (0)

Files changed (2)

MoinMoin/converter/freemind_in.py

+# Copyright: 2010 MoinMoin:BerndStolle
+# License: GNU GPL v2 (or any later version), see LICENSE.txt for details.
+
+"""
+MoinMoin - Freemind converter
+Converts a Freemind mindmap into an internal Document tree.
+"""
+
+from emeraldtree import ElementTree as ET
+
+from MoinMoin.util.tree import moin_page, xlink, xml, html
+
+from MoinMoin import log
+logging = log.getLogger(__name__)
+
+class NameSpaceError(Exception):
+    pass
+
+class Converter(object):
+    """
+    Convert a mindmap to internal representation.
+    """
+
+    @classmethod
+    def _factory(cls, input, output, **kw):
+        return cls()
+
+    def __call__(self, content, aruments=None):
+        self.section_depth = 0
+        self.heading_level = 0
+        self.is_section = False
+
+        self.standard_attribute = {}
+
+        mm_str = u''.join(content)
+        logging.debug(mm_str)
+        try:
+            tree = ET.XML(mm_str.encode('utf-8'))
+        except ET.ParseError as detail:
+            return self.error(str(detail))
+
+        try:
+            result = self.start_dom_tree(tree, 0)
+            result.write(logging.info)
+            return result
+        except NameSpaceError as detail:
+            return self.error(str(detail))
+
+    def visit(self, element, depth):
+        """
+        Function called at each element, to process it.
+
+        It will just determine the namespace of our element,
+        then call a dedicated function to handle conversion
+        for the given namespace.
+        """
+        name = element.tag
+        if name is not None:
+            method_name = 'visit_' + name
+            method = getattr(self, method_name, None)
+            if method is not None:
+                return method(element, depth)
+
+        # We did not recognize the namespace, we stop the conversion.
+        raise NameSpaceError("Unknown namespace")
+
+    def visit_map(self, element, depth):
+        children = []
+        for child in element:
+            c = self.visit(child, depth + 1)
+            if c:
+                if isinstance(c, list):
+                    children.extend(c)
+                else:
+                    children.append(c)
+        return children
+
+    def visit_node(self, element, depth):
+        text = element.get("TEXT")
+        children = []
+        body_tag = None
+        if text:
+            self.is_section = True
+            if depth <= 2:
+                attrib = {moin_page('outline-level'): depth}
+                children.append(self.new(moin_page.h, attrib, children=[text]))
+            else:
+                body_tag = self.new(moin_page('list-item-body'),
+                           attrib={}, children=[text])
+                children.append(self.new(moin_page('list-item'), {}, children=[body_tag]))
+        listitems = []
+        for child in element:
+            c = self.visit(child, depth+1)
+            if c:
+                if isinstance(c, list):
+                    listitems.extend(c)
+                else:
+                    listitems.append(c)
+        if len(listitems) > 0:
+            if body_tag:
+                body_tag.append(self.new(moin_page.list, {moin_page('item-label-generate'): 'unordered'}, children=listitems))
+            elif depth+1 > 2:
+                children.append(self.new(moin_page.list, {moin_page('item-label-generate'): 'unordered'}, children=listitems))
+            else:
+                children.extend(listitems)
+        return children
+
+    def visit_icon(self, element, depth):
+        pass
+
+    def visit_edge(self, element, depth):
+        pass
+
+    def visit_font(self, element, depth):
+        pass
+
+    def visit_richcontent(self, element, depth):
+        pass
+
+    def visit_hook(self, element, depth):
+        pass
+
+    def new(self, tag, attrib, children):
+        """
+        Return a new element for the DocBook Tree.
+        """
+        if self.standard_attribute:
+            attrib.update(self.standard_attribute)
+            self.standard_attribute = {}
+        return ET.Element(tag, attrib=attrib, children=children)
+
+    def error(self, message):
+        """
+        Return a DOM Tree containing an error message.
+        """
+        error = self.new(moin_page('error'), attrib={}, children=[message])
+        part = self.new(moin_page('part'), attrib={}, children=[error])
+        body = self.new(moin_page('body'), attrib={}, children=[part])
+        return self.new(moin_page('page'), attrib={}, children=[body])
+
+    def start_dom_tree(self, element, depth):
+        """
+        Return the root element of the DOM tree, with all the children.
+
+        We also add a <table-of-content> element if needed.
+        """
+        attrib = {}
+        if self.standard_attribute:
+            attrib.update(self.standard_attribute)
+            self.standard_attribute = {}
+        children = []
+        children.extend(self.visit(element, depth))
+        # We show the table of content only if it is not empty
+        if self.is_section:
+            children.insert(0, self.new(moin_page('table-of-content'),
+                                    attrib={}, children={}))
+        body = self.new(moin_page.body, attrib={}, children=children)
+        return self.new(moin_page.page, attrib=attrib, children=[body])
+
+
+from . import default_registry
+from MoinMoin.util.mime import Type, type_moin_document
+default_registry.register(Converter._factory, Type('application/x-freemind'), type_moin_document)

MoinMoin/items/__init__.py

 
 item_registry.register(DocBook._factory, Type('application/docbook+xml'))
 
+class Freemind(MarkupItem):
+    """ Mindmap """
+
+item_registry.register(Freemind._factory, Type('application/x-freemind'))
 
 class TWikiDraw(TarMixin, Image):
     """
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.