Attachment 'xmlhelper.py'

Download

   1 # -*- coding: utf8 -*-
   2 # XML Helper for GEdit
   3 # 
   4 # Copyright (c) 2007 Matej Cepl <matej@ceplovi.cz>
   5 #
   6 # Permission is hereby granted, free of charge, to any person obtaining
   7 # a copy of this software and associated documentation files (the
   8 # "Software"), to deal in the Software without restriction, including
   9 # without limitation the rights to use, copy, modify, merge, publish,
  10 # distribute, sublicense, and/or sell copies of the Software, and to
  11 # permit persons to whom the Software is furnished to do so, subject to
  12 # the following conditions:
  13 # 
  14 # The above copyright notice and this permission notice shall be
  15 # included in all copies or substantial portions of the Software.
  16 # 
  17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  20 # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  21 # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  22 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  23 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24 
  25 import gedit
  26 import gtk
  27 import re,sys
  28 import enum
  29 
  30 end_tag_str = """
  31 <ui>
  32 	<menubar name="MenuBar">
  33 		<menu name="EditMenu" action="Edit">
  34 			<placeholder name="EditOps_6">
  35 				<menuitem name="LastTag" action="LastTag"/>
  36 				<menuitem name="EndTag" action="EndTag"/>
  37 			</placeholder>
  38 		</menu>
  39 	</menubar>
  40 </ui>
  41 """
  42 
  43 debug = False
  44 
  45 def prDebug(string):
  46 	if debug:
  47 		print >>sys.stderr,string
  48 
  49 class XMLHelper(gedit.Plugin):
  50 	def __init__(self):
  51 		gedit.Plugin.__init__(self)
  52 		self.elementEndness=enum.Enum("end","start","single")
  53 		
  54 	def __get_tag(self,iter):
  55 		if not(iter.forward_char()):
  56 			raise RuntimeError, "we are in trouble"
  57 		searchRet=iter.forward_search(">",gtk.TEXT_SEARCH_TEXT_ONLY)
  58 		if searchRet:
  59 			begEnd,endEnd=searchRet
  60 			retStr = iter.get_text(begEnd)
  61 			if (retStr[-1]=="/") or (retStr[:3]=="!--"):
  62 				hasEndTag = self.elementEndness.single
  63 				retStr = retStr.rstrip("/")
  64 			elif  retStr[0] == "/":
  65 				hasEndTag = self.elementEndness.end
  66 				retStr = retStr.lstrip("/")
  67 			else:
  68 				hasEndTag = self.elementEndness.start
  69 			# cut element's parameters
  70 			retStr = retStr.split(" ")[0]
  71 			prDebug("tag found is %s and the value of hasEndTag is %s" % (retStr,hasEndTag))
  72 			return retStr,hasEndTag
  73 		else:
  74 			raise IOError, "Never ending tag at line %d" % (iter.get_line()+1)
  75 
  76 	def findLastEndableTag(self,position):
  77 		tagStack = []
  78 		res = position.backward_search("<", gtk.TEXT_SEARCH_TEXT_ONLY)
  79 		while res:
  80 			start_match,end_match=res
  81 			tag,isEndTag=self.__get_tag(start_match)
  82 			if isEndTag==self.elementEndness.end:
  83 				tagStack.append(tag)
  84 				prDebug("Push tag '%s'" % tag)
  85 			elif isEndTag==self.elementEndness.single:
  86 				prDebug("Ignoring single tag '%s'" % tag)
  87 			elif len(tagStack) != 0: # stack not empty
  88 				poppedTag=tagStack.pop()
  89 				prDebug("Popped tag '%s'" % poppedTag)
  90 				if poppedTag != tag:
  91 					raise IOError,"mismatching tags.\nFound %s and expecting %s." % \
  92 						(tag,poppedTag)
  93 			else: # stack is empty and this is not end tag == we found it
  94 				prDebug("We found tag '%s'" % tag)
  95 				return tag
  96 			start_match.backward_char()
  97 			res = start_match.backward_search("<",gtk.TEXT_SEARCH_TEXT_ONLY)
  98 
  99 		# not totally sure what following means, but doesn't look right to me
 100 		if len(tagStack) != 0:
 101 			raise IOError, "whatever"
 102 		if not(res): # There is no open tag in the current buffer
 103 			return None
 104 
 105 	def end_tag(self, action, window):
 106 		buffer = window.get_active_view().get_buffer()
 107 		inp_mark=buffer.get_iter_at_mark(buffer.get_insert())
 108 		tagname=self.findLastEndableTag(inp_mark)
 109 		if tagname:
 110 			buffer.insert(inp_mark,'</%s>' % tagname)
 111 
 112 	def previous_tag(self,action,window):
 113 		buffer = window.get_active_view().get_buffer()
 114 		inp_mark = buffer.get_iter_at_mark(buffer.get_insert())
 115 		res = inp_mark.backward_search("<", gtk.TEXT_SEARCH_TEXT_ONLY)
 116 		if res:
 117 			start_match,end_match = res
 118 			tag,isEndTag = self.__get_tag(start_match)
 119 			if isEndTag == self.elementEndness.end:
 120 				buffer.insert(inp_mark,'<%s>' % tag)
 121 
 122 	def activate(self, window):
 123 		actions = [
 124 			('EndTag', None, 'End Tag', None, "End Tag", self.end_tag),
 125 			('LastTag', None, 'Last Tag', None, "Last Tag", self.previous_tag),
 126 		]
 127 
 128 		# store per window data in the window object
 129 		windowdata = dict()
 130 		window.set_data("XMLHelperWindowDataKey", windowdata)
 131 		windowdata["action_group"] = gtk.ActionGroup("GeditXMLHelperActions")
 132 		windowdata["action_group"].add_actions(actions, window)
 133 		manager = window.get_ui_manager()
 134 		manager.insert_action_group(windowdata["action_group"], -1)
 135 		windowdata["ui_id"] = manager.add_ui_from_string(end_tag_str)
 136 		
 137 		window.set_data("XMLHelperInfo", windowdata)
 138 
 139 	def deactivate(self, window):
 140 		windowdata = window.get_data("XMLHelperWindowDataKey")
 141 		manager = window.get_ui_manager()
 142 		manager.remove_ui(windowdata["ui_id"])
 143 		manager.remove_action_group(windowdata["action_group"])
 144 
 145 	def update_ui(self, window):
 146 		view = window.get_active_view()
 147 		windowdata = window.get_data("XMLHelperWindowDataKey")
 148 		windowdata["action_group"].set_sensitive(bool(view and view.get_editable()))

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2021-02-25 09:43:47, 0.3 KB) [[attachment:xmlhelper.gedit-plugin]]
  • [get | view] (2021-02-25 09:43:47, 5.1 KB) [[attachment:xmlhelper.py]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.