Posted By

s1w on 06/13/11


Tagged

toggle html python script comment uncomment notepad++ npp n++ pythonscript


Versions (?)

Toggle HTML Comment >> PythonScript for Notepad++


 / Published in: Python
 

URL: http://siwego.net

  1. #Toggle HTML Comment >> PythonScript for Notepad++
  2. # -comments single line without selection/removes comment tags in NON-GREEDY or GREEDY style (see options)
  3. # -comments selection/clears all comments from selection
  4. # -intelligently handles '--> ... <!--' or '<!-- . . <!-- .. -->' in relation to single line when nothing selected
  5. # -recognizes incorrect tags like <!----
  6. # -script can remove also stream comments '/* */' and others own defined, which macro in N++ was not supported
  7. # -all of this under one shortcut. author: s1w_
  8. #note: this is NOT begin-end validity checker, use HTML parsers instead
  9. import re, string
  10.  
  11. class commentPair:
  12. """Objects of this class will contain pairs of comment tags;
  13. you can define your additional bracket pairs below.
  14. Constructor takes two parameters: <opening> and <closing>
  15. raw string describing new definition of comment pair.
  16.  
  17. If you want use '\' char in parameter, you have to double it,
  18. because it is recognized as escape sign. '\\**' and '***\\\\'
  19. in fact is passed as '\**' and '***\\'. If you forget about
  20. this, you will have syntax error (quantity of '\' should be
  21. no different than even). Do not escape other characters!
  22.  
  23. Order of defining comment pairs is crucial in this script,
  24. because it will determine comments recognition order.
  25. First (top) defined pair is used for main script functionality.
  26.  
  27. Additional definitions apply only for operation of cleaning.
  28. It performs if script detects in selected text or in current
  29. line one of defined comments: step by step and in the same
  30. order as were defined (from top to bottom).
  31.  
  32. To promote additional comment pair to main functionality, you
  33. will want to create multiple copies of this script under
  34. different names and binds each one under different shortcut
  35. key. Each instance of script may define different order of
  36. comment pairs."""
  37.  
  38. global esc; esc = re.escape
  39.  
  40. def __init__( self, left='<!--', right='-->' ):
  41. self.right = right.strip(); self.left = left.strip()
  42. self.rplus = esc(self.right)
  43. self.rplus = re.sub(r'^([\\]?.)', r'\1+', self.rplus, 1);
  44. self.lplus = esc(self.left)+'+'
  45. self.lmore = self.lplus + '[ \t]*'
  46. self.rmore = '[ \t]*' + self.rplus
  47. self.combo = esc(self.left)+'+'+esc(self.right)
  48. self.tail = self.right[0]
  49.  
  50.  
  51. #top-most main comment pair definition:
  52. commentTags = [ commentPair('<!--', '-->') ] # always first served and used while commenting line or selection
  53.  
  54. #additional comment pairs definitions (only for cleaning):
  55. commentTags.append( commentPair('/*', '*/') ) # you can add more statements like this in desired order
  56.  
  57. #options:
  58. GREEDY_MODE = 0 #greedy(1): widest matches; non-greedy(0): narrowest matches (recommended)
  59. MULTIPLE_CLEANING = 1 #allow cleaning multiple braces from selection
  60. ALIGN_TO_INDENT = 1 #align line to indent if new leading spaces detected (for non-selections)
  61. CONSOLE_DEBUG = 0 #print script actions to console;
  62.  
  63. #declarations:
  64. position, line = editor.getCurrentPos(), editor.getCurLine()
  65. currentLine = editor.lineFromPosition(position)
  66. indent = editor.getLineIndentPosition(currentLine)
  67. indstr = re.match('[ \t]*', line).group(0)
  68. selStart, selEnd = editor.getSelectionStart(), editor.getSelectionEnd()
  69. cright, cleft = ' '+commentTags[0].right, commentTags[0].left+' '
  70. alt = position - indent
  71.  
  72. #functions:
  73. def combine_pattern(comm):
  74. "checks mode and selection dependences and creates adequate pattern compilation for regex functions"
  75. if selStart == selEnd:
  76. if not GREEDY_MODE:
  77. return re.compile('^[ \t]*(.*?)(?P<left>((?P<combo>'+comm.combo+')|(?P<lt>'+comm.lmore+')|(?P<rt>'+comm.rmore+')))(?P<block>.*?)(?P<right>((?(combo)|(?(rt)|(?(lt)((?='+esc(comm.left)+')|'+comm.rmore+'))))|(\r?\n|$)))')
  78. else: return re.compile('^[ \t]*(?P<b1>(.*?('+comm.combo+'|(?=('+esc(comm.left)+'|'+comm.rplus+'))))+)(?P<left>((?P<cb1>'+comm.combo+')|'+comm.lmore+'|'+comm.rplus+'))(?P<b>.*)(?P<right>((?P<cb2>'+comm.combo+')|'+comm.lmore+'|[ \t]'+comm.rplus+'|((?<![ \t])(?<!<!)(?<!'+esc(comm.tail)+')'+comm.rplus+')))(?P<b2>.*?)(\r?\n|$)'), \
  79. re.compile('^.*?(?P<left>((?P<combo>'+comm.combo+')|'+comm.lmore+'|'+comm.rmore+'))')
  80. else: return re.compile('('+comm.combo+')|('+esc(comm.left)+')('+esc(comm.tail)+'*[ ]?)|([ ]?'+esc(comm.tail)+'*)('+esc(comm.right)+')'), \
  81. re.compile('('+comm.combo+'|'+comm.lplus+'[ ]?|[ ]?'+comm.rplus+')')
  82.  
  83. def format_line(comment_pairs):
  84. global position
  85. global line; spaces = 0
  86. if not GREEDY_MODE:
  87. normal = combine_pattern(comment_pairs)
  88. mod = normal.match(line); mod_exclude = ''
  89. if CONSOLE_DEBUG:
  90. console.write('\n\n\n>removing '+(mod.group("combo") or IfIn(mod.group("left"), comment_pairs.left, comment_pairs.right))+
  91. ' '+IfIn(mod.group("right"), comment_pairs.right, comment_pairs.left)+'\nfrom line "'+line.strip()+'"')
  92. line = normal.sub(r'\1\g<block>', line).rstrip()
  93. else:
  94. greed, single = combine_pattern(comment_pairs)
  95. mod = greed.match(line)
  96. if CONSOLE_DEBUG: #console output section for debug:
  97. debug = greed.sub(r'\g<b1>[R1]\g<left>\g<b>\g<right>[R2]\g<b2>', line)
  98. if mod: console.write('\n\n\nprocessing: '+debug.strip()+'\n'+('='*25))
  99. chunks = greed.subn(r'\nleft garbage: \g<b1>\nleft tag: \g<left>\nright garbage: \g<b2>\nright tag: \g<right>\n'+('='*25), line)
  100. if chunks[1]: console.write(chunks[0]+'\n')
  101. if not mod: #remove single comment without its pair
  102. mod = single.match(line); mod_exclude = 'right'
  103. if CONSOLE_DEBUG:
  104. console.write('\n\n\n>removing single '+(mod.group("combo") or
  105. IfIn(mod.group("left"), comment_pairs.left, comment_pairs.right))+'\nfrom line "'+line.strip()+'"')
  106. line = re.sub('('+comment_pairs.combo+'|'+comment_pairs.lmore+'|'+comment_pairs.rmore+')', '', line).rstrip()
  107. else: #determining to remove two comment tags with greedy mode
  108. flag = 0; mod_exclude = ''; rcombo = False #map of flags was included at the end of script if eventually needed to fathom details
  109. rcombo = (comment_pairs.left in mod.group("right") and comment_pairs.right in mod.group("right")) #<!---->
  110. flag = flag|(bool(mod.group("b1").strip())*0x8) #left garbage
  111. flag = flag|((comment_pairs.right in mod.group("left"))*0x4) #left tag
  112. flag = flag|((comment_pairs.right in mod.group("right"))*0x2) #right tag
  113. flag = flag|(bool(mod.group("b2").strip())*0x1) #right garbage
  114. if CONSOLE_DEBUG: console.write('flag = '+str("%X" % flag)+', removing: ')
  115. if flag not in [0x4,0x6,0x8,0xC,0xD,0xE,0xF] and (not rcombo or rcombo and flag not in [0x2,0x3,0xA,0xB]):
  116. line = re.sub('('+esc(mod.group("b1"))+')'+esc(mod.group("left")), '\\1', line, 1).rstrip() #remove left
  117. if flag not in [0x2,0x3,0xA,0xB] or rcombo: mod_exclude = 'right'
  118. if CONSOLE_DEBUG: console.write((mod.group("cb1") or IfIn(mod.group("left"), comment_pairs.left, comment_pairs.right))+' ')
  119. if flag not in [0x0,0x1,0x5,0x7,0x9] and (not rcombo or rcombo and flag not in [0x3]):
  120. line = re.sub('^(.*)'+esc(mod.group("right")), '\\1', line).rstrip() #remove right
  121. if flag not in [0x2,0x3,0xA,0xB] or rcombo: mod_exclude = 'left'
  122. if CONSOLE_DEBUG: console.write(mod.group("cb2") or IfIn(mod.group("right"), comment_pairs.right, comment_pairs.left))
  123. if ALIGN_TO_INDENT:
  124. spaces = len(re.match('[ \t]*', line).group(0));
  125. line = line.lstrip();
  126. if not GREEDY_MODE or ALIGN_TO_INDENT:
  127. line = indstr+line
  128. if line.isspace(): line = line.strip()
  129. checkCursorPosition(mod, spaces, mod_exclude)
  130. return
  131.  
  132. def setSelectionArea(begin, end):
  133. "checks if selection was in rectangle mode, then sets new selection area"
  134. if editor.selectionIsRectangle():
  135. editor.setSelectionMode(1)
  136. editor.setRectangularSelectionAnchor(begin)
  137. editor.setRectangularSelectionCaret(end)
  138. else:
  139. editor.setSel(begin, end)
  140.  
  141. def checkCursorPosition(mod, sp, exclude='', tag='right'):
  142. "sets new cursor position after line modifications"
  143. global position;
  144. newlength = len(line) - len(indstr)
  145. if alt > len(line.strip()) or newlength < 0:
  146. position = indent + newlength
  147. return
  148. elif not exclude == tag and mod.group(tag):
  149. spaces = (tag == 'left') and sp or 0
  150. beg = mod.start(tag) - len(indstr)
  151. end = mod.end(tag) + spaces - len(indstr)
  152. if alt > beg:
  153. if beg < alt and end > alt: position = beg + indent
  154. else: position -= mod.end(tag)+spaces - mod.start(tag)
  155. if tag != 'left': checkCursorPosition(mod, sp, exclude, 'left')
  156. return
  157.  
  158. def IfIn(targetStr, *checkargs):
  159. "function checks targetStr if it contains any of checkargs strings. Returns first match or empty string"
  160. if targetStr.strip():
  161. for str in checkargs:
  162. if str in targetStr: return str
  163. return ''
  164.  
  165. formatted = 0
  166. #final script code:
  167. if selStart == selEnd:
  168. #fast single line modification
  169. for comments in commentTags:
  170. if comments.left in line or comments.right in line:
  171. format_line(comments); formatted = 1; break
  172. if not formatted:
  173. if line.isspace(): line = line[:alt-2]
  174. if alt > len(line.strip()): position = indent + len(line.strip())
  175. line = re.sub('([ \t]*)(.*)[ \t]*(\r?\n|$)', r'\1'+cleft+r'\2', line).rstrip() + cright
  176. if indent <= position: position += len(cleft)
  177. if CONSOLE_DEBUG: console.write('\n\n\n>commenting line... '+cleft+cright)
  178. editor.replaceLine(currentLine, line)
  179. editor.setSel(position, position)
  180. else:
  181. #selection modification: if tags detected clear, else comment
  182. if MULTIPLE_CLEANING:
  183. for comments in commentTags:
  184. if formatted: break
  185. counter = 0; modrange = 0;
  186. list, rem = combine_pattern(comments)
  187. for linePos in range(editor.lineFromPosition(selStart), editor.lineFromPosition(selEnd)+1):
  188. linebeg, lineend = editor.getLineSelStartPosition(linePos), editor.getLineSelEndPosition(linePos)
  189. lineStr = editor.getTextRange(linebeg, lineend)
  190. editor.setTargetStart(linebeg); editor.setTargetEnd(lineend)
  191. if comments.left in lineStr or comments.right in lineStr:
  192. if CONSOLE_DEBUG: console.write('\n\n>removing ')
  193. for tag in list.findall(lineStr):
  194. if CONSOLE_DEBUG: console.write((tag[0] or tag[1] or tag[4])+' '); counter+=1
  195. modrange+=len("".join(tag));
  196. if CONSOLE_DEBUG: console.write('\nfrom selection "'+lineStr.strip()+'"')
  197. lineStr = rem.sub('', lineStr)
  198. editor.replaceTarget(lineStr); formatted = 1
  199. setSelectionArea(selStart, selEnd-modrange)
  200. if formatted and CONSOLE_DEBUG:
  201. console.write('\n:total removals '+str(counter)+' :total range '+str(modrange))
  202. if not formatted:
  203. editor.setTargetStart(selEnd); editor.setTargetEnd(selEnd)
  204. editor.replaceTarget(cright)
  205. editor.setTargetStart(selStart); editor.setTargetEnd(selStart)
  206. editor.replaceTarget(cleft)
  207. if CONSOLE_DEBUG:
  208. console.write('\n\n>commenting selection... '+cleft+' '+cright)
  209. setSelectionArea(selStart, selEnd+len(cleft)+len(cright))
  210.  
  211.  
  212. #author: s1w_
  213.  
  214. #flag_legend_for_greedy_engine: ------------------------------------
  215. # string action flag condition
  216. # |--> * -->| rem right 0110 x6
  217. # |abc --> * -->| rem right 1110 xE
  218. # |abc --> * --> abc| rem right 1111 xF
  219. # |--> * <!--| rem right 0100 x4
  220. # |abc --> * <!--| rem right 1100 xC
  221. # |abc --> * <!-- abc| rem right 1101 xD
  222. # |abc <!-- * <!--| rem right 1000 x8
  223. # |<!-- * -->| rem right 0010 x2 if right--> === <!---->
  224. # |abc <!-- * -->| rem right 1010 xA if right--> === <!---->
  225. # |abc <!-- * --> abc| rem right 1011 xB if right--> === <!---->
  226. # |<!-- * --> abc| rem left 0011 x3 if right--> === <!---->
  227. # |--> * --> abc| rem left 0111 x7
  228. # |--> * <!-- abc| rem left 0101 x5
  229. # |<!-- * <!--| rem left 0000 x0
  230. # |<!-- * <!-- abc| rem left 0001 x1
  231. # |abc <!-- * <!-- abc| rem left 1001 x9
  232. # |<!-- * -->| rem both 0010 x2 if right--> != <!---->
  233. # |<!-- * --> abc| rem both 0011 x3 if right--> != <!---->
  234. # |abc <!-- * -->| rem both 1010 xA if right--> != <!---->
  235. # |abc <!-- * --> abc| rem both 1011 xB if right--> != <!---->
  236. # where <!----> === -->
  237.  
  238. #testing_samples: --------------------------------------------------
  239. # asd <!--asdg -----> <!----> dd <!--- ---> sdfaf --->
  240. # asd <!---- /**<!-- asdg <!--- */dd --->sdfaf ---> ---> asda
  241. # asd <!----> a<!---->sdg<!---->sd -----> <!----> dd
  242. # <!----> <!--- asdg -----> <!----> dd <!--- --->

Report this snippet  

Comments

RSS Icon Subscribe to comments
Posted By: killjim01 on October 18, 2014

red bottom heels oakley sunglasses wholesale chi flat iron,chi hair strighteners toms wedges michael kors sale marc jacobs,marc jacobs handbags,marc jacobs bags,marc jacobs outlet moncler jackets christian louboutin,christian louboutin shoes,christian louboutin outlet fitflop coach outlet stores ugg shoes,uggs for cheap,uggs outlet,uggs for kids,ugg boots sale,uggs sale,uggs on sale,ugg gloves,ugg bailey button,ugg boots cheap,ugg moccasins,uggs canada,uggs for women,fake uggs,ugg boots,ugg uk,ugg boots on sale coach factory outlet coach cyber monday 2014,coach cyber monday,cyber monday 2014,cyber monday deals,cyber monday sales,cyber monday,louis vuitton cyber monday 2014,louis vuitton cyber monday,michael kors cyber monday 2014,michael kors cyber monday

You need to login to post a comment.