Created
March 3, 2012 10:35
-
-
Save gmt4/1965448 to your computer and use it in GitHub Desktop.
vimoutliner/scripts: outline_freemind utf-8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/vimoutliner/scripts/outline_freemind/freemind.py b/vimoutliner/scripts/outline_freemind/freemind.py | |
new file mode 100755 | |
index 0000000..d00d7fd | |
--- /dev/null | |
+++ b/vimoutliner/scripts/outline_freemind/freemind.py | |
@@ -0,0 +1,191 @@ | |
+#!/usr/bin/python | |
+ | |
+''' | |
+usage: | |
+ freemind.py -o [fmt] <files>, where ofmt selects output format: {otl,mm} | |
+ | |
+freemind.py -o otl <files>: | |
+ Read in an freemind XML .mm file and generate a outline file compatable with vim-outliner. | |
+freemind.py -o mm <files>: | |
+ Read in an otl file and generate an XML mind map viewable in freemind | |
+ | |
+NOTE: | |
+ Make sure that you check that round trip on your file works. | |
+ | |
+Author: Julian Ryde | |
+''' | |
+import os | |
+import re | |
+import sys | |
+import getopt | |
+import codecs | |
+import commands | |
+ | |
+import otl | |
+import textwrap | |
+import xml.etree.ElementTree as et | |
+from xml.etree.ElementTree import XMLParser | |
+ | |
+debug = False | |
+ | |
+class Outline: # The target object of the parser | |
+ depth = -1 | |
+ indent = '\t' | |
+ current_tag = None | |
+ def start(self, tag, attrib): # Called for each opening tag. | |
+ self.depth += 1 | |
+ self.current_tag = tag | |
+ # print the indented heading | |
+ if tag == 'node' and self.depth > 1: | |
+ #if 'tab' in attrib['TEXT']: | |
+ #import pdb; pdb.set_trace() | |
+ print (self.depth-2)*self.indent + attrib['TEXT'] | |
+ def end(self, tag): # Called for each closing tag. | |
+ self.depth -= 1 | |
+ self.current_tag = None | |
+ def data(self, data): | |
+ if self.current_tag == 'p': | |
+ bodyline = data.rstrip('\r\n') | |
+ bodyindent = (self.depth-5)*self.indent + ": " | |
+ #textlines = textwrap.wrap(bodytext, width=77-len(bodyindent), break_on_hyphens=False) | |
+ #for line in textlines: | |
+ print bodyindent + bodyline | |
+ | |
+ def close(self): # Called when all data has been parsed. | |
+ pass | |
+ | |
+def mm2otl(*arg, **kwarg): | |
+ fname = arg[0][0] | |
+ file = codecs.open(fname, 'r', encoding='utf-8') | |
+ | |
+ filelines = file.readlines(); | |
+ outline = Outline() | |
+ parser = XMLParser(target=outline, encoding='utf-8') | |
+ parser.feed(filelines[0].encode('utf-8')) | |
+ parser.close() | |
+ | |
+ | |
+# TODO body text with manual breaks | |
+# TODO commandline arguments for depth, maxlength etc. | |
+# TODO do not read whole file into memory? | |
+# TODO handle decreasing indent by more than one tab | |
+# TODO handle body text lines sometimes not ending with space | |
+ | |
+depth = 99 | |
+ | |
+def attach_note(node, textlines): | |
+ et.ElementTree | |
+ # Format should look like | |
+ #<richcontent TYPE="NOTE"> | |
+ #<html> | |
+ # <head> </head> | |
+ # <body> | |
+ # %s | |
+ # </body> | |
+ #</html> | |
+ #</richcontent> | |
+ notenode = et.SubElement(node, 'richcontent') | |
+ notenode.set('TYPE', 'NOTE') | |
+ htmlnode = et.SubElement(notenode, 'html') | |
+ headnode = et.SubElement(htmlnode, 'head') | |
+ bodynode = et.SubElement(htmlnode, 'body') | |
+ for line in textlines: | |
+ pnode = et.SubElement(bodynode, 'p') | |
+ pnode.text = line | |
+ | |
+def otl2mm(*arg, **kwarg): | |
+ fname = arg[0][0] | |
+ otlfile = open(fname) | |
+ indent = ' ' | |
+ | |
+ # node ID should be based on the line number of line in the otl file for easier | |
+ # debugging | |
+ #for lineno, line in enumerate(open(fname)): | |
+ # enumerate starts at 0 I want to start at 1 | |
+ lineno = 0 | |
+ | |
+ mapnode = et.Element('map') | |
+ mapnode.set('version', '0.9.0') | |
+ | |
+ topnode = et.SubElement(mapnode, 'node') | |
+ topnode.set('TEXT', fname) | |
+ | |
+ parents = [mapnode, topnode] | |
+ | |
+ #left_side = True # POSITION="right" | |
+ | |
+ # read otl file into memory | |
+ filelines = codecs.open(fname, 'r', encoding='utf-8') | |
+ | |
+ # first handle the body texts turn it into a list of headings with associated | |
+ # body text for each one this is because the body text especially multi-line is | |
+ # what makes it awkward. | |
+ headings = [] | |
+ bodytexts = [] | |
+ for line in filelines: | |
+ if otl.is_heading(line): | |
+ headings.append(line) | |
+ bodytexts.append([]) | |
+ else: | |
+ # TODO this ': ' removal should go in otl.py? | |
+ bodytexts[-1].append(line.lstrip()[2:] + '\n') | |
+ | |
+ #import pdb; pdb.set_trace() | |
+ oldheading = '' | |
+ for heading, bodytext in zip(headings, bodytexts): | |
+ if debug: print heading, bodytext | |
+ | |
+ level = otl.level(heading) | |
+ oldlevel = otl.level(oldheading) | |
+ | |
+ if level == oldlevel: | |
+ pass | |
+ elif level > oldlevel: | |
+ # about to go down in the hierarchy so add this line as a parent to the | |
+ # stack | |
+ parents.append(node) | |
+ elif level < oldlevel: | |
+ # about to go up in the hierarchy so remove parents from the stack | |
+ leveldiff = oldlevel - level | |
+ parents = parents[:-leveldiff] | |
+ | |
+ node = et.SubElement(parents[-1], 'node') | |
+ node.set('TEXT', heading.lstrip().rstrip('\r\n')) | |
+ #if len(bodytext) > 0: | |
+ attach_note(node, bodytext) | |
+ | |
+ oldheading = heading | |
+ | |
+ xmltree = et.ElementTree(mapnode) | |
+ xmltree.write(sys.stdout, 'utf-8') | |
+ | |
+def usage(): | |
+ print "usage: %s -[mo] <files>" % (sys.argv[0]) | |
+ | |
+def main(): | |
+ args = sys.argv | |
+ try: | |
+ opts, args = getopt.getopt(sys.argv[1:], 'moh', [""]) | |
+ except getopt.GetoptError, err: | |
+ usage() | |
+ print str(err) | |
+ sys.exit(2) | |
+ | |
+ for o, a in opts: | |
+ if o == "-m": | |
+ otl2mm(args); | |
+ elif o == "-o": | |
+ mm2otl(args); | |
+ elif o == "-h": | |
+ usage() | |
+ sys.exit(0) | |
+ else: | |
+ usage() | |
+ assert False, "unhandled option: %s" % o | |
+ return args | |
+ | |
+if __name__ == "__main__": | |
+ main() | |
+ | |
+# vim: set noet : | |
diff --git a/vimoutliner/scripts/outline_freemind/freemind_outline.py b/vimoutliner/scripts/outline_freemind/freemind_outline.py | |
old mode 100644 | |
new mode 100755 | |
index 22782a9..2df8fa8 | |
--- a/vimoutliner/scripts/outline_freemind/freemind_outline.py | |
+++ b/vimoutliner/scripts/outline_freemind/freemind_outline.py | |
@@ -1,3 +1,4 @@ | |
+#!/usr/bin/python | |
'''Converts a freemind xml .mm file to an outline file compatable with vim | |
outliner. | |
@@ -8,6 +9,7 @@ Author: Julian Ryde | |
import sys | |
from xml.etree.ElementTree import XMLParser | |
import textwrap | |
+import codecs | |
class Outline: # The target object of the parser | |
depth = -1 | |
@@ -36,9 +38,11 @@ class Outline: # The target object of the parser | |
pass | |
outline = Outline() | |
-parser = XMLParser(target=outline) | |
+parser = XMLParser(target=outline, encoding='utf-8') | |
fname = sys.argv[1] | |
-filelines = open(fname).readlines() | |
-parser.feed(''.join(filelines)) | |
+file = codecs.open(fname, 'r', encoding='utf-8') | |
+filelines = file.readlines(); | |
+print "filelines", type(filelines[0]), filelines[0] | |
+parser.feed(filelines[0].encode('utf-8')) | |
parser.close() | |
diff --git a/vimoutliner/scripts/outline_freemind/otl.py b/vimoutliner/scripts/outline_freemind/otl.py | |
old mode 100644 | |
new mode 100755 | |
diff --git a/vimoutliner/scripts/outline_freemind/otl.pyc b/vimoutliner/scripts/outline_freemind/otl.pyc | |
index ee18939..38fdc61 100644 | |
Binary files a/vimoutliner/scripts/outline_freemind/otl.pyc and b/vimoutliner/scripts/outline_freemind/otl.pyc differ | |
diff --git a/vimoutliner/scripts/outline_freemind/outline_freemind.py b/vimoutliner/scripts/outline_freemind/outline_freemind.py | |
old mode 100644 | |
new mode 100755 | |
index 9cc4fc9..accbb1e | |
--- a/vimoutliner/scripts/outline_freemind/outline_freemind.py | |
+++ b/vimoutliner/scripts/outline_freemind/outline_freemind.py | |
@@ -1,3 +1,4 @@ | |
+#!/usr/bin/python | |
'''Read in an otl file and generate an xml mind map viewable in freemind | |
Make sure that you check that round trip on your file works. | |
@@ -9,6 +10,7 @@ import sys | |
import os | |
import xml.etree.ElementTree as et | |
import otl | |
+import codecs | |
fname = sys.argv[1] | |
max_length = 40 | |
@@ -62,7 +64,7 @@ parents = [mapnode, topnode] | |
#left_side = True # POSITION="right" | |
# read otl file into memory | |
-filelines = open(fname).readlines() | |
+filelines = codecs.open(fname, 'r', encoding='utf-8') | |
# remove those that are too deep or body text and pesky end of line characters | |
#filelines = [line.rstrip('\r\n') for line in filelines if otl.level(line) <= depth] | |
@@ -109,5 +111,4 @@ for heading, bodytext in zip(headings, bodytexts): | |
xmltree = et.ElementTree(mapnode) | |
xmltree.write(sys.stdout, 'utf-8') | |
-#xmltree.write('test.mm') | |
diff --git a/vimoutliner/scripts/outline_freemind/test.sh b/vimoutliner/scripts/outline_freemind/test.sh | |
index 812f7e4..15607a1 100755 | |
--- a/vimoutliner/scripts/outline_freemind/test.sh | |
+++ b/vimoutliner/scripts/outline_freemind/test.sh | |
@@ -1,6 +1,10 @@ | |
-outputdir=/tmp | |
-#fname=$1 | |
-fname=test.otl | |
-python outline_freemind.py $fname > $outputdir/test.mm | |
-python freemind_outline.py $outputdir/test.mm > $outputdir/return.otl | |
-diff $fname $outputdir/return.otl | |
+#!/bin/sh | |
+ | |
+tmp=/tmp | |
+dirname=`dirname $0` | |
+fname=$dirname/test.otl | |
+[ -n "$1" ] && fname=$1 | |
+ | |
+$dirname/freemind.py -m $fname > $tmp/test.mm | |
+$dirname/freemind.py -o $tmp/test.mm > $tmp/return.otl | |
+diff -Nur $fname $tmp/return.otl |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment