Align text based on quotes and other delimiters?

Align text based on quotes and other delimiters?

1581
Power UserPower User
1581

    Feb 07, 2016#1

    For example, I have this text:

    Code: Select all

    (COMMAND "_.STYLE" "ARIAL" "ARIAL.TTF" "0" "1" "0" "_N" "_N")
    (COMMAND "_.STYLE" "SIGNUMK" "SIMPLEX.SHX" "0" "0.8" "15" "_N" "_N" "_N")
    
    I want to align the quoted strings in "columns" based on the quotes:

    Code: Select all

    (COMMAND "_.STYLE" "ARIAL"      "ARIAL.TTF"     "0" "1"     "0"     "_N" "_N")
    (COMMAND "_.STYLE" "SIGNUMK"    "SIMPLEX.SHX"   "0" "0.8"   "15"    "_N" "_N" "_N")
    
    Is there a way to get it (semi)-automatically?

    Peter
    UE 26.20.0.74 German / Win 10 x 64 Pro

    6,681583
    Grand MasterGrand Master
    6,681583

      Feb 07, 2016#2

      Yes, this alignment task can be done with an UltraEdit script.

      Code: Select all

      if (UltraEdit.document.length > 0)  // Is any file opened?
      {
         // Is anything selected in active file?
         if (UltraEdit.activeDocument.isSel())
         {
            // Define environment for this script.
            UltraEdit.insertMode();
            if (typeof(UltraEdit.columnModeOff) == "function") UltraEdit.columnModeOff();
            else if (typeof(UltraEdit.activeDocument.columnModeOff) == "function") UltraEdit.activeDocument.columnModeOff();
      
            // Get the current selection loaded into memory.
            var sBlock = UltraEdit.activeDocument.selection;
      
            // Get line termintor type directly from selected text.
            var sLineTerm = "";
            if (sBlock.indexOf("\r\n") >= 0) sLineTerm = "\r\n";
            else if (sBlock.indexOf("\n") >= 0) sLineTerm = "\n";
            else if (sBlock.indexOf("\r") >= 0) sLineTerm = "\r";
      
            // Is at least one line with line termination selected?
            if (sLineTerm.length)
            {
               var asLines = sBlock.split(sLineTerm);
      
               // Is more than just one line with line termination selected?
               if ((asLines.length > 2) || (asLines[1].length))
               {
                  // Find out number of strings and length of each string.
                  var nStringLength;
                  var anLengths = [];
                  var aasStrings = [];
                  var sSpaces = "                    ";
      
                  for (var nLine = 0; nLine < asLines.length; nLine++)
                  {
                     // Skip empty lines.
                     if (!asLines[nLine].length) continue;
      
                     // Get all double quotes strings into an array.
                     var asStrings = asLines[nLine].match(/".*?"/g);
      
                     // Skip lines not containing double quoted strings.
                     if (asStrings == null) continue;
      
                     // Insert in array string left of first double quote.
                     var nFirstQuote = asLines[nLine].indexOf('"');
                     if (nFirstQuote > 0)
                     {
                        // Ignore space left of first double quote.
                        if (asLines[nLine][nFirstQuote-1] == " ")
                        {
                           nFirstQuote--;
                        }
                        asStrings.unshift(asLines[nLine].substring(0,nFirstQuote));
                     }
      
                     // Append to array string right of last double quote.
                     var nLastQuote = asLines[nLine].lastIndexOf('"') + 1;
                     if (nLastQuote < asLines[nLine].length)
                     {
                        // Ignore space right of last double quote.
                        if (asLines[nLine][nLastQuote] == " ")
                        {
                           nLastQuote++;
                        }
                        asStrings.push(asLines[nLine].substring(nLastQuote));
                     }
      
                     // Determine length of each string except the last string
                     // and compare them with already determined string lengths
                     // to keep the largest length of each string.
                     // Build also longest string consisting of only spaces.
                     for (nString = 0; nString < (asStrings.length-1); nString++)
                     {
                        nStringLength = asStrings[nString].length;
                        if (nString >= anLengths.length)
                        {
                           anLengths.push(nStringLength);
                        }
                        else if(anLengths[nString] < nStringLength)
                        {
                           anLengths[nString] = nStringLength;
                        }
                        while(sSpaces.length < nStringLength)
                        {
                           sSpaces += " ";
                        }
                     }
                     aasStrings[nLine] = asStrings;
                  }
      
                  // Append spaces to each line string to align them
                  // depending on longest string with same string index.
                  // Then join the strings together to complete line string.
                  for (var nLine = 0; nLine < asLines.length; nLine++)
                  {
                     if (aasStrings[nLine] == null) continue;
      
                     for (nString = 0; nString < (aasStrings[nLine].length-1); nString++)
                     {
                        var nStringLength = aasStrings[nLine][nString].length;
                        aasStrings[nLine][nString] += sSpaces.substring(nStringLength,anLengths[nString]);
                     }
      
                     asLines[nLine] = aasStrings[nLine].join(" ");
                  }
      
                  // Join the lines together to block string and write this
                  // block into active file overwriting current selection.
                  sBlock = asLines.join(sLineTerm);
                  UltraEdit.activeDocument.write(sBlock);
               }
            }
         }
      }
      
      Let me know if a double quote can exist within a double quoted string using an escape character.
      Best regards from an UC/UE/UES for Windows user from Austria

      1581
      Power UserPower User
      1581

        Feb 07, 2016#3

        Mofi, the miracle-man :wink:

        Great, thanks!

        Small cosmetics:
        The last string in the line, example '"_N")' , gets an unnecessary blank: '"_N" )'
        UE 26.20.0.74 German / Win 10 x 64 Pro

        6,681583
        Grand MasterGrand Master
        6,681583

          Feb 07, 2016#4

          Peter wrote:The last string in the line, example '"_N")' , gets an unnecessary blank: '"_N" )'
          This can be changed by replacing the line:

          Code: Select all

                         asLines[nLine] = aasStrings[nLine].join(" ");
          by

          Code: Select all

                         var nLastIndex = aasStrings[nLine].length - 1;
                         var sLastString = aasStrings[nLine][nLastIndex];
                         aasStrings[nLine].pop();
                         asLines[nLine] = aasStrings[nLine].join(" ") + sLastString;
          
          near end of the script.
          Best regards from an UC/UE/UES for Windows user from Austria

          1581
          Power UserPower User
          1581

            Feb 08, 2016#5

            I don't want to be impertinent, but just now I see that also at the beginning of the line there is an unnecessary blank:

            Code: Select all

            ("P2503" "Diode leer mit Strich" "2503_03" 3 3)
            ->
            ( "P2503" "Diode leer mit Strich" "2503_03" 3 3)
            Not important, more a cosmetic thing.

            Thank you

            Peter
            UE 26.20.0.74 German / Win 10 x 64 Pro

            6,681583
            Grand MasterGrand Master
            6,681583

              Feb 08, 2016#6

              In other words what is left of first double quote and what is right of last double quote should be kept as is on all lines containing double quoted strings. I thought the string left of first double quote can vary in length and must be therefore also aligned with inserting an appropriate number of spaces before first double quoted string on each line. But this was obviously a wrong assumption on the requirements for this alignment task.

              Here is a script simplified a little bit as now the strings at begin and end of each line are kept unmodified.

              Code: Select all

              if (UltraEdit.document.length > 0)  // Is any file opened?
              {
                 // Is anything selected in active file?
                 if (UltraEdit.activeDocument.isSel())
                 {
                    // Define environment for this script.
                    UltraEdit.insertMode();
                    if (typeof(UltraEdit.columnModeOff) == "function") UltraEdit.columnModeOff();
                    else if (typeof(UltraEdit.activeDocument.columnModeOff) == "function") UltraEdit.activeDocument.columnModeOff();
              
                    // Get the current selection loaded into memory.
                    var sBlock = UltraEdit.activeDocument.selection;
              
                    // Get line termintor type directly from selected text.
                    var sLineTerm = "";
                    if (sBlock.indexOf("\r\n") >= 0) sLineTerm = "\r\n";
                    else if (sBlock.indexOf("\n") >= 0) sLineTerm = "\n";
                    else if (sBlock.indexOf("\r") >= 0) sLineTerm = "\r";
              
                    // Is at least one line with line termination selected?
                    if (sLineTerm.length)
                    {
                       var asLines = sBlock.split(sLineTerm);
              
                       // Is more than just one line with line termination selected?
                       if ((asLines.length > 2) || (asLines[1].length))
                       {
                          // Find out number of strings and length of each string.
                          var nStringLength;
                          var anLengths = [];
                          var aasQuoted = [];
                          var asBegin = [];
                          var asEnd = [];
                          var sSpaces = "                    ";
              
                          for (var nLine = 0; nLine < asLines.length; nLine++)
                          {
                             // Skip empty lines.
                             if (!asLines[nLine].length) continue;
              
                             // Get all double quotes strings into an array.
                             var asQuoted = asLines[nLine].match(/".*?"/g);
              
                             // Skip lines not containing double quoted strings.
                             if (asQuoted == null) continue;
              
                             // Insert in array string left of first double quote.
                             var nFirstQuote = asLines[nLine].indexOf('"');
                             asBegin[nLine] = asLines[nLine].substring(0,nFirstQuote);
              
                             // Append to array string right of last double quote.
                             var nLastQuote = asLines[nLine].lastIndexOf('"') + 1;
                             asEnd[nLine] = asLines[nLine].substring(nLastQuote)
              
                             // Determine length of each double quoted string and compare
                             // them with already determined string lengths to keep the
                             // largest length of each string. Build also longest string
                             // consisting of only spaces.
                             for (nString = 0; nString < asQuoted.length; nString++)
                             {
                                nStringLength = asQuoted[nString].length;
                                if (nString >= anLengths.length)
                                {
                                   anLengths.push(nStringLength);
                                }
                                else if(anLengths[nString] < nStringLength)
                                {
                                   anLengths[nString] = nStringLength;
                                }
                                while(sSpaces.length < nStringLength)
                                {
                                   sSpaces += " ";
                                }
                             }
                             aasQuoted[nLine] = asQuoted;
                          }
              
                          // Append spaces to each quoted string to align them
                          // depending on longest string with same string index.
                          // Then join the strings together to complete line string.
                          for (var nLine = 0; nLine < asLines.length; nLine++)
                          {
                             if (aasQuoted[nLine] == null) continue;
              
                             for (nString = 0; nString < aasQuoted[nLine].length; nString++)
                             {
                                var nStringLength = aasQuoted[nLine][nString].length;
                                aasQuoted[nLine][nString] += sSpaces.substring(nStringLength,anLengths[nString]);
                             }
              
                             asLines[nLine] = asBegin[nLine] + aasQuoted[nLine].join(" ") + asEnd[nLine];
                          }
              
                          // Join the lines together to block string and write this
                          // block into active file overwriting current selection.
                          sBlock = asLines.join(sLineTerm);
                          UltraEdit.activeDocument.write(sBlock);
                       }
                    }
                 }
              }
              
              Best regards from an UC/UE/UES for Windows user from Austria

              1581
              Power UserPower User
              1581

                Feb 09, 2016#7

                Mofi wrote:...I thought the string left of first double quote can vary in length and must be therefore also aligned with inserting an appropriate number of spaces before first double quoted string on each line. ...
                Mofi,
                your assumptions were right - my requirements were not precisely enough for what I needed. Big thanks again - now I have two versions of the script and can use them side by side :)

                  Feb 18, 2016#8

                  BTW - here is a challenge for long winter evenings - align in two steps on commas and spaces :idea:

                  Example - Code from AutoHotKey:

                  The basic syntax for example is this:

                  Code: Select all

                  Gui, Add, ControlType [, Options, Text]
                  The parameter(-group) are divided with commas, some are optional and the number of values can differ in a group

                  Code: Select all

                      Gui, Add, Button, xm w70 y370 vWebseite, Web
                      Gui, Add, Button, x+20 w70 gSysteminfo vSysteminfo, Systeminfo
                      Gui, Add, Button, x+20 w70 h30 gEmail vEmail, E-Mail
                  
                  So the commas must be aligned, inside the commas the spaces must be aligned:

                  Code: Select all

                      Gui, Add, Button, xm   w70 y370        vWebseite         , Web
                      Gui, Add, Button, x+20 w70 gSysteminfo vSysteminfo       , Systeminfo
                      Gui, Add, Button, x+20 w70 h30         gEmail      vEmail, E-Mai
                  This example shows the problem that the alignment is not always "logical", but only "visual" (alignment of h.., y.. and g...)

                  This feature is not really important, it is more a "challenge" for people who wants to solve it!
                  UE 26.20.0.74 German / Win 10 x 64 Pro

                  6,681583
                  Grand MasterGrand Master
                  6,681583

                    Mar 28, 2016#9

                    Hello Peter, here is the script code for this special alignment.

                    Code: Select all

                    if (UltraEdit.document.length > 0)  // Is any file opened?
                    {
                       // Is anything selected in active file?
                       if (UltraEdit.activeDocument.isSel())
                       {
                          // Define environment for this script.
                          UltraEdit.insertMode();
                          if (typeof(UltraEdit.columnModeOff) == "function") UltraEdit.columnModeOff();
                          else if (typeof(UltraEdit.activeDocument.columnModeOff) == "function") UltraEdit.activeDocument.columnModeOff();
                    
                          // Get the current selection loaded into memory.
                          var sBlock = UltraEdit.activeDocument.selection;
                    
                          // Get line termintor type directly from selected text.
                          var sLineTerm = "";
                          if (sBlock.indexOf("\r\n") >= 0) sLineTerm = "\r\n";
                          else if (sBlock.indexOf("\n") >= 0) sLineTerm = "\n";
                          else if (sBlock.indexOf("\r") >= 0) sLineTerm = "\r";
                    
                          // Is at least one line with line termination selected?
                          if (sLineTerm.length)
                          {
                             var asLines = sBlock.split(sLineTerm);
                    
                             // Is more than just one line with line termination selected?
                             if ((asLines.length > 2) || (asLines[1].length))
                             {
                                // Find out number of comma and next space separated strings
                                // and get length of each string stored an array (for lines)
                                // containing an array (for comma separated columns) of an
                                // array of strings (separated by spaces).
                                var aanLengths = [];
                                var aaasValues = [];
                                var sMaxIndent = "";
                                var sSpaces = "                    ";
                    
                                for (var nLine = 0; nLine < asLines.length; nLine++)
                                {
                                   // Get position of first character in line not
                                   // being a space or a horizontal tab character.
                                   var nFirstNonWhiteSpace = asLines[nLine].search(/[^\t ]/);
                    
                                   // Has this line leading (indenting) tabs or spaces?
                                   if (nFirstNonWhiteSpace > 0)
                                   {
                                      // Get the indenting whitespaces and keep them if
                                      // this indentation is longer than the previous one.
                                      var sIndent = asLines[nLine].substr(0,nFirstNonWhiteSpace);
                                      if (sIndent.length > sMaxIndent.length) sMaxIndent = sIndent;
                                      // Remove the indenting tabs and spaces from the line.
                                      asLines[nLine] = asLines[nLine].substr(nFirstNonWhiteSpace);
                                   }
                                   else if (nFirstNonWhiteSpace < 0)
                                   {
                                      continue;   // Skip empty and blank lines.
                                   }
                    
                                   // Replace each occurrence of multiple spaces by a single space.
                                   asLines[nLine] = asLines[nLine].replace(/ +/g," ");
                    
                                   // Replace each occurrence of comma + space by a comma.
                                   asLines[nLine] = asLines[nLine].replace(/, /g,",");
                    
                                   // Append an empty column array for this line.
                                   aaasValues[nLine] = [];
                    
                                   // Get strings separated by comma and process them.
                                   var asColumns = asLines[nLine].split(",");
                    
                                   for (var nColumn = 0; nColumn < asColumns.length; nColumn++)
                                   {
                                      // Append an empty string array for this column.
                                      aaasValues[nLine][nColumn] = [];
                    
                                      // Has this line more comma separated columns than all
                                      // previous lines? Yes, append an empty lengths array.
                                      if (nColumn >= aanLengths.length)
                                      {
                                         aanLengths[nColumn] = [];
                                      }
                    
                                      // Get strings separated by space and process them.
                                      var asStrings = asColumns[nColumn].split(" ");
                    
                                      for (var nString = 0; nString < asStrings.length; nString++)
                                      {
                                         // Store this string in values array with all strings.
                                         aaasValues[nLine][nColumn][nString] = asStrings[nString];
                    
                                         // Get length of this string.
                                         var nLength = asStrings[nString].length;
                    
                                         // Has the column of this line more strings
                                         // than same column in all previous lines?
                                         if (nString >= aanLengths[nColumn].length)
                                         {
                                            // Yes, append this length to the array.
                                            aanLengths[nColumn][nString] = nLength;
                                            // If necessary make the spaces string longer.
                                            while (nLength > sSpaces.length) sSpaces += " ";
                                         }
                                         // Is this string in this column longer than
                                         // all previous space separated strings at
                                         // this postion in this comma separated column?
                                         else if (nLength > aanLengths[nColumn][nString])
                                         {
                                            // Yes, this is a greater length than before.
                                            aanLengths[nColumn][nString] = nLength;
                                            // If necessary make the spaces string longer.
                                            while (nLength > sSpaces.length) sSpaces += " ";
                                         }
                                      }
                                   }
                                }
                    
                                // Maximum length for each space separated string in
                                // each comma separated column determined. Reconstruct
                                // the lines taking the maximum lengths into account.
                                for (var nLine = 0; nLine < asLines.length; nLine++)
                                {
                                   // Again skip empty and blank lines.
                                   if (aaasValues[nLine] == null) continue;
                    
                                   // Each line starts now with maximum identation.
                                   var sLine = sMaxIndent;
                    
                                   // Process each comma separated column of this line.
                                   for (nColumn = 0; nColumn < aaasValues[nLine].length; nColumn++)
                                   {
                                      // Except on first column append first comma + space
                                      // before the strings of this column are appended.
                                      if (nColumn > 0) sLine += ", ";
                    
                                      // Process each string in current column and line.
                                      nString = 0;
                                      while (nString < aaasValues[nLine][nColumn].length)
                                      {
                                         // Except on first string of column append first a
                                         // space. Next append the stored string to the line.
                                         if (nString > 0) sLine += ' ';
                                         var sValue = aaasValues[nLine][nColumn][nString];
                                         sLine += sValue;
                    
                                         // Determine the number of spaces which need
                                         // to be additionally appended for this string.
                                         var nSpacesToAdd = aanLengths[nColumn][nString] - sValue.length;
                                         if (nSpacesToAdd > 0)
                                         {
                                            // Appended the alignment spaces.
                                            sLine += sSpaces.substr(0,nSpacesToAdd);
                                         }
                                         nString++;
                                      }
                    
                                      // It could be that the current column in current line has
                                      // less strings than another line and therefore append even
                                      // more spaces if that is necessary for proper alignment.
                                      while (nString < aanLengths[nColumn].length)
                                      {
                                         sLine += ' ';
                                         sLine += sSpaces.substr(0,aanLengths[nColumn][nString]);
                                         nString++;
                                      }
                                   }
                    
                                   // Replace line in array by reconstructed line with
                                   // removing additionally all not needed trailing spaces.
                                   asLines[nLine] = sLine.replace(/ +$/,"");
                                }
                    
                                // Join the lines to a single string and write this
                                // string over the selected lines in active file.
                                UltraEdit.activeDocument.write(asLines.join(sLineTerm));
                             }
                          }
                       }
                    }
                    
                    Best regards from an UC/UE/UES for Windows user from Austria

                    1581
                    Power UserPower User
                    1581

                      Jul 07, 2016#10

                      Thanks Mofi

                      it seems that I missed the notification of your reply.
                      UE 26.20.0.74 German / Win 10 x 64 Pro