#@+leo-ver=4
#@+node:@file color_markup.py
"""Handle coloring for markup in doc parts and Python triple-double-quoted strings"""

from leoPlugins import *
from leoGlobals import *
import string  # zfill does not exist in Python 2.2.1

try:    import Tkinter
except: Tkinter = None

#@+others
#@+node:initAnyMarkup
def initAnyMarkup (tag,keywords):
	
	"""initialize colorer.markup_string
	
	The colorer completely recolors the body pane when this changes"""
	
	keys = ("colorer","v")
	colorer,v = [keywords.get(key) for key in keys]

	c = colorer.commands
	if not c or not v or not top(): return

	# trace()
	dict = scanDirectives(c,v=v) # v arg is essential.
	pluginsList = dict.get("pluginsList")
	
	if pluginsList:
		for d,v,s,k in pluginsList:
			if d == "markup":
				kind = s[k:]
				if kind:
					colorer.markup_string = kind
					return
					
	colorer.markup_string = "unknown" # default
#@nonl
#@-node:initAnyMarkup
#@+node:colorWikiMarkup
colorCount = 0

def colorWikiMarkup (tag,keywords):

	keys = ("colorer","v","s","i","j","colortag")
	colorer,v,s,i,j,colortag = [keywords.get(key) for key in keys]

	global colorCount ; colorCount += 1
	
	c = colorer.commands
	dict = scanDirectives(c,v=v) # v arg is essential.
	pluginsList = dict.get("pluginsList")
	
	if pluginsList:
		for d,v,s2,k in pluginsList:
			if d == "markup":
				# trace(`colorCount`,`d`)
				if match_word(s2,k,"wiki"):
					doWikiText(colorer,v,s,i,j,colortag)
					return true # We have colored the text.
			
	# trace(`colorCount`,"no markup")
	return None # We have not colored the text.
#@nonl
#@-node:colorWikiMarkup
#@+node:doWikiText
def doWikiText (colorer,v,s,i,end,colortag):

	firsti = i ; inserted = 0

	while i < end:
		#@		<< set first to a tuple describing the first tag to be handled >>
		#@+node:<< set first to a tuple describing the first tag to be handled >>
		first = None
		
		for tag,delim1,delim2 in (
			("bold","__","__"),
			("italic","''","''"),
			("picture","{picture file=","}"),
			("color","~~","~~")):
			n1 = s.find(delim1,i,end)
			if n1 > -1:
				n2 = s.find(delim2,n1+len(delim1),end)
				if n2 > -1:
					if not first or (first and n1 < first[1]):
						first = tag,n1,n2,delim1,delim2
		#@-node:<< set first to a tuple describing the first tag to be handled >>
		#@nl
		if first:
			tag,n1,n2,delim1,delim2 = first
			i = n2 + len(delim2)
			#@			<< handle the tag using n1,n2,delim1,delim2 >>
			#@+node:<< handle the tag using n1,n2,delim1,delim2 >>
			if tag =="picture":
				colorer.tag("elide",n1,n2+len(delim2)) # Elide everything.
				filename = s[n1+len(delim1):n2]
				filename = os.path.join(app().loadDir,filename)
				filename = os.path.normpath(filename)
				inserted += insertWikiPicture(colorer,filename,n2+len(delim2))
			elif tag == "color":
				#@	<< parse and handle color field >>
				#@+node:<< parse and handle color field >>
				# Parse the color value.
				j = n1+len(delim1)
				n = s.find(":",j,n2)
				if n2 > n > j > -1:
					name = s[j:n]
					if name[0] == '#' and len(name) > 1:
						name = '#' + string.zfill(name[1:],6)
					if name in colorer.color_tags_list:
						colorer.tag("elide",n1,n+1)
						colorer.tag(name,n+1,n2)
						colorer.tag("elide",n2,n2+len(delim2))
					else:
						try:
							# print "entering", name
							colorer.body.tag_configure(name,foreground=name)
							colorer.color_tags_list.append(name)
							colorer.tag("elide",n1,n+1)
							colorer.tag(name,n+1,n2)
							colorer.tag("elide",n2,n2+len(delim2))
						except: # an invalid color name: elide nothing.
							pass # es_exception()
				#@nonl
				#@-node:<< parse and handle color field >>
				#@nl
			else:
				# look for nested bold or italic.
				if tag == "bold":
					delim3,delim4 = "''","''" # Look for nested italic.
				else:
					delim3,delim4 = "__","__" # Look for nested bold.
				n3 = s.find(delim3,n1+len(delim1),n2) ; n4 = -1
				if n3 > -1:
					n4 = s.find(delim4,n3+len(delim3),n2+len(delim2))
				if n3 > -1 and n4 > -1:
					colorer.tag("elide",n1,n1+len(delim1))
					colorer.tag("elide",n2,n2+len(delim2))
					colorer.tag("elide",n3,n3+len(delim3))
					colorer.tag("elide",n4,n4+len(delim4))
					colorer.tag(tag,n1+len(delim1),n3)
					colorer.tag("bolditalic",n3+len(delim3),n4)
					colorer.tag(tag,n4+len(delim4),n2)
				else:
					# No nested tag.
					colorer.tag("elide",n1,n1+len(delim1))
					colorer.tag("elide",n2,n2+len(delim2))
					colorer.tag(tag,n1+len(delim1),n2)
			#@nonl
			#@-node:<< handle the tag using n1,n2,delim1,delim2 >>
			#@nl
		else: i = end
		
	colorer.tag(colortag,firsti,end+inserted)
#@nonl
#@-node:doWikiText
#@+node:insertWikiPicture
def insertWikiPicture (colorer,filename,i):
	
	"""Try to insert a picture with the give filename.
	
	Returns the number of characters actually inserted"""
	
	# trace(`colorer.color_pass`)
	if colorer.color_pass == 0:
		colorer.redoColoring = true # schedule a two-pass recoloring.
		return 0
		
	if colorer.color_pass == 2:
		return 0 # The second redo pass.
		
	# trace(`filename`,`v`)
	if not os.path.exists(filename):
		return 0

	try:
		# Create the image
		photo = Tkinter.PhotoImage(master=app().root, file=filename)
		image = colorer.c.bodyCtrl.image_create(colorer.index(i),image=photo,padx=0) # 10/27/03

		# Keep references so images stay on the canvas.
		colorer.image_references.append((photo,image,colorer.line_index,i),)
		return 1
	except:
		es_exception()
		return 0
#@nonl
#@-node:insertWikiPicture
#@-others

if Tkinter and 1: # Register the handlers...

	if app.gui is None:
		app.createTkGui(__file__)

	if app.gui.guiName() == "tkinter":
		
		print "wiki markup enabled"

		registerHandler("color-optional-markup", colorWikiMarkup)
		registerHandler("init-color-markup", initAnyMarkup)
	
		__version__ = "1.1"
		plugin_signon(__name__)
#@nonl
#@-node:@file color_markup.py
#@-leo
