Skip to content

Text2mindmap custom tool

jaap-karssenberg edited this page Oct 25, 2013 · 2 revisions
====== Example ======
Content of a saved ZIM page:
	Seasons
		Spring
			March
			__April__
				2
				11
				9
			May
		__Summer__
			June
			July
			August
		**Autumn**
			September
			October
			November
				z
				x
				y
		Winter
		aaa
			//December//
			January
			February
		a
		b
		__c__
		__d__
		e	

Output of this custom tool script:

Script file:

#!/usr/bin/python
 
## This custom tool helps to create mindmap like diagrams
 
# the main core algorithm comes from http://blog.ynema.com/?p=192
# adapted to suit the ZIM structure and some additional improvement of nodes (like a formating feature)
# write page with content corresponding to the webpage http://www.text2mindmap.com/

# it automatically creates a png file in the same folder as a source text (page) => has to be inserted to the page manually
# the source text (page) corresponds to a page title (it allows few mindmaps per page)

## examples of file generation (source mindmap.txt)
# single mindmap generates two files: mindmap.dot and mindmap.png
# multiple mindmaps generate multiple files: mindmap_rootnode1.dot, mindmap_rootnode1.png, mindmap_rootnode2.dot, mindmap_rootnode2.png

## U S A G E
# write indented text in the page (use a TAB key)
# save the page (ctrl+s) and reload the page (ctrl+r) => check wether there are no empty lines in the mindmaps => if so, use delete instead of backspace (this is important, else it generates two mindmaps)
# the script distincts formating of keyards according to formatting types (bold, italic and underline)
# activate the command tool (this script) with attached parameter of a absolute path to the page (%s)

import pydot
import sys
import os

# Configuration variables
ranksep = '2 equally' # distance between nodes (suggested values: 1-3) => (graphviz varialbe)
overlap='true' # whether the nodes overlap each other (true or false) => (graphviz varialbe)
splines='true' # whether the lines are straight or curved (true or false) => (graphviz varialbe)
gen_dot = False # whether the dot file should be generated => (python varialbe)

# the list can be managed by a manually defined array of colors
# http://www.graphviz.org/doc/info/colors.html
def GenerateColors():
	colors_nodes = InitArrayOfcolors('black', ['grey', '#fdd49e', '#fc8d59', '#d7301f', '#b00300', '#700f00'])
	colors_font = InitArrayOfcolors('white', ['black', 'black', 'black'])
	return (colors_nodes, colors_font)

def getAttributes(node, level):
	# provides access to colors
	colors_nodes, colors_font = GenerateColors()
	# investigates edge
	# root node
	if level is 0:
		return {'shape':'box, filled',
		'fillcolor':'gray',
		'style':'"filled"',
		'penwidth':'3',
		'color':colors_nodes[level + 1],
		'fontcolor':'black',
		'fontsize':'32'}
	# default edge
	if type(node) is tuple:
		return {
		'penwidth':'2',
		'color':colors_nodes[level + 1]}
	# investigates node
	# remove whitespaces
	node = node.strip()
	# __underlined__
	if node.startswith("__") and node.endswith("__"):
		return {'shape':'box',
		'style':'"rounded,filled"',
		'penwidth':'2',
		'label':node[2:-2],
		'fillcolor':'yellow',
		'color':colors_nodes[level],
		'fontcolor':'black'}
	# **bold**
	if node.startswith("**") and node.endswith("**"):
		return {'shape':'box',
		'style':'"rounded, filled"',
		'penwidth':'2',
		'label':node[2:-2],
		'color':'black',
		'fillcolor':'red',
		'fontcolor':'black',
		'fontsize':'15'}
	# //italic//
	if node.startswith("//") and node.endswith("//"):
		return {'shape':'box',
		'style':'"rounded, filled"',
		'penwidth':'2',
		'label':node[2:-2],
		'color':'black',
		'fillcolor':'green',
		'fontcolor':'black', }
	# standard node
	else:
		return {'shape':'box',
		'style':'filled',
		'penwidth':'2',
		'fillcolor':colors_nodes[level],
		'color':colors_nodes[level + 1],
		'fontcolor':colors_font[level]}

def InitArrayOfcolors(default, colors):
	# generates an array of 12 colors
	colors_nodes = [default for x in range(12)]
	return colors + colors_nodes[len(colors):]

def ReadFile(filename):
	fh = open(filename)
	return [x.rstrip() for x in fh.readlines()]

def CreateEdges(lines):
	edge_list = ['' for x in range(50)]
	mindmaps = []
	edges = []
	for line in lines:
		if (line is "" and len(edges) > 0):
			print "mindmap name: %s" % edges[0][0]
			mindmaps.append(edges)
			edges = []
			continue
		# identify right indent (tabs excluding tabs in the text)
		tabs_all = line.count('\t')
		line = line.strip()
		pos = tabs_all - line.count('\t')
		# removes comments (tabbed text)
		index = line.find("\t")
		if index is not -1: line = line[:index]
		# assign extracted text from a line
		edge_list[pos] = line
		if pos:
			edges.append((edge_list[pos - 1], edge_list[pos], pos - 1))
	if (len(edges) > 0):
		print "mindmap name: %s" % edges[0][0]
		mindmaps.append(edges)
	return mindmaps

def CreateGraphFromEdges(mindmaps, path):
	for edges in mindmaps:
		# defines graph (according to configuration variables)
		g = pydot.Dot(splines=splines, overlap=overlap, ranksep=ranksep, root="%s" % edges[0][0])
		# iterates through edges
		for edge in edges:
			g.add_node(pydot.Node(edge[0], **getAttributes(edge[0], edge[2])))
			g.add_node(pydot.Node(edge[1], **getAttributes(edge[1], edge[2] + 1)))
			g.add_edge(pydot.Edge(edge[0], edge[1], **getAttributes((edge[0], edge[0]), edge[2])))
		# in a case that there is only one mindmap on a page there is no reason for extension of a mm_title to a mm_title_rootnode
		if len(mindmaps) == 1:
			output = "%s" % (path)
		else:
			# extending a file name in a case of multiple mindmaps per file
			output = "%s_%s" % (path, edges[0][0])
		# creates dot file according to prog parameter
		if gen_dot:
			g.write('%s.dot' % str(output), prog='twopi')
		# creates image file according to prog parameter
		g.write_png('%s.png' % str(output), prog='twopi')

def main(argv):
	# extract path to an attachment directory (remove *.txt extension)
	path = argv[1][:-4]
	# extract page name from a path
	page = str(path.split("/")[-1:][0])
	# construct output directory (deprecated)
	path = "%s" % (path)
	CreateGraphFromEdges(CreateEdges(ReadFile(argv[1])), path)

if __name__ == "__main__":
	main(sys.argv)
Clone this wiki locally