Alcaic Research and technology, not iambic verse.


XSL hacking for fun (and mindmapping interop)

The itch to scratch this time is the need to have an efficient mind mapping environment that also allows for clean graphics and a lot of flexibility, as well as be cross-platform and well supported.

What was tried first

I wanted a free, well supported mind mapping program, preferably cross-platform. It should enable quick creation of mind maps (to be shared with others) and editable to add cross links and clean up in an graphical editor afterwards. My program of choice, Omnigraffle, is nice, but it is not cross-platform, nor is it (for me) anywhere need efficient enough to quickly mind map (through keyboard controls). Don't mention the price either.

So, the choice was narrowed down to FreeMind (whose format also seems to be widely supported). The one minus: it did not have the capability to add names to connecting links. Another candidate, Xmind had that capacity, but I did not care much for the interface, nor did it seem as well supported or as future proof. This took care of the mindmapping part.

For the editor, I could live with it not being crossplatform, so the next step was to find a way to get FreeMind (FM) files into Omnigraffle (OG). No dice. Copy-pasting the text did not work, there is no export format supported in FM that OG can import, and going through OmniOutliner also seemed to be a dead end (although this was suggested in some fora).

Try 2

Now, I luckily remembered that OG reads graphviz .dot files. And according to this , there is an XSLT ("whatever that is", was my initial response) that allows for the export. Unfortunately, a download of that file proved empty (Sourceforge error?).

I was really annoyed, so I looked at some examples of XSLT, and decided to craft my own. This is what came up with : transformfreemind2dot - here is the github repo:

Commented code

If you do not know XSLT, you should! It is a really powerful way to map one markup (or more specifically, xml markup) into another shape/format. Here is an explanation of how the code works:

We want to output text:


And now we're going to search for the first map tag. Once found, we output the start of the .dot file, and go through all the nodes twice: once to create them and once to link them. digraph export {


Here we create the labels. We match each node and then create a label name based on its ID attribute (which should be unique). A label is assigned then, based on the TEXT attribute (which is what you inputted into the mind map). This is done recursively, if there are subnodes (the choose statement is probably superfluous, but I wanted to add a blank line). [label=""];  

This is the part that creates the links. We first check with test="parent::node" if we are at least one deep in the map (otherwise, there is no parent node) and then link each node with its parent. Since a FreeMind mindmap has no crosslinks (i.e. each node has only one parent, this works).

-> ;


final result


The mindmap in freemind

The mindmap in freemind


Converted to .dot

Converted to .dot (shown using graphviz)

Ending at:

Editable in OmniGraffle

Editable in OmniGraffle

Future work

I'll probably add some additional code to also convert internal links to additional graph edges.

Comments (0) Trackbacks (0)

No comments yet.

Leave a comment

No trackbacks yet.