HTML/XML tag completion in UEStudio '11

HTML/XML tag completion in UEStudio '11

62
Advanced UserAdvanced User
62

    Feb 26, 2016#1

    Hi,

    I have a script for html/xml tag completion. But the script does not work in UEStudio '11.

    Please could somebody help me to modify this script to get it working properly also with UEStudio '11.

    The script is the UltraEdit Tag Completion Script written by Rob Dawson.

    Thanks, Samir

    6,686585
    Grand MasterGrand Master
    6,686585

      Feb 26, 2016#2

      Script does not work in UEStudio '11 does not describe what is not working. Explain on an example what the script should do and what it currently does.

      Is there any error message printed by JavaScript interpreter into the output window because of a syntax error in script or an unknown command or property? Open the output window before executing the script.

      Why do use that script at all? For UltraEdit a scripting solution is needed, but UEStudio has this feature built-in. There is in HTML toolbar of UEStudio the Close Tag command which UltraEdit does not have.

      I restored UEStudio v11.00.0.1009 from an archive, opened an XML file, removed two closing tags on a block and executed the script written by Rob Dawson twice and it worked fine and added the two missing closing tags.
      Best regards from an UC/UE/UES for Windows user from Austria

      62
      Advanced UserAdvanced User
      62

        Mar 05, 2016#3

        Original tag:

        Code: Select all

        <p class="list-item1 parahangblk1"><a id="toc-loc" href="@@@.html#loc"><em>List of Contributors</em></a></p>
        After deleting two closing tags "</a></p>" the result is as follows:

        Code: Select all

        <p class="list-item1 parahangblk1"><a id="toc-loc" href="@@@.html#loc"><em>List of Contributors</em>
        After executed the script written by Rob Dawson twice, the result is as follows:

        Code: Select all

        <p class="list-item1 parahangblk1"><a id="toc-loc" href="@@@.html#loc"><em>List of Contributors</em></a></em>
        Please help me to get the actual result.

        6,686585
        Grand MasterGrand Master
        6,686585

          Mar 05, 2016#4

          I wrote into a *.html file the following three lines:

          Code: Select all

          <p>First paragraph</p>
          <p class="list-item1 parahangblk1"><a id="toc-loc" href="@@@.html#loc"><em>List of Contributors</em>
          <p>Third paragraph</p>
          Then I set caret to end of line 2 and executed the script the first time. The result was:

          Code: Select all

          <p>First paragraph</p>
          <p class="list-item1 parahangblk1"><a id="toc-loc" href="@@@.html#loc"><em>List of Contributors</em></a>
          <p>Third paragraph</p>
          With </a> inserted and caret still blinking at end of second line, I executed the script a second time. The result was:

          Code: Select all

          <p>First paragraph</p>
          <p class="list-item1 parahangblk1"><a id="toc-loc" href="@@@.html#loc"><em>List of Contributors</em></a></p>
          <p>Third paragraph</p>
          So the script is working perfect (using UE v22.20.0.49).
          Best regards from an UC/UE/UES for Windows user from Austria

          62
          Advanced UserAdvanced User
          62

            Mar 10, 2016#5

            But the script is not working properly in UEStudio '11.

            6,686585
            Grand MasterGrand Master
            6,686585

              Mar 13, 2016#6

              I analyzed the script with my/your example with UEStudio v11.00.0.1011 and found out that the script indeed produces the wrong result if there are two start tags with no character between in active file and the end tag for the outer element is missing at current position of the caret.

              The difference on result is caused by the fact that UES v11.00 sets caret to begin of found string on running upwards a Perl regular expression find with search string <[^!%?>][^>]*>, for example beginning of <em>, while UE v22.20.0.49 sets caret to end of string found by the upwards search.

              The difference on search behavior can be easily seen by copying and pasting into a new file:

              Code: Select all

              <p class="list-item1 parahangblk1"><a id="toc-loc" href="@@@.html#loc"><em>List of Contributors</em>
              Now running 3 times a Perl regular expression find in upwards direction with search string <[^!%?>][^>]*> started from end of file results in getting selected
              • with UE v22.20.0.49 the strings </em> and <em> and <a id="toc-loc" href="@@@.html#loc"> with caret each time blinking at end of those 3 strings
              and
              • with UES v11.00.0.1011 the strings </em> and <em> and <a id="toc-loc" href="@@@.html#loc"><em> with caret each time blinking at beginning of those 3 strings.
              The additionally selected <em> causes the wrong result with UES v11.00.

              As it is not possible from within the script to find out if the current version of UE/UES sets caret to begin or end of found string, I introduced a global boolean variable gl_bCaretAtBegin at top of the script after the introducing comment block which must be initialized with value true for UES v11.00 and with false for UE v22.20. And I made some other small improvements on the script written by Rob Dawson.

              Code: Select all

              /*
                   This script adds HTML/XML tag-completion functionality to the UltraEdit text editor. For details
                   of how to install and use UltraEdit scripts see here:
              
                        https://www.ultraedit.com/support/tutorials-power-tips/ultraedit/scripting-engine-tutorial.html
              
                   The script searches backwards through the active document looking for HTML/XML style tags that have
                   been opened but not yet closed - the first such tag that is found will have an appropriate closing
                   tag inserted into the document at the cursor location.
              
                   HTML/XML/JSP comments, CDATA sections, DOCTYPE declarations and special JSP directives / scriptlets /
                   declarations are all ignored.
              
                   The default configuration will ignore the 9 'self-closing' HTML tags contained in the 'ignoredTags'
                   array near the top of the code - when used in an HTML document these tags should not be closed, however
                   in XHTML/XML documents all tags must be closed, so this line should be modified or commented out
                   according to your needs.
              
                   For the latest version of this script visit:
                        http://codebox.org.uk/pages/ultraedit-scripts/html-xml-tag-auto-complete
              
                   For licensing information go to:
                        http://codebox.org.uk/pages/about
              
               */
              
              var gl_bCaretAtBegin = true;
              
              if (CODEBOX === undefined){
                  var CODEBOX = {};
              }
              
              CODEBOX.tagComplete = function(){
                  var closedTags = [], tag, haveRestored = false, parts = [];
                  var whitespaceRegex = /^\s+|\s+$/g;
                  var ignoredTags = ['area', 'base', 'basefont', 'br', 'hr', 'input', 'img', 'link' , 'meta']; // Comment this line out to stop ignoring them
              
                  var doc = UltraEdit.activeDocument;
                  var previousPos = doc.currentPos;
                  var currentPos;
              
               // Remember where we start from
                  var restorePosn = (function(col, line){
                          return function(){
                              doc.gotoLine(line, col);
                              haveRestored = true;
                         };
                     })((typeof(UltraEdit.activeDocumentIdx) == "undefined") ? doc.currentColumnNum + 1 : doc.currentColumnNum, doc.currentLineNum);
              
               // Set up the find options
                  UltraEdit.perlReOn();
                  doc.findReplace.matchCase  = false;
                  doc.findReplace.matchWord  = false;
                  doc.findReplace.regExp     = true;
                  doc.findReplace.searchDown = false;
                  doc.findReplace.mode       = 0;
                  if (typeof(doc.findReplace.searchInColumn) == "boolean"){
                      doc.findReplace.searchInColumn=false;
                  }
              
                  function extractTagName(tag){
                      if (tag.charAt(0) === '/'){
                       // Strip out the leading slash character if its a closing tag
                          tag = tag.substring(1);
                      } else {
                       // Remove any attributes if its an opening tag
                          tag = tag.split(/\s/)[0];
                      }
                      return tag;
                  }
              
                  function isIgnoredTag(tag){
                   // Is this tag one of the 'ignored' ones listed above
                      if (typeof(ignoredTags) !== 'undefined'){
                          tag = extractTagName(tag);
                          for(var i=0, l=ignoredTags.length; i<l; i++){
                              if (ignoredTags[i] === tag){
                                  return true;
                              }
                          }
                      }
                      return false;
                  }
              
                  while (true) {
                      previousPos = currentPos;
                      tag = getNextTag();
                      if (!isIgnoredTag(tag)){
                          currentPos = doc.currentPos;
              
                          if (previousPos <= currentPos){
                           // Our search has hit the top of the document and begun again from the bottom, so stop
                              break;
                          }
              
                          if (tag.length > 0){
                              if (tag.charAt(0) === '/'){
                               // This is a closing tag, eg </div> - push it onto the stack and continue searching
                                  closedTags.push(extractTagName(tag));
              
                              } else if (tag.charAt(tag.length - 1) === '/'){
                               // This is an empty element, eg <div /> - ignore and continue
                              } else {
                               /* If the tag has attributes we want to remove them, so split tag contents on
                                  whitespace and take the first part */
                                  tag = extractTagName(tag);
              
                                  if ((closedTags.length > 0) && (tag === closedTags[closedTags.length - 1])){
                                   /* This is an opening tag but there is already a corresponding closing tag, so just
                                      pop the entry off the stack and continue moving back through the document */
                                      closedTags.pop();
              
                                  } else {
                                   /* This looks like an opening tag that has no corresponding close tag, so move back
                                      to where we started from and write one. */
                                      restorePosn();
                                      doc.write('</' + tag + '>');
                                      break;
                                  }
                              }
                          }
                      }
                  };
              
                  if (!haveRestored) {
                      restorePosn();
                  }
              
                  function getNextTag(){
                   /* Search backwards through the document looking for text inside angle-brackets, ignoring
                      anything that looks like an XML/HTML comment, a CDATA tag, a DOCTYPE declaration, or
                      any of the special JSP directives  */
                      function trim(txt){
                          return txt.replace(whitespaceRegex, '');
                      }
                      doc.findReplace.find("<[^!%?>][^>]*>");
                      var match = doc.selection;
                   // Cancel the selection with caret set at beginning of tag.
                      if (gl_bCaretAtBegin){
                          doc.key("RIGHT ARROW");
                          doc.key("LEFT ARROW");
                      }
              
                      if (match.length > 2){
                       // remove the brackets and just return what's inside
                          return trim(match.substring(1, match.length - 1));
                      } else {
                          return '';
                      }
                  }
              
              };
              
              CODEBOX.tagComplete();
              
              Best regards from an UC/UE/UES for Windows user from Austria

              62
              Advanced UserAdvanced User
              62

                Mar 15, 2016#7

                Thanks Mofi. The script is working perfect now using UES v11, but works very slow on large file.

                I have written a macro solution. The macro solution uses 2 macros.

                First macro with name 1 is:

                Code: Select all

                InsertMode
                ColumnModeOff
                HexOff
                Key Ctrl+HOME
                Loop 9999
                PerlReOn
                Find RegExp "<([a-z][\w-]*)(?: [^>]+?)?/>"
                Replace All ""
                IfNotFound
                ExitLoop
                EndIf
                EndLoop
                Loop 9999
                PerlReOn
                Find RegExp "<([a-z][\w-]*)(?: [^>]+?)?>[^<]*?</\1>"
                Replace All ""
                IfNotFound
                ExitLoop
                EndIf
                EndLoop
                
                The second macro is:

                Code: Select all

                InsertMode
                ColumnModeOff
                HexOff
                SelectToTop
                Copy
                NewFile
                Paste
                Key Ctrl+HOME
                PlayMacro 1 "1"
                Key Ctrl+END
                PerlReOn
                Find RegExp Up "(?<=<)([a-z][\w-]*)"
                ClearClipboard
                Clipboard 2
                Copy
                CloseFile NoSave
                Clipboard 1
                Cut
                Clipboard 1
                Paste
                "</"
                Clipboard 2
                Paste
                ">"
                ClearClipboard
                Clipboard 0
                
                I want this concept for script. How to code the script working like this macro?

                6,686585
                Grand MasterGrand Master
                6,686585

                  Mar 24, 2016#8

                  Well, you could open View - Views/Lists - Tag List. The default tag list file contains the two groups UE/UES Macro Commands and UE/UES Script Commands. The descriptions of the commands existing as macro command and as scripting command are identical.

                  Using the tag list UE/UES Script Commands it should be no problem for you to convert your two macros into a script with a JavaScript function for first macro called from main script code. You should (must) give the JavaScript function a better name than 1.

                  In scripts variables can be used for selected strings instead of using the user clipboards as variable storage. But you can of course also use the user clipboards.

                  Please read also JavaScript tutorial, power tips and more, especially the post with the most common mistakes made on writing a script.
                  Best regards from an UC/UE/UES for Windows user from Austria

                  62
                  Advanced UserAdvanced User
                  62

                    Mar 24, 2016#9

                    I do not know anything about the script environment. I have only recorded manual executions into a macro. Please give as much benefit if you have to script. I want to know more. How to record a script like a macro record in UEStudio?

                    6,686585
                    Grand MasterGrand Master
                    6,686585

                      Mar 24, 2016#10

                      Scripts can't be recorded. Script code must be written in a text editor or IDE. This requires basic skills in writing JavaScript code. The referenced announcement topic contains lots of links to tutorials. Yes, for writing scripts it is necessary to read and learn something as I and every other JavaScript code writer needed also to do. Good luck on extending your skills into area of JavaScript code writing.
                      Best regards from an UC/UE/UES for Windows user from Austria

                      62
                      Advanced UserAdvanced User
                      62

                        Mar 24, 2016#11

                        Thanks for advice.

                        Sure, I am trying to learn JavaScript.