9 Replies Latest reply on May 19, 2013 7:34 AM by Trevorׅ

    [CS5.5][JS] Delete character located before search result

    JohnDevlon Level 1

      Hi,

       

      I have a small question.

       

      I would like to delete all spaces before all text tagged with a specific character style.

       

      Example: "Appel:[SPACE][BEGIN CHAR STYLE FRUIT]5 pieces[END CHAR STYLE FRUIT]

       

      I would like to delete the space...

       

      A piece of my code:

       

                   app.findTextPreferences = NothingEnum.nothing;

                   app.findTextPreferences.appliedCharacterStyle = "FRUIT"

       

                    myResultsList = app.activeDocument.findText();                                                     

       

                    for (var k =myResultsList.length-1; k > -1; k = k -1) {

       

                               // How do I delete the space before the result ?

       

                     }

       

      Does aynone have any idea?

       

      Thanks

       

      John

        • 1. Re: [CS5.5][JS] Delete character located before search result
          JohnDevlon Level 1

          Hi,

           

          For those who are interested: I found a solution:

           

                       app.findTextPreferences = NothingEnum.nothing;

                       app.findTextPreferences.appliedCharacterStyle = "FRUIT"

           

                        myResultsList = app.activeDocument.findText();                                                     

           

                        for (var k =myResultsList.length-1; k > -1; k = k -1) {

                                     var myLocation = myResultsList[k].insertionPoints[0].index;

                                     var myCharacters = myResultsList[k].parentTextFrames[0].characters;

                                     myCharacters.itemByRange(myLocation-1,1).remove();

                         }

           

          John

          • 2. Re: [CS5.5][JS] Delete character located before search result
            Jump_Over Level 5

            Hi,

             

            What about 2 steps:

            //1st step to find replace inserting some "original" chars combination:
            // let say: em-space en-space
            app.findGrepPreferences = app.changeGrepPreferences = NothingEnum.nothing;
            app.findGrepPreferences.appliedCharacterStyle = "FRUIT";
            app.findGrepPreferences.findWhat = ".+";
            app.changeGrepPreferences.changeTo = "~m~>$0";
            app.activeDocument.changeGrep();
            
            // 2nd step to remove spaces with "original" combination
            app.findGrepPreferences = app.changeGrepPreferences = NothingEnum.nothing;
            app.findGrepPreferences.findWhat = "\\s+~m~>";  // I edited this cause used wrong slash
            app.changeGrepPreferences.changeTo = "";
            app.activeDocument.changeGrep();
            

             

            rgds

            Jarek

             

            Message was edited by: Jump_Over

            • 3. Re: [CS5.5][JS] Delete character located before search result
              Trevorׅ Adobe Community Professional

              Hi J & J,

               

              I have a bit of a problem with both the scripts here.

              Jarek's is obviously going to be very quick but it presumes there is no local formatting on the FRUIT style words i.e. no bold / italics / color / underline overrides applied to those texts. If that is the case then his script (maybe with a more original original combination) IS they way to go. If not then not!

               

              John, I don't understand how the script you found could possibly work.

              There are 2 major bugs with it.

               

              var myCharacters = myResultsList[k].parentTextFrames[0].characters;

              myCharacters.itemByRange(myLocation-1,1).remove();

              must be changed to

              var myCharacters = myResultsList[k].parentStory.characters;

              myCharacters.itemByRange(myLocation-1, myLocation).remove();

               

              Using parentTextFrames is not a good idea because it's going to fail on treaded textframe, the index give the character possiosion from the start of the story and not the start of the textframe.

              having itemByRange(myLocation-1,1).remove() is going to remove from the find until the second character in the story. I understood you just want to remove the space(s) before the style!

              This brings to a 3rd problem in your script that it removes the (once fixed up) any character that precedes the style regardless of whether or not it is a space.

               

              Anyway my way of doing it would be with one of these 2 functions depending on wether there is always a space before the fruit style or not.

              It will only remove spaces (not returns or other characters) that precede the style.

               

              The first function "removeCharacterBeforeStyle" is the equivalent of your corrected one but scripted better (at least in my humble opinion)

               

              // http://forums.adobe.com/thread/1213463?tstart=0word.
              // Removes  letter / spaces before a character style
              app.doScript("removeAllSpacesBeforeStyle()", ScriptLanguage.javascript, undefined, UndoModes.ENTIRE_SCRIPT);
              //app.doScript("removeCharacterBeforeStyle()", ScriptLanguage.javascript, undefined, UndoModes.ENTIRE_SCRIPT);
              
              function removeCharacterBeforeStyle() {
                  // to delete ANY character that precedes the FRUIT style. short and sweet :-)
                  app.findTextPreferences = null;
                  app.findTextPreferences.appliedCharacterStyle = "FRUIT";
                  var  myFinds =  app.documents[0].findText(),
                         l = myFinds.length, pos;
                  while (l--)   myFinds[l].parentStory.characters.itemByRange (pos = myFinds[l].insertionPoints[0].index-1, pos++).remove();
              };
              
              
              function removeAllSpacesBeforeStyle() {
                  // This will delete spaces (including hairspaces), tabs etc. but not returns that precedes the FRUIT style
                  // see http://www.indiscripts.com/post/2011/09/what-exactly-is-a-word for hairspace and other potential issues
                  // not so short and not so sweet :-(
                  // but does the job without messing up most of the local overrides of the character style |:-)
                  var doc = app.documents[0];
                  app.findTextPreferences = app.changeTextPreferences = null;
                  app.findTextPreferences.findWhat = "^|"; // this is one way of dealing with hairline spaces (warning their format will get messed up)
                  app.changeTextPreferences.changeTo = "^4^4^4^4^3";
                  doc.changeText();
                  app.findTextPreferences = null;
                  app.findTextPreferences.appliedCharacterStyle = "FRUIT";
                  var  myFinds = doc.findText(),
                         l = myFinds.length,
                         ps, find_CharacterInStoryIndex, find_WordInStoryIndex, StartOfGap, EndOfGap;
                  app.findTextPreferences = app.findGrepPreferences = app.changeGrepPreferences = null;
                  app.findGrepPreferences.findWhat = "((?![\\r\\n])\\s)+"; // find spaces that are not returns about the same as "[~m~>~f~S~s~<~/~.~3~4~%\\x{20}~|\\t]+" I have not compaired the speeds
                  while (l--)  {
                      ps = myFinds[l].parentStory;
                      find_CharacterInStoryIndex = myFinds[l].insertionPoints[0].index-1;         
                      if ((find_WordInStoryIndex = ps.words.itemByRange(ps.words[0], myFinds[l].words[0]).words.length-2) <0) continue; 
                      // the 'if' checks that the find is not the first word in the story if it was the ALL the spaces in the whole story would be removed
                      StartOfGap = ps.words[find_WordInStoryIndex].insertionPoints[-1].index;
                      EndOfGap = ps.words[find_WordInStoryIndex+1].index-1;
                      // if the FRUIT style starts at the beginning  of a word remove spaces before that word
                      if (find_CharacterInStoryIndex == EndOfGap)  ps.characters.itemByRange(StartOfGap,EndOfGap).changeGrep(); 
                  }
                  app.findTextPreferences.findWhat = "^4^4^4^4^3"; // put the hairspaces back
                  app.changeTextPreferences.changeTo = "^|";
                  doc.changeText();
                  app.findTextPreferences  = app.changeTextPreferences = app.findGrepPreferences = null;
              }
              

              Regards

               

              Trevor

               

              P.s. If you don't have hairspaces (and you probably don't) the you could for aesthetic reasons remove at least 6 lines of the code.

              • 4. Re: [CS5.5][JS] Delete character located before search result
                Jump_Over Level 5

                Hi Trevor,

                ~ Trevor ~ wrote:

                 

                [...] it presumes there is no local formatting on the FRUIT style words i.e. no bold / italics / color / underline overrides applied to those texts. If that is the case then his script (maybe with a more original original combination) IS they way to go. If not then not! [...]

                 

                Can't agree (at least in my humble opinion)

                1. Does local formatting remove applied charStyle?

                2. Does app.findGrepPreferences.appliedCharacterStyle pass over this "modified" part of text?

                 

                Answers are NO && NO so this script has a preety BIG chance to go

                It fails of course if local formatting means some other charStyle is applied but an input condition was IS APPLIED not WAS APPLIED.

                 

                Jarek

                PS. I am also afraid that John's script works BUT only with his specific textFrame's contents, which wasn't described deep enough.

                • 5. Re: [CS5.5][JS] Delete character located before search result
                  Trevorׅ Adobe Community Professional

                  Hi Jarek,

                   

                  Sorry to say but your script because it uses the $0 to replace it's own text does remove / move / change local formatting on the replaced word.

                  See the screen shots of my test document

                  look at the numbers 3 till 8 and spot the difference

                   

                  Before running a script

                  Before.png

                   

                  After running your script - local formatting changed

                  After J.png

                   

                  After running my script - local formatting not changed

                  After T.png

                   

                  I still can't undestand how John script could possible work, can you give a example case were it would work.

                  • 6. Re: [CS5.5][JS] Delete character located before search result
                    Jump_Over Level 5

                    Hi Trevor,

                     

                    In case of overridding local formatting I agree. I didn't consider this, so you are right.

                     

                    in case of John's script; an example when it should work is:

                    - all these found texts are located in separated text frames (maybe data merge proceeded)

                    - all these frames starts with some space to be removed -  followed by FRUIT style - followed by any other text

                    so John's script removes character range from "found" -1 back to 1 (one space left)

                     

                    Do you agree?

                     

                    Jarek

                    • 7. Re: [CS5.5][JS] Delete character located before search result
                      Trevorׅ Adobe Community Professional

                      Hi Jarek,

                       

                      JohnDevlon wrote:

                       

                      Example: "Appel:[SPACE][BEGIN CHAR STYLE FRUIT]5 pieces[END CHAR STYLE FRUIT]

                       

                      Well in a case that you describe It would work.

                       

                      But I understand from John's example that the Idea is to remove the space after the colon after the name of the fruit and before the quantity of fruit.

                      I.e the space after Appel: (Apple?)

                       

                      As to my knowledge and I'm very sure about it, all fruit names contain at least 1 letter so "a: 5 pieces" would become "a5 pieces" and not "a:5 pieces" as he wanted.

                      In truth as most fruit names contain more that 1 letter the results would be pretty bad.

                       

                      However in all honesty I do think your script is highly likely to be the best solution in the real case situation.

                      Only the  overrides which are not applied to the whole style (line 2) will get lost so as long as John is aware of the issue and knows that it doesn't affect his document he should use your method. If it is an issue he should use mine.

                      Before J2.pngAfter J2.png

                       

                      @ HEY JOHN !

                       

                      What did you do in the end?

                      Whose script did you end up using? Please mark it as correct.

                      Do your fruit name have more than 0 letters in them? (sorry about that one, I'm feeling a bit of a fruit and nut today )

                       

                      Regards to all,

                       

                      Trevor

                      • 8. Re: [CS5.5][JS] Delete character located before search result
                        JohnDevlon Level 1

                        Hi Trevor and Jarek,

                         

                        Thanks for all your great feedback. I learned a lot.

                         

                        Each approach has it own strong points, and in the future, I will certainly consider one of both solutions.

                         

                        In the end, I went for a modified approach of my own solution...

                         

                                     app.findTextPreferences = NothingEnum.nothing;

                                     app.findTextPreferences.appliedCharacterStyle = "FRUIT"

                         

                                      myResultsList = app.activeDocument.findText();                                                    

                         

                                      for (var k =myResultsList.length-1; k > -1; k = k -1) {

                                                   var myLocation = myResultsList[k].insertionPoints[0].index;

                                                   var myCharacters = myResultsList[k].parentStory.characters;

                                                   var myChar = myCharacters.itemByRange(myLocation-1,myLocation-1);

                         

                                                   if (myChar.contents == " "){

                                                        myChar.remove();

                                                   }

                         

                                       }

                         

                        I noticed that there were still a few bugs in the script, so I changed it a little...

                        It is still not perfect or as sophisticated as your provided solutions. It will not remove all the different type of spaces, but in the document I was working on, it was not the case.

                         

                        The feedback of Trevor regarding to the parentStory helpt a lot.

                         

                        Thanks again Trevor and Jarek for all your all great insights... I will certainly recommend using your provided solutions in the future.

                         

                        John

                        • 9. Re: [CS5.5][JS] Delete character located before search result
                          Trevorׅ Adobe Community Professional

                          Hi John,

                           

                          Nice solution, but just because I (as well known) suffer from "Can't keep my gob shut - itis"

                          When you are only refering to "one" "whatever" you don't have to use itemByRange so you can condence your whole for loop to this.

                           

                          for (var k =myResultsList.length-1; k > -1; k--)  if ((myChar =  myResultsList[k].parentStory.characters [myResultsList[k].index-1]).contents == " ") myChar.remove();
                          

                           

                          Glad we helped.