#@+leo
#@+node:0::@file plugins/mod_rst.py
#@+body
"""Double clicking the icon box launches an file with the name of the headline."""

# By Josef Dalcolmo: contributed under the same licensed as Leo.py itself.

# EKR: The code now lets other plugins handle @folder and @url nodes.

from leoPlugins import *
from leoGlobals import *


#@<< about this plugin >>
#@+node:1::<<about this plugin >>
#@+body
#@+at
#  This plugin writes out @rst nodes as a reStructuredText file.
# 
# If the filename ends in .html or .htm and if you have docutils_ (a Python
# module) installed, then it will be written as HTML. The HTML converter is far
# from bug-free, but remember, docutils is alpha software. (Perhaps a future
# version will allow automatic translation to other formats, like OpenOffice.org
# as well).
# 
# Headlines are translated into reStructuredText headlines, e.g. underlined
# depending on the level and empty line separated from body text otherwise, text
# is written as it is. The "#" character is not used for underlining, so it may
# be used for a title as in::
# 
# 	#####
# 	Title
# 	#####
# 
# Otherwise, section underlining is discouraged, since it is automatically generated.
# 
# .. _docutils: http://docutils.sourceforge.net
#@-at
#@-body
#@-node:1::<<about this plugin >>


#@<< change log >>
#@+node:2::<< change log >>
#@+body
#@+at
#  New stuff in this version:
# 
# - New tree types: @rst has been added.
# 
# - EKR: The code now lets other plugins handle @folder and @url nodes.
# 
# - HTML generation: @rst nodes can now generate HTML, if Python docutils_ are
# installed. Simply give the filename an extension .htm or .html. You can try
# this out by renaming the filename in this @rst tree.
# 
# - underlines: I changed the order of the underline characters again. The ">" is
# doesn't really look good as an underline in my opinion, so I moved it to a very
# low level.
#@-at
#@-body
#@-node:2::<< change log >>



#@+others
#@+node:3::onIconDoubleClick
#@+body
# @folder behavior after an idea and sample code by:
# korakot ( Korakot Chaovavanich ) @folder for files annotation 2002-11-27 02:39
# 
# open file (double-click = startfile) behavior added 
# nodes with @url, @folder, @rst are treated special
#
# by Josef Dalcolmo 2003-01-13
#
# this does not check for proper filename syntax.
# path is the current dir, or the place @folder points to
# this should probably be changed to @path or so.

def onIconDoubleClick(tag,keywords):

	import os
	v = keywords.get("v")
	h = v.headString().strip()
	if match_word(h,0,"@url") or match_word(h,0,"@folder"):
		return # Let other plugins handle these
	elif match_word(h,0,"@rst"):
		fname = h[5:]
		ext = os.path.splitext(fname)[1].lower()
		if ext in ('.htm','.html'):
			
			#@<< write rST as HTML >>
			#@+node:1::<< write rST as HTML >>
			#@+body
			try:
				import docutils
				import StringIO
				rstFile = StringIO.StringIO()
				writeTreeAsRst(rstFile, fname, v)
				rstText = rstFile.getvalue()
				
				#@<< convert rST to HTML >>
				#@+node:1::<< convert rST to HTML >>
				#@+body
				# this code snipped has been taken from code contributed by Paul Paterson 2002-12-05
				from docutils.core import Publisher
				from docutils.io import StringOutput, StringInput
				
				pub = Publisher()
				# Initialize the publisher
				pub.source = StringInput(pub.settings, source=rstText)
				pub.destination = StringOutput(pub.settings, encoding="utf-8")
				pub.set_reader('standalone', None, 'restructuredtext')
				pub.set_writer('html')
				output = pub.publish()
				#@-body
				#@-node:1::<< convert rST to HTML >>

				htmlFile = file(fname,'w')
				htmlFile.write(output)
				htmlFile.close()
				rstFile.close()
				es('written: '+`fname`)
			except:
				es('HTML generation requires docutils')
			#@-body
			#@-node:1::<< write rST as HTML >>

		else:
			
			#@<< write rST file >>
			#@+node:2::<< write rST file >>
			#@+body
			rstFile = file(fname,'w')
			writeTreeAsRst(rstFile, fname, v)
			rstFile.close()
			es('written: '+`fname`)
			#@-body
			#@-node:2::<< write rST file >>

	else:
		# open file with associated application
		
		#@<< find path and start file >>
		#@+node:3::<< find path and start file >>
		#@+body
		# Set the base directory by searching for @folder directives in ancestors.
		try:
			basedir = os.curdir	# use current dir as default.
			parv = v.parent()	# start with parent
			while parv:	# stop when no more parent found
				p = parv.headString().strip()
				if match_word(p,0,'@folder'):
					basedir = p[8:]	# take rest of headline as pathname
					break	# we found the closest @folder
				else:
					parv = parv.parent()	# try the parent of the parent
			fname = os.path.join(basedir,h) # join path and filename
			os.startfile(fname)	# Try to open the file; it may not work for all file types.
		except:
			es(os.path.join(os.getcwd(),fname)+' - file or application not found')
			es_exception()
		
		#@-body
		#@-node:3::<< find path and start file >>
#@-body
#@-node:3::onIconDoubleClick
#@+node:4::writeTreeAsRst
#@+body
def writeTreeAsRst(rstFile, fname, vnode):
	'Writes the tree under vnode to the file rstFile (fname is the filename)'
	# we don't write a title, so the titlepage can be customized
	# use '#' for title under/overline
	rstFile.write('.. filename: '+fname+'\n')
	rstFile.write('\n')
	rstFile.write(vnode.bodyString()+'\n')		# write body of titlepage
	rstFile.write('\n')
	
	toplevel = vnode.level()
	stopHere = vnode.nodeAfterTree()
	v = vnode.threadNext()
	# repeat for all nodes in this tree
	while v != stopHere:
		h = v.headString()
		rstFile.write(h+'\n')
		rstFile.write(underline(h,v.level()-toplevel))
		rstFile.write('\n')
		rstFile.write(v.bodyString()+'\n')
		rstFile.write('\n')
		v = v.threadNext()

#@-body
#@-node:4::writeTreeAsRst
#@+node:5::underline
#@+body
# note the first character is intentionally unused, to serve as the underline
# character in a title (in the body of the @rst node)
def underline(h,level):
	str = """#=+*^~"'`-:><_"""[level]
	return str*max(len(h),4)+'\n'
#@-body
#@-node:5::underline
#@-others


if 1: # Register the handlers...
	registerHandler("icondclick1",onIconDoubleClick)
	
	import mod_rst
	es("...@rst v1.1: " + plugin_date(mod_rst))

#@-body
#@-node:0::@file plugins/mod_rst.py
#@-leo
