############################################################################### # This is a list of a few handy tasks: # # - Escape HTML Chars (inspired by JohnLBevan's "Escape Characters for HTML") # This script will convert "&", "<", ">" chars to their HTML escaped equivalents. # Deluxe: The affected text is left highlighted so the extent of the changes # is easy to see. # # - Unescape HTML Chars (inspired by JohnLBevan's "Escape Characters for HTML") # This script will convert 3 common HTML escaped character sequences back # to "&", "<", ">". Deluxe: The affected text is left highlighted so the extent # of the changes is easy to see. # # I make these scripts available in the public domain. There are no restrictions on # their use, and no attribution is necessary. No warranty is made. Use at your own risk. # # Author: Rob Favero # ############################################################################### import pn import scintilla from pypn.decorators import script # # Converts "<", ">", and "&" to/from their HTML escaped equivalents. If at least one replacement # occurs, a portion of the text will be highlighted. The highlighted portion will start just # before the first replacement and end just after the last replacement. This is handy to see # exactly what portion of the document was affected by the replacement. # def ReplaceHtmlChars(doEsc): doc = pn.CurrentDoc() if doc is None: return editor = scintilla.Scintilla(doc) start = editor.SelectionStart end = editor.SelectionEnd if (start == end): start = 0 end = editor.Length text = editor.GetTextRange(start, end) if (doEsc): # # Narrow the targeted replacement area to start at the first replacment # and end at the last. # tmpText = text.replace("<", "&").replace(">", "&") nStart = tmpText.find("&") if (nStart < 0): return nEnd = tmpText.rfind("&") + 1 nText = text[nStart:nEnd] # This is now the text from the narrowed # targeted replacement area. start = start + nStart # Adjust start and end end = end - (len(text) - nEnd) modText = nText.replace("&", "&").replace("<", "<").replace(">", ">") else: # # Narrow the targeted replacement area to start at the first replacment # and end at the last. This more more complex than above, because the # strings to be replaced are not all the same size. # nStart = text.find("&") nStartLt = text.find("<") nStartGt = text.find(">") if ((nStart < 0) or ((nStartLt >= 0) and (nStartLt < nStart))): nStart = nStartLt if ((nStart < 0) or ((nStartGt >= 0) and (nStartGt < nStart))): nStart = nStartGt if (nStart < 0): return nEnd = text.rfind("&") nEndLen = 5 nEndLt = text.rfind("<") nEndGt = text.rfind(">") if (nEndLt > nEnd): nEnd = nEndLt nEndLen = 4 if (nEndGt > nEnd): nEnd = nEndGt nEndLen = 4 nEnd = nEnd + nEndLen nText = text[nStart:nEnd] # This is now the text from the narrowed # targeted replacement area. start = start + nStart end = end - (len(text) - nEnd) modText = nText.replace("&", "&", ).replace("<", "<").replace(">", ">") editor.BeginUndoAction() editor.SetSel(start, end) editor.ReplaceSel(modText) editor.SetSel(start, start + len(modText)) editor.EndUndoAction() return # # Converts "<", ">", and "&" to their HTML escaped equivalents. # @script("Escape HTML Chars", "Handy Tasks") def EscHtmlChars(): ReplaceHtmlChars(True) return # # Converts to "<", ">", and "&" from their HTML escaped equivalents. # @script("Unescape HTML Chars", "Handy Tasks") def UnescHtmlChars(): ReplaceHtmlChars(False) return