All pastes #146643 Raw Edit

Unnamed

public text v1 · immutable
#146643 ·published 2006-08-23 19:33 UTC
rendered paste body
# -*- coding: utf-8 -*-
# Copyright © 2005 Lateef Alabi-Oki
#
# This file is part of Scribes.
#
# Scribes is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Scribes is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Scribes; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
# USA

"""
This module documents a class that creates an object that processes
templates.

@author: Lateef Alabi-Oki
@organization: The Scribes Project
@copyright: Copyright © 2005 Lateef Alabi-Oki
@license: GNU GPLv2 or Later
@contact: mystilleef@gmail.com
"""
def debug(*message):
	print "debug message: ", message

class TemplateProcessor(object):
	"""
	This class creates an object inserts templates with placeholders
	into the text editor's buffer and provides mechanisms for navigating
	between the placeholders.
	"""

	def __init__(self, manager, trigger, result):
		"""
		Initialize the processor.

		@param self: Reference to the TemplateProcessor instance.
		@type self: A TemplateProcessor object.

		@param manager: The text editor's template manager.
		@type manager: A TemplateManager object.

		@param trigger: A template trigger.
		@type trigger: A String object.
		"""
		self.__init_attributes(manager, trigger, result)
		self.manager.remove_template_trigger(trigger)
		from cursor import get_cursor_iterator
		cursor_position = get_cursor_iterator(self.editor.textbuffer)
		self.begin_mark = self.editor.textbuffer.create_mark(None, cursor_position, True)
		self.end_mark = self.editor.textbuffer.create_mark(None, cursor_position, False)
		template = self.manager.get_template(trigger)
		self.editor.textbuffer.begin_user_action()
		self.manager.insert_template(template)
		self.editor.textbuffer.end_user_action()
		self.__generate_mirror_list(result)
		self.__prepare_placeholders()
		debug("dict keys : ", self.placeholder_dictionary.keys())
		if self.placeholder_dictionary == {}:
			debug("empty placeholder dict")
			self.__preemptivedestroy()
		else:
			self.editor.textbuffer.begin_user_action()
			self.__tag_placeholders()
			self.__reset_last_placeholder()
			self.__select_first_placeholder()
			self.editor.textbuffer.end_user_action()
			self.cursor_movement_id = self.editor.connect("cursor-moved", self.__processor_cursor_moved_cb)
			self.text_id  = self.editor.textbuffer.connect("insert-text", self.__processor_insert_text_cb)
			self.text_id2 = self.editor.textbuffer.connect_after("insert-text", self.__processor_insert_text_after_cb)
			message = "Template mode is active"
			self.status_id = self.editor.feedback.set_modal_message(message, "info")

	def __init_attributes(self, manager, trigger, result):
		"""
		Initialize the processor's data attributes.

		@param self: Reference to the TemplateProcessor instance.
		@type self: A TemplateProcessor object.

		@param manager: The text editor's template manager.
		@type manager: A TemplateManager object.

		@param trigger: A template trigger.
		@type trigger: A String object.
		"""
		self.manager = manager
		self.trigger = trigger
		self.editor = manager.editor
		self.begin_mark = None
		self.end_mark = None
		self.special_placeholders = ["${time}", "${timestring}", "${timestamp}", "${date}", "${day}", "${month}", "${year}"]
		self.placeholder_dictionary = {}
		self.mirror_dictionary = {}
		self.mirror_list = []
		self.result = result
		self.pre_tag = self.__create_pre_tag()
		self.post_tag = self.__create_post_tag()
		self.editing_tag  = self.__create_editing_tag()
		self.index = 0
		self.last_index = None
		self.cursor_movement_id = None
		# True if there are more than one placeholders with the same
		# name.
		self.has_mirrors = False
		return

	def next_placeholder(self):
		"""
		Move to the next placeholder if possible.

		@param self: Reference to the TemplateProcessor instance.
		@type self: A TemplateProcessor object.
		"""
		# Destroy this template object if there is no next placeholder
		# to move to.
		if self.index == self.last_index:
			self.destroy()
			return
		debug("self.index: ", self.index)
		debug("self.placeholder_dictionary.keys: ", self.placeholder_dictionary.keys())
		# Tag the current placeholder before moving to the next one.
		begin_mark, end_mark = self.placeholder_dictionary[self.index]
		begin = self.editor.textbuffer.get_iter_at_mark(begin_mark)
		end = self.editor.textbuffer.get_iter_at_mark(end_mark)
		self.editor.textbuffer.remove_tag(self.pre_tag, begin, end)
		self.editor.textbuffer.remove_tag(self.editing_tag, begin, end)
		self.editor.textbuffer.apply_tag(self.post_tag, begin, end)
		if (begin_mark, end_mark) in self.mirror_dictionary.keys():
			self.__update_mirrors()
		self.index = self.__calculate_next_index()
		try:
			# Select the next placeholder.
			begin_mark, end_mark = self.placeholder_dictionary[self.index]
			begin = self.editor.textbuffer.get_iter_at_mark(begin_mark)
			end = self.editor.textbuffer.get_iter_at_mark(end_mark)
			self.editor.textbuffer.select_range(begin, end)
		except:
			# Move to the last placeholder position.
			marker = self.placeholder_dictionary[self.index]
			position = self.editor.textbuffer.get_iter_at_mark(marker[0])
			self.editor.textbuffer.place_cursor(position)
		from cursor import move_view_to_cursor
		move_view_to_cursor(self.editor.textview)
		message = "Moved to next placeholder"
		self.editor.feedback.update_status_message(message, "succeed")
		return

	def previous_placeholder(self):
		"""
		Move to the previous placeholder if possible.

		@param self: Reference to the TemplateProcessor instance.
		@type self: A TemplateProcessor object.
		"""
		# Destroy this template object if there is no previous placeholder
		# to move to.
		if self.index < 0:
			self.destroy()
			return
		# Tag the current placeholder before moving to the next one.
		try:
			begin_mark, end_mark = self.placeholder_dictionary[self.index]
			if (begin_mark, end_mark) in self.mirror_dictionary.keys():
				self.__update_mirrors()
			begin = self.editor.textbuffer.get_iter_at_mark(begin_mark)
			end = self.editor.textbuffer.get_iter_at_mark(end_mark)
			self.editor.textbuffer.remove_tag(self.pre_tag, begin, end)
			self.editor.textbuffer.remove_tag(self.editing_tag, begin, end)
			self.editor.textbuffer.apply_tag(self.post_tag, begin, end)
		except:
			pass
		# Adjust the placeholder index.
		self.index = self.__calculate_previous_index()
		try:
			# Select the previous placeholder.
			begin_mark, end_mark = self.placeholder_dictionary[self.index]
			begin = self.editor.textbuffer.get_iter_at_mark(begin_mark)
			end = self.editor.textbuffer.get_iter_at_mark(end_mark)
			self.editor.textbuffer.select_range(begin, end)
		except:
			self.destroy()
		from cursor import move_view_to_cursor
		move_view_to_cursor(self.editor.textview)
		message = "Moved to previous placeholder"
		self.editor.feedback.update_status_message(message, "succeed")
		return

	def __preemptivedestroy(self):
		"""
		Destroy the template object, remove all marks and tags.

		@param self: Reference to the TemplateProcessor instance.
		@type self: A TemplateProcessor object.
		"""
		# Remove all tags associated with this template object.
		begin_position = self.editor.textbuffer.get_iter_at_mark(self.begin_mark)
		end_position = self.editor.textbuffer.get_iter_at_mark(self.end_mark)
		self.editor.textbuffer.remove_tag(self.pre_tag, begin_position, end_position)
		self.editor.textbuffer.remove_tag(self.post_tag, begin_position, end_position)
		self.editor.textbuffer.remove_tag(self.editing_tag, begin_position, end_position)
		# Remove all marks associated with this template object.
		if self.begin_mark.get_deleted() is False:
			self.editor.textbuffer.delete_mark(self.begin_mark)
		if self.end_mark.get_deleted() is False:
			self.editor.textbuffer.delete_mark(self.end_mark)
		for placeholders in self.placeholder_dictionary.values():
			for marker in placeholders:
				if marker.get_deleted() is False:
					self.editor.textbuffer.delete_mark(marker)
		message = "Inserted template"
		self.editor.feedback.update_status_message(message, "succeed")
		# Destroy this template object and call the garbage collector.
		self = None
		del self
		from gc import collect
		collect()
		return

	def destroy(self):
		"""
		Destroy the template object, remove all marks and tags.

		@param self: Reference to the TemplateProcessor instance.
		@type self: A TemplateProcessor object.
		"""
		# Disconnect all signals associated with this template object.
		self.editor.disconnect(self.cursor_movement_id)
		self.editor.textbuffer.disconnect(self.text_id)
		self.editor.textbuffer.disconnect(self.text_id2)
		# Remove this template object from the template manager.
		self.manager.template_list.remove(self)
		# Remove all tags associated with this template object.
		begin_position = self.editor.textbuffer.get_iter_at_mark(self.begin_mark)
		end_position = self.editor.textbuffer.get_iter_at_mark(self.end_mark)
		self.editor.textbuffer.remove_tag(self.pre_tag, begin_position, end_position)
		self.editor.textbuffer.remove_tag(self.post_tag, begin_position, end_position)
		self.editor.textbuffer.remove_tag(self.editing_tag, begin_position, end_position)
		# Remove all marks associated with this template object.
		if self.begin_mark.get_deleted() is False:
			self.editor.textbuffer.delete_mark(self.begin_mark)
		if self.end_mark.get_deleted() is False:
			self.editor.textbuffer.delete_mark(self.end_mark)
		for placeholders in self.placeholder_dictionary.values():
			for marker in placeholders:
				if marker.get_deleted() is False:
					self.editor.textbuffer.delete_mark(marker)
		self.editor.feedback.unset_modal_message(self.status_id, False)
		message = "Inserted template"
		self.editor.feedback.update_status_message(message, "succeed")
		# Destroy this template object and call the garbage collector.
		self = None
		del self
		from gc import collect
		collect()
		return

	def __prepare_placeholders(self):
		"""
		Tag placeholders in templates.

		@param self: Reference to the TemplateManager instance.
		@type self: A TemplateManager object.

		@param result: A list of placeholders in the template.
		@type result: A List object.

		@param begin_mark: The beginning position of a template.
		@type begin_mark: A gtk.TextMark object.

		@param end_mark: The end position of a template.
		@type end_mark: A gtk.TextMark object.
		"""
		begin_position = self.editor.textbuffer.get_iter_at_mark(self.begin_mark)
		from gtk import TEXT_SEARCH_VISIBLE_ONLY
		from cursor import get_cursor_iterator
		count = 0
		for placeholder in self.result:
			end_position = self.editor.textbuffer.get_iter_at_mark(self.end_mark)
			begin, end = begin_position.forward_search(placeholder, TEXT_SEARCH_VISIBLE_ONLY, end_position)
			self.editor.textbuffer.place_cursor(begin)
			self.editor.textbuffer.begin_user_action()
			self.editor.textbuffer.delete(begin, end)
			self.editor.textbuffer.end_user_action()
			cursor_position = get_cursor_iterator(self.editor.textbuffer)
			#Is it the cursor tag?
			if placeholder == "${cursor}":
				emark = self.editor.textbuffer.create_mark(None, cursor_position, False)
				emark.set_visible(True)
				self.placeholder_dictionary["cursor"] = (emark,)
			#Is it in the special dictionary?
			elif self.special_placeholders.count(placeholder) > 0:
				escaped_variable = self.__replace_variable(placeholder)
				bmark = self.editor.textbuffer.create_mark(None, cursor_position, True)
				emark = self.editor.textbuffer.create_mark(None, cursor_position, False)
				self.editor.textbuffer.begin_user_action()
				self.editor.textbuffer.insert_at_cursor(escaped_variable)
				self.editor.textbuffer.end_user_action()
				rbegin = self.editor.textbuffer.get_iter_at_mark(bmark)
				rend = self.editor.textbuffer.get_iter_at_mark(emark)
				self.editor.textbuffer.apply_tag(self.pre_tag, rbegin, rend)
			else:
				bmark = self.editor.textbuffer.create_mark(None, cursor_position, True)
				emark = self.editor.textbuffer.create_mark(None, cursor_position, False)
				self.placeholder_dictionary[count] = (bmark, emark)
				count += 1
				escaped_placeholder = self.__escape_placeholder(placeholder)
				if escaped_placeholder in self.mirror_list:
					self.mirror_dictionary[(bmark, emark)] = escaped_placeholder
				self.editor.textbuffer.begin_user_action()
				if escaped_placeholder == "":
					escaped_placeholder = " "
				self.editor.textbuffer.insert_at_cursor(escaped_placeholder)
				self.editor.textbuffer.end_user_action()
			begin_position = self.editor.textbuffer.get_iter_at_mark(emark)
		return


	def __escape_placeholder(self, placeholder):
		"""
		Remove foreign characters from placeholders.

		@param self: Reference to the TemplateProcessor instance.
		@type self: A TemplateProcessor object.

		@param placeholder: A placeholder.
		@type placeholder: A String object.

		@return: A placeholder with removed foreign characters.
		@rtype: A String object.
		"""
		placeholder = placeholder.lstrip("$")
		placeholder = placeholder.lstrip("{")
		placeholder = placeholder.rstrip("}")
		#for character in ("$", "{", "}"):
		#	placeholder = placeholder.replace(character, "")
		return placeholder

	def __tag_placeholders(self):
		"""
		Tag all placeholders.

		@param self: Reference to the TemplateProcessor instance.
		@type self: A TemplateProcessor object.
		"""
		for position in self.placeholder_dictionary.values():
			if len(position) == 2:
				begin = self.editor.textbuffer.get_iter_at_mark(position[0])
				end = self.editor.textbuffer.get_iter_at_mark(position[1])
				self.editor.textbuffer.apply_tag(self.post_tag, begin, end)
		return

	def __select_first_placeholder(self):
		"""
		Select the first placeholder.

		@param self: Reference to the TemplateProcessor instance.
		@type self: A TemplateProcessor object.
		"""
		if len(self.placeholder_dictionary[0]) < 2:
			return
		begin_mark, end_mark = self.placeholder_dictionary[0]
		begin = self.editor.textbuffer.get_iter_at_mark(begin_mark)
		end = self.editor.textbuffer.get_iter_at_mark(end_mark)
		self.editor.textbuffer.select_range(begin, end)
		return

	def __create_pre_tag(self):
		"""
		Create a tag for placeholders that have not been edited.

		@param self: Reference to the TemplateProcessor instance.
		@type self: A TemplateProcessor object.

		@return: A tag for editing templates.
		@rtype: A gtk.TextTag object.
		"""
		tag = self.editor.textbuffer.create_tag()
		tag.set_property("background", "yellow")
		tag.set_property("foreground", "blue")
		from pango import WEIGHT_HEAVY
		tag.set_property("weight", WEIGHT_HEAVY)
		return tag

	def __create_post_tag(self):
		"""
		Create a tag for edited placeholders.

		@param self: Reference to the TemplateProcessor instance.
		@type self: A TemplateProcessor object.

		@return: A tag for editing templates.
		@rtype: A gtk.TextTag object.
		"""
		tag = self.editor.textbuffer.create_tag()
		tag.set_property("foreground", "blue")
		from pango import WEIGHT_HEAVY, STYLE_ITALIC
		tag.set_property("weight", WEIGHT_HEAVY)
		tag.set_property("style", STYLE_ITALIC)
		return tag

	def __create_editing_tag(self):
		"""
		Create a tag for editing placeholders.

		@param self: Reference to the TemplateProcessor instance.
		@type self: A TemplateProcessor object.

		@return: A tag for editing templates.
		@rtype: A gtk.TextTag object.
		"""
		tag = self.editor.textbuffer.create_tag()
		tag.set_property("background", "#ADD8E6")
		return tag

	def __processor_cursor_moved_cb(self, editor):
		"""
		Handles callback when the "cursor-moved" signal is emitted.

		@param self: Reference to the class instance.
		@type self: A class object.

		@param editor: Reference to the text editor.
		@type editor: An Editor object.
		"""
		# Destroy this template object if the cursor moves outside the
		# template region.
		from cursor import get_cursor_iterator
		cursor_position = get_cursor_iterator(self.editor.textbuffer)
		begin_position = self.editor.textbuffer.get_iter_at_mark(self.begin_mark)
		end_position = self.editor.textbuffer.get_iter_at_mark(self.end_mark)
		if not cursor_position.in_range(begin_position, end_position):
			if cursor_position.equal(end_position):
				pass
			else:
				self.destroy()
		return

	def __processor_insert_text_cb(self, textbuffer, iterator, text, length):
		"""
		Handles callback when the "insert-text" signal is emitted.

		@param self: Reference to the TemplateProcessor instance.
		@type self: A TemplateProcessor object.

		@param textbuffer: The text editor's buffer.
		@type textbuffer: A ScribesTextBuffer object.

		@param iterator: The position to insert text.
		@type iterator: A gtk.TextIter object.

		@param text: Text to be entered in the text editor's buffer.
		@type text: A String object.

		@param length: The length of text to be entered in the buffer.
		@type length: An Integer object.

		@return: True to propagate signals to parent widgets.
		@type: A Boolean Object.
		"""
		try:
			begin_mark, end_mark = self.placeholder_dictionary[self.last_index]
			begin = self.editor.textbuffer.get_iter_at_mark(begin_mark)
			end = self.editor.textbuffer.get_iter_at_mark(end_mark)
			if iterator.in_range(begin, end) or iterator.equal(begin) or iterator.equal(end):
				self.destroy()
				return False
		except:
			marker = self.placeholder_dictionary[self.last_index]
			position = self.editor.textbuffer.get_iter_at_mark(marker[0])
			if iterator.equal(position):
				self.destroy()
				return False
		return False

	def __processor_insert_text_after_cb(self, textbuffer, iterator, text, length):
		"""
		Handles callback when the "insert-text" signal is emitted.

		@param self: Reference to the TemplateProcessor instance.
		@type self: A TemplateProcessor object.

		@param textbuffer: The text editor's buffer.
		@type textbuffer: A ScribesTextBuffer object.

		@param iterator: The position to insert text.
		@type iterator: A gtk.TextIter object.

		@param text: Text to be entered in the text editor's buffer.
		@type text: A String object.

		@param length: The length of text to be entered in the buffer.
		@type length: An Integer object.

		@return: True to propagate signals to parent widgets.
		@type: A Boolean Object.
		"""
		result = self.__editing_placeholders()
		if result:
			begin_position = self.editor.textbuffer.get_iter_at_mark(result[0])
			end_position = self.editor.textbuffer.get_iter_at_mark(result[1])
			self.editor.textbuffer.apply_tag(self.editing_tag, begin_position, end_position)
			self.__update_index(result[0], result[1])
		return False

	def __reset_last_placeholder(self):
		"""
		Determine the last index in the placeholder dictionary.

		@param self: Reference to the TemplateProcessor instance.
		@type self: A TemplateProcessor object.
		"""
		if self.placeholder_dictionary == {}:
			return
		if self.placeholder_dictionary.has_key("cursor"):
			cursor_marker = self.placeholder_dictionary["cursor"]
			if len(self.placeholder_dictionary) == 1:
				self.last_index = 0
				self.placeholder_dictionary[self.last_index] = cursor_marker
			elif len(self.placeholder_dictionary) > 1:
				del self.placeholder_dictionary["cursor"]
				self.last_index = max(self.placeholder_dictionary.keys()) + 1
				self.placeholder_dictionary[self.last_index] = cursor_marker
		else:
			self.last_index = max(self.placeholder_dictionary.keys())
		return

	def __editing_placeholders(self):
		"""
		Return the position of placeholders if they are being edited.

		@param self: Reference to the TemplateProcessor instance.
		@type self: A TemplateProcessor object.

		@param iterator: The position of inserted text.
		@type iterator: A gtk.TextIter object.

		@return: The position of the placeholder being edited.
		@rtype: A List object.
		"""
		result = None
		placeholders = self.placeholder_dictionary.values()
		from cursor import get_cursor_iterator
		for placeholder in placeholders:
			if len(placeholder) == 1:
				continue
			begin = self.editor.textbuffer.get_iter_at_mark(placeholder[0])
			end = self.editor.textbuffer.get_iter_at_mark(placeholder[1])
			iterator = get_cursor_iterator(self.editor.textbuffer)
			if iterator.in_range(begin, end) or iterator.equal(begin) or iterator.equal(end):
				return placeholder
		return result

	def __generate_mirror_list(self, placeholders):
		"""
		Generate a dictionary containing possible mirrors.

		@param self: Reference to the TemplateProcessor instance.
		@type self: A TemplateProcessor object.

		@param placeholders: A list of placeholders
		@type placeholders: A List object.
		"""
		for placeholder in placeholders:
			if placeholder and (placeholders.count(placeholder) > 1) and (self.special_placeholders.count(placeholder) == 0):
				self.has_mirrors = True
				placeholder = self.__escape_placeholder(placeholder)
				if not placeholder in self.mirror_list:
					debug("mirror variable:", placeholder)
					self.mirror_list.append(placeholder)
		return

	def __is_mirror_placeholder(self, iterator):
		"""
		Check if the position is within a mirror placeholder.

		@param self: Reference to the TemplateProcessor instance.
		@type self: A TemplateProcessor object.

		@param iterator: A position in the text editor's buffer.
		@type iterator: A gtk.TextIter object.

		@return: The position of the mirror.
		@rtype: A List object.
		"""
		result = None
		placeholders = self.mirror_dictionary.keys()
		for placeholder in placeholders:
			if len(placeholder) == 1:
				continue
			begin = self.editor.textbuffer.get_iter_at_mark(placeholder[0])
			end = self.editor.textbuffer.get_iter_at_mark(placeholder[1])
			if iterator.in_range(begin, end) or iterator.equal(begin) or iterator.equal(end):
				result = (placeholder[0], placeholder[1])
				return result
		return result

	def __calculate_next_index(self):
		"""
		Determine the next placeholder index to jump to.

		@param self: Reference to the TemplateProcessor instance.
		@type self: A TemplateProcessor object.

		@return: The next placeholder index.
		@rtype: An Integer object.
		"""
		if self.has_mirrors:
			is_first_mirror = True
			index = self.index + 1
			try:
				begin_mark, end_mark = self.placeholder_dictionary[index]
			except:
				return index
			if (begin_mark, end_mark) in self.mirror_dictionary.keys():
				placeholder = self.mirror_dictionary[(begin_mark, end_mark)]
				for value in range(index):
					mark_one, mark_two = self.placeholder_dictionary[value]
					if (mark_one, mark_two) in self.mirror_dictionary.keys():
						if placeholder == self.mirror_dictionary[(mark_one, mark_two)]:
							is_first_mirror = False
							break
			if is_first_mirror is False:
				while True:
					index += 1
					if index == self.last_index:
						break
					begin_mark, end_mark = self.placeholder_dictionary[index]
					if (begin_mark, end_mark) in self.mirror_dictionary.keys():
						if placeholder != self.mirror_dictionary[(begin_mark, end_mark)]:
							break
					else:
						break
		else:
			index = self.index + 1
		return index

	def __calculate_previous_index(self):
		"""
		Determine the previous placeholder index to jump to.

		@param self: Reference to the TemplateProcessor instance.
		@type self: A TemplateProcessor object.

		@return: The next placeholder index.
		@rtype: An Integer object.
		"""
		if self.has_mirrors:
			index = self.index - 1
			is_first_mirror = True
			try:
				begin_mark, end_mark = self.placeholder_dictionary[index]
			except:
				return index
			if (begin_mark, end_mark) in self.mirror_dictionary.keys():
				placeholder = self.mirror_dictionary[(begin_mark, end_mark)]
				for value in range(index):
					mark_one, mark_two = self.placeholder_dictionary[value]
					if (mark_one, mark_two) in self.mirror_dictionary.keys():
						if placeholder == self.mirror_dictionary[(mark_one, mark_two)]:
							is_first_mirror = False
							break

			if is_first_mirror is False:
				while True:
					index -= 1
					if index < 0:
						break
					begin_mark, end_mark = self.placeholder_dictionary[index]
					if (begin_mark, end_mark) in self.mirror_dictionary.keys():
						if placeholder == self.mirror_dictionary[(begin_mark, end_mark)]:
							is_first_mirror = True
							for value in range(index):
								mark_one, mark_two = self.placeholder_dictionary[value]
								if (mark_one, mark_two) in self.mirror_dictionary.keys():
									if placeholder == self.mirror_dictionary[(mark_one, mark_two)]:
										is_first_mirror = False
							if is_first_mirror:
								break
						else:
							break
					else:
						break
		else:
			index = self.index - 1
		return index

	def __update_index(self, begin_mark, end_mark):
		"""
		Update the current placeholder index.

		@param self: Reference to the TemplateProcessor instance.
		@type self: A TemplateProcessor object.
		"""
		for value in range(self.last_index + 1):
			if (begin_mark, end_mark) == self.placeholder_dictionary[value]:
				self.index = value
				break
		return

	def __update_mirrors(self):
		"""
		Update other mirrors when one mirror is edited.

		@param self: Reference to the TemplateProcessor instance.
		@type self: A TemplateProcessor object.
		"""
		begin_mark, end_mark = self.placeholder_dictionary[self.index]
		mirror_list = []
		for key, value in self.mirror_dictionary.items():
			if value == self.mirror_dictionary[(begin_mark, end_mark)]:
				if key != (begin_mark, end_mark):
					mirror_list.append(key)
		if mirror_list:
			self.editor.textbuffer.handler_block(self.text_id2)
			self.editor.textbuffer.begin_user_action()
			for placeholder in mirror_list:
				begin_position = self.editor.textbuffer.get_iter_at_mark(begin_mark)
				end_position = self.editor.textbuffer.get_iter_at_mark(end_mark)
				begin = self.editor.textbuffer.get_iter_at_mark(placeholder[0])
				end = self.editor.textbuffer.get_iter_at_mark(placeholder[1])
				self.editor.textbuffer.begin_user_action()
				self.editor.textbuffer.delete(begin, end)
				self.editor.textbuffer.end_user_action()
				begin_position = self.editor.textbuffer.get_iter_at_mark(begin_mark)
				end_position = self.editor.textbuffer.get_iter_at_mark(end_mark)
				begin = self.editor.textbuffer.get_iter_at_mark(placeholder[0])
				end = self.editor.textbuffer.get_iter_at_mark(placeholder[1])
				self.editor.textbuffer.begin_user_action()
				self.editor.textbuffer.insert_range(begin, begin_position, end_position)
				self.editor.tehttp://pastebin.ca/146634xtbuffer.end_user_action()
				debug("begin")
				begin_position = self.editor.textbuffer.get_iter_at_mark(begin_mark)
				end_position = self.editor.textbuffer.get_iter_at_mark(end_mark)
				begin = self.editor.textbuffer.get_iter_at_mark(placeholder[0])
				end = self.editor.textbuffer.get_iter_at_mark(placeholder[1])
				self.editor.textbuffer.remove_tag(self.pre_tag, begin, end)
				self.editor.textbuffer.remove_tag(self.editing_tag, begin, end)
				self.editor.textbuffer.apply_tag(self.post_tag, begin, end)
			self.editor.textbuffer.end_user_action()
			self.editor.textbuffer.handler_unblock(self.text_id2)
		return
		
	def __replace_variable(self, variable):
		"""
		Replaces a variable/'special placeholder' with it's value.
		
		Any variables added here need to be added
		to self.special_placeholders in self.__init_attributes
		"""
		from switch import Switch
		#trim the excess
		variable = variable[2:-1]		
		for case in Switch(variable):
			if case('day'):
				from time import localtime
				thetime = localtime()
				return str(thetime[2])
				break
			if case('month'):
				from time import localtime
				thetime = localtime()
				return str(thetime[1])
				break
			if case('year'):
				from time import localtime
				thetime = localtime()
				return str(thetime[0])
				break
			if case('date'):
				from time import localtime
				thetime = localtime()
				return "%d:%d:%d" % (thetime[0], thetime[1], thetime[2])
				break
			if case('time'):
				from time import localtime
				thetime = localtime()
				return "%d:%d:%d" % (thetime[3], thetime[4], thetime[5])
				break
			if case('timestring'):
				from time import ctime
				return ctime()
				break
			if case('timestamp'):
				from time import localtime
				thetime = localtime()
				return "[%d-%d-%d] %d:%d:%d" % (thetime[0], thetime[1], thetime[2], thetime[3], thetime[4], thetime[5])
				break
		return ""