Import and export: Difference between revisions
(→VYM) |
|||
(94 intermediate revisions by 27 users not shown) | |||
Line 1: | Line 1: | ||
: ''For conversion scripts and XSLT, see also [[Accessories]].'' | : ''For conversion scripts and XSLT, see also [[Accessories]].'' | ||
== | |||
Import and export to other applications, alias conversion between FreeMind and other data formats: | |||
== Overview and miscellaneous == | |||
* '''To and from Microsoft Excel''' Import and export with Microsoft Excel works by drag & drop or copy & paste of complete nodes. You can copy a selection of cells in Excel and drop it in FreeMind. Doing this with several columns, creates corresponding child nodes. This also works with the '''OpenOffice.org Calc''' spreadsheet application. | * '''To and from Microsoft Excel''' Import and export with Microsoft Excel works by drag & drop or copy & paste of complete nodes. You can copy a selection of cells in Excel and drop it in FreeMind. Doing this with several columns, creates corresponding child nodes. This also works with the '''OpenOffice.org Calc''' spreadsheet application. | ||
Line 6: | Line 9: | ||
* '''To Microsoft Word 2003''' To export to Microsoft Word, you need to select only the top-most node, which you want to export. Next, copy the node in Freemind and paste it into Word. this will copy the entire hierarchy starting with the selected node. This works even, when not all sub-notes were to the right of the one selected. If you would select and copy all nodes, export would end up with duplicate nodes and sub-nodes. | * '''To Microsoft Word 2003''' To export to Microsoft Word, you need to select only the top-most node, which you want to export. Next, copy the node in Freemind and paste it into Word. this will copy the entire hierarchy starting with the selected node. This works even, when not all sub-notes were to the right of the one selected. If you would select and copy all nodes, export would end up with duplicate nodes and sub-nodes. | ||
*'''From Microsoft Word 2003''' Importing from Microsoft Word ended up with a confused hierarchy. (Please, can someone try how to do this best). | *'''From Microsoft Word 2003''' Importing from Microsoft Word ended up with a confused hierarchy. (Please, can someone try how to do this best). | ||
* '''From KeyNote''' To prepare a file from Keynote save your tree structure by selecting 'Tree > Save Tree to File'. Open the created file as a text file and use select all to copy all content. | * '''From KeyNote''' To prepare a file from Keynote, save your tree structure by selecting 'Tree > Save Tree to File'. Open the created file as a text file and use select all to copy all content. In FreeMind, select a node and paste the content. FreeMind analyzes the tree structure in the file and builds a mind map. | ||
* '''From the Internet''' You can copy part of a web page in your browser and paste it to FreeMind. FreeMind analyzes the tree structure in the HTML and builds a mind map. The other formatting (bold, font sizes, etc.) is not taken into FreeMind. | * '''From the Internet''' You can copy part of a web page in your browser and paste it to FreeMind. FreeMind analyzes the tree structure in the HTML and builds a mind map. The other formatting (bold, font sizes, etc.) is not taken into FreeMind. | ||
* '''To and from GanttProject''' To do this you will need the [http://johanneskutsam.spaces.live.com/blog/cns!1961B7AE7280AAFD!264.entry XSL conversion script]. If you don't want to download the xalan package, you can use the xsl template in the zip archive on this page from FreeMind File > [[Export using XSLT]].... | |||
* '''To and from | |||
* Almost every outliner should be capable of exporting to a tab-indented outline. This can be pasted to FreeMind. | * Almost every outliner should be capable of exporting to a tab-indented outline. This can be pasted to FreeMind. | ||
* '''To and from GoalEnforcer''' Click the ""Software Integration"" button on GoalEnforcer Hyperfocus main window. Select ""Import from FreeMind"" or ""Export to FreeMind."" | * '''To and from GoalEnforcer''' Click the ""Software Integration"" button on GoalEnforcer Hyperfocus main window. Select ""Import from FreeMind"" or ""Export to FreeMind."" | ||
== Emacs and Wikipedia outlines | == FreeMind == | ||
FreeMind to FreeMind (Hoist): | |||
Changing the root node of a map could make it much easier to print. This hoist.xsl script needs a graphical link from the actual root node to the desired root node after the hoist operation. The former parent node become a child node of the new root and the ancestor tree turns like an umbrella in the storm. Try it: | |||
# select the root node and the desired new root and place a graphical link. | |||
# export using hoist.xsl | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> | |||
<xsl:template match="*|@*"> | |||
<xsl:copy> | |||
<xsl:copy-of select="@*"/> | |||
<xsl:apply-templates/> | |||
</xsl:copy> | |||
</xsl:template> | |||
<xsl:template match="/map"> | |||
<xsl:copy> | |||
<xsl:copy-of select="attribute_registry"/> | |||
<xsl:apply-templates select="//node[@ID=/map/node/arrowlink/@DESTINATION]"/> | |||
</xsl:copy> | |||
</xsl:template> | |||
<xsl:template match="//node[@ID=/map/node/arrowlink/@DESTINATION]"> | |||
<xsl:copy> | |||
<xsl:copy-of select="*|@*"/> | |||
<xsl:apply-templates select="." mode="aws"/> | |||
</xsl:copy> | |||
</xsl:template> | |||
<xsl:template match="node" mode="aws"> | |||
<xsl:if test="parent::node"> | |||
<xsl:element name="node"> | |||
<xsl:attribute name="TEXT"> | |||
<xsl:value-of select="../@TEXT"/> | |||
</xsl:attribute> | |||
<xsl:attribute name="ID"> | |||
<xsl:value-of select="../@ID"/> | |||
</xsl:attribute> | |||
<xsl:if test="../@BACKGROUND_COLOR"> | |||
<xsl:attribute name="BACKGROUND_COLOR"> | |||
<xsl:value-of select="../@BACKGROUND_COLOR"/> | |||
</xsl:attribute> | |||
</xsl:if> | |||
<xsl:if test="../@COLOR"> | |||
<xsl:attribute name="COLOR"> | |||
<xsl:value-of select="../@COLOR"/> | |||
</xsl:attribute> | |||
</xsl:if> | |||
<xsl:if test="../@STYLE"> | |||
<xsl:attribute name="STYLE"> | |||
<xsl:value-of select="../@STYLE"/> | |||
</xsl:attribute> | |||
</xsl:if> | |||
<xsl:if test="../@POSITION"> | |||
<xsl:attribute name="POSITION"> | |||
<xsl:value-of select="../@POSITION"/> | |||
</xsl:attribute> | |||
</xsl:if> | |||
<xsl:apply-templates select="../edge|../arrowlink|../font|../icon"/> | |||
<xsl:apply-templates select="preceding-sibling::node"/> | |||
<xsl:apply-templates select="following-sibling::node"/> | |||
<xsl:apply-templates select="parent::node" mode="aws"/> | |||
<xsl:apply-templates select="../attribute"/> | |||
</xsl:element> | |||
</xsl:if> | |||
</xsl:template> | |||
</xsl:stylesheet> | |||
# if you are missing something, you have to add it to the template match="node" mode="aws" (I only need edge, font, icon and attribute and don't know what else is possible.) | |||
# load your new map | |||
[[User:JR|JR]] 03:32, 17 Apr 2008 (PDT) | |||
== Emacs == | |||
Convesion from FreeMind to Emacs outlines and Wikipedia outlines: | |||
There are two ways how to export FreeMind's mind map to the outline format understood by Emacs outlining mode and Wikipedia. Their descriptions follow. | There are two ways how to export FreeMind's mind map to the outline format understood by Emacs outlining mode and Wikipedia. Their descriptions follow. | ||
Line 21: | Line 94: | ||
=== Use conversion scripts === | === Use conversion scripts === | ||
Our | Our users have created two perl scripts for conversion between FreeMind and Emacs's outline. | ||
<!-- | <!-- | ||
Line 31: | Line 104: | ||
* [http://www.clemburg.com/install/mm2outline mm2outline] for Emacs outline (Perl) (This version does not work for wikipedia!) | * [http://www.clemburg.com/install/mm2outline mm2outline] for Emacs outline (Perl) (This version does not work for wikipedia!) | ||
Unfortunately none of those links works at the moment (2008-02-20). | <pre>#!/usr/bin/perl -w | ||
I am also unable to find the scripts somewhere else | use strict; | ||
use Getopt::Std; | |||
use XML::Simple; | |||
use Data::Dumper qw(Dumper); | |||
# Copyright (c) 2004 Christian Lemburg. | |||
# | |||
# All rights reserved. This program is free software; | |||
# you can redistribute it and/or modify it under the | |||
# same terms as Perl itself. | |||
# usage | |||
my $usage = <<'EOU'; | |||
Usage: $0 < freemind.mm > emacs-outline.txt | |||
Options: | |||
h: print help | |||
p: outline mode heading indicator pattern atom (default "*") | |||
s: suppress topic of mind map as title in outline output (default off) | |||
EOU | |||
# setup | |||
my %opts; | |||
getopts('hsp:', \%opts); | |||
die $usage if $opts{h}; | |||
my $heading_pattern_atom = $opts{p} || "*"; | |||
my $suppress_title = $opts{'s'}; | |||
my $QUOTE = "&quot;"; | |||
my $LESS_THAN = "&lt;"; | |||
my $GREATER_THAN = "&gt;"; | |||
my $NEWLINE = "&#xa;"; | |||
# action | |||
my $xs = new XML::Simple(); | |||
my $ref = $xs->XMLin(\*STDIN); | |||
die "Could not find mind map in input" unless exists $ref->{node}; | |||
my $start = $ref->{node}; | |||
print unquote($start->{TEXT}), "\n\n" unless $suppress_title; | |||
my $level = 0; | |||
process_children($start); | |||
# subs | |||
sub process_node { | |||
my ($node) = @_; | |||
process_node_text($node, $level); | |||
if (not is_leaf($node)) { | |||
process_children($node); | |||
} | |||
} | |||
sub process_children { | |||
my ($node) = @_; | |||
$level++; | |||
if (ref($node->{node}) eq "ARRAY") { | |||
for my $child (@{$node->{node}}) { | |||
process_node($child); | |||
} | |||
} else { | |||
my $child = $node->{node}; | |||
process_node($child); | |||
} | |||
$level--; | |||
} | |||
sub process_node_text { | |||
my ($node, $level) = @_; | |||
if (is_paragraph_leaf($node)) { | |||
print unquote($node->{TEXT}), "\n\n"; | |||
} else { | |||
print make_heading($level), " ", unquote($node->{TEXT}), "\n\n"; | |||
} | |||
} | |||
sub is_leaf { | |||
my ($node) = @_; | |||
return not exists $node->{node}; | |||
} | |||
sub is_paragraph_leaf { | |||
my ($node) = @_; | |||
# define: paragraph leaf = leaf with text that contains newlines | |||
return is_leaf($node) && $node->{TEXT} =~ /$NEWLINE/; | |||
} | |||
sub make_heading { | |||
my ($level) = @_; | |||
return $heading_pattern_atom x $level; | |||
} | |||
sub unquote { | |||
my ($s) = @_; | |||
$s =~ s/$QUOTE/"/g; | |||
$s =~ s/$LESS_THAN/</g; | |||
$s =~ s/$GREATER_THAN/>/g; | |||
$s =~ s/$NEWLINE/\n/g; | |||
return $s; | |||
}</pre> | |||
* outline2mm for Emacs outline (Perl) | |||
<pre> | |||
#!/usr/bin/perl | |||
use strict; | |||
use Getopt::Std; | |||
use POSIX; | |||
# Copyright (c) 2004 Christian Lemburg. | |||
# | |||
# All rights reserved. This program is free software; | |||
# you can redistribute it and/or modify it under the | |||
# same terms as Perl itself. | |||
# usage | |||
my $usage = <<'EOU'; | |||
Usage: $0 < emacs-outline.txt > freemind.mm | |||
Options: | |||
h: print help | |||
l: pattern atom length (default 1) | |||
p: outline mode regex to recognize headings (default "^(\\*+)") | |||
s: show suppressed text paragraphs (default off) | |||
t: topic (top level node text) for mind map output (default "Start") | |||
EOU | |||
# setup | |||
my %opts; | |||
getopts('hsl:p:t:', \%opts); | |||
die $usage if $opts{h}; | |||
my $QUOTE = "&quot;"; | |||
my $LESS_THAN = "&lt;"; | |||
my $GREATER_THAN = "&gt;"; | |||
my $NEWLINE = "&#xa;"; | |||
my $AMPERSAND = "&amp;"; | |||
my $atom_length = $opts{l} || 1; | |||
my $pattern = $opts{p} || "^(\\*+)"; | |||
my $topic = $opts{t} || "Start"; | |||
my $show_suppressed_text_paragraphs = $opts{'s'}; | |||
# action | |||
open_map(); | |||
open_node(0, 1, $topic); | |||
my $n; | |||
my @l; | |||
my $found_heading = 0; | |||
my $text = ""; | |||
while (<>) { | |||
if (s/$pattern//) { | |||
# header number calculation | |||
# use only one global by using empty first place in @l | |||
$n = POSIX::floor(length($1) / $atom_length); | |||
$n < $l[0] ? @l[$n+1..$#l] = (0)x($#l-$n) : 0; | |||
maybe_discharge_text($n); | |||
maybe_close_node($n, $l[0]); | |||
open_node($n, $l[0], $_); | |||
$l[$n]++; | |||
$l[0] = $n; | |||
} else { | |||
accumulate_text($_); | |||
} | |||
} | |||
maybe_close_node(0, $l[0]); | |||
close_map(); | |||
# subs | |||
sub open_node { | |||
my ($n, $o, $s) = @_; | |||
# push, maybe multiple with empty parents | |||
for (my $i = 0; $i < $n - $o - 1; $i++) { | |||
print indent($o + $i + 1), "<node TEXT=\"\">\n"; | |||
} | |||
$s =~ s/^\s+//; | |||
$s =~ s/\s+$//; | |||
print indent($n), "<node TEXT=\"", quote($s), "\">\n"; | |||
} | |||
sub maybe_close_node { | |||
my ($n, $o) = @_; | |||
return unless $found_heading++; | |||
# pop, maybe multiple | |||
for (my $i = 0; $i < $o + 1 - $n; $i++) { | |||
print indent($o - $i), "</node>\n"; | |||
} | |||
} | |||
sub open_map { | |||
print "<map>\n"; | |||
} | |||
sub close_map { | |||
print "</map>\n"; | |||
} | |||
sub indent { | |||
my ($l) = @_; | |||
# the map element is one above us | |||
$l++; | |||
return " " x $l; | |||
} | |||
sub accumulate_text { | |||
my ($s) = @_; | |||
$s =~ s/\s+$//; | |||
$s .= $NEWLINE; | |||
$text .= $s; | |||
} | |||
sub maybe_discharge_text { | |||
my ($n) = @_; | |||
return unless $show_suppressed_text_paragraphs; | |||
print indent($n + 1), "<node TEXT=\"" . quote($text) . "\"/>\n" | |||
unless is_only_whitespace($text); | |||
$text = ""; | |||
} | |||
sub quote { | |||
my ($s) = @_; | |||
$s =~ s/"/$QUOTE/g; | |||
$s =~ s/</$LESS_THAN/g; | |||
$s =~ s/>/$GREATER_THAN/g; | |||
$s =~ s/&/$AMPERSAND/go; | |||
return $s; | |||
} | |||
sub is_only_whitespace { | |||
my ($s) = @_; | |||
$s =~ s/$NEWLINE/\n/g; | |||
return $s =~ /\A\s*\Z/; | |||
}</pre> | |||
<!-- Unfortunately none of those links works at the moment (2008-02-20). | |||
I am also unable to find the scripts somewhere else --> | |||
=== Export from Emacs with freemind.el === | === Export from Emacs with freemind.el === | ||
Line 67: | Line 404: | ||
(I made an [http://sourceforge.net/tracker/index.php?func=detail&aid=932531&group_id=7118&atid=357118 feature request] out of this.) | (I made an [http://sourceforge.net/tracker/index.php?func=detail&aid=932531&group_id=7118&atid=357118 feature request] out of this.) | ||
==MindManager | ==MindManager== | ||
=== Indirect MindManager 4.0 to FreeMind conversion | Conversion from MindManager to FreeMind and vice versa: | ||
===From MindManager 4.0=== | |||
Indirect MindManager 4.0 to FreeMind conversion: | |||
How I converted all my mindmanager-mindmaps to freemind in one go. This works for me. Perhaps not for you. | How I converted all my mindmanager-mindmaps to freemind in one go. This works for me. Perhaps not for you. | ||
Line 121: | Line 462: | ||
--[[User:Apalmer00|Apalmer00]] 10:27, 26 Jan 2005 (PST) | --[[User:Apalmer00|Apalmer00]] 10:27, 26 Jan 2005 (PST) | ||
=== Direct MindManager X5 to FreeMind conversion | ===From MindManager X5=== | ||
Direct MindManager X5 to FreeMind conversion: | |||
I received a couple of MindManager mindmaps that I had to convert to FreeMind. These mmap files turned out to be zip-files containing an XML file with the mindmap data. So I've written a basic XSLT which directly transforms this XML to the FreeMind format without the need to install MindManager. I suppose a convenient Import from MindManager could thus be provided in FreeMind using this info/xslt. I also suppose that this XSLT could be extended to transform additional specifics like edge-color, edge-width, etc, but I could not immediately figure out where such data is stored in MindManager's XML, as I do not have MindManager. | I received a couple of MindManager mindmaps that I had to convert to FreeMind. These mmap files turned out to be zip-files containing an XML file with the mindmap data. So I've written a basic XSLT which directly transforms this XML to the FreeMind format without the need to install MindManager. I suppose a convenient Import from MindManager could thus be provided in FreeMind using this info/xslt. I also suppose that this XSLT could be extended to transform additional specifics like edge-color, edge-width, etc, but I could not immediately figure out where such data is stored in MindManager's XML, as I do not have MindManager. | ||
NB: I changed ''"concat(#,'' below to ''"concat('#', below to make it work. I also used jar xf file.mmap to extract the files. | NB: I changed ''"concat(#,'' below to ''"concat('#', below to make it work. I also used jar xf file.mmap to extract the files. | ||
Line 193: | Line 534: | ||
</xsl:stylesheet> | </xsl:stylesheet> | ||
An '''online conversion utility''' that uses the above XSLT to convert a MindManager .mmap file to FreeMind .mm format: | |||
* [http://www.liberatedcomputing.net/mm2fm liberatedcomputing.net/mm2fm] | |||
'''Q:''' How can I convert a mmap file with non-latin characters, such as Chinese and Japanese characters? Those words and sentenses will became several Question Marks! | '''Q:''' How can I convert a mmap file with non-latin characters, such as Chinese and Japanese characters? Those words and sentenses will became several Question Marks! | ||
Line 214: | Line 555: | ||
'' | '' | ||
=== | ===From MindManager (2)=== | ||
From MindManager directly into FreeMind 0.9b9: | |||
Starting with freemind 0.9 b9 (?) it became possible to import a Mmap-File directly | Starting with freemind 0.9 b9 (?) it became possible to import a Mmap-File directly | ||
Line 270: | Line 586: | ||
</xsl:template> | </xsl:template> | ||
=== To fix problems with character encoding == | ===To MindManager=== | ||
To export a mind map to MindManager: | |||
# Export the FreeMind mind map with no folded nodes to HTML. | |||
# Open the HTML file in Microsoft Word and save it as Word file (.doc). | |||
# Open the Word file in MindManager. | |||
MindManager supports direct import of Word files and other Microsoft Office documents. | |||
===Notes=== | |||
The file format of MindManager 5.0 and later is a zipped file. It is possible to get the contents of .mmap by renaming a copy of it to .zip and opening in favorite zip application. | |||
It is not true for files saved using MindManager 4.0 Standard Edition. | |||
To fix problems with character encoding: | |||
* Try to change the encoding="UTF-8" to encoding="iso-8859-1" in the xslt sheet posted above. | |||
==Plain text== | |||
Conversion from plain text to FreeeMind: | |||
[[WouterBolsterlee|Wouter Bolsterlee]] wrote a small tool named Text-to-Freemind. This program converts tab-indented text files into an XML format suitable for display by FreeMind. It was written out of annoyance with the FreeMind user interface, and the lack of ‘merging’ capabilities when collaborating with other people. More information, including an example and download links, is available from [http://uwstopia.nl/blog/2007/10/text-to-freemind-released Wouter Bolsterlee's blog entry on Text-to-Freemind]. | [[WouterBolsterlee|Wouter Bolsterlee]] wrote a small tool named Text-to-Freemind. This program converts tab-indented text files into an XML format suitable for display by FreeMind. It was written out of annoyance with the FreeMind user interface, and the lack of ‘merging’ capabilities when collaborating with other people. More information, including an example and download links, is available from [http://uwstopia.nl/blog/2007/10/text-to-freemind-released Wouter Bolsterlee's blog entry on Text-to-Freemind]. | ||
==CSV text | Alternatively you can Cut and Paste directly tabular idented texts into a new or existing FreeMind maps. For example the text editor [http://www.crimsoneditor.com/ Crimson Editor] can be used to create or edit tabular indented texts and use them directly in FreeMind. | ||
==CSV text== | |||
Conversion from FreeMind to CVS text: | |||
This is an XSLT to output a Freemind mind map as a CSV text file with extra commas to represent the hierarchy. This is useful for importing into Excel to represent the nesting of nodes as a colum view. | This is an XSLT to output a Freemind mind map as a CSV text file with extra commas to represent the hierarchy. This is useful for importing into Excel to represent the nesting of nodes as a colum view. | ||
Line 329: | Line 664: | ||
Alternatively, one could also try to add an "encoding" parameter to the "output" element of the XSLT sheet, like in [http://www.zvon.org/xxl/XSLTreference/OutputOverview/xslt_output_encoding_frame.html Zvon's XSLT Reference]. | Alternatively, one could also try to add an "encoding" parameter to the "output" element of the XSLT sheet, like in [http://www.zvon.org/xxl/XSLTreference/OutputOverview/xslt_output_encoding_frame.html Zvon's XSLT Reference]. | ||
==Tabulator separated text | ==Tabulator separated text== | ||
This is a modification of the above XSLT script to output a FreeMind map as a tabulator separated text file with the first column represent the hierarchy, the 2nd the path as 1.1.1 number, followed by the node title and the attribute value pairs (FreeMind 0.9.0 | Conversion from FreeMind to tabulator separated text: | ||
This is a modification of the above XSLT script to output a FreeMind map as a tabulator separated text file with the first column represent the hierarchy, the 2nd the path as 1.1.1 number, followed by the node title and the attribute value pairs (FreeMind 0.9.0 beta16) which are present in the attribute_registry. This is extremely useful if you keep the position of your attributes constant over the whole tree! Importing into Calc or Excel is straight forward. | |||
<?xml version="1.0"?> | <?xml version="1.0"?> | ||
Line 362: | Line 699: | ||
<xsl:value-of select="@TEXT"/> | <xsl:value-of select="@TEXT"/> | ||
<xsl:call-template name="tabulator"/> | <xsl:call-template name="tabulator"/> | ||
<xsl:apply-templates select="child::attribute"/> | <xsl:apply-templates select="child::attribute[@NAME=//attribute_registry/attribute_name/@NAME]"/> | ||
<xsl:call-template name="linebreak"/> | <xsl:call-template name="linebreak"/> | ||
<xsl:apply-templates select="child::node"> | <xsl:apply-templates select="child::node"> | ||
Line 369: | Line 706: | ||
</xsl:stylesheet> | </xsl:stylesheet> | ||
== VYM | [[User:JR|JR]] 07:38, 20 Mar 2008 (PDT) | ||
== VYM == | |||
There is a useful project at [https://sourceforge.net/projects/vym2fm/ Sourceforge: vym2fm]. | |||
Conversion from VYM to FreeMind: | |||
The following XSLT converts an XML export file from VYM to freemind format (only links, Icons and colors are preserved): | The following XSLT converts an XML export file from VYM to freemind format (only links, Icons and colors are preserved): | ||
Line 433: | Line 776: | ||
[[User:McRee|McRee]] 03:12, 14 Nov 2006 (PST) | [[User:McRee|McRee]] 03:12, 14 Nov 2006 (PST) | ||
== Mantis bug tracker | == Mantis bug tracker == | ||
Importing issues from the Mantis bug tracker to FreeMind: There is a script to export issues from Mantis to FreeMind: [http://bugs.mantisbt.org/view.php?id=7214 the script]. | |||
Mantis 1.12 ships with an integrated FreeMind support: "This is similar to the relationship diagrams are already available in Mantis. However, the Freemind features comes with a built in Flash viewer (hence, easier to get up and running), includes details about the issues, relationships, attachments, statuses, links, etc. It is also possible to export a Freemind file." [http://www.mantisbt.org/blog/?p=19 Blog post] | |||
The Freemind export & browser support is now packaged as a plugin for Mantis >=1.2.0: [http://blog.teambits.de/2010/11/02/mantis-plugin-freemind-export-and-browser/ Info & Download]. | |||
==Microsoft Office== | |||
It is possible to export FreeMind mind maps to the XML formats of Microsoft Office 2003 and newer. The resulting files are in the new XML format, so the extensions of the files are "docx", TODO. The export is available to Excel, Word, and Project. PowerPoint isn't supported, as it doesn't support an XML format. | |||
The generic procedure of how to export to one of Microsoft products is the following: | |||
# Use the menu item File > Export > Using XSLT... | |||
# Open the XSL file, depending on which product you have in mind: | |||
#* Word: "mm2wordml_utf8.xsl" | |||
#* Excel: "mm2xls_utf8.xsl" | |||
# Name the export file | |||
# Open the generated file by double-clicking it | |||
For instructions per product, see the sections for the products including [[#Microsoft Excel]], [[#Microsoft Word]] and [[#Microsoft Project]]. | |||
==Microsoft Excel== | |||
To export to Microsoft Excel: | |||
# Use the menu item File > Export > Using XSLT... | |||
# Open the XSL file "mm2xls_utf8.xsl" (in /FreeMind/accessories) | |||
# Name the export file something.xls | |||
# Open the generated file by double-clicking it | |||
==Microsoft Word== | |||
'''Export - method 1:''' | |||
To export to Microsoft Word: | |||
# Use the menu item File > Export > Using XSLT... | |||
# Open the XSL file "mm2wordml_utf8.xsl" (in /FreeMind/accessories) | |||
# Name the export file something.docx | |||
* This seems to generate empty documents with Freemind 0.9.0 beta 12 on Windows XP. [Mike B 26 Feb 2009] | |||
* This works using Version:0.9.0 and if the export file is named something.doc. Word reports corrupt file if the mm export is given a docx suffix [Mike D 22 Feb 2011] | |||
'''Export - method 2:''' | |||
To export to Microsoft Word: | |||
# Export the mind map to HTML using Control + H. | |||
# Copy and paste the resulting HTML from the web browser to Microsoft Word | |||
Export - method 3 | |||
To export to Microsoft Word: | |||
# Export the mind map to HTML using Control + H. | |||
# Copy the path and filename from the browser's location bar, e.g. "file:///C:/Temp/tmm116427495429051789.html". | |||
# Open Microsoft Word. | |||
# Press CTRL + O and CTRL + V to paste the location of the previously generated HTML. | |||
# Click OK. | |||
'''Note''': This method seems to retain the layout and formatting better than method 2. | |||
'''Import:''' | |||
To translate a MS Word outline into a FreeMind branch, a workaround is to insert tabs before paragraphs. | |||
This is a simple Word macro to do that for all paragraphs with a heading style. Optionally, all body text can be removed first (backup document!). | |||
Once the tabs have been inserted, the text can be pasted directly into FreeMind. However, only one branch will be added to the root, so if the outline contains several top level headings, the first will be 'upgraded' to the first branch node. Thus it is not possible to convert an entire document into a mindmap, but each branch has to be imported separately. | |||
Warning: This does not work in Freemind 0.9.0 Beta 9, but has been tested in FM Scholar, which is based on the FM 0.8.1 release. | |||
<pre> | |||
Sub InsertLeadingTabs() | |||
'' Insert heading level x tabs before each outline paragraph found. | |||
opt = MsgBox("Remove body text first?", vbYesNoCancel, "Insert leading tabs") | |||
If opt = vbCancel Then Exit Sub | |||
If opt = vbYes Then FilterHeadings | |||
With Selection.Find | |||
' work around, since simple search for style does not act on sequential paras | |||
.ClearFormatting | |||
.Replacement.ClearFormatting | |||
.MatchWildcards = False | |||
.text = "^p" | |||
.Replacement.text = "^p###" | |||
.Forward = True | |||
.Wrap = wdFindContinue | |||
.Execute Replace:=wdReplaceAll | |||
End With | |||
For i = 1 To 9 | |||
With Selection.Find | |||
.ClearFormatting | |||
.Replacement.ClearFormatting | |||
.text = "###" | |||
.Style = ActiveDocument.Styles("Heading " & i) | |||
.Replacement.text = Right("^t^t^t^t^t^t^t^t^t^&", 2 + i * 2) | |||
.Forward = True | |||
.Wrap = wdFindContinue | |||
End With | |||
Selection.Find.Execute Replace:=wdReplaceAll | |||
Next i | |||
With Selection.Find | |||
.ClearFormatting | |||
.Replacement.ClearFormatting | |||
.text = "###" | |||
.Replacement.text = "" | |||
.Forward = True | |||
.Wrap = wdFindContinue | |||
.Execute Replace:=wdReplaceAll | |||
End With | |||
If Selection.Start = Selection.End Then ActiveDocument.Range.Select | |||
Selection.Copy | |||
If MsgBox("Tabbed outline copied to clipboard. Restore text now? (Body text that has been removed cannot be restored.)", _ | |||
vbYesNo, "Insert leading tabs") = vbYes Then RemoveLeadingTabs | |||
Selection.HomeKey Unit:=wdStory | |||
End Sub ' InsertLeadingTabs | |||
Sub RemoveLeadingTabs() | |||
'' Strip any tabs after a paragraph break, at the beginning of a line. | |||
If ActiveDocument.Characters(1) = vbTab Then ActiveDocument.Characters(1).delete | |||
With Selection.Find | |||
.ClearFormatting | |||
.Replacement.ClearFormatting | |||
.text = "^p^t" | |||
.Replacement.text = "^p" | |||
.Forward = True | |||
.Wrap = wdFindContinue | |||
End With | |||
For i = 1 To 9 | |||
Selection.Find.Execute Replace:=wdReplaceAll | |||
Next i | |||
Selection.HomeKey Unit:=wdStory | |||
End Sub ' RemoveLeadingTabs | |||
Sub FilterHeadings() | |||
'' Remove all paragraphs but headings. | |||
If MsgBox("Delete all text except headings. Are you sure?", vbOKCancel, "Filter headings") = vbCancel Then Exit Sub | |||
For Each p In ActiveDocument.Paragraphs | |||
If Left(p.Style, 7) <> "Heading" Then p.Range.delete | |||
Next p | |||
End Sub ' FilterHeadings | |||
</pre> | |||
== Microsoft Word using Outlining == | |||
=== Export === | |||
<pre> | |||
Sub ToMap() | |||
' This Word macro uses the currently active document as the basis for creating a FreeMind format (.mm) file | |||
' It creates an output file using the Outline structure of the active document to determine the nodes in | |||
' the FreeMind file | |||
' The created document should be saved in text format and the resultant file renamed to .mm for FreeMind | |||
' Notes: | |||
' We only go down one step at once - for example source content going from Level 1 to Level 10 (normal text) | |||
' will only result in a single step in the node hierarchy | |||
' Basic formatting (bold/normal and font size) is preserved in the node file | |||
' | |||
Set scrdoc = ActiveDocument | |||
Set nodedoc = Documents.Add ' create our output document | |||
' insert a minimal header | |||
nodedoc.Content.InsertAfter ("<map version=""0.9.0"">" + Chr(10)) | |||
nodedoc.Content.InsertAfter ("<node TEXT=""New Mindmap"">" + Chr(10)) | |||
reflevel = 1 ' the assumed starting level | |||
newlevel = 1 | |||
For Each para In scrdoc.Paragraphs | |||
If (para.OutlineLevel > reflevel) Then newlevel = newlevel + 1 ' only step down 1 level | |||
If (para.OutlineLevel < reflevel) Then newlevel = para.OutlineLevel ' step back to document level | |||
reflevel = para.OutlineLevel | |||
magic = curlevel - newlevel + 1 ' then +1 ensures we get </node><node> when staying on the same level | |||
curlevel = newlevel | |||
If (magic > 0) Then ' unwind to new level | |||
For ncount = 1 To magic | |||
nodedoc.Content.InsertAfter ("</node>" + Chr(10)) | |||
Next ncount | |||
End If | |||
' create the new node | |||
txt = Replace(para.Range.Text, """", "'") ' always single quotes | |||
nodedoc.Content.InsertAfter ("<node TEXT=""" + Left(txt, Len(txt) - 1) + """>" + Chr(10)) | |||
' preserve basic formatting | |||
nodedoc.Content.InsertAfter ("<font NAME=""Dialog"" ") | |||
Set fstyle = ActiveDocument.Styles(-1 - para.OutlineLevel).Font | |||
nodedoc.Content.InsertAfter ("SIZE=""" + Format(fstyle.Size) + """ ") | |||
btxt = "false" | |||
If (fstyle.Bold) Then btxt = "true" | |||
nodedoc.Content.InsertAfter ("BOLD=""" + btxt + """ />" + Chr(10)) | |||
Next para | |||
' unwind back to our base level | |||
For ncount = 1 To curlevel | |||
nodedoc.Content.InsertAfter ("</node>" + Chr(10)) | |||
Next ncount | |||
' terminate the xml | |||
nodedoc.Content.InsertAfter ("</node>" + Chr(10)) | |||
nodedoc.Content.InsertAfter ("</map>" + Chr(10)) | |||
' propmt for output file name - save as "Plain Text(*.txt)" | |||
Set fd = Application.FileDialog(msoFileDialogSaveAs) | |||
fd.Show | |||
fd.Execute | |||
' all done | |||
nodedoc.Close | |||
End Sub | |||
</pre> | |||
=== Import === | |||
<pre> | |||
Sub xmltodoc() | |||
' This Word macro uses the currently active document as the basis for creating a Word document with Outline | |||
' levels corresponding to the node structure of the FreeMind (.mm) source file | |||
' To load the source file, rename the .mm to .xml and open using Word | |||
' The macro parses the node tree to determine the Outline level and then allocates the text for each node to | |||
' the appropriate level | |||
' The resultant document can be saved to Word (.doc) format | |||
' | |||
' A word of caution is necessary with any recursive function | |||
Dim objElement As XMLNode | |||
Set adoc = ActiveDocument | |||
Set outlinedoc = Documents.Add ' create our destination document | |||
outlinedoc.Content.InsertAfter ("" + Chr(10)) ' we need a starting point for our Promote/Demote sequence | |||
outlinedoc.Paragraphs(outlinedoc.Paragraphs.Count).OutlinePromote | |||
For Each objElement In adoc.XMLNodes.Item(1).ChildNodes ' start with the top level children | |||
xmllevel objElement, outlinedoc, False | |||
Next | |||
End Sub | |||
Sub xmllevel(nodes, outlinedoc, top) | |||
If (top) Then outlinedoc.Paragraphs(outlinedoc.Paragraphs.Count).OutlineDemote | |||
If nodes.NodeType = wdXMLNodeElement Then | |||
If (nodes.BaseName = "node") Then | |||
For acount = 1 To nodes.Attributes.Count | |||
If (nodes.Attributes(acount).BaseName = "TEXT") Then ' insert the outline text | |||
outlinedoc.Content.InsertAfter (nodes.Attributes(acount).NodeValue + Chr(10)) | |||
For Each objElement In nodes.ChildNodes ' descend to the next level children | |||
xmllevel objElement, outlinedoc, True | |||
Next | |||
End If | |||
Next acount | |||
End If | |||
End If | |||
outlinedoc.Paragraphs(outlinedoc.Paragraphs.Count).OutlinePromote ' unwind | |||
==Microsoft Project | End Sub | ||
</pre> | |||
==Microsoft Project== | |||
Conversion from Microsoft Project to FreeMind and vice versa? | |||
===From MS Project=== | ===From MS Project=== | ||
I' | These are Python programs to create a FreeMind map (.mm) from an MS Project file. | ||
mpp2mm.1.0.py will handle XML format (doesn't require win32com.client) | |||
mpp2mm.py will handle .mpp and XML formats (and does require win32com.client) | |||
mpp2mmw.pyw is a PyQt4 Dialog to invoke mpp2mm.py | |||
Sample usage for mpp2mm.py is: | |||
<pre> | |||
mpp2mm.py -i "c:\fullpath name\project.mpp" -c -a | |||
</pre> | |||
This will produce a mindmap from MS Project file project.mpp, flag completed tasks and set some attributes. The output file will have the same name with a .mm extension. | |||
Processing a .mpp file always requires the full path name | |||
(I'm only a Python beginner so apologies for any "indiscretions". | |||
I haven't extensively tested them either) | |||
AnGus | |||
mpp2mm.py | |||
<pre> | |||
#!/usr/bin/env python | |||
# | |||
"""Create a FreeMind (.mm) mind map from a/an MS Project file. | |||
usage: mpp2mm -i <mppfile> -o <mmfile> -a -c | |||
Options and arguments: | |||
-a : generate (some) Attributes | |||
-c : generate icons for completed tasks | |||
-i mppfile : input MS Project mpp or xml file | |||
-o mmfile : output FreeMind map (name defaults to input filename) | |||
Copyright (c) 2009, AnGus King | |||
This code is licensed under the GPLv2 or later. | |||
(http://www.gnu.org/licenses/) | |||
""" | |||
__author__ = "AnGus King" | |||
__copyright__ = "Copyright (C) 2009, AnGus King" | |||
__license__ = "GPLv2 (http://www.gnu.org/licenses/)" | |||
__version__ = "1.1" | |||
import getopt | |||
import sys | |||
import win32com.client | |||
import xml.etree.ElementTree as ET | |||
class Mpp2Mm: | |||
def __init__(self): | |||
self.mmn = [] # create an empty node tree | |||
self.mmn.append("") | |||
self.lst_lvl = 0 # last level is 0 | |||
self.do_attr = False # by default don't create Attributes | |||
self.do_flag = False # by default don't flag completion | |||
def open(self, infile): | |||
""" Open the .mpp or .xml file and create a tree """ | |||
if infile.endswith('.xml'): | |||
self.proj = None | |||
try: | |||
self.tree = ET.parse(infile) | |||
return self.tree | |||
except Exception, e: | |||
print "Error opening file",e | |||
usage() | |||
else: | |||
try: | |||
self.mpp = win32com.client.Dispatch("MSProject.Application") | |||
self.mpp.Visible = False | |||
self.mpp.FileOpen(infile) | |||
self.proj = self.mpp.ActiveProject | |||
return self.proj | |||
except Exception, e: | |||
print "Error opening file",e | |||
usage() | |||
def write(self, outfile, attr, flag): | |||
""" Create the .mm file :-) """ | |||
self.do_attr = attr | |||
# create the mindmap as version 8.1 or 9.0) if generating | |||
# attribute tags | |||
if self.do_attr: | |||
self.mm = ET.Element("map",version="0.9.0") | |||
else: | |||
self.mm = ET.Element("map",version="0.8.1") | |||
self.do_flag = flag | |||
if self.proj is None: # .xml file | |||
root = self.tree.getroot() | |||
# process Task elements and fabricate hierarchy based upon OutlineLevel | |||
for node in root: | |||
if node.tag == "{http://schemas.microsoft.com/project}Name": | |||
self.mmn[0] = ET.SubElement(self.mm, "node", text=node.text) | |||
elif node.tag == "{http://schemas.microsoft.com/project}Author": | |||
if self.do_attr: | |||
self.mmn[0].append(ET.Element("attribute", \ | |||
NAME="prj-Author", VALUE=node.text)) | |||
elif node.tag == "{http://schemas.microsoft.com/project}StartDate": | |||
if self.do_attr: | |||
self.mmn[0].append(ET.Element("attribute", \ | |||
NAME="prj-StartDate", VALUE=node.text)) | |||
else: | |||
# the guts of it is the Tasks | |||
if node.tag == "{http://schemas.microsoft.com/project}Tasks": | |||
for nod in node: | |||
if nod.tag == "{http://schemas.microsoft.com/project}Task": | |||
if nod.findtext("{http://schemas.microsoft.com/project}UID") <> "0": | |||
# UID, Name, Start, Finish, WBS | |||
lvl = nod.findtext("{http://schemas.microsoft.com/project}OutlineLevel") | |||
txt = nod.findtext("{http://schemas.microsoft.com/project}Name") | |||
lvli = int(lvl) | |||
if lvli > self.lst_lvl: | |||
self.mmn.append("") | |||
self.lst_lvl = lvli | |||
self.mmn[lvli] = ET.SubElement(self.mmn[lvli-1], "node",text=txt) | |||
if self.do_attr: | |||
self.mmn[lvli].append(ET.Element("attribute", NAME="tsk-Duration", \ | |||
VALUE=nod.findtext("{http://schemas.microsoft.com/project}Duration"))) | |||
if self.do_flag: | |||
txt = nod.findtext("{http://schemas.microsoft.com/project}PercentComplete") | |||
if txt == "100": | |||
self.mmn[lvli].append(ET.Element("icon", BUILTIN="button_ok")) | |||
else: # .mpp file | |||
self.mmn[0] = ET.SubElement(self.mm, "node", text=self.proj.Project) | |||
if self.do_attr: | |||
self.mmn[0].append(ET.Element("attribute", \ | |||
NAME="prj-Author", VALUE=self.proj.Author)) | |||
self.mmn[0].append(ET.Element("attribute", \ | |||
NAME="prj-StartDate", VALUE=str(self.proj.ProjectStart))) | |||
for task in self.proj.Tasks: | |||
lvli = task.OutlineLevel | |||
txt = task.Name | |||
if lvli > self.lst_lvl: | |||
self.mmn.append("") | |||
self.lst_lvl = lvli | |||
self.mmn[lvli] = ET.SubElement(self.mmn[lvli-1], "node",text=txt) | |||
if self.do_attr: | |||
txt = str(task.Duration / 480) + "d" # convert to days | |||
self.mmn[lvli].append(ET.Element("attribute", NAME="tsk-Duration", \ | |||
VALUE=txt)) | |||
if self.do_flag: | |||
txt = task.PercentComplete | |||
if txt == 100: | |||
self.mmn[lvli].append(ET.Element("icon", BUILTIN="button_ok")) | |||
self.mpp.Quit() | |||
tree = ET.ElementTree(self.mm) | |||
tree.write(outfile) | |||
return | |||
def usage(): | |||
print __doc__ | |||
sys.exit(-1) | |||
def main(): | |||
try: | |||
opts , args = getopt.getopt(sys.argv[1:], "i:o:hac", \ | |||
["help", "input=", "output="]) | |||
except getopt.GetoptError, err: | |||
# print help information and exit: | |||
print err # will print something like "option -x not recognized" | |||
usage() | |||
input = None | |||
output = None | |||
attr = False | |||
complete = False | |||
for o, a in opts: | |||
if o == "-a": # wants attributes printed | |||
attr = True | |||
elif o == "-c": # wants completion flags | |||
complete = True | |||
elif o in ("-h", "--help"): | |||
usage() | |||
elif o in ("-i", "--input"): | |||
input = a | |||
elif o in ("-o", "--output"): | |||
output = a | |||
else: | |||
assert False, "unhandled option" | |||
if input == None: | |||
print "Input file required" | |||
usage() | |||
if not (input.endswith('.xml') or input.endswith('.mpp')): | |||
print "Input file must end with '.mpp' or '.xml'" | |||
usage() | |||
if output == None: | |||
output = input[:-3] + "mm" | |||
if not output.endswith('.mm'): | |||
print "Output file must end with '.mm'" | |||
usage() | |||
mpp2mm = Mpp2Mm() | |||
tree = mpp2mm.open(input) | |||
mpp2mm.write(output,attr,complete) | |||
print output + " created." | |||
if __name__ == "__main__": | |||
main() | |||
</pre> | |||
mpp2mmw.pyw | |||
<pre> | |||
#!/usr/bin/env python | |||
"""PyQt4 menu to invoke mpp2mm.py (plagiarised from example from Qt v4.x)""" | |||
import sys | |||
from PyQt4 import QtCore, QtGui | |||
from mpp2mm import Mpp2Mm | |||
class Dialog(QtGui.QDialog): | |||
def __init__(self, parent=None): | |||
QtGui.QDialog.__init__(self, parent) | |||
self.openFilesPath = QtCore.QString() | |||
self.errorMessageDialog = QtGui.QErrorMessage(self) | |||
frameStyle = QtGui.QFrame.Sunken | QtGui.QFrame.Panel | |||
self.messageLabel = QtGui.QLabel() | |||
self.messageLabel.setFrameStyle(frameStyle) | |||
self.cancelButton = QtGui.QPushButton(self.tr("Cancel")) | |||
self.okButton = QtGui.QPushButton(self.tr("&OK")) | |||
buttonLayout = QtGui.QHBoxLayout() | |||
buttonLayout.addStretch(1) | |||
buttonLayout.addWidget(self.okButton) | |||
buttonLayout.addWidget(self.cancelButton) | |||
self.connect(self.cancelButton, QtCore.SIGNAL("clicked()"), self, QtCore.SLOT("reject()")) | |||
self.connect(self.okButton, QtCore.SIGNAL("clicked()"), self, QtCore.SLOT("accept()")) | |||
self.openFileNameLabel = QtGui.QLabel() | |||
self.openFileNameLabel.setFrameStyle(frameStyle) | |||
self.openFileNameButton = QtGui.QPushButton(self.tr("Open Project File")) | |||
self.saveFileNameLabel = QtGui.QLabel() | |||
self.saveFileNameLabel.setFrameStyle(frameStyle) | |||
self.saveFileNameButton = QtGui.QPushButton(self.tr("Save FreeMind File")) | |||
self.attributeCheckBox = QtGui.QCheckBox(self.tr("Create Attributes")) | |||
self.attributeCheckBox.setChecked(False) | |||
self.flagCheckBox = QtGui.QCheckBox(self.tr("Flag completed tasks")) | |||
self.flagCheckBox.setChecked(False) | |||
self.connect(self.openFileNameButton, QtCore.SIGNAL("clicked()"), self.setOpenFileName) | |||
self.connect(self.saveFileNameButton, QtCore.SIGNAL("clicked()"), self.setSaveFileName) | |||
layout = QtGui.QGridLayout() | |||
layout.setColumnStretch(1, 1) | |||
layout.setColumnMinimumWidth(1, 250) | |||
layout.addWidget(self.openFileNameButton, 7, 0) | |||
layout.addWidget(self.openFileNameLabel, 7, 1) | |||
layout.addWidget(self.saveFileNameButton, 9, 0) | |||
layout.addWidget(self.saveFileNameLabel, 9, 1) | |||
layout.addWidget(self.attributeCheckBox, 11, 0) | |||
layout.addWidget(self.flagCheckBox, 11, 1) | |||
layout.addWidget(self.messageLabel, 13, 1) | |||
layout.addLayout(buttonLayout,15,1) | |||
self.setLayout(layout) | |||
self.setWindowTitle(self.tr("MS Project to FreeMind")) | |||
def setOpenFileName(self): | |||
fileName = QtGui.QFileDialog.getOpenFileName(self, | |||
self.tr("QFileDialog.getOpenFileName()"), | |||
self.openFileNameLabel.text(), | |||
self.tr("Project Files (*.mpp);;XML Files (*.xml);;All Files (*)")) | |||
if not fileName.isEmpty(): | |||
self.openFileNameLabel.setText(fileName) | |||
def setSaveFileName(self): | |||
fileName = QtGui.QFileDialog.getSaveFileName(self, | |||
self.tr("QFileDialog.getSaveFileName()"), | |||
self.saveFileNameLabel.text(), | |||
self.tr("FreeMind Files (*.mm);;All Files (*)")) | |||
if not fileName.isEmpty(): | |||
self.saveFileNameLabel.setText(fileName) | |||
def accept(self): | |||
mpp2mm = Mpp2Mm() | |||
infile = str(self.openFileNameLabel.text()) | |||
tree = mpp2mm.open(infile) | |||
if self.saveFileNameLabel.text() == "": | |||
oufile = infile[:-3] + "mm" | |||
else: | |||
oufile = str(self.saveFileNameLabel.text()) | |||
mpp2mm.write(oufile,self.attributeCheckBox.isChecked(),self.flagCheckBox.isChecked()) | |||
self.messageLabel.setText(oufile + " created.") | |||
if __name__ == '__main__': | |||
app = QtGui.QApplication(sys.argv) | |||
dialog = Dialog() | |||
sys.exit(dialog.exec_()) | |||
</pre> | |||
mpp2mm.1.0.py | |||
<pre> | |||
#!/usr/bin/env python | |||
# | |||
"""Create a FreeMind (.mm) mind map from a/an MS Project XML file. | |||
usage: mpp2mm -i <mppfile> -o <mmfile> -a -c | |||
Options and arguments: | |||
-a : generate (some) Attributes | |||
-c : generate icons for completed tasks | |||
-i mppfile : input MS Project xml file | |||
-o mmfile : output FreeMind map (name defaults to input filename) | |||
Copyright (c) 2009, AnGus King | |||
This code is licensed under the GPLv2 or later. | |||
(http://www.gnu.org/licenses/) | |||
""" | |||
__author__ = "AnGus King" | |||
__copyright__ = "Copyright (C) 2009, AnGus King" | |||
__license__ = "GPLv2 (http://www.gnu.org/licenses/)" | |||
__version__ = "1.1" | |||
import getopt | |||
import sys | |||
import xml.etree.ElementTree as ET | |||
class Mpp2Mm: | |||
def __init__(self): | |||
self.mmn = [] # create an empty node tree | |||
self.mmn.append("") | |||
self.lst_lvl = 0 # last level is 0 | |||
self.do_attr = False # by default don't create Attributes | |||
self.do_flag = False # by default don't flag completion | |||
def open(self, infile): | |||
""" Open the .xml file and create a tree """ | |||
try: | |||
self.tree = ET.parse(infile) | |||
return self.tree | |||
except Exception, e: | |||
print "Error opening file",e | |||
usage() | |||
def write(self, outfile, attr, flag): | |||
""" Create the .mm file :-) """ | |||
self.do_attr = attr | |||
# create the mindmap as version 8.1 or 9.0) if generating | |||
# attribute tags | |||
if self.do_attr: | |||
self.mm = ET.Element("map",version="0.9.0") | |||
else: | |||
self.mm = ET.Element("map",version="0.8.1") | |||
self.do_flag = flag | |||
root = self.tree.getroot() | |||
# process Task elements and fabricate hierarchy based upon OutlineLevel | |||
for node in root: | |||
if node.tag == "{http://schemas.microsoft.com/project}Name": | |||
# print "Project:" , node.text | |||
self.mmn[0] = ET.SubElement(self.mm, "node", text=node.text) | |||
elif node.tag == "{http://schemas.microsoft.com/project}Author": | |||
# print "Author:" , node.text | |||
if self.do_attr: | |||
self.mmn[0].append(ET.Element("attribute", \ | |||
NAME="prj-Author", VALUE=node.text)) | |||
elif node.tag == "{http://schemas.microsoft.com/project}StartDate": | |||
# print "StartDate:" , node.text | |||
if self.do_attr: | |||
self.mmn[0].append(ET.Element("attribute", \ | |||
NAME="prj-StartDate", VALUE=node.text)) | |||
else: | |||
# the guts of it is the Tasks | |||
if node.tag == "{http://schemas.microsoft.com/project}Tasks": | |||
for nod in node: | |||
if nod.tag == "{http://schemas.microsoft.com/project}Task": | |||
if nod.findtext("{http://schemas.microsoft.com/project}UID") <> "0": | |||
# print "UID:", nod.findtext("{http://schemas.microsoft.com/project}UID") | |||
# print "Name:", nod.findtext("{http://schemas.microsoft.com/project}Name") | |||
# print "Start:", nod.findtext("{http://schemas.microsoft.com/project}Start") | |||
# print "Finish:", nod.findtext("{http://schemas.microsoft.com/project}Finish") | |||
# print "WBS:", nod.findtext("{http://schemas.microsoft.com/project}WBS") | |||
lvl = nod.findtext("{http://schemas.microsoft.com/project}OutlineLevel") | |||
txt = nod.findtext("{http://schemas.microsoft.com/project}Name") | |||
# print "Level/Task:", lvl + " " + txt | |||
lvli = int(lvl) | |||
if lvli > self.lst_lvl: | |||
self.mmn.append("") | |||
self.lst_lvl = lvli | |||
self.mmn[lvli] = ET.SubElement(self.mmn[lvli-1], "node",text=txt) | |||
if self.do_attr: | |||
self.mmn[lvli].append(ET.Element("attribute", NAME="tsk-Duration", \ | |||
VALUE=nod.findtext("{http://schemas.microsoft.com/project}Duration"))) | |||
if self.do_flag: | |||
txt = nod.findtext("{http://schemas.microsoft.com/project}PercentComplete") | |||
if txt == "100": | |||
self.mmn[lvli].append(ET.Element("icon", BUILTIN="button_ok")) | |||
tree = ET.ElementTree(self.mm) | |||
tree.write(outfile) | |||
return | |||
def usage(): | |||
print __doc__ | |||
sys.exit(-1) | |||
def main(): | |||
try: | |||
opts , args = getopt.getopt(sys.argv[1:], "i:o:hac", \ | |||
["help", "input=", "output="]) | |||
except getopt.GetoptError, err: | |||
# print help information and exit: | |||
print err # will print something like "option -x not recognized" | |||
usage() | |||
input = None | |||
output = None | |||
attr = False | |||
complete = False | |||
for o, a in opts: | |||
if o == "-a": # wants attributes printed | |||
attr = True | |||
elif o == "-c": # wants completion flags | |||
complete = True | |||
elif o in ("-h", "--help"): | |||
usage() | |||
elif o in ("-i", "--input"): | |||
input = a | |||
elif o in ("-o", "--output"): | |||
output = a | |||
else: | |||
assert False, "unhandled option" | |||
if input == None: | |||
print "Input file required" | |||
usage() | |||
if not input.endswith('.xml'): | |||
print "Input file must end with '.xml'" | |||
usage() | |||
if output == None: | |||
output = input[:-3] + "mm" | |||
if not output.endswith('.mm'): | |||
print "Output file must end with '.mm'" | |||
usage() | |||
mpp2mm = Mpp2Mm() | |||
tree = mpp2mm.open(input) | |||
mpp2mm.write(output,attr,complete) | |||
print output + " created." | |||
if __name__ == "__main__": | |||
main() | |||
</pre> | |||
===To MS Project=== | ===To MS Project=== | ||
====Method 1==== | |||
An XSLT stylesheet to transform a FreeMind mindmap into a XML file that can be opened within MS Project as a project. | An XSLT stylesheet to transform a FreeMind mindmap into a XML file that can be opened within MS Project as a project. | ||
Line 529: | Line 1,575: | ||
====Method 2==== | |||
From [http://sourceforge.net/forum/message.php?msg_id=3098981 help forum]: | |||
PPS (by mlflanagan): Great contribution from Mauro, thanks. I modified the xsl file to also export notes from the .mm file. Changes are in <b>bold</b>: | |||
... | |||
<RemainingDuration>PT8H0M0S</RemainingDuration> | |||
<b><xsl:apply-templates select="hook"/></b> | |||
</Task> | |||
<xsl:apply-templates select="node"/> | |||
</xsl:template> | |||
<b><xsl:template match="hook"> | |||
<Notes><xsl:value-of select="text"/></Notes> | |||
</xsl:template></b> | |||
ALSO: to be clear about how to export: | |||
# Copy this code and save it to a file such as mm2project.xsl. | |||
# In Freemind, select File --> Export --> Using XSLT ... | |||
# Browse for the xsl file (mm2project.xsl) in the "choose XSL file" field. | |||
# Browse to your target folder and name the exported file, such as project.xml. Note: The filename MUST have a .xml extension! | |||
# Press the Export button to create the export file. | |||
# Open the file with MS Project (using File --> Open ...). | |||
# Follow the MS Project dialog to open the file. | |||
# "Save as" to the standard .mpp format. | |||
====Method 3==== | |||
From [http://sourceforge.net/forum/message.php?msg_id=7399063 help forum]: | |||
# Create the project plan using Freemind features. Use link arrows to create predecedence. Default is for all tasks to start on the project start date | |||
# Add an attribute (Alt-F9) to each low level task to specify the duration. Attribute is tsk-Duration value is either in standard MS (PTnHnMnS) format, allowing specifying hours, minutes and seconds or if you use AnGus' XSLT you can enter (whole) months, days or hours by suffixing the value with m, d or h respectively (eg. 2d for 2 days) | |||
# Export the file as XSLT - File->Export->Using XLST ... You identify the XSLT translator (either the standard "C:\Program Files\Freemind\accessories\mm2msp_utf8.xsl" or "..\mm2msp_utf8_ak.xsl" to use the alternative duration formats. Remember to save the exported file with xml file type | |||
# Open MS Project and import the file - Open->Files of Type->xml. First time import as a new file | |||
# To load durations you actually need to open the file again and Merge it into the existing project (if you specify Start and Finish dates then the durations will be included on first import) | |||
AnGus | |||
mm2msp_utf8_ak.xsl | |||
<pre> | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!-- | |||
(c) by Naoki Nose, 2006, and Eric Lavarde, 2008 | |||
This code is licensed under the GPLv2 or later. | |||
(http://www.gnu.org/copyleft/gpl.html) | |||
Check 'mm2msp_utf8_TEMPLATE.mm' for detailed instructions on how to use | |||
this sheet. | |||
This version has been modified by Angus King to allow task durations to | |||
be in (whole) months and days (based upon 8 hours a day and 20 days a | |||
month) - just suffix the period with d or m (or nothing for hours) | |||
--> | |||
<xsl:stylesheet version="1.0" | |||
xmlns="http://schemas.microsoft.com/project" | |||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> | |||
<xsl:output method="xml" indent="yes" encoding="UTF-8" standalone="yes"/> | |||
<xsl:key name="deps" match="arrowlink" use="@DESTINATION"/> | |||
<xsl:template match="/"> | |||
<Project> | |||
<xsl:apply-templates/> | |||
</Project> | |||
</xsl:template> | |||
<xsl:template match="//map"> | |||
<Title><xsl:value-of select="node/@TEXT"/></Title> | |||
<xsl:apply-templates select="node/attribute"> | |||
<xsl:with-param name="prefix" select="'prj'"/> | |||
</xsl:apply-templates> | |||
<Tasks> | |||
<xsl:apply-templates select="node" mode="tasks"/> | |||
</Tasks> | |||
</xsl:template> | |||
<xsl:template match="node" mode="tasks"> | |||
<xsl:param name="level" select="0"/> | |||
<Task> | |||
<UID><xsl:if test="$level > 0"> | |||
<xsl:number level="any" count="//map/node//node" | |||
format="1"/></xsl:if> | |||
<xsl:if test="$level = 0">0</xsl:if> | |||
</UID> | |||
<xsl:call-template name="output-node-text-as-name"/> | |||
<xsl:call-template name="output-note-text-as-notes"/> | |||
<OutlineLevel><xsl:value-of select="$level"/></OutlineLevel> | |||
<xsl:if test="not(attribute[@NAME = 'tsk-FixedCostAccrual'])"> | |||
<FixedCostAccrual>1</FixedCostAccrual> | |||
</xsl:if> | |||
<xsl:apply-templates select="attribute"> | |||
<xsl:with-param name="prefix" select="'tsk'"/> | |||
</xsl:apply-templates> | |||
<xsl:for-each select="key('deps',@ID)"> | |||
<xsl:call-template name="output-arrow-as-predecessor"> | |||
<xsl:with-param name="level" select="$level"/> | |||
</xsl:call-template> | |||
</xsl:for-each> | |||
</Task> | |||
<xsl:apply-templates mode="tasks"> | |||
<xsl:with-param name="level" select="$level + 1"/> | |||
</xsl:apply-templates> | |||
</xsl:template> | |||
<xsl:template name="output-node-text-as-name"> | |||
<Name><xsl:choose> | |||
<xsl:when test="@TEXT"> | |||
<xsl:value-of select="normalize-space(@TEXT)" /> | |||
</xsl:when> | |||
<xsl:when test="richcontent[@TYPE='NODE']"> | |||
<xsl:value-of | |||
select="normalize-space(richcontent[@TYPE='NODE']/html/body)" /> | |||
</xsl:when> | |||
<xsl:otherwise> | |||
<xsl:text></xsl:text> | |||
</xsl:otherwise> | |||
</xsl:choose></Name> | |||
</xsl:template> | |||
<xsl:template name="output-note-text-as-notes"> | |||
<xsl:if test="richcontent[@TYPE='NOTE']"> | |||
<Notes><xsl:value-of | |||
select="string(richcontent[@TYPE='NOTE']/html/body)" /> | |||
</Notes> | |||
</xsl:if> | |||
</xsl:template> | |||
<xsl:template name="output-arrow-as-predecessor"> | |||
<xsl:param name="level" select="0"/> | |||
<PredecessorLink> | |||
<PredecessorUID><xsl:if test="$level > 0"> | |||
<xsl:number level="any" count="//map/node//node" format="1"/> | |||
</xsl:if> | |||
<xsl:if test="$level = 0">0</xsl:if></PredecessorUID> | |||
<Type><xsl:choose> | |||
<xsl:when test="@ENDARROW = 'Default'"> | |||
<xsl:choose> | |||
<xsl:when test="@STARTARROW = 'Default'">3</xsl:when> | |||
<xsl:otherwise>1</xsl:otherwise> | |||
</xsl:choose> | |||
</xsl:when> | |||
<xsl:otherwise> | |||
<xsl:choose> | |||
<xsl:when test="@STARTARROW = 'Default'">2</xsl:when> | |||
<xsl:otherwise>0</xsl:otherwise> | |||
</xsl:choose> | |||
</xsl:otherwise> | |||
</xsl:choose></Type> | |||
</PredecessorLink> | |||
</xsl:template> | |||
<xsl:template match="attribute"> | |||
<xsl:param name="prefix" /> | |||
<xsl:if test="starts-with(@NAME,concat($prefix,'-'))"> | |||
<xsl:element name="{substring-after(@NAME,concat($prefix,'-'))}"> | |||
<!-- Cater for duration in months, days, hours - rounded to nearest whole number --> | |||
<xsl:choose> | |||
<xsl:when test="@NAME = concat($prefix,'-Duration')"> | |||
<xsl:choose> | |||
<xsl:when test="substring(@VALUE ,1,2) = 'PT'"> <!-- Assume MS format (PTnHnMnS) --> | |||
<xsl:value-of select="@VALUE"/> | |||
</xsl:when> | |||
<xsl:when test="substring(@VALUE ,string-length(@VALUE),1) = 'm'"> <!-- months --> | |||
<xsl:value-of select="concat(concat('PT',round(substring(@VALUE,1,string-length(@VALUE)-1)*8*20)),'H0M0S')"/> | |||
</xsl:when> | |||
<xsl:when test="substring(@VALUE ,string-length(@VALUE),1) = 'd'"> <!-- days --> | |||
<xsl:value-of select="concat(concat('PT',round(substring(@VALUE,1,string-length(@VALUE)-1)*8)),'H0M0S')"/> | |||
</xsl:when> | |||
<xsl:when test="substring(@VALUE ,string-length(@VALUE),1) = 'h'"> <!-- hours --> | |||
<xsl:value-of select="concat(concat('PT',round(substring(@VALUE,1,string-length(@VALUE)-1))),'H0M0S')"/> | |||
</xsl:when> | |||
<xsl:otherwise> <!-- default is hours --> | |||
<xsl:value-of select="concat(concat('PT',round(@VALUE)),'H0M0S')"/> | |||
</xsl:otherwise> | |||
</xsl:choose> | |||
</xsl:when> | |||
<xsl:otherwise> | |||
<xsl:value-of select="@VALUE"/> | |||
</xsl:otherwise> | |||
</xsl:choose> | |||
</xsl:element> | |||
</xsl:if> | |||
</xsl:template> | |||
<!-- required to _not_ output other things than nodes --> | |||
<xsl:template match="*" mode="tasks"></xsl:template> | |||
</xsl:stylesheet> | |||
</pre> | |||
SampleProject.mm (map showing how to use above XSLT) | |||
<pre> | |||
<map version="0.9.0"> | |||
<!-- To view this file, download free mind mapping software FreeMind from http://freemind.sourceforge.net --> | |||
<node CREATED="1236062058732" ID="ID_1005289263" MODIFIED="1237874353965" STYLE="fork"> | |||
<richcontent TYPE="NODE"><html> | |||
<head> | |||
</head> | |||
<body> | |||
<p> | |||
SampleProject | |||
</p> | |||
<p> | |||
Using XML export feature of Freemind v9 | |||
</p> | |||
</body> | |||
</html></richcontent> | |||
<richcontent TYPE="NOTE"><html> | |||
<head> | |||
</head> | |||
<body> | |||
<p> | |||
This is a simple sample of using Freemind to create a MS-Project project. See "C:\Program Files\Freemind\accessories\mm2msp_utf8_TEMPLATE.mm" for a more expansive sample. Process is: | |||
</p> | |||
<ol> | |||
<li> | |||
Create the project plan using Freemind features. Use link arrows to create predecedence. Default is all start on project start date | |||
</li> | |||
<li> | |||
Add an attribute (Alt-F9) to each low level task to specify the duration. Attribute is <u>tsk-Duration</u> value is either in standard MS (<u>PTnHnMnS</u>) format, allowing specifying hours, minutes and seconds or if you use AKs XSLT you can enter (whole) months, days or hours by suffixing the value with  m, d or h respectively (eg. <u>2d</u> for 2 days) | |||
</li> | |||
<li> | |||
Export the file as XSLT - File->Export->Using XLST ... You identify the XSLT translator (either the standard "<u>C:\Program Files\Freemind\accessories\mm2msp_utf8.xsl</u>" or "<u>..\mm2msp_utf8_ak.xsl</u>" to use the alternative duration formats. Remember to save the exported file with <u>xml</u> file type<br /> | |||
</li> | |||
<li> | |||
Open MS Project and import the file - Open->Files of Type->xml. First time import as a new file | |||
</li> | |||
<li> | |||
To load durations you actually need to open the file again and Merge it into the existing project (if you specify Start and Finish dates then the durations will be included on first import) | |||
</li> | |||
<li> | |||
See Angus for help | |||
</li> | |||
</ol> | |||
<p> | |||
       | |||
</p> | |||
</body> | |||
</html> | |||
</richcontent> | |||
<attribute_layout NAME_WIDTH="113" VALUE_WIDTH="125"/> | |||
<attribute NAME="prj-StartDate" VALUE="2009-03-10"/> | |||
<attribute NAME="prj-Author" VALUE="Angus King"/> | |||
<node CREATED="1236062115811" ID="ID_1928578570" MODIFIED="1237874135571" POSITION="right" TEXT="Sample Task 1"> | |||
<richcontent TYPE="NOTE"><html> | |||
<head> | |||
</head> | |||
<body> | |||
<p> | |||
Doesn't need a duration as this will come from sub tasks. | |||
</p> | |||
</body> | |||
</html></richcontent> | |||
<arrowlink DESTINATION="ID_1616088595" ENDARROW="Default" ENDINCLINATION="85;0;" ID="Arrow_ID_1010462294" STARTARROW="None" STARTINCLINATION="85;0;"/> | |||
<attribute_layout NAME_WIDTH="76" VALUE_WIDTH="125"/> | |||
<node CREATED="1236062115811" ID="ID_1617986385" MODIFIED="1237873897971" TEXT="Sub Task 1.1"> | |||
<richcontent TYPE="NOTE"><html> | |||
<head> | |||
</head> | |||
<body> | |||
<p> | |||
Task is 2 days long | |||
</p> | |||
</body> | |||
</html></richcontent> | |||
<arrowlink DESTINATION="ID_775688033" ENDARROW="Default" ENDINCLINATION="71;0;" ID="Arrow_ID_1152852365" STARTARROW="None" STARTINCLINATION="71;0;"/> | |||
<attribute_layout NAME_WIDTH="76" VALUE_WIDTH="125"/> | |||
<attribute NAME="tsk-Duration" VALUE="2d"/> | |||
</node> | |||
<node CREATED="1236062115811" ID="ID_775688033" MODIFIED="1237873915113" TEXT="Sub Task 1.2"> | |||
<richcontent TYPE="NOTE"><html> | |||
<head> | |||
</head> | |||
<body> | |||
<p> | |||
Task is 2 months long. Sub Task 1.1 is a Predecessor | |||
</p> | |||
</body> | |||
</html></richcontent> | |||
<attribute_layout NAME_WIDTH="76" VALUE_WIDTH="125"/> | |||
<attribute NAME="tsk-Duration" VALUE="2m"/> | |||
</node> | |||
</node> | |||
<node CREATED="1236142029373" ID="ID_1616088595" MODIFIED="1236144026607" POSITION="right" TEXT="Sample Task 2"> | |||
<node CREATED="1236142043702" ID="ID_1046123070" MODIFIED="1237874027985" TEXT="Sub Task 2.1"> | |||
<richcontent TYPE="NOTE"><html> | |||
<head> | |||
</head> | |||
<body> | |||
<p> | |||
Task is 48 hours, or 6 days long (MS Project format). Sample Task 1 is a Predecessor | |||
</p> | |||
</body> | |||
</html></richcontent> | |||
<attribute NAME="tsk-Duration" VALUE="PT48H0M0S"/> | |||
</node> | |||
</node> | |||
</node> | |||
</map> | |||
</pre> | |||
== OpenOffice Writer == | |||
OpenOffice Writer to FreeMind: | |||
Sometimes it's useful to be able to create a FreeMind mind map from an OpenOffice Writer document. The OpenOffice macro below does precisely this. It will extract all paragraphs of format "Heading 1" to "Heading 5" and create a .mm document that can be opened by FreeMind. The only constraint is that the Writer document ''must'' be correctly structured, with all heading levels correctly nested i.e. you can't go from "Heading 1" directly to "Heading 3". I hope you find this macro useful! | |||
Sub headingsToMindMap | |||
newline = CHR$( 10 ) | |||
headings = "" | |||
Dim levels(10) | |||
levels(0) = "</node>" & newline | |||
levels(1) = "</node></node>" & newline | |||
levels(2) = "</node></node></node>" & newline | |||
levels(3) = "</node></node></node></node>" & newline | |||
levels(4) = "</node></node></node></node></node>" & newline | |||
levels(5) = "</node></node></node></node></node></node>" & newline | |||
oldLevel = 1 | |||
level = 1 | |||
outURL = ThisComponent.getURL() & ".mm" | |||
n = FreeFile() | |||
open outURL for output access write as #n | |||
enum = ThisComponent.Text.CreateEnumeration() | |||
headings = "<map version=""0.8.0"">" & newline | |||
Do While enum.hasMoreElements() | |||
par = enum.nextElement() | |||
if par.supportsService("com.sun.star.text.Paragraph") Then | |||
style = par.ParaStyleName | |||
if StrComp("Heading 1", style) = 0 Then | |||
headings = headings & " <node TEXT=""" & par.getString() & """>" & newline | |||
level = 1 | |||
End If | |||
if StrComp("Heading 2", style) = 0 Then | |||
level = 2 | |||
if (level <= oldLevel) Then | |||
headings = headings & levels( oldLevel - level) | |||
End If | |||
headings = headings & " <node POSITION=""right"" TEXT=""" & par.getString() & """>" | |||
End If | |||
if StrComp("Heading 3", style) = 0 Then | |||
level = 3 | |||
if (level <= oldLevel) Then | |||
headings = headings & levels( oldLevel - level) | |||
End If | |||
headings = headings & " <node POSITION=""right"" TEXT=""" & par.getString() & """>" & newline | |||
End If | |||
if StrComp("Heading 4", style) = 0 Then | |||
level = 4 | |||
if (level <= oldLevel) Then | |||
headings = headings & levels( oldLevel - level) | |||
End If | |||
headings = headings & " <node POSITION=""right"" TEXT=""" & par.getString() & """>" & newline | |||
End If | |||
if StrComp("Heading 5", style) = 0 Then | |||
level = 5 | |||
if (level <= oldLevel) Then | |||
headings = headings & levels( oldLevel - level) | |||
End If | |||
headings = headings & " <node POSITION=""right"" TEXT=""" & par.getString() & """>" & newline5 | |||
End If | |||
oldLevel = level | |||
End If | |||
Loop | |||
headings = headings & levels( level - 1) | |||
headings = headings & " " & newline & "</map>" | |||
MsgBox CStr( headings ) | |||
print #n headings | |||
close #n | |||
End Sub | |||
--[[User:Jimarlow|Jimarlow]] 14:12, 19 May 2009 (UTC) | |||
==3D Topicscape== | |||
Conversion from 3D Topicscape to FreeMind and vice versa: | |||
[http://en.wikipedia.org/wiki/3D_Topicscape 3D Topicscape] '''Pro''' and the '''Student Edition''' (SE is free as in beer) have built-in conversion to and from FreeMind ('''0.9.0'''). | [http://en.wikipedia.org/wiki/3D_Topicscape 3D Topicscape] '''Pro''' and the '''Student Edition''' (SE is free as in beer) have built-in conversion to and from FreeMind ('''0.9.0'''). | ||
If you make extensive use of FreeMind attributes for your own purposes, Topicscape won't know about them, and they will not be carried back again, but for a straightforward mindmap it seems to maintain integrity both ways. | If you make extensive use of FreeMind attributes for your own purposes, Topicscape won't know about them, and they will not be carried back again, but for a straightforward mindmap it seems to maintain integrity both ways. | ||
Topicscape can express structures that FreeMind can't (like multiple parents for one child and loose associations). The conversion translates these into color-coded curved lines with a single arrowhead and re-interprets this back to the multi-parent type of relationship on re-import. | Topicscape can express structures that FreeMind can't (like multiple parents for one child and loose associations). The conversion translates these into color-coded curved lines with a single arrowhead and re-interprets this back to the multi-parent type of relationship on re-import. | ||
=== FreeMind to 3D Topicscape conversion | |||
===To 3D Topicscape=== | |||
FreeMind to 3D Topicscape conversion: | |||
This allows a 3D mindmap to be built from a 2D FreeMind mindmap. | This allows a 3D mindmap to be built from a 2D FreeMind mindmap. | ||
# File menu->Import | # File menu->Import | ||
Line 547: | Line 1,979: | ||
NOTE: The above process will not be able to handle any user-defined attributes on the nodes. | NOTE: The above process will not be able to handle any user-defined attributes on the nodes. | ||
=== 3D Topicscape to FreeMind conversion | |||
===From 3D Topicscape=== | |||
3D Topicscape to FreeMind conversion: | |||
This allows a FreeMind (0.9.0) mindmap to be built from a 3D Topicscape. | This allows a FreeMind (0.9.0) mindmap to be built from a 3D Topicscape. | ||
# File menu->Export | # File menu->Export | ||
Line 556: | Line 1,992: | ||
# If you used the color scheme in Topicscape that allows each topic to be assigned a color automatically, the colors will be transferred (approximately) to the FreeMind map. | # If you used the color scheme in Topicscape that allows each topic to be assigned a color automatically, the colors will be transferred (approximately) to the FreeMind map. | ||
NOTE: The above process makes specific Topicscape attributes on the FreeMind nodes. To preserve the original Topicscape's integrity if you contemplate re-importing the mindmap to Topicscape, you need to avoid changing these atributes. The export may make double-headed gray lines and single-headed red lines. These are used to record multi-parent topics and loose associations. If you change them, then on any re-import to Topicscape, the structure will reflect those changes. | NOTE: The above process makes specific Topicscape attributes on the FreeMind nodes. To preserve the original Topicscape's integrity if you contemplate re-importing the mindmap to Topicscape, you need to avoid changing these atributes. The export may make double-headed gray lines and single-headed red lines. These are used to record multi-parent topics and loose associations. If you change them, then on any re-import to Topicscape, the structure will reflect those changes. | ||
=== 3D Topicscape | |||
=== Round-trip === | |||
3D Topicscape to FreeMind and back again; a round-trip: | |||
You can import to Topicscape and re-export to FreeMind - back and forth round trips are supported, provided you take into account the information in the NOTE paragraphs above. | You can import to Topicscape and re-export to FreeMind - back and forth round trips are supported, provided you take into account the information in the NOTE paragraphs above. | ||
The Topicscape on-line manual has an entry about these conversions here: | The Topicscape on-line manual has an entry about these conversions here: | ||
- http://www.topicscape.com/Topicscape-Pro/usersguide/help.php?page=132 | - http://www.topicscape.com/Topicscape-Pro/usersguide/help.php?page=132 | ||
== Rearrange folder structure == | |||
The following describes a method and a script for copying directory and files structures in Windows with a structure defined as a FreeMind mind map. It uses copying and pasting from FreeMind to MS Word then a script of Visual Basic Script. | |||
1. Import the existing directory/directories structure with freemind (File > Import > Folder Structure). Each final node has a link (Control + k) to the real file. It is preferable to set the preferences links path to absolute (Preferences > Appearence > Links = absolute) | |||
2. Rearrange the file structure. The node description represents the name of the file and can be modified in order to rename the file or directory. The file then will be copied under the new name. It is important ''not'' to update the link of nodes as the are the only information in freemind about the real file location. To delete a file or directory, just delete it from the map and it will not be copied to the new file system. | |||
3. Copy the branch or mind map to MS Word. I obtain a outlined and tabulated text like: | |||
: My Music <file:/C:/Documents and Settings/xxx/My Documents/My Temp/Music/> | |||
:: give it to me | |||
::: give it to me.mp3 <file:/C:/Documents and Settings/xxx/My Documents/My Temp/Music/give it to me.mp3> | |||
4. Add the following macro to the Word document | |||
Sub freemind_exportFolder() | |||
' | |||
' exportFolder Macro | |||
' Macro recorded 11/24/2004 by fbanag | |||
' | |||
Dim current_depth As Long | |||
Dim previous_depth As Long | |||
Dim diff_depth As Long | |||
' Define the Root directory | |||
ChDir ActiveDocument.Path | |||
Selection.GoTo what:=wdGoToLine, which:=wdGoToFirst ' start from beginning | |||
unit_indent = 17.5 'to be updated for the .dot used | |||
previous_depth = -100 | |||
Do | |||
Selection.EndOf unit:=wdParagraph, Extend:=wdExtend | |||
' Depth extraction, use the outline level | |||
current_indent = Selection.Paragraphs(1).LeftIndent | |||
current_depth = current_indent / unit_indent | |||
current_outline = Selection.Paragraphs(1).OutlineLevel | |||
' Update the unit_indent when outline is < 8 | |||
If current_outline < 8 And current_outline > 1 Then | |||
unit_indent = current_indent / (current_outline - 1) | |||
End If | |||
' Calculate the change in depth | |||
diff_depth = current_depth - previous_depth | |||
' Update the directory level | |||
If diff_depth = 1 Then | |||
ChDir node_name | |||
Else | |||
Do While diff_depth < 0 | |||
ChDir "./.." | |||
diff_depth = diff_depth + 1 | |||
Loop | |||
End If | |||
previous_depth = current_depth | |||
'remove the last character of the selection | |||
Selection.MoveRight unit:=wdCharacter, Count:=-1, Extend:=wdExtend | |||
' define if is directory or file | |||
directory_node = 0 | |||
If Selection.Text Like "*<file:*" Then 'include the path | |||
'check if directory | |||
If Selection.Text Like "*/>" Then | |||
directory_node = 1 | |||
End If | |||
' extract the node name | |||
Selection.MoveEndUntil Cset:="<", Count:=wdBackward | |||
Selection.MoveRight unit:=wdCharacter, Count:=-2, Extend:=wdExtend | |||
Else | |||
directory_node = 1 | |||
End If | |||
node_name = Selection.Text | |||
' check now if the selection is a file | |||
If directory_node = 0 Then | |||
' selectionne the path | |||
Selection.EndOf unit:=wdParagraph, Extend:=wdExtend | |||
With Selection.Find | |||
.Text = "<file:/" | |||
.Replacement.Text = "" | |||
.Forward = True | |||
.Wrap = wdFindAsk | |||
.Format = False | |||
.MatchCase = False | |||
.MatchWholeWord = False | |||
.MatchWildcards = False | |||
.MatchSoundsLike = False | |||
.MatchAllWordForms = False | |||
End With | |||
Selection.Find.Execute | |||
Selection.Collapse Direction:=wdCollapseEnd | |||
Selection.MoveEndUntil Cset:=">", Count:=wdForward | |||
filepath = Selection.Text | |||
' using the name written in the freeemind | |||
'FileCopy | |||
FileCopy filepath, node_name | |||
Else ' if not, then it is a directory | |||
asc_code = Asc(node_name) | |||
' Check no empty name | |||
If node_name Like "o" Or node_name Like "" Then | |||
node_name = "NewFolder" | |||
End If | |||
' create a directory | |||
' doesn't handle the duplicate folder names at the same level and the end of file | |||
' I will have to add that (a day) | |||
If Asc(node_name) <> 13 Then | |||
MkDir node_name | |||
End If | |||
End If | |||
Loop While Selection.MoveDown(unit:=wdParagraph, Count:=1) | |||
End Sub | |||
5. Place the word file in the new root directory where You want files to be copied (don't forget to save the word document) | |||
6. Run the macro | |||
Known issues: | |||
* the script stops with an error message if there is special characters in the file name or path | |||
* the script stops if exists two files with the same name under the same directory | |||
This method and script has plenty of room for improvement, but it has been good enough for my task of reorganizing hundred of files (result of years of filling up several hard drives). It is a task I would not even have started without FreeMind. | |||
Thank You to the Freemind team. | |||
== ECCO == | |||
FreeMind to ECCO: | |||
If a branch is copied and pasted directly in ECCO PRO, a well appreciated and freely available PIM (see [http://en.wikipedia.org/wiki/Ecco_Pro Wikipedia: Ecco Pro]). | |||
The mind map structure is gracefully transformed in an outline and can be printed in a professional way. | |||
== IIS == | |||
FreeMind to IIS: | |||
By: gobinathoss | |||
Hi, | |||
i need help to view the freemind file through IIS website | |||
i am getting the following error: This URL is malformed! no protocol: | |||
myfreemind.mm | |||
myfreemind.mm is my file name located in the IIS server | |||
... | |||
I got the solution | |||
1 ) copy freemindbrowser.html, freemindbrowser.jar and <yourmap>.mm to some | |||
folder | |||
2 ) go to IIS, right-click on your web site and choose properties. Go to HTTP | |||
Headers tab and click on MIME Types. Add the following MIME type : | |||
extension : mm | |||
MIME type : application/freemind | |||
Thanks | |||
S.Gobinath | |||
==See also== | |||
* [[Accessories]] | |||
* [[Export using XSLT]] | |||
[[Category:Documentation]] |
Latest revision as of 05:29, 28 November 2013
- For conversion scripts and XSLT, see also Accessories.
Import and export to other applications, alias conversion between FreeMind and other data formats:
Overview and miscellaneous
- To and from Microsoft Excel Import and export with Microsoft Excel works by drag & drop or copy & paste of complete nodes. You can copy a selection of cells in Excel and drop it in FreeMind. Doing this with several columns, creates corresponding child nodes. This also works with the OpenOffice.org Calc spreadsheet application.
- To and from OpenOffice Writer To export to OpenOffice Writer you first need to have all of the nodes on the right-hand side of the main/parent node in the mindmap (please make a correction if this is wrong). Then choose 'Select all' in the FreeMind mind map, go to OpenOffice Writer and select 'File > Paste'. OpenOffice Writer layouts using tab indentation can also be pasted into FreeMind which will recreate their tree structure.
NB: Upcoming Freemind 0.9 supports direct export to OpenOffice Writer File (odt). - To Microsoft Word 2003 To export to Microsoft Word, you need to select only the top-most node, which you want to export. Next, copy the node in Freemind and paste it into Word. this will copy the entire hierarchy starting with the selected node. This works even, when not all sub-notes were to the right of the one selected. If you would select and copy all nodes, export would end up with duplicate nodes and sub-nodes.
- From Microsoft Word 2003 Importing from Microsoft Word ended up with a confused hierarchy. (Please, can someone try how to do this best).
- From KeyNote To prepare a file from Keynote, save your tree structure by selecting 'Tree > Save Tree to File'. Open the created file as a text file and use select all to copy all content. In FreeMind, select a node and paste the content. FreeMind analyzes the tree structure in the file and builds a mind map.
- From the Internet You can copy part of a web page in your browser and paste it to FreeMind. FreeMind analyzes the tree structure in the HTML and builds a mind map. The other formatting (bold, font sizes, etc.) is not taken into FreeMind.
- To and from GanttProject To do this you will need the XSL conversion script. If you don't want to download the xalan package, you can use the xsl template in the zip archive on this page from FreeMind File > Export using XSLT....
- Almost every outliner should be capable of exporting to a tab-indented outline. This can be pasted to FreeMind.
- To and from GoalEnforcer Click the ""Software Integration"" button on GoalEnforcer Hyperfocus main window. Select ""Import from FreeMind"" or ""Export to FreeMind.""
FreeMind
FreeMind to FreeMind (Hoist):
Changing the root node of a map could make it much easier to print. This hoist.xsl script needs a graphical link from the actual root node to the desired root node after the hoist operation. The former parent node become a child node of the new root and the ancestor tree turns like an umbrella in the storm. Try it:
- select the root node and the desired new root and place a graphical link.
- export using hoist.xsl
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="*|@*"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:apply-templates/> </xsl:copy> </xsl:template> <xsl:template match="/map"> <xsl:copy> <xsl:copy-of select="attribute_registry"/> <xsl:apply-templates select="//node[@ID=/map/node/arrowlink/@DESTINATION]"/> </xsl:copy> </xsl:template> <xsl:template match="//node[@ID=/map/node/arrowlink/@DESTINATION]"> <xsl:copy> <xsl:copy-of select="*|@*"/> <xsl:apply-templates select="." mode="aws"/> </xsl:copy> </xsl:template> <xsl:template match="node" mode="aws"> <xsl:if test="parent::node"> <xsl:element name="node"> <xsl:attribute name="TEXT"> <xsl:value-of select="../@TEXT"/> </xsl:attribute> <xsl:attribute name="ID"> <xsl:value-of select="../@ID"/> </xsl:attribute> <xsl:if test="../@BACKGROUND_COLOR"> <xsl:attribute name="BACKGROUND_COLOR"> <xsl:value-of select="../@BACKGROUND_COLOR"/> </xsl:attribute> </xsl:if> <xsl:if test="../@COLOR"> <xsl:attribute name="COLOR"> <xsl:value-of select="../@COLOR"/> </xsl:attribute> </xsl:if> <xsl:if test="../@STYLE"> <xsl:attribute name="STYLE"> <xsl:value-of select="../@STYLE"/> </xsl:attribute> </xsl:if> <xsl:if test="../@POSITION"> <xsl:attribute name="POSITION"> <xsl:value-of select="../@POSITION"/> </xsl:attribute> </xsl:if> <xsl:apply-templates select="../edge|../arrowlink|../font|../icon"/> <xsl:apply-templates select="preceding-sibling::node"/> <xsl:apply-templates select="following-sibling::node"/> <xsl:apply-templates select="parent::node" mode="aws"/> <xsl:apply-templates select="../attribute"/> </xsl:element> </xsl:if> </xsl:template> </xsl:stylesheet>
- if you are missing something, you have to add it to the template match="node" mode="aws" (I only need edge, font, icon and attribute and don't know what else is possible.)
- load your new map
JR 03:32, 17 Apr 2008 (PDT)
Emacs
Convesion from FreeMind to Emacs outlines and Wikipedia outlines:
There are two ways how to export FreeMind's mind map to the outline format understood by Emacs outlining mode and Wikipedia. Their descriptions follow.
Use conversion scripts
Our users have created two perl scripts for conversion between FreeMind and Emacs's outline.
- mm2outline for Emacs outline (Perl) (This version does not work for wikipedia!)
#!/usr/bin/perl -w use strict; use Getopt::Std; use XML::Simple; use Data::Dumper qw(Dumper); # Copyright (c) 2004 Christian Lemburg. # # All rights reserved. This program is free software; # you can redistribute it and/or modify it under the # same terms as Perl itself. # usage my $usage = <<'EOU'; Usage: $0 < freemind.mm > emacs-outline.txt Options: h: print help p: outline mode heading indicator pattern atom (default "*") s: suppress topic of mind map as title in outline output (default off) EOU # setup my %opts; getopts('hsp:', \%opts); die $usage if $opts{h}; my $heading_pattern_atom = $opts{p} || "*"; my $suppress_title = $opts{'s'}; my $QUOTE = """; my $LESS_THAN = "<"; my $GREATER_THAN = ">"; my $NEWLINE = "
"; # action my $xs = new XML::Simple(); my $ref = $xs->XMLin(\*STDIN); die "Could not find mind map in input" unless exists $ref->{node}; my $start = $ref->{node}; print unquote($start->{TEXT}), "\n\n" unless $suppress_title; my $level = 0; process_children($start); # subs sub process_node { my ($node) = @_; process_node_text($node, $level); if (not is_leaf($node)) { process_children($node); } } sub process_children { my ($node) = @_; $level++; if (ref($node->{node}) eq "ARRAY") { for my $child (@{$node->{node}}) { process_node($child); } } else { my $child = $node->{node}; process_node($child); } $level--; } sub process_node_text { my ($node, $level) = @_; if (is_paragraph_leaf($node)) { print unquote($node->{TEXT}), "\n\n"; } else { print make_heading($level), " ", unquote($node->{TEXT}), "\n\n"; } } sub is_leaf { my ($node) = @_; return not exists $node->{node}; } sub is_paragraph_leaf { my ($node) = @_; # define: paragraph leaf = leaf with text that contains newlines return is_leaf($node) && $node->{TEXT} =~ /$NEWLINE/; } sub make_heading { my ($level) = @_; return $heading_pattern_atom x $level; } sub unquote { my ($s) = @_; $s =~ s/$QUOTE/"/g; $s =~ s/$LESS_THAN/</g; $s =~ s/$GREATER_THAN/>/g; $s =~ s/$NEWLINE/\n/g; return $s; }
- outline2mm for Emacs outline (Perl)
#!/usr/bin/perl use strict; use Getopt::Std; use POSIX; # Copyright (c) 2004 Christian Lemburg. # # All rights reserved. This program is free software; # you can redistribute it and/or modify it under the # same terms as Perl itself. # usage my $usage = <<'EOU'; Usage: $0 < emacs-outline.txt > freemind.mm Options: h: print help l: pattern atom length (default 1) p: outline mode regex to recognize headings (default "^(\\*+)") s: show suppressed text paragraphs (default off) t: topic (top level node text) for mind map output (default "Start") EOU # setup my %opts; getopts('hsl:p:t:', \%opts); die $usage if $opts{h}; my $QUOTE = """; my $LESS_THAN = "<"; my $GREATER_THAN = ">"; my $NEWLINE = "
"; my $AMPERSAND = "&"; my $atom_length = $opts{l} || 1; my $pattern = $opts{p} || "^(\\*+)"; my $topic = $opts{t} || "Start"; my $show_suppressed_text_paragraphs = $opts{'s'}; # action open_map(); open_node(0, 1, $topic); my $n; my @l; my $found_heading = 0; my $text = ""; while (<>) { if (s/$pattern//) { # header number calculation # use only one global by using empty first place in @l $n = POSIX::floor(length($1) / $atom_length); $n < $l[0] ? @l[$n+1..$#l] = (0)x($#l-$n) : 0; maybe_discharge_text($n); maybe_close_node($n, $l[0]); open_node($n, $l[0], $_); $l[$n]++; $l[0] = $n; } else { accumulate_text($_); } } maybe_close_node(0, $l[0]); close_map(); # subs sub open_node { my ($n, $o, $s) = @_; # push, maybe multiple with empty parents for (my $i = 0; $i < $n - $o - 1; $i++) { print indent($o + $i + 1), "<node TEXT=\"\">\n"; } $s =~ s/^\s+//; $s =~ s/\s+$//; print indent($n), "<node TEXT=\"", quote($s), "\">\n"; } sub maybe_close_node { my ($n, $o) = @_; return unless $found_heading++; # pop, maybe multiple for (my $i = 0; $i < $o + 1 - $n; $i++) { print indent($o - $i), "</node>\n"; } } sub open_map { print "<map>\n"; } sub close_map { print "</map>\n"; } sub indent { my ($l) = @_; # the map element is one above us $l++; return " " x $l; } sub accumulate_text { my ($s) = @_; $s =~ s/\s+$//; $s .= $NEWLINE; $text .= $s; } sub maybe_discharge_text { my ($n) = @_; return unless $show_suppressed_text_paragraphs; print indent($n + 1), "<node TEXT=\"" . quote($text) . "\"/>\n" unless is_only_whitespace($text); $text = ""; } sub quote { my ($s) = @_; $s =~ s/"/$QUOTE/g; $s =~ s/</$LESS_THAN/g; $s =~ s/>/$GREATER_THAN/g; $s =~ s/&/$AMPERSAND/go; return $s; } sub is_only_whitespace { my ($s) = @_; $s =~ s/$NEWLINE/\n/g; return $s =~ /\A\s*\Z/; }
Export from Emacs with freemind.el
There is an Emacs library on EmacsWiki that exports to FreeMind:
Patch FreeMind to paste outline to clipboard
Patching the source code is sensible, only if you are a software developer. In FreeMind's source in modes/mindmapmode/!MindMapNodeModel.java replace the lines
for (int i=0; i < depth; ++i) { fileout.write(" "); } if (this.toString().matches(" *")) {
with
for (int i=0; i < depth; ++i) { fileout.write("*"); } //changed fileout.write(" "); // new if (this.toString().matches(" *")) {
and if you copy a node in FreeMind you will find an Emacs/Wiki outline in the clipboard!
See also: How to compile FreeMind
Does anybody know how to patch FreeMind that it will also import these outline? (I made an feature request out of this.)
MindManager
Conversion from MindManager to FreeMind and vice versa:
From MindManager 4.0
Indirect MindManager 4.0 to FreeMind conversion:
How I converted all my mindmanager-mindmaps to freemind in one go. This works for me. Perhaps not for you. Mindmanager 4.0: MMScript?-Editor has a problem with: Dim mm As MmImageType?
- Download Download XSLT transformations sheets from Christoph Rissner from http://hkrott.iicm.edu/docs/seminar/sem2002_mindmaps.tar.gz and extract. You need some of those files in step 4 an step 8.
- Open Mindmap in Mindmanager 2002 (With Mindmanager 4.0 I had a problem with "Dim mm As MmImageType?". You CAN use further the MMScript?-Editor after the 21-days-trial-tim)
- Menu->Tools->MMScript?-Editor
- MMScript?-Editor: Menu->Open File->exportXML.MMScript? (see step 1)
- Menu->Makro->Ausführen (or key "F5")
- (x) Export whole map, Choose destination file, (OK)
- Copy all xml-Files in a new directory or make of cource a backup of all your mindmaps! Sorry windows, with linux the following conversion is very easy. Perhaps do it with windows with a batch-file or something else.
- Save the following bash-script to "mmtofmconvert" and make it executable with "chmod a+x mmtofmconvert":
#! /bin/sh # mmtofm-convert # Leerzeichen in Dateinamen in _ umwandeln for f in *\ *; do mv "$f" "`echo $f | tr \ _`"; done # xml-Dateien in mm umwandeln # Pfad zur Datei mm2fm.xslt muss angepasst werden! See step 1 # xsltproc: http://xmlsoft.org/XSLT/ for f in *.xml; do xsltproc -o `basename $f .xml`.mm /home/pete/mm2fm.xslt $f; done # ACHTUNG! Entferne alle xml und mmp-Dateien. # Attention! Delete all xml- and mmp-files! #rm *.xml *.mmp # Codierung von utf-8 in lokal erwünschte umwandeln. With work for me. recode utf-8 *.mm
- execute script from step 8 in every directory with the xml-files you want to transform.
- the exported mindmaps have exactly the same structure like the original! I am lucky.
Regards, Peter
NOTE: The above version of the XSLT script does not process the MindManager "notes" if they exist for each node. This is my first time working with XSLT, but the following ammendment to "mm2fm.xslt" worked for me (sections below added after line 55 in the template '<xsl:template match="data">'):
<xsl:if test="boolean(note)"> <xsl:element name="node"> <xsl:apply-templates select="note"/> </xsl:element> </xsl:if> </xsl:template>
<xsl:template match="note"> <xsl:apply-templates select="color"/> <xsl:apply-templates select="text"/> <xsl:element name="font"> <xsl:apply-templates select="font"/> </xsl:element> </xsl:template>
--Apalmer00 10:27, 26 Jan 2005 (PST)
From MindManager X5
Direct MindManager X5 to FreeMind conversion:
I received a couple of MindManager mindmaps that I had to convert to FreeMind. These mmap files turned out to be zip-files containing an XML file with the mindmap data. So I've written a basic XSLT which directly transforms this XML to the FreeMind format without the need to install MindManager. I suppose a convenient Import from MindManager could thus be provided in FreeMind using this info/xslt. I also suppose that this XSLT could be extended to transform additional specifics like edge-color, edge-width, etc, but I could not immediately figure out where such data is stored in MindManager's XML, as I do not have MindManager.
NB: I changed "concat(#, below to "concat('#', below to make it work. I also used jar xf file.mmap to extract the files.
<?xml version="1.0" encoding="iso-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ap="http://schemas.mindjet.com/MindManager/Application/2003" > <xsl:output method="xml" version="1.0" encoding="iso-8859-1" omit-xml-declaration="yes" indent="yes" /> <xsl:template match="/"> <xsl:element name="map"> <xsl:attribute name="version">0.7.1</xsl:attribute> <xsl:apply-templates select="ap:Map/ap:OneTopic/ap:Topic" /> </xsl:element> </xsl:template> <xsl:template match="ap:Topic"> <xsl:element name="node"> <xsl:attribute name="TEXT"> <xsl:value-of select="ap:Text/@PlainText" /> </xsl:attribute> <xsl:if test="ap:Text/ap:Font/@Color"> <xsl:attribute name="COLOR"> <xsl:value-of select="concat('#', substring(ap:Text/ap:Font/@Color, 3, 6))" /> </xsl:attribute> </xsl:if> <xsl:variable name="OId" select="@OId" /> <xsl:variable name="relation" select="/ap:Map/ap:Relationships/ap:Relationship[ap:ConnectionGroup[@Index=0]/ap:Connection/ap:ObjectReference/@OIdRef=$OId]" /> <xsl:if test="$relation"> <xsl:variable name="toId" select="$relation/ap:ConnectionGroup[@Index=1]/ap:Connection/ap:ObjectReference/@OIdRef" /> <xsl:element name="arrowlink"> <xsl:attribute name="ENDARROW">Default</xsl:attribute> <xsl:attribute name="DESTINATION"> <xsl:value-of select="$relation/ap:ConnectionGroup[@Index=1]/ap:Connection/ap:ObjectReference/@OIdRef" /> </xsl:attribute> <xsl:attribute name="STARTARROW">None</xsl:attribute> </xsl:element> </xsl:if> <xsl:variable name="toId" select="/ap:Map/ap:Relationships/ap:Relationship/ap:ConnectionGroup[@Index=1]/ap:Connection/ap:ObjectReference[@OIdRef=$OId]/@OIdRef" /> <xsl:if test="$toId"> <xsl:attribute name="ID"> <xsl:value-of select="$toId" /> </xsl:attribute> </xsl:if> <xsl:apply-templates select="ap:SubTopics"/> </xsl:element> </xsl:template> </xsl:stylesheet>
An online conversion utility that uses the above XSLT to convert a MindManager .mmap file to FreeMind .mm format:
Q: How can I convert a mmap file with non-latin characters, such as Chinese and Japanese characters? Those words and sentenses will became several Question Marks!
NB: Please check your JVM default property "file.encoding".
String defaultEncodingName = System.getProperty( "file.encoding" ); System.out.println(defaultEncodingName);
Since "mmap" file's encoding is "UTF8", so that we have to use "UTF8" with "file.encoding" property. I straightly change the startup script to support it.
E.g: In Windows Version, it has a "freemind.bat".
java -Dfile.encoding=UTF8 -cp lib\freemind.jar;...
From MindManager (2)
From MindManager directly into FreeMind 0.9b9: Starting with freemind 0.9 b9 (?) it became possible to import a Mmap-File directly
To convert notes from Mindmanager to Freemind notes you have to replace the following lines in mindmanager2mm.xsl
<xsl:template match="ap:NotesGroup"> <xsl:element name="hook"> <xsl:attribute name="NAME"> <xsl:text>accessories/plugins/NodeNote.properties</xsl:text> </xsl:attribute> <xsl:element name="text"> <xsl:value-of select="ap:NotesXhtmlData/@PreviewPlainText"/> </xsl:element> </xsl:element> </xsl:template>
with
<xsl:template match="ap:NotesGroup"> <richcontent TYPE="NOTE"><html> <head> </head> <body> <p> <xsl:value-of select="ap:NotesXhtmlData/@PreviewPlainText" disable-output-escaping="yes" /> </p> </body> </html> </richcontent> </xsl:template>
To MindManager
To export a mind map to MindManager:
- Export the FreeMind mind map with no folded nodes to HTML.
- Open the HTML file in Microsoft Word and save it as Word file (.doc).
- Open the Word file in MindManager.
MindManager supports direct import of Word files and other Microsoft Office documents.
Notes
The file format of MindManager 5.0 and later is a zipped file. It is possible to get the contents of .mmap by renaming a copy of it to .zip and opening in favorite zip application.
It is not true for files saved using MindManager 4.0 Standard Edition.
To fix problems with character encoding:
- Try to change the encoding="UTF-8" to encoding="iso-8859-1" in the xslt sheet posted above.
Plain text
Conversion from plain text to FreeeMind:
Wouter Bolsterlee wrote a small tool named Text-to-Freemind. This program converts tab-indented text files into an XML format suitable for display by FreeMind. It was written out of annoyance with the FreeMind user interface, and the lack of ‘merging’ capabilities when collaborating with other people. More information, including an example and download links, is available from Wouter Bolsterlee's blog entry on Text-to-Freemind.
Alternatively you can Cut and Paste directly tabular idented texts into a new or existing FreeMind maps. For example the text editor Crimson Editor can be used to create or edit tabular indented texts and use them directly in FreeMind.
CSV text
Conversion from FreeMind to CVS text:
This is an XSLT to output a Freemind mind map as a CSV text file with extra commas to represent the hierarchy. This is useful for importing into Excel to represent the nesting of nodes as a colum view.
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:template match="/"> <xsl:apply-templates/> </xsl:template> <xsl:template name="linebreak"> <xsl:text> </xsl:text> </xsl:template> <xsl:template match="map"> <xsl:apply-templates select="child::node"/> </xsl:template> <xsl:template match="node"> <xsl:param name="commaCount">0</xsl:param> <xsl:if test="$commaCount > 0"> <xsl:call-template name="writeCommas"> <xsl:with-param name="commaCount" select="$commaCount"/> </xsl:call-template> </xsl:if> <xsl:value-of select="@TEXT"/> <xsl:call-template name="linebreak"/> <xsl:apply-templates select="child::node"> <xsl:with-param name="commaCount" select="$commaCount + 1"/> </xsl:apply-templates> </xsl:template> <xsl:template name="writeCommas"> <xsl:param name="commaCount">0</xsl:param> <xsl:if test="$commaCount > 0">,<xsl:call-template name="writeCommas"> <xsl:with-param name="commaCount" select="$commaCount - 1"/> </xsl:call-template> </xsl:if> </xsl:template> </xsl:stylesheet>
Developed by Mike Bell at Simulacra.
If you have issues with accuented characters not being transferred correctly in Excel, you can do the following:
- save the exported file as somename.txt (instead of somename.csv)
- start Excel
- menu point File -> Open...
- choose "Files of Type" = Text Files (...*.txt...)
- then you get a dialogue where you can choose the "File Origin", which in Western Europe and USA is most probably one of Unicode (UTF-8) or Western European (ISO or Windows, I'd guess). Anyway, change the "origin" (correctly it's called charset) until the accents in the preview window are correctly shown.
Something similar should work under oocalc from OpenOffice.
Alternatively, one could also try to add an "encoding" parameter to the "output" element of the XSLT sheet, like in Zvon's XSLT Reference.
Tabulator separated text
Conversion from FreeMind to tabulator separated text:
This is a modification of the above XSLT script to output a FreeMind map as a tabulator separated text file with the first column represent the hierarchy, the 2nd the path as 1.1.1 number, followed by the node title and the attribute value pairs (FreeMind 0.9.0 beta16) which are present in the attribute_registry. This is extremely useful if you keep the position of your attributes constant over the whole tree! Importing into Calc or Excel is straight forward.
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:template match="/"> <xsl:apply-templates/> </xsl:template> <xsl:template name="linebreak"> <xsl:text> </xsl:text> </xsl:template> <xsl:template name="tabulator"> <xsl:text> </xsl:text> </xsl:template> <xsl:template match="map"> <xsl:apply-templates select="child::node"/> </xsl:template> <xsl:template match="attribute"> <xsl:value-of select="@NAME"/> <xsl:text> =</xsl:text> <xsl:call-template name="tabulator"/> <xsl:value-of select="@VALUE"/> <xsl:call-template name="tabulator"/> </xsl:template> <xsl:template match="node"> <xsl:value-of select="count(../ancestor-or-self::node)" /> <xsl:call-template name="tabulator"/> <xsl:number count="node" level="multiple" format="1.1"/> <xsl:call-template name="tabulator"/> <xsl:value-of select="@TEXT"/> <xsl:call-template name="tabulator"/> <xsl:apply-templates select="child::attribute[@NAME=//attribute_registry/attribute_name/@NAME]"/> <xsl:call-template name="linebreak"/> <xsl:apply-templates select="child::node"> </xsl:apply-templates> </xsl:template> </xsl:stylesheet>
JR 07:38, 20 Mar 2008 (PDT)
VYM
There is a useful project at Sourceforge: vym2fm.
Conversion from VYM to FreeMind:
The following XSLT converts an XML export file from VYM to freemind format (only links, Icons and colors are preserved):
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <xsl:apply-templates select="/vymmap/mapcenter" /> </xsl:template> <xsl:template match="/vymmap/mapcenter"> <map version="0.8.0"> <node ID="_" TEXT="map imported from VYM"> <xsl:apply-templates select="branch" /> </node> </map> </xsl:template> <xsl:template match="branch"> <node CREATED="0" MODIFIED="0"> <xsl:attribute name="TEXT"> <xsl:value-of select="heading" /> </xsl:attribute> <xsl:attribute name="COLOR"> <xsl:value-of select="heading/@textColor" /> </xsl:attribute> <xsl:if test="@url != ''"> <xsl:attribute name="LINK"> <xsl:value-of select="@url" /> </xsl:attribute> </xsl:if> <xsl:attribute name="ID">VYM_<xsl:value-of select="@x1" />_<xsl:value-of select="@y1" /></xsl:attribute> <xsl:apply-templates select="standardflag" /> <xsl:apply-templates select="branch" /> </node> </xsl:template> <xsl:template match="standardflag"> <xsl:choose> <xsl:when test=". = 'lifebelt'"><icon BUILTIN="flag"/></xsl:when> <xsl:when test=". = 'flash'"><icon BUILTIN="clanbomber"/></xsl:when> <xsl:when test=". = 'heart'"><icon BUILTIN="bookmark"/></xsl:when> <xsl:when test=". = 'thumb-down'"><icon BUILTIN="button_cancel"/></xsl:when> <xsl:when test=". = 'thumb-up'"><icon BUILTIN="button_ok"/></xsl:when> <xsl:when test=". = 'arrow-down'"><icon BUILTIN="full-7"/></xsl:when> <xsl:when test=". = 'arrow-up'"><icon BUILTIN="full-1"/></xsl:when> <xsl:when test=". = 'lamp'"><icon BUILTIN="idea"/></xsl:when> <xsl:when test=". = 'clock'"><icon BUILTIN="bell"/></xsl:when> <xsl:when test=". = 'smiley-sad'"><icon BUILTIN="button_cancel"/></xsl:when> <xsl:when test=". = 'smiley-good'"><icon BUILTIN="ksmiletris"/></xsl:when> <xsl:when test=". = 'stopsign'"><icon BUILTIN="stop"/></xsl:when> <xsl:when test=". = 'cross-red'"><icon BUILTIN="button_cancel"/></xsl:when> <xsl:when test=". = 'hook-green'"><icon BUILTIN="button_ok"/></xsl:when> <xsl:when test=". = 'questionmark'"><icon BUILTIN="help"/></xsl:when> <xsl:when test=". = 'exclamationmark'"><icon BUILTIN="messagebox_warning"/></xsl:when> </xsl:choose> </xsl:template> </xsl:transform>
McRee 03:12, 14 Nov 2006 (PST)
Mantis bug tracker
Importing issues from the Mantis bug tracker to FreeMind: There is a script to export issues from Mantis to FreeMind: the script.
Mantis 1.12 ships with an integrated FreeMind support: "This is similar to the relationship diagrams are already available in Mantis. However, the Freemind features comes with a built in Flash viewer (hence, easier to get up and running), includes details about the issues, relationships, attachments, statuses, links, etc. It is also possible to export a Freemind file." Blog post
The Freemind export & browser support is now packaged as a plugin for Mantis >=1.2.0: Info & Download.
Microsoft Office
It is possible to export FreeMind mind maps to the XML formats of Microsoft Office 2003 and newer. The resulting files are in the new XML format, so the extensions of the files are "docx", TODO. The export is available to Excel, Word, and Project. PowerPoint isn't supported, as it doesn't support an XML format.
The generic procedure of how to export to one of Microsoft products is the following:
- Use the menu item File > Export > Using XSLT...
- Open the XSL file, depending on which product you have in mind:
- Word: "mm2wordml_utf8.xsl"
- Excel: "mm2xls_utf8.xsl"
- Name the export file
- Open the generated file by double-clicking it
For instructions per product, see the sections for the products including #Microsoft Excel, #Microsoft Word and #Microsoft Project.
Microsoft Excel
To export to Microsoft Excel:
- Use the menu item File > Export > Using XSLT...
- Open the XSL file "mm2xls_utf8.xsl" (in /FreeMind/accessories)
- Name the export file something.xls
- Open the generated file by double-clicking it
Microsoft Word
Export - method 1:
To export to Microsoft Word:
- Use the menu item File > Export > Using XSLT...
- Open the XSL file "mm2wordml_utf8.xsl" (in /FreeMind/accessories)
- Name the export file something.docx
- This seems to generate empty documents with Freemind 0.9.0 beta 12 on Windows XP. [Mike B 26 Feb 2009]
- This works using Version:0.9.0 and if the export file is named something.doc. Word reports corrupt file if the mm export is given a docx suffix [Mike D 22 Feb 2011]
Export - method 2:
To export to Microsoft Word:
- Export the mind map to HTML using Control + H.
- Copy and paste the resulting HTML from the web browser to Microsoft Word
Export - method 3
To export to Microsoft Word:
- Export the mind map to HTML using Control + H.
- Copy the path and filename from the browser's location bar, e.g. "file:///C:/Temp/tmm116427495429051789.html".
- Open Microsoft Word.
- Press CTRL + O and CTRL + V to paste the location of the previously generated HTML.
- Click OK.
Note: This method seems to retain the layout and formatting better than method 2.
Import:
To translate a MS Word outline into a FreeMind branch, a workaround is to insert tabs before paragraphs.
This is a simple Word macro to do that for all paragraphs with a heading style. Optionally, all body text can be removed first (backup document!).
Once the tabs have been inserted, the text can be pasted directly into FreeMind. However, only one branch will be added to the root, so if the outline contains several top level headings, the first will be 'upgraded' to the first branch node. Thus it is not possible to convert an entire document into a mindmap, but each branch has to be imported separately.
Warning: This does not work in Freemind 0.9.0 Beta 9, but has been tested in FM Scholar, which is based on the FM 0.8.1 release.
Sub InsertLeadingTabs() '' Insert heading level x tabs before each outline paragraph found. opt = MsgBox("Remove body text first?", vbYesNoCancel, "Insert leading tabs") If opt = vbCancel Then Exit Sub If opt = vbYes Then FilterHeadings With Selection.Find ' work around, since simple search for style does not act on sequential paras .ClearFormatting .Replacement.ClearFormatting .MatchWildcards = False .text = "^p" .Replacement.text = "^p###" .Forward = True .Wrap = wdFindContinue .Execute Replace:=wdReplaceAll End With For i = 1 To 9 With Selection.Find .ClearFormatting .Replacement.ClearFormatting .text = "###" .Style = ActiveDocument.Styles("Heading " & i) .Replacement.text = Right("^t^t^t^t^t^t^t^t^t^&", 2 + i * 2) .Forward = True .Wrap = wdFindContinue End With Selection.Find.Execute Replace:=wdReplaceAll Next i With Selection.Find .ClearFormatting .Replacement.ClearFormatting .text = "###" .Replacement.text = "" .Forward = True .Wrap = wdFindContinue .Execute Replace:=wdReplaceAll End With If Selection.Start = Selection.End Then ActiveDocument.Range.Select Selection.Copy If MsgBox("Tabbed outline copied to clipboard. Restore text now? (Body text that has been removed cannot be restored.)", _ vbYesNo, "Insert leading tabs") = vbYes Then RemoveLeadingTabs Selection.HomeKey Unit:=wdStory End Sub ' InsertLeadingTabs Sub RemoveLeadingTabs() '' Strip any tabs after a paragraph break, at the beginning of a line. If ActiveDocument.Characters(1) = vbTab Then ActiveDocument.Characters(1).delete With Selection.Find .ClearFormatting .Replacement.ClearFormatting .text = "^p^t" .Replacement.text = "^p" .Forward = True .Wrap = wdFindContinue End With For i = 1 To 9 Selection.Find.Execute Replace:=wdReplaceAll Next i Selection.HomeKey Unit:=wdStory End Sub ' RemoveLeadingTabs Sub FilterHeadings() '' Remove all paragraphs but headings. If MsgBox("Delete all text except headings. Are you sure?", vbOKCancel, "Filter headings") = vbCancel Then Exit Sub For Each p In ActiveDocument.Paragraphs If Left(p.Style, 7) <> "Heading" Then p.Range.delete Next p End Sub ' FilterHeadings
Microsoft Word using Outlining
Export
Sub ToMap() ' This Word macro uses the currently active document as the basis for creating a FreeMind format (.mm) file ' It creates an output file using the Outline structure of the active document to determine the nodes in ' the FreeMind file ' The created document should be saved in text format and the resultant file renamed to .mm for FreeMind ' Notes: ' We only go down one step at once - for example source content going from Level 1 to Level 10 (normal text) ' will only result in a single step in the node hierarchy ' Basic formatting (bold/normal and font size) is preserved in the node file ' Set scrdoc = ActiveDocument Set nodedoc = Documents.Add ' create our output document ' insert a minimal header nodedoc.Content.InsertAfter ("<map version=""0.9.0"">" + Chr(10)) nodedoc.Content.InsertAfter ("<node TEXT=""New Mindmap"">" + Chr(10)) reflevel = 1 ' the assumed starting level newlevel = 1 For Each para In scrdoc.Paragraphs If (para.OutlineLevel > reflevel) Then newlevel = newlevel + 1 ' only step down 1 level If (para.OutlineLevel < reflevel) Then newlevel = para.OutlineLevel ' step back to document level reflevel = para.OutlineLevel magic = curlevel - newlevel + 1 ' then +1 ensures we get </node><node> when staying on the same level curlevel = newlevel If (magic > 0) Then ' unwind to new level For ncount = 1 To magic nodedoc.Content.InsertAfter ("</node>" + Chr(10)) Next ncount End If ' create the new node txt = Replace(para.Range.Text, """", "'") ' always single quotes nodedoc.Content.InsertAfter ("<node TEXT=""" + Left(txt, Len(txt) - 1) + """>" + Chr(10)) ' preserve basic formatting nodedoc.Content.InsertAfter ("<font NAME=""Dialog"" ") Set fstyle = ActiveDocument.Styles(-1 - para.OutlineLevel).Font nodedoc.Content.InsertAfter ("SIZE=""" + Format(fstyle.Size) + """ ") btxt = "false" If (fstyle.Bold) Then btxt = "true" nodedoc.Content.InsertAfter ("BOLD=""" + btxt + """ />" + Chr(10)) Next para ' unwind back to our base level For ncount = 1 To curlevel nodedoc.Content.InsertAfter ("</node>" + Chr(10)) Next ncount ' terminate the xml nodedoc.Content.InsertAfter ("</node>" + Chr(10)) nodedoc.Content.InsertAfter ("</map>" + Chr(10)) ' propmt for output file name - save as "Plain Text(*.txt)" Set fd = Application.FileDialog(msoFileDialogSaveAs) fd.Show fd.Execute ' all done nodedoc.Close End Sub
Import
Sub xmltodoc() ' This Word macro uses the currently active document as the basis for creating a Word document with Outline ' levels corresponding to the node structure of the FreeMind (.mm) source file ' To load the source file, rename the .mm to .xml and open using Word ' The macro parses the node tree to determine the Outline level and then allocates the text for each node to ' the appropriate level ' The resultant document can be saved to Word (.doc) format ' ' A word of caution is necessary with any recursive function Dim objElement As XMLNode Set adoc = ActiveDocument Set outlinedoc = Documents.Add ' create our destination document outlinedoc.Content.InsertAfter ("" + Chr(10)) ' we need a starting point for our Promote/Demote sequence outlinedoc.Paragraphs(outlinedoc.Paragraphs.Count).OutlinePromote For Each objElement In adoc.XMLNodes.Item(1).ChildNodes ' start with the top level children xmllevel objElement, outlinedoc, False Next End Sub Sub xmllevel(nodes, outlinedoc, top) If (top) Then outlinedoc.Paragraphs(outlinedoc.Paragraphs.Count).OutlineDemote If nodes.NodeType = wdXMLNodeElement Then If (nodes.BaseName = "node") Then For acount = 1 To nodes.Attributes.Count If (nodes.Attributes(acount).BaseName = "TEXT") Then ' insert the outline text outlinedoc.Content.InsertAfter (nodes.Attributes(acount).NodeValue + Chr(10)) For Each objElement In nodes.ChildNodes ' descend to the next level children xmllevel objElement, outlinedoc, True Next End If Next acount End If End If outlinedoc.Paragraphs(outlinedoc.Paragraphs.Count).OutlinePromote ' unwind End Sub
Microsoft Project
Conversion from Microsoft Project to FreeMind and vice versa?
From MS Project
These are Python programs to create a FreeMind map (.mm) from an MS Project file.
mpp2mm.1.0.py will handle XML format (doesn't require win32com.client)
mpp2mm.py will handle .mpp and XML formats (and does require win32com.client)
mpp2mmw.pyw is a PyQt4 Dialog to invoke mpp2mm.py
Sample usage for mpp2mm.py is:
mpp2mm.py -i "c:\fullpath name\project.mpp" -c -a
This will produce a mindmap from MS Project file project.mpp, flag completed tasks and set some attributes. The output file will have the same name with a .mm extension.
Processing a .mpp file always requires the full path name
(I'm only a Python beginner so apologies for any "indiscretions". I haven't extensively tested them either)
AnGus
mpp2mm.py
#!/usr/bin/env python # """Create a FreeMind (.mm) mind map from a/an MS Project file. usage: mpp2mm -i <mppfile> -o <mmfile> -a -c Options and arguments: -a : generate (some) Attributes -c : generate icons for completed tasks -i mppfile : input MS Project mpp or xml file -o mmfile : output FreeMind map (name defaults to input filename) Copyright (c) 2009, AnGus King This code is licensed under the GPLv2 or later. (http://www.gnu.org/licenses/) """ __author__ = "AnGus King" __copyright__ = "Copyright (C) 2009, AnGus King" __license__ = "GPLv2 (http://www.gnu.org/licenses/)" __version__ = "1.1" import getopt import sys import win32com.client import xml.etree.ElementTree as ET class Mpp2Mm: def __init__(self): self.mmn = [] # create an empty node tree self.mmn.append("") self.lst_lvl = 0 # last level is 0 self.do_attr = False # by default don't create Attributes self.do_flag = False # by default don't flag completion def open(self, infile): """ Open the .mpp or .xml file and create a tree """ if infile.endswith('.xml'): self.proj = None try: self.tree = ET.parse(infile) return self.tree except Exception, e: print "Error opening file",e usage() else: try: self.mpp = win32com.client.Dispatch("MSProject.Application") self.mpp.Visible = False self.mpp.FileOpen(infile) self.proj = self.mpp.ActiveProject return self.proj except Exception, e: print "Error opening file",e usage() def write(self, outfile, attr, flag): """ Create the .mm file :-) """ self.do_attr = attr # create the mindmap as version 8.1 or 9.0) if generating # attribute tags if self.do_attr: self.mm = ET.Element("map",version="0.9.0") else: self.mm = ET.Element("map",version="0.8.1") self.do_flag = flag if self.proj is None: # .xml file root = self.tree.getroot() # process Task elements and fabricate hierarchy based upon OutlineLevel for node in root: if node.tag == "{http://schemas.microsoft.com/project}Name": self.mmn[0] = ET.SubElement(self.mm, "node", text=node.text) elif node.tag == "{http://schemas.microsoft.com/project}Author": if self.do_attr: self.mmn[0].append(ET.Element("attribute", \ NAME="prj-Author", VALUE=node.text)) elif node.tag == "{http://schemas.microsoft.com/project}StartDate": if self.do_attr: self.mmn[0].append(ET.Element("attribute", \ NAME="prj-StartDate", VALUE=node.text)) else: # the guts of it is the Tasks if node.tag == "{http://schemas.microsoft.com/project}Tasks": for nod in node: if nod.tag == "{http://schemas.microsoft.com/project}Task": if nod.findtext("{http://schemas.microsoft.com/project}UID") <> "0": # UID, Name, Start, Finish, WBS lvl = nod.findtext("{http://schemas.microsoft.com/project}OutlineLevel") txt = nod.findtext("{http://schemas.microsoft.com/project}Name") lvli = int(lvl) if lvli > self.lst_lvl: self.mmn.append("") self.lst_lvl = lvli self.mmn[lvli] = ET.SubElement(self.mmn[lvli-1], "node",text=txt) if self.do_attr: self.mmn[lvli].append(ET.Element("attribute", NAME="tsk-Duration", \ VALUE=nod.findtext("{http://schemas.microsoft.com/project}Duration"))) if self.do_flag: txt = nod.findtext("{http://schemas.microsoft.com/project}PercentComplete") if txt == "100": self.mmn[lvli].append(ET.Element("icon", BUILTIN="button_ok")) else: # .mpp file self.mmn[0] = ET.SubElement(self.mm, "node", text=self.proj.Project) if self.do_attr: self.mmn[0].append(ET.Element("attribute", \ NAME="prj-Author", VALUE=self.proj.Author)) self.mmn[0].append(ET.Element("attribute", \ NAME="prj-StartDate", VALUE=str(self.proj.ProjectStart))) for task in self.proj.Tasks: lvli = task.OutlineLevel txt = task.Name if lvli > self.lst_lvl: self.mmn.append("") self.lst_lvl = lvli self.mmn[lvli] = ET.SubElement(self.mmn[lvli-1], "node",text=txt) if self.do_attr: txt = str(task.Duration / 480) + "d" # convert to days self.mmn[lvli].append(ET.Element("attribute", NAME="tsk-Duration", \ VALUE=txt)) if self.do_flag: txt = task.PercentComplete if txt == 100: self.mmn[lvli].append(ET.Element("icon", BUILTIN="button_ok")) self.mpp.Quit() tree = ET.ElementTree(self.mm) tree.write(outfile) return def usage(): print __doc__ sys.exit(-1) def main(): try: opts , args = getopt.getopt(sys.argv[1:], "i:o:hac", \ ["help", "input=", "output="]) except getopt.GetoptError, err: # print help information and exit: print err # will print something like "option -x not recognized" usage() input = None output = None attr = False complete = False for o, a in opts: if o == "-a": # wants attributes printed attr = True elif o == "-c": # wants completion flags complete = True elif o in ("-h", "--help"): usage() elif o in ("-i", "--input"): input = a elif o in ("-o", "--output"): output = a else: assert False, "unhandled option" if input == None: print "Input file required" usage() if not (input.endswith('.xml') or input.endswith('.mpp')): print "Input file must end with '.mpp' or '.xml'" usage() if output == None: output = input[:-3] + "mm" if not output.endswith('.mm'): print "Output file must end with '.mm'" usage() mpp2mm = Mpp2Mm() tree = mpp2mm.open(input) mpp2mm.write(output,attr,complete) print output + " created." if __name__ == "__main__": main()
mpp2mmw.pyw
#!/usr/bin/env python """PyQt4 menu to invoke mpp2mm.py (plagiarised from example from Qt v4.x)""" import sys from PyQt4 import QtCore, QtGui from mpp2mm import Mpp2Mm class Dialog(QtGui.QDialog): def __init__(self, parent=None): QtGui.QDialog.__init__(self, parent) self.openFilesPath = QtCore.QString() self.errorMessageDialog = QtGui.QErrorMessage(self) frameStyle = QtGui.QFrame.Sunken | QtGui.QFrame.Panel self.messageLabel = QtGui.QLabel() self.messageLabel.setFrameStyle(frameStyle) self.cancelButton = QtGui.QPushButton(self.tr("Cancel")) self.okButton = QtGui.QPushButton(self.tr("&OK")) buttonLayout = QtGui.QHBoxLayout() buttonLayout.addStretch(1) buttonLayout.addWidget(self.okButton) buttonLayout.addWidget(self.cancelButton) self.connect(self.cancelButton, QtCore.SIGNAL("clicked()"), self, QtCore.SLOT("reject()")) self.connect(self.okButton, QtCore.SIGNAL("clicked()"), self, QtCore.SLOT("accept()")) self.openFileNameLabel = QtGui.QLabel() self.openFileNameLabel.setFrameStyle(frameStyle) self.openFileNameButton = QtGui.QPushButton(self.tr("Open Project File")) self.saveFileNameLabel = QtGui.QLabel() self.saveFileNameLabel.setFrameStyle(frameStyle) self.saveFileNameButton = QtGui.QPushButton(self.tr("Save FreeMind File")) self.attributeCheckBox = QtGui.QCheckBox(self.tr("Create Attributes")) self.attributeCheckBox.setChecked(False) self.flagCheckBox = QtGui.QCheckBox(self.tr("Flag completed tasks")) self.flagCheckBox.setChecked(False) self.connect(self.openFileNameButton, QtCore.SIGNAL("clicked()"), self.setOpenFileName) self.connect(self.saveFileNameButton, QtCore.SIGNAL("clicked()"), self.setSaveFileName) layout = QtGui.QGridLayout() layout.setColumnStretch(1, 1) layout.setColumnMinimumWidth(1, 250) layout.addWidget(self.openFileNameButton, 7, 0) layout.addWidget(self.openFileNameLabel, 7, 1) layout.addWidget(self.saveFileNameButton, 9, 0) layout.addWidget(self.saveFileNameLabel, 9, 1) layout.addWidget(self.attributeCheckBox, 11, 0) layout.addWidget(self.flagCheckBox, 11, 1) layout.addWidget(self.messageLabel, 13, 1) layout.addLayout(buttonLayout,15,1) self.setLayout(layout) self.setWindowTitle(self.tr("MS Project to FreeMind")) def setOpenFileName(self): fileName = QtGui.QFileDialog.getOpenFileName(self, self.tr("QFileDialog.getOpenFileName()"), self.openFileNameLabel.text(), self.tr("Project Files (*.mpp);;XML Files (*.xml);;All Files (*)")) if not fileName.isEmpty(): self.openFileNameLabel.setText(fileName) def setSaveFileName(self): fileName = QtGui.QFileDialog.getSaveFileName(self, self.tr("QFileDialog.getSaveFileName()"), self.saveFileNameLabel.text(), self.tr("FreeMind Files (*.mm);;All Files (*)")) if not fileName.isEmpty(): self.saveFileNameLabel.setText(fileName) def accept(self): mpp2mm = Mpp2Mm() infile = str(self.openFileNameLabel.text()) tree = mpp2mm.open(infile) if self.saveFileNameLabel.text() == "": oufile = infile[:-3] + "mm" else: oufile = str(self.saveFileNameLabel.text()) mpp2mm.write(oufile,self.attributeCheckBox.isChecked(),self.flagCheckBox.isChecked()) self.messageLabel.setText(oufile + " created.") if __name__ == '__main__': app = QtGui.QApplication(sys.argv) dialog = Dialog() sys.exit(dialog.exec_())
mpp2mm.1.0.py
#!/usr/bin/env python # """Create a FreeMind (.mm) mind map from a/an MS Project XML file. usage: mpp2mm -i <mppfile> -o <mmfile> -a -c Options and arguments: -a : generate (some) Attributes -c : generate icons for completed tasks -i mppfile : input MS Project xml file -o mmfile : output FreeMind map (name defaults to input filename) Copyright (c) 2009, AnGus King This code is licensed under the GPLv2 or later. (http://www.gnu.org/licenses/) """ __author__ = "AnGus King" __copyright__ = "Copyright (C) 2009, AnGus King" __license__ = "GPLv2 (http://www.gnu.org/licenses/)" __version__ = "1.1" import getopt import sys import xml.etree.ElementTree as ET class Mpp2Mm: def __init__(self): self.mmn = [] # create an empty node tree self.mmn.append("") self.lst_lvl = 0 # last level is 0 self.do_attr = False # by default don't create Attributes self.do_flag = False # by default don't flag completion def open(self, infile): """ Open the .xml file and create a tree """ try: self.tree = ET.parse(infile) return self.tree except Exception, e: print "Error opening file",e usage() def write(self, outfile, attr, flag): """ Create the .mm file :-) """ self.do_attr = attr # create the mindmap as version 8.1 or 9.0) if generating # attribute tags if self.do_attr: self.mm = ET.Element("map",version="0.9.0") else: self.mm = ET.Element("map",version="0.8.1") self.do_flag = flag root = self.tree.getroot() # process Task elements and fabricate hierarchy based upon OutlineLevel for node in root: if node.tag == "{http://schemas.microsoft.com/project}Name": # print "Project:" , node.text self.mmn[0] = ET.SubElement(self.mm, "node", text=node.text) elif node.tag == "{http://schemas.microsoft.com/project}Author": # print "Author:" , node.text if self.do_attr: self.mmn[0].append(ET.Element("attribute", \ NAME="prj-Author", VALUE=node.text)) elif node.tag == "{http://schemas.microsoft.com/project}StartDate": # print "StartDate:" , node.text if self.do_attr: self.mmn[0].append(ET.Element("attribute", \ NAME="prj-StartDate", VALUE=node.text)) else: # the guts of it is the Tasks if node.tag == "{http://schemas.microsoft.com/project}Tasks": for nod in node: if nod.tag == "{http://schemas.microsoft.com/project}Task": if nod.findtext("{http://schemas.microsoft.com/project}UID") <> "0": # print "UID:", nod.findtext("{http://schemas.microsoft.com/project}UID") # print "Name:", nod.findtext("{http://schemas.microsoft.com/project}Name") # print "Start:", nod.findtext("{http://schemas.microsoft.com/project}Start") # print "Finish:", nod.findtext("{http://schemas.microsoft.com/project}Finish") # print "WBS:", nod.findtext("{http://schemas.microsoft.com/project}WBS") lvl = nod.findtext("{http://schemas.microsoft.com/project}OutlineLevel") txt = nod.findtext("{http://schemas.microsoft.com/project}Name") # print "Level/Task:", lvl + " " + txt lvli = int(lvl) if lvli > self.lst_lvl: self.mmn.append("") self.lst_lvl = lvli self.mmn[lvli] = ET.SubElement(self.mmn[lvli-1], "node",text=txt) if self.do_attr: self.mmn[lvli].append(ET.Element("attribute", NAME="tsk-Duration", \ VALUE=nod.findtext("{http://schemas.microsoft.com/project}Duration"))) if self.do_flag: txt = nod.findtext("{http://schemas.microsoft.com/project}PercentComplete") if txt == "100": self.mmn[lvli].append(ET.Element("icon", BUILTIN="button_ok")) tree = ET.ElementTree(self.mm) tree.write(outfile) return def usage(): print __doc__ sys.exit(-1) def main(): try: opts , args = getopt.getopt(sys.argv[1:], "i:o:hac", \ ["help", "input=", "output="]) except getopt.GetoptError, err: # print help information and exit: print err # will print something like "option -x not recognized" usage() input = None output = None attr = False complete = False for o, a in opts: if o == "-a": # wants attributes printed attr = True elif o == "-c": # wants completion flags complete = True elif o in ("-h", "--help"): usage() elif o in ("-i", "--input"): input = a elif o in ("-o", "--output"): output = a else: assert False, "unhandled option" if input == None: print "Input file required" usage() if not input.endswith('.xml'): print "Input file must end with '.xml'" usage() if output == None: output = input[:-3] + "mm" if not output.endswith('.mm'): print "Output file must end with '.mm'" usage() mpp2mm = Mpp2Mm() tree = mpp2mm.open(input) mpp2mm.write(output,attr,complete) print output + " created." if __name__ == "__main__": main()
To MS Project
Method 1
An XSLT stylesheet to transform a FreeMind mindmap into a XML file that can be opened within MS Project as a project.
>>> TESTED ONLY WITH "MS PROJECT 2003 e 2007"! <<<
- Copy and paste this code using an editor such as notepad
- Save the file with the XSLT extension
- In pull-down menu use "File->Export->Using XSLT..." (Do not forget that you must export using the XML extension)
<?xml version="1.0" encoding="iso-8859-1"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" version="1.0" indent="yes" /> <xsl:template match="/"> <Project xmlns="http://schemas.microsoft.com/project"> <Name>Project1</Name> <Author>Freemind2MSProject Conversor</Author> <Tasks> <Task> <UID>0</UID> <ID>0</ID> <Type>1</Type> <IsNull>0</IsNull> <WBS>0</WBS> <OutlineNumber>0</OutlineNumber> <OutlineLevel>0</OutlineLevel> <FixedCostAccrual>3</FixedCostAccrual> <RemainingDuration>PT8H0M0S</RemainingDuration> </Task> <xsl:apply-templates select="map/node" /> </Tasks> </Project> </xsl:template> <xsl:template match="node"> <xsl:variable name="outlineLevel" select="(count(ancestor::node())-1)"/> <Task> <UID>1</UID> <ID>1</ID> <Name><xsl:value-of select="@TEXT"/></Name> <Type>1</Type> <IsNull>0</IsNull> <OutlineNumber>1</OutlineNumber> <OutlineLevel><xsl:value-of select="$outlineLevel"/></OutlineLevel> <FixedCostAccrual>3</FixedCostAccrual> <RemainingDuration>PT8H0M0S</RemainingDuration> </Task> <xsl:apply-templates select="node"/> </xsl:template> </xsl:stylesheet>
Regards,
Mauro Alexandre
PS (by lafs.info): I used the same code Mauro posted to covert .mm file into a MS Project file. I´m using MS Project 2007 in brazilian portuguese. I removed two spaces in all lines, before it the .xsl file didn´t work!
Method 2
From help forum:
PPS (by mlflanagan): Great contribution from Mauro, thanks. I modified the xsl file to also export notes from the .mm file. Changes are in bold:
... <RemainingDuration>PT8H0M0S</RemainingDuration> <xsl:apply-templates select="hook"/> </Task> <xsl:apply-templates select="node"/> </xsl:template> <xsl:template match="hook"> <Notes><xsl:value-of select="text"/></Notes> </xsl:template>
ALSO: to be clear about how to export:
- Copy this code and save it to a file such as mm2project.xsl.
- In Freemind, select File --> Export --> Using XSLT ...
- Browse for the xsl file (mm2project.xsl) in the "choose XSL file" field.
- Browse to your target folder and name the exported file, such as project.xml. Note: The filename MUST have a .xml extension!
- Press the Export button to create the export file.
- Open the file with MS Project (using File --> Open ...).
- Follow the MS Project dialog to open the file.
- "Save as" to the standard .mpp format.
Method 3
From help forum:
- Create the project plan using Freemind features. Use link arrows to create predecedence. Default is for all tasks to start on the project start date
- Add an attribute (Alt-F9) to each low level task to specify the duration. Attribute is tsk-Duration value is either in standard MS (PTnHnMnS) format, allowing specifying hours, minutes and seconds or if you use AnGus' XSLT you can enter (whole) months, days or hours by suffixing the value with m, d or h respectively (eg. 2d for 2 days)
- Export the file as XSLT - File->Export->Using XLST ... You identify the XSLT translator (either the standard "C:\Program Files\Freemind\accessories\mm2msp_utf8.xsl" or "..\mm2msp_utf8_ak.xsl" to use the alternative duration formats. Remember to save the exported file with xml file type
- Open MS Project and import the file - Open->Files of Type->xml. First time import as a new file
- To load durations you actually need to open the file again and Merge it into the existing project (if you specify Start and Finish dates then the durations will be included on first import)
AnGus
mm2msp_utf8_ak.xsl
<?xml version="1.0" encoding="UTF-8"?> <!-- (c) by Naoki Nose, 2006, and Eric Lavarde, 2008 This code is licensed under the GPLv2 or later. (http://www.gnu.org/copyleft/gpl.html) Check 'mm2msp_utf8_TEMPLATE.mm' for detailed instructions on how to use this sheet. This version has been modified by Angus King to allow task durations to be in (whole) months and days (based upon 8 hours a day and 20 days a month) - just suffix the period with d or m (or nothing for hours) --> <xsl:stylesheet version="1.0" xmlns="http://schemas.microsoft.com/project" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" encoding="UTF-8" standalone="yes"/> <xsl:key name="deps" match="arrowlink" use="@DESTINATION"/> <xsl:template match="/"> <Project> <xsl:apply-templates/> </Project> </xsl:template> <xsl:template match="//map"> <Title><xsl:value-of select="node/@TEXT"/></Title> <xsl:apply-templates select="node/attribute"> <xsl:with-param name="prefix" select="'prj'"/> </xsl:apply-templates> <Tasks> <xsl:apply-templates select="node" mode="tasks"/> </Tasks> </xsl:template> <xsl:template match="node" mode="tasks"> <xsl:param name="level" select="0"/> <Task> <UID><xsl:if test="$level > 0"> <xsl:number level="any" count="//map/node//node" format="1"/></xsl:if> <xsl:if test="$level = 0">0</xsl:if> </UID> <xsl:call-template name="output-node-text-as-name"/> <xsl:call-template name="output-note-text-as-notes"/> <OutlineLevel><xsl:value-of select="$level"/></OutlineLevel> <xsl:if test="not(attribute[@NAME = 'tsk-FixedCostAccrual'])"> <FixedCostAccrual>1</FixedCostAccrual> </xsl:if> <xsl:apply-templates select="attribute"> <xsl:with-param name="prefix" select="'tsk'"/> </xsl:apply-templates> <xsl:for-each select="key('deps',@ID)"> <xsl:call-template name="output-arrow-as-predecessor"> <xsl:with-param name="level" select="$level"/> </xsl:call-template> </xsl:for-each> </Task> <xsl:apply-templates mode="tasks"> <xsl:with-param name="level" select="$level + 1"/> </xsl:apply-templates> </xsl:template> <xsl:template name="output-node-text-as-name"> <Name><xsl:choose> <xsl:when test="@TEXT"> <xsl:value-of select="normalize-space(@TEXT)" /> </xsl:when> <xsl:when test="richcontent[@TYPE='NODE']"> <xsl:value-of select="normalize-space(richcontent[@TYPE='NODE']/html/body)" /> </xsl:when> <xsl:otherwise> <xsl:text></xsl:text> </xsl:otherwise> </xsl:choose></Name> </xsl:template> <xsl:template name="output-note-text-as-notes"> <xsl:if test="richcontent[@TYPE='NOTE']"> <Notes><xsl:value-of select="string(richcontent[@TYPE='NOTE']/html/body)" /> </Notes> </xsl:if> </xsl:template> <xsl:template name="output-arrow-as-predecessor"> <xsl:param name="level" select="0"/> <PredecessorLink> <PredecessorUID><xsl:if test="$level > 0"> <xsl:number level="any" count="//map/node//node" format="1"/> </xsl:if> <xsl:if test="$level = 0">0</xsl:if></PredecessorUID> <Type><xsl:choose> <xsl:when test="@ENDARROW = 'Default'"> <xsl:choose> <xsl:when test="@STARTARROW = 'Default'">3</xsl:when> <xsl:otherwise>1</xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> <xsl:choose> <xsl:when test="@STARTARROW = 'Default'">2</xsl:when> <xsl:otherwise>0</xsl:otherwise> </xsl:choose> </xsl:otherwise> </xsl:choose></Type> </PredecessorLink> </xsl:template> <xsl:template match="attribute"> <xsl:param name="prefix" /> <xsl:if test="starts-with(@NAME,concat($prefix,'-'))"> <xsl:element name="{substring-after(@NAME,concat($prefix,'-'))}"> <!-- Cater for duration in months, days, hours - rounded to nearest whole number --> <xsl:choose> <xsl:when test="@NAME = concat($prefix,'-Duration')"> <xsl:choose> <xsl:when test="substring(@VALUE ,1,2) = 'PT'"> <!-- Assume MS format (PTnHnMnS) --> <xsl:value-of select="@VALUE"/> </xsl:when> <xsl:when test="substring(@VALUE ,string-length(@VALUE),1) = 'm'"> <!-- months --> <xsl:value-of select="concat(concat('PT',round(substring(@VALUE,1,string-length(@VALUE)-1)*8*20)),'H0M0S')"/> </xsl:when> <xsl:when test="substring(@VALUE ,string-length(@VALUE),1) = 'd'"> <!-- days --> <xsl:value-of select="concat(concat('PT',round(substring(@VALUE,1,string-length(@VALUE)-1)*8)),'H0M0S')"/> </xsl:when> <xsl:when test="substring(@VALUE ,string-length(@VALUE),1) = 'h'"> <!-- hours --> <xsl:value-of select="concat(concat('PT',round(substring(@VALUE,1,string-length(@VALUE)-1))),'H0M0S')"/> </xsl:when> <xsl:otherwise> <!-- default is hours --> <xsl:value-of select="concat(concat('PT',round(@VALUE)),'H0M0S')"/> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> <xsl:value-of select="@VALUE"/> </xsl:otherwise> </xsl:choose> </xsl:element> </xsl:if> </xsl:template> <!-- required to _not_ output other things than nodes --> <xsl:template match="*" mode="tasks"></xsl:template> </xsl:stylesheet>
SampleProject.mm (map showing how to use above XSLT)
<map version="0.9.0"> <!-- To view this file, download free mind mapping software FreeMind from http://freemind.sourceforge.net --> <node CREATED="1236062058732" ID="ID_1005289263" MODIFIED="1237874353965" STYLE="fork"> <richcontent TYPE="NODE"><html> <head> </head> <body> <p> SampleProject </p> <p> Using XML export feature of Freemind v9 </p> </body> </html></richcontent> <richcontent TYPE="NOTE"><html> <head> </head> <body> <p> This is a simple sample of using Freemind to create a MS-Project project. See "C:\Program Files\Freemind\accessories\mm2msp_utf8_TEMPLATE.mm" for a more expansive sample. Process is: </p> <ol> <li> Create the project plan using Freemind features. Use link arrows to create predecedence. Default is all start on project start date </li> <li> Add an attribute (Alt-F9) to each low level task to specify the duration. Attribute is <u>tsk-Duration</u> value is either in standard MS (<u>PTnHnMnS</u>) format, allowing specifying hours, minutes and seconds or if you use AKs XSLT you can enter (whole) months, days or hours by suffixing the value with m, d or h respectively (eg. <u>2d</u> for 2 days) </li> <li> Export the file as XSLT - File->Export->Using XLST ... You identify the XSLT translator (either the standard "<u>C:\Program Files\Freemind\accessories\mm2msp_utf8.xsl</u>" or "<u>..\mm2msp_utf8_ak.xsl</u>" to use the alternative duration formats. Remember to save the exported file with <u>xml</u> file type<br /> </li> <li> Open MS Project and import the file - Open->Files of Type->xml. First time import as a new file </li> <li> To load durations you actually need to open the file again and Merge it into the existing project (if you specify Start and Finish dates then the durations will be included on first import) </li> <li> See Angus for help </li> </ol> <p> </p> </body> </html> </richcontent> <attribute_layout NAME_WIDTH="113" VALUE_WIDTH="125"/> <attribute NAME="prj-StartDate" VALUE="2009-03-10"/> <attribute NAME="prj-Author" VALUE="Angus King"/> <node CREATED="1236062115811" ID="ID_1928578570" MODIFIED="1237874135571" POSITION="right" TEXT="Sample Task 1"> <richcontent TYPE="NOTE"><html> <head> </head> <body> <p> Doesn't need a duration as this will come from sub tasks. </p> </body> </html></richcontent> <arrowlink DESTINATION="ID_1616088595" ENDARROW="Default" ENDINCLINATION="85;0;" ID="Arrow_ID_1010462294" STARTARROW="None" STARTINCLINATION="85;0;"/> <attribute_layout NAME_WIDTH="76" VALUE_WIDTH="125"/> <node CREATED="1236062115811" ID="ID_1617986385" MODIFIED="1237873897971" TEXT="Sub Task 1.1"> <richcontent TYPE="NOTE"><html> <head> </head> <body> <p> Task is 2 days long </p> </body> </html></richcontent> <arrowlink DESTINATION="ID_775688033" ENDARROW="Default" ENDINCLINATION="71;0;" ID="Arrow_ID_1152852365" STARTARROW="None" STARTINCLINATION="71;0;"/> <attribute_layout NAME_WIDTH="76" VALUE_WIDTH="125"/> <attribute NAME="tsk-Duration" VALUE="2d"/> </node> <node CREATED="1236062115811" ID="ID_775688033" MODIFIED="1237873915113" TEXT="Sub Task 1.2"> <richcontent TYPE="NOTE"><html> <head> </head> <body> <p> Task is 2 months long. Sub Task 1.1 is a Predecessor </p> </body> </html></richcontent> <attribute_layout NAME_WIDTH="76" VALUE_WIDTH="125"/> <attribute NAME="tsk-Duration" VALUE="2m"/> </node> </node> <node CREATED="1236142029373" ID="ID_1616088595" MODIFIED="1236144026607" POSITION="right" TEXT="Sample Task 2"> <node CREATED="1236142043702" ID="ID_1046123070" MODIFIED="1237874027985" TEXT="Sub Task 2.1"> <richcontent TYPE="NOTE"><html> <head> </head> <body> <p> Task is 48 hours, or 6 days long (MS Project format). Sample Task 1 is a Predecessor </p> </body> </html></richcontent> <attribute NAME="tsk-Duration" VALUE="PT48H0M0S"/> </node> </node> </node> </map>
OpenOffice Writer
OpenOffice Writer to FreeMind:
Sometimes it's useful to be able to create a FreeMind mind map from an OpenOffice Writer document. The OpenOffice macro below does precisely this. It will extract all paragraphs of format "Heading 1" to "Heading 5" and create a .mm document that can be opened by FreeMind. The only constraint is that the Writer document must be correctly structured, with all heading levels correctly nested i.e. you can't go from "Heading 1" directly to "Heading 3". I hope you find this macro useful!
Sub headingsToMindMap newline = CHR$( 10 ) headings = "" Dim levels(10) levels(0) = "</node>" & newline levels(1) = "</node></node>" & newline levels(2) = "</node></node></node>" & newline levels(3) = "</node></node></node></node>" & newline levels(4) = "</node></node></node></node></node>" & newline levels(5) = "</node></node></node></node></node></node>" & newline oldLevel = 1 level = 1 outURL = ThisComponent.getURL() & ".mm" n = FreeFile() open outURL for output access write as #n enum = ThisComponent.Text.CreateEnumeration() headings = "<map version=""0.8.0"">" & newline Do While enum.hasMoreElements() par = enum.nextElement() if par.supportsService("com.sun.star.text.Paragraph") Then style = par.ParaStyleName if StrComp("Heading 1", style) = 0 Then headings = headings & " <node TEXT=""" & par.getString() & """>" & newline level = 1 End If if StrComp("Heading 2", style) = 0 Then level = 2 if (level <= oldLevel) Then headings = headings & levels( oldLevel - level) End If headings = headings & " <node POSITION=""right"" TEXT=""" & par.getString() & """>" End If if StrComp("Heading 3", style) = 0 Then level = 3 if (level <= oldLevel) Then headings = headings & levels( oldLevel - level) End If headings = headings & " <node POSITION=""right"" TEXT=""" & par.getString() & """>" & newline End If if StrComp("Heading 4", style) = 0 Then level = 4 if (level <= oldLevel) Then headings = headings & levels( oldLevel - level) End If headings = headings & " <node POSITION=""right"" TEXT=""" & par.getString() & """>" & newline End If if StrComp("Heading 5", style) = 0 Then level = 5 if (level <= oldLevel) Then headings = headings & levels( oldLevel - level) End If headings = headings & " <node POSITION=""right"" TEXT=""" & par.getString() & """>" & newline5 End If oldLevel = level End If Loop headings = headings & levels( level - 1) headings = headings & " " & newline & "</map>" MsgBox CStr( headings ) print #n headings close #n End Sub
--Jimarlow 14:12, 19 May 2009 (UTC)
3D Topicscape
Conversion from 3D Topicscape to FreeMind and vice versa:
3D Topicscape Pro and the Student Edition (SE is free as in beer) have built-in conversion to and from FreeMind (0.9.0).
If you make extensive use of FreeMind attributes for your own purposes, Topicscape won't know about them, and they will not be carried back again, but for a straightforward mindmap it seems to maintain integrity both ways. Topicscape can express structures that FreeMind can't (like multiple parents for one child and loose associations). The conversion translates these into color-coded curved lines with a single arrowhead and re-interprets this back to the multi-parent type of relationship on re-import.
To 3D Topicscape
FreeMind to 3D Topicscape conversion:
This allows a 3D mindmap to be built from a 2D FreeMind mindmap.
- File menu->Import
- Radio button: Other products and select FreeMind (.mm) from the drop down
- Radio button: Choose whether you want a new Topicscape to be built, or a floating topic in the currently-open Topicscape
- Give the full file path to the FreeMind file, including the file's name - explicitly or by browsing to it.
- Press OK
- If you selected the new Topicscape radio button, you will then see the dialog that lets you choose the new Topicscape's name and where it is to be placed. Make the selections you want and press OK. After a pause, you will either see the new Topicscape as a 3D landscape, or perhaps a report about files in the FreeMind map that cannot be found at their expected locations. The report panel provides options for dealing with this and once handled, you're done. The hierarchy defined in the FreeMind mindmap will now be represented in 3D.
- If you selected the floating topic radio button, you will next see the "Create New Topic" panel. Please name the topic. Use Hint if you wish to see if there is a similarly-named topic present in the Topicscape. Press Add. Drag the small red cone to its new parent, and drop it there. You're done. The 3D structure defined in the FreeMind mindmap will now be represented in 3D.
NOTE: The above process will not be able to handle any user-defined attributes on the nodes.
From 3D Topicscape
3D Topicscape to FreeMind conversion:
This allows a FreeMind (0.9.0) mindmap to be built from a 3D Topicscape.
- File menu->Export
- Radio button: XML and select FreeMind (.mm) from the drop down (currently it's the only one).
- Check boxes: Select which components to export. Topics at least must be exported (a topic will become a node). Occurrences will become attachments. Descriptions and Association details will become added attributes.
- Give the full file path to where the FreeMind file is to be placed, including the file's name - explicitly or by browsing to it. The Topicscape's name is used as a default.
- Press OK. A panel shows progress and completion will be announced.
- If you used the color scheme in Topicscape that allows each topic to be assigned a color automatically, the colors will be transferred (approximately) to the FreeMind map.
NOTE: The above process makes specific Topicscape attributes on the FreeMind nodes. To preserve the original Topicscape's integrity if you contemplate re-importing the mindmap to Topicscape, you need to avoid changing these atributes. The export may make double-headed gray lines and single-headed red lines. These are used to record multi-parent topics and loose associations. If you change them, then on any re-import to Topicscape, the structure will reflect those changes.
Round-trip
3D Topicscape to FreeMind and back again; a round-trip:
You can import to Topicscape and re-export to FreeMind - back and forth round trips are supported, provided you take into account the information in the NOTE paragraphs above. The Topicscape on-line manual has an entry about these conversions here: - http://www.topicscape.com/Topicscape-Pro/usersguide/help.php?page=132
Rearrange folder structure
The following describes a method and a script for copying directory and files structures in Windows with a structure defined as a FreeMind mind map. It uses copying and pasting from FreeMind to MS Word then a script of Visual Basic Script.
1. Import the existing directory/directories structure with freemind (File > Import > Folder Structure). Each final node has a link (Control + k) to the real file. It is preferable to set the preferences links path to absolute (Preferences > Appearence > Links = absolute)
2. Rearrange the file structure. The node description represents the name of the file and can be modified in order to rename the file or directory. The file then will be copied under the new name. It is important not to update the link of nodes as the are the only information in freemind about the real file location. To delete a file or directory, just delete it from the map and it will not be copied to the new file system.
3. Copy the branch or mind map to MS Word. I obtain a outlined and tabulated text like:
- My Music <file:/C:/Documents and Settings/xxx/My Documents/My Temp/Music/>
- give it to me
- give it to me.mp3 <file:/C:/Documents and Settings/xxx/My Documents/My Temp/Music/give it to me.mp3>
- give it to me
4. Add the following macro to the Word document
Sub freemind_exportFolder() ' ' exportFolder Macro ' Macro recorded 11/24/2004 by fbanag ' Dim current_depth As Long Dim previous_depth As Long Dim diff_depth As Long ' Define the Root directory ChDir ActiveDocument.Path Selection.GoTo what:=wdGoToLine, which:=wdGoToFirst ' start from beginning unit_indent = 17.5 'to be updated for the .dot used previous_depth = -100 Do Selection.EndOf unit:=wdParagraph, Extend:=wdExtend ' Depth extraction, use the outline level current_indent = Selection.Paragraphs(1).LeftIndent current_depth = current_indent / unit_indent current_outline = Selection.Paragraphs(1).OutlineLevel ' Update the unit_indent when outline is < 8 If current_outline < 8 And current_outline > 1 Then unit_indent = current_indent / (current_outline - 1) End If ' Calculate the change in depth diff_depth = current_depth - previous_depth ' Update the directory level If diff_depth = 1 Then ChDir node_name Else Do While diff_depth < 0 ChDir "./.." diff_depth = diff_depth + 1 Loop End If previous_depth = current_depth 'remove the last character of the selection Selection.MoveRight unit:=wdCharacter, Count:=-1, Extend:=wdExtend ' define if is directory or file directory_node = 0 If Selection.Text Like "*<file:*" Then 'include the path 'check if directory If Selection.Text Like "*/>" Then directory_node = 1 End If ' extract the node name Selection.MoveEndUntil Cset:="<", Count:=wdBackward Selection.MoveRight unit:=wdCharacter, Count:=-2, Extend:=wdExtend Else directory_node = 1 End If node_name = Selection.Text ' check now if the selection is a file If directory_node = 0 Then ' selectionne the path Selection.EndOf unit:=wdParagraph, Extend:=wdExtend With Selection.Find .Text = "<file:/" .Replacement.Text = "" .Forward = True .Wrap = wdFindAsk .Format = False .MatchCase = False .MatchWholeWord = False .MatchWildcards = False .MatchSoundsLike = False .MatchAllWordForms = False End With Selection.Find.Execute Selection.Collapse Direction:=wdCollapseEnd Selection.MoveEndUntil Cset:=">", Count:=wdForward filepath = Selection.Text ' using the name written in the freeemind 'FileCopy FileCopy filepath, node_name Else ' if not, then it is a directory asc_code = Asc(node_name) ' Check no empty name If node_name Like "o" Or node_name Like "" Then node_name = "NewFolder" End If ' create a directory ' doesn't handle the duplicate folder names at the same level and the end of file ' I will have to add that (a day) If Asc(node_name) <> 13 Then MkDir node_name End If End If Loop While Selection.MoveDown(unit:=wdParagraph, Count:=1) End Sub
5. Place the word file in the new root directory where You want files to be copied (don't forget to save the word document)
6. Run the macro
Known issues:
- the script stops with an error message if there is special characters in the file name or path
- the script stops if exists two files with the same name under the same directory
This method and script has plenty of room for improvement, but it has been good enough for my task of reorganizing hundred of files (result of years of filling up several hard drives). It is a task I would not even have started without FreeMind.
Thank You to the Freemind team.
ECCO
FreeMind to ECCO:
If a branch is copied and pasted directly in ECCO PRO, a well appreciated and freely available PIM (see Wikipedia: Ecco Pro).
The mind map structure is gracefully transformed in an outline and can be printed in a professional way.
IIS
FreeMind to IIS:
By: gobinathoss
Hi,
i need help to view the freemind file through IIS website
i am getting the following error: This URL is malformed! no protocol: myfreemind.mm
myfreemind.mm is my file name located in the IIS server
...
I got the solution
1 ) copy freemindbrowser.html, freemindbrowser.jar and <yourmap>.mm to some
folder
2 ) go to IIS, right-click on your web site and choose properties. Go to HTTP Headers tab and click on MIME Types. Add the following MIME type :
extension : mm MIME type : application/freemind
Thanks S.Gobinath