21 Replies Latest reply on Feb 19, 2013 1:48 PM by MrTIFF

    FindChangebyList with strings of text?

    dmmgina99

      I'm trying to setup a findchangebylist document to change strings of text to match my company's verbiage. I've been successful changing items like:  $10.00 to read as $10 but I cannot get regular text like:  over-sized to read as oversized

       

      More examples of text I'm trying to convert:

      over-sized to oversized

      CAT to CAT(R)   (adding the registration mark)

      screenprint to screen print

       

      Is this possible with this script?? There's over 100 words that follow this mindset. The custom dictionary isn't something that works, as it only checks for single words and not 2 words with a space inbetween.

       

      Anything would be helpful.

      Thanks!

        • 1. Re: FindChangebyList with strings of text?
          nukleas Level 1

          Indeed! Assuming you're adding lines to your FindChangeList.txt, you can do as follows using GREP:

           

          NOTE: Spaces between grep and bracketed statements should be a tab

           

          grep     {findWhat:"(over)(-)(sized)"}     {changeTo:"$1$3"}     {includeFootnotes:true, includeMasterPages:true, includeHiddenLayers:true, wholeWord:true}

           

          What this does is find the word over-sized, split it into three groups ($1=over, $2=-, $3=sized) and only places the $1 and $3 in the replace, nixing the hyphen and preserving the word.

           

          And lets say you want to close up any form of the prefix over- :
          grep     {findWhat:"(over)(-)(\\S*?)"}     {changeTo:"$1$3"}     {includeFootnotes:true, includeMasterPages:true, includeHiddenLayers:true, wholeWord:true}

           

          The (\\S*?) finds all non-whitespace characters (\\S is a non-whitespace character, * means zero (or one, i forget) or more matches, and the ? at the end tells it to not be too greedy and grab too much stuff. More precautionary than anything, someone can correct me if i should/shouldn't add it.

           

          Now, this will catch all forms of over-, but not capitalized versions of it. That's why we can add:

           

          grep     {findWhat:"([O|o]ver)(-)(\\S*?)"}     {changeTo:"$1$3"}     {includeFootnotes:true, includeMasterPages:true, includeHiddenLayers:true, wholeWord:true}

           

          This now makes it so you can start the word with an O or an o, (the logic is [a|b] means a OR b.) so if its in the beginning of a sentence, we're still good.

           

          Now let me assume you dont want some things such as offical titles and numbers to remove the hyphen, such as Over-Sized Ordering System or over-200.

           

          In this case, we can add something like so:

          grep     {findWhat:"([O|o]ver)(-)(?!\\u|\\d)(\\S*?)"}     {changeTo:"$1$3"}     {includeFootnotes:true, includeMasterPages:true, includeHiddenLayers:true, wholeWord:true}

           

          (?!\\u|\\d) split up is (?! ), which is a negative lookahead. So if there's a \u (uppercase character) or \d (digit) after the over-, don't match that.

           

          Now, if you wanted to use these queries in the Ctrl-F GREP dialog, just replace the double backslashes with single ones. This is because they need to be properly escaped in the .txt file but not in the query panel.

           

          We can apply these examples to your other queries:

           

          CAT to CAT(R)   (adding the registration mark)

           

          grep     {findWhat:"CAT"}     {changeTo:"CAT~r"}     {includeFootnotes:true, includeMasterPages:true, includeHiddenLayers:true, wholeWord:true}

           

          (~r is the symbol for registered copyright symbol, it can be found in the cntrl-F dialog.)

           

          screenprint to screen print

           

          grep     {findWhat:"([S|s]creen) (print)"}     {changeTo:"$1$2"}     {includeFootnotes:true, includeMasterPages:true, includeHiddenLayers:true, wholeWord:true}

           

           

           

          If anything is unclear, please let me know!

          • 2. Re: FindChangebyList with strings of text?
            Trevorׅ Adobe Community Professional

            Hi Nukleas

             

            I know this is a bit of an old post I was searching for something and came across this post (I was not what I was looking for)

             

            Greps is not the way to go about this!

            A simple find change text is much more appropriate in this case.

             

            either set up an  array like this and loop though it

             

            app.findTextPreferences = app.changeTextPreferences = null;
            app.findChangeTextOptions.caseSensitive = 0;
            app.findChangeTextOptions.wholeWord = 1;
            myChanges = 
            [
            'over-sized' , 'oversize',
            'pussy cat' , 'pussy',
            'CAT' , 'CAT®',
            ];
            
            for (var c=0; c<myChanges.length;)
            {
            app.findTextPreferences.findWhat = myChanges[c];
            app.changeTextPreferences.changeTo = myChanges[c+1];
            app.documents[0].changeText(1);
            c+=2;
            }
            

             

            or make a 2 column (change from, change to) excel file and get the script to make an array from the file.

             

            Regarding cases sensiteve words like CAT best to stick them in a seperate array and make app.findChangeTextOptions.caseSensitive = 1.

             

            One has to be particular to put the two word item before the one word subset i.e. pussy cat before cat otherwise pussy cat will become pussycat®

             

            Trevor

            • 3. Re: FindChangebyList with strings of text?
              nukleas Level 1

              Hi Trevor:

               

              A simple text change may be appropriate in some cases, and it really depends on the extent of the company style discussed before. I used the FindChangeReplace script examples as that was part of the question, but writing a separate script works as well (and probably reads a lot clearer too)

               

              There is the conflict of case sensitivity and some words you don't want to close up. A good example of this is in official titles (So you don't want to close up Over-All Program Goals 2012, but you are fine closing up over-all goals or over-stated nature. Also, if whole word is turned on in the given regular text search example, over-size will not be converted to oversize. over-sized would be converted to oversize. A decent grep example will close them all up and save for exceptions, such as if the companies want to keep over-reaching (you can have the search ignore over- followed by an r-word, for example) or not closing up over-the-counter.

               

              This is also a concern copy editors have with closing up schoolteacher. In most cases it's fine, until you have a teacher that works at a high school. A high school teacher should probably not be written as high schoolteacher (although I'm sure some of them need to be to deal with some of today's youth.) and that's only really avoidable with a negative lookbehind.

               

              However, if these are not of too much concern, a simpler script is not a bad idea.

               

              Thank you Trevor for your input.

              • 4. Re: FindChangebyList with strings of text?
                Trevorׅ Adobe Community Professional

                Hi Nukleas,

                 

                 

                nukleas wrote:

                 

                There is the conflict of case sensitivity and some words you don't want to close up. A good example of this is in official titles (So you don't want to close up Over-All Program Goals 2012, but you are fine closing up over-all goals or over-stated nature.

                By adding a tag at the begining of words one wants to be stictly case sensertive one can deal with this

                By useing slice and toUpperCase() one can make sure that over-sized becomes oversized and Over-sized becomes Oversized.

                 

                In the case that one only wants the upper case to be changed that would not need tagging i.e. in our example only CAT would become CAT®, cat would stay the same.

                 

                To avoid Over-All being closed one also would not need to tag it because of the capitol A of All.

                One would only need to tag something like Over-all if one did not want it to become Overall but wanted over-all to become overall.

                nukleas wrote:

                 

                Also, if whole word is turned on in the given regular text search example, over-size will not be converted to oversize. over-sized would be converted to oversize.

                True, over-size would not be converted to oversize unless over-size was included in the word list.

                False, over-sized would be converted to oversized and not oversize

                 

                nukleas wrote:

                 

                A decent grep example will close them all up and save for exceptions, such as if the companies want to keep over-reaching (you can have the search ignore over- followed by an r-word, for example) or not closing up over-the-counter.

                This is true that if you want all over- followed by non r-words to be closed up it's going to be easier by grep, see change in script bellow that allows for greps to be included in the array , again by use of a tag.

                 

                nukleas wrote:

                 

                This is also a concern copy editors have with closing up schoolteacher. In most cases it's fine, until you have a teacher that works at a high school. A high school teacher should probably not be written as high schoolteacher (although I'm sure some of them need to be to deal with some of today's youth.) and that's only really avoidable with a negative lookbehind.

                This can easily be dealt with by adding in the array after the entry of ' school teacher'  , 'schoolteacher'

                'high schoolteacher' , 'high school teacher'

                see script below

                 

                 

                Sorry for lecturing like an over-reacting high school teacher ,

                 

                Regards

                 

                Trevor

                 

                // Made by Trevor http://forums.adobe.com/message/4602248#4602248
                
                app.findTextPreferences = app.changeTextPreferences = null;
                app.changeGrepPreferences = app.findGrepPreferences = null;
                app.findChangeTextOptions.caseSensitive = 0;
                app.findChangeTextOptions.wholeWord = 1;
                myDoc = app.documents[0];
                myChanges = 
                [
                'over-sized' , 'oversize',
                '`pussy cat' , 'pussy', // Pussy cat will stay Pussy cat because of the ` tag
                'CAT' , 'CAT®',
                'school teacher' , 'schoolteacher',
                'high schoolteacher' , 'high school teacher',
                ';(never)\\-(?=\\S)' , '$1' // Because of the ; (semicolon) tag will be dealt with as a grep
                ];
                
                for (var c=0; c<myChanges.length;)
                {
                if  (myChanges[c][0] != "`" && myChanges[c][0] != ";")
                {
                    app.findTextPreferences.findWhat = myChanges[c];
                    app.changeTextPreferences.changeTo = myChanges[c+1];
                    myDoc.changeText();
                    capitalChangeFrom =  myChanges[c][0].toUpperCase() + myChanges[c].slice(1,myChanges[c].length);
                    capitalChangeTo =  myChanges[c+1][0].toUpperCase() + myChanges[c+1].slice(1,myChanges[c+1].length);
                    app.findTextPreferences.findWhat = capitalChangeFrom;
                    app.changeTextPreferences.changeTo = capitalChangeTo;
                    myDoc.changeText();
                }
                else if (myChanges[c][0] != ";")
                {
                    app.findTextPreferences.findWhat = myChanges[c].slice(1,myChanges[c].length);
                    app.changeTextPreferences.changeTo = myChanges[c+1];
                    myDoc.changeText();
                }
                else
                {
                    app.findGrepPreferences.findWhat = myChanges[c].slice(1,myChanges[c].length);
                    app.changeGrepPreferences.changeTo = myChanges[c+1];
                    myDoc.changeGrep();
                }
                c+=2;
                }
                
                • 5. Re: FindChangebyList with strings of text?
                  nukleas Level 1

                  Hi Trevor:


                  I have to admit, I like your script (The syntax for the arrays is pretty clean, esp. with the tags) but we don't need to completely reinvent the wheel, and we have a lot of functionality within the FindChangeReplace script that wouldn't need too many more additions.

                   

                   

                  nukleas wrote:

                   

                  There is the conflict of case sensitivity and some words you don't want to close up. A good example of this is in official titles (So you don't want to close up Over-All Program Goals 2012, but you are fine closing up over-all goals or over-stated nature.

                  By adding a tag at the begining of words one wants to be stictly case sensertive one can deal with this

                  By useing slice and toUpperCase() one can make sure that over-sized becomes oversized and Over-sized becomes Oversized.

                   

                  In the case that one only wants the upper case to be changed that would not need tagging i.e. in our example only CAT would become CAT®, cat would stay the same.

                   

                  To avoid Over-All being closed one also would not need to tag it because of the capitol A of All.

                  One would only need to tag something like Over-all if one did not want it to become Overall but wanted over-all to become overall.

                   

                  True, but why don't we just add this to FindChangeReplace:

                   

                  grep     {findWhat:"(Over|over)-(?!\\u|\\d)(\\S*)"}     {changeTo:"$1$2"}     {includeFootnotes:true, includeMasterPages:true, includeHiddenLayers:true, wholeWord:true}
                  

                   

                  This way we don't need to write any more javascript code, and we preserve the features from that script, especially the option to do the search on individual stories or selections rather than the whole document, which is default for the script (I see these things usually from an inCopy standpoint, where you are working closely with the text) Having an easily editable text document as a list of things is probably not a bad idea either.

                   

                  We also catch any hyphenations of digits (which we ought to keep hyphenated) or uppercase letters and keep whatever formatting existed previously with a single entry.

                   

                  nukleas wrote:

                   

                  Also, if whole word is turned on in the given regular text search example, over-size will not be converted to oversize. over-sized would be converted to oversize.

                  True, over-size would not be converted to oversize unless over-size was included in the word list.

                  False, over-sized would be converted to oversized and not oversize

                   

                   

                  Check the spelling in the script >.> (Yes, this is kinda pedantic, I apologize)

                   

                  nukleas wrote:

                   

                  This is also a concern copy editors have with closing up schoolteacher. In most cases it's fine, until you have a teacher that works at a high school. A high school teacher should probably not be written as high schoolteacher (although I'm sure some of them need to be to deal with some of today's youth.) and that's only really avoidable with a negative lookbehind.

                  This can easily be dealt with by adding in the array after the entry of ' school teacher'  , 'schoolteacher'

                  'high schoolteacher' , 'high school teacher'

                  see script below

                  Or in one line:

                   

                  grep {findWhat:"(?<![high|elementary|middle] )([S|s]chool) (teacher)"} {changeTo:"$1$2"}     {includeFootnotes:true, includeMasterPages:true, includeHiddenLayers:true, wholeWord:true}
                  

                   

                  Using the FindChangeReplace, we basically configure the text or grep search each time, so if we want, we can have something like this:

                   

                  Makes million/billion/trillion units not break over lines:

                   

                  grep     {findWhat:"(\\d+) (mil|bil|tril)(?=lion)"}     {changeTo:"$0",noBreak:true}     {includeFootnotes:true, includeMasterPages:true, includeHiddenLayers:true, wholeWord:true}
                  

                   

                  This way we don't need to set about defining tags, since the way the script is written we can just call them when we need them.

                   

                  And in this case, wouldn't we be in trouble if the query we wanted has a semicolon or something at the beginning of it? This can be the case in changing delimiters and other things. By defining options outside of the query, we better sanitize the query from errant symbols.

                   

                  I think it might be best to also avoid changing things in the first place (like school teacher to schoolteacher and then backtrack with high schoolteacher to high school teacher) and the more exceptions or backtracks we need to make, the more likely errors will make it through.

                   

                  Then again, for some, if not most changes that need to be made without exceptions, regular text search is fine. However, there can be a lot more errors introduced without lookaheads or lookbehinds than it could be worth, and this is one of the things that keeps copy editors like me employed

                   

                  Also, with the script, why keep Pussy cat if it begins the sentence? The example would be perhaps the Pussy Cat Lounge, in that case you dont want to close that up or change that. However: Pussy cat is another term for a feline. Would not get changed, but it ought to. The script catches school teachers and high school teachers correctly, but not "School teachers are important to our nation" and (correctly) School Teacher's Association. These may need different capitalized versions of each type, or would possibly be better with grep and just brackets with both types alone. Case insensitivity in the grep can also preserve the capitalization of the original text, whereas I believe the text replace would change it to whatever the result is that is provided.

                   

                  grep     {findWhat:"([pP]ussy) (cat)"}     {changeTo:"$1"}     {includeFootnotes:true, includeMasterPages:true, includeHiddenLayers:true, wholeWord:true}
                  

                   

                  (and the problem with this, that I would have to get to later, is that the plurals need to be dealt with)

                   

                  All in all, I don't think it truly matters whether one uses GREP or text for such changes (it's actually best to know both!) and I appreciate you laying out how to perform these searches using javascript, I have definitely learned from it!

                   

                  I apologize for any errors, I typed this quite fast D:

                   

                  Many thanks Trevor,

                   

                  Nukleas

                  • 6. Re: FindChangebyList with strings of text?
                    Trevorׅ Adobe Community Professional

                    Hi again Nukleas,

                     

                    There's a few points that you wrote that I could debate about but I'll focus briefly on two of them.

                     

                    1) For sure Greps are an essential part of indesign and without a thorough knowledge of them one is unknowing severely handicapped in the program.

                    However the fact is (I think) that the average user knows diddlysquat about them.

                    To me a greps used to be just a burp (greps is the Yiddish word for a burp) but comparably recently I learnt up the topic, read up Peter Karhels excellent book http://shop.oreilly.com/product/9780596156015.do asked a couple of questions on the forum and now am quite a smarty-pants on the topic .

                     

                    To expect the average user to make a list of 100+ greps without messing up majorly is a bit unrealistic.

                     

                    To illustrate lets take the school teacher example

                     

                    Your Grep is

                    grep {findWhat:"(?<![high|elementary|middle] )([S|s]chool) (teacher)"} {changeTo:"$1$2"}     {includeFootnotes:true, includeMasterPages:true, includeHiddenLayers:true, wholeWord:true}

                     

                    This is not correct, you have combined a negative lookbehind with a [character class] with | or in it using words.

                    There's a bunch of mistakes in that.

                    The expression you wrote is the same as "(?<![adeghilmntry|] ) ([S|s]cool) (teacher)"

                    There are no "|" or statements in a character classes and no limitation to the order or repetitiveness of the characters in them.

                     

                    In other words we wanted to achieve that the words school teacher will be joined unless preceded by the words high, elementary or middle but your greps going to not join "the school teacher"  that's quite a nasty exception worse still in not going to join "the mad school teacher" it's not even going to join the "nutty school teacher" even though there's no "u" in the character class  because of the "y" of nutty is in list. As long  the last letter is in the character class it's going to return a true value (each character in it list is considered as separated by an or).

                     

                    The correct grep expression to use would be

                    ((?<![Hh]igh\s)(?<![Mm]iddle\s)(?<![Ee]lementary\s))([S|s]chool)\s(teacher)

                    change to $2$3

                     

                    This means join any School or school teacher that are not preceded by any of the listed words.

                     

                    The use of the [Hh] etc. character classes here to deal with capitols in this case might well not be appropriate I put them in to demonstrate there "correct" usage.

                     

                    Maybe you used the square brackets because of a typepo but even if you changed them to () only the "high school teacher" is not going to be joined, the middle and elementary school teacher will get joined.

                     

                    Peters Grep book and Grep editor are musts for learning the topic.

                     

                    2) It's probably going to take a fraction of the time to make a regular text list than to work out the correct Greps (deppending on the word list)

                     

                    Obviously if one wants ALL "over-" words joined except for those followed by "r" words it's best to use a grep.

                     

                    "To Grep or not to Grep? that is the question" the answer is it depends.

                     

                     

                    I'm sure you learnt something from this post .

                     

                    Regards

                     

                    Trevor

                     

                    Message was edited by: ~ Trevor ~

                    For some weird reason the site is changing my grep expression and  teacher is becoming tea cher.

                    weird! Please consider that it says teacher.

                    • 7. Re: FindChangebyList with strings of text?
                      Trevorׅ Adobe Community Professional

                      Arguably on the grep princaple of change as little as you can, the best school teacher grep would be

                      (?<!(H|h)igh\p{Zs}(S|s)chool)(?<!(M|m)iddle\p{Zs}(S|s)chool)(?<!(E|e)lementary\p{Zs}(S|s)c hool)\p{Zs}(?=(T|t)eacher)

                      change to "" (nothing)

                      This just removes the space without replacing any words and avoid problems like changing

                       

                      London High School

                      Teachers List:

                       

                      to "London High School Teachers List:" i.e. the new grep won't remove the paragraph mark.

                       

                      There's a lot of pot holes out there!

                       

                       

                       

                      Regarding the scope of the search by the script it easily to modifiy the script by changeing myDoc to myScope and either make a quick dialog or escape the unwanted lines like this.

                       

                       

                      myScope = app.documents[0]; // Search whole doc
                      //myScope = app.selection[0]; // Search selected text
                      //myScope =app.selection[0].parentStory; // Search Story
                      

                       

                      Trevor

                      • 8. Re: FindChangebyList with strings of text?
                        nukleas Level 1

                        Trevor:

                         

                        You are correct! I booted up the program and tried it, and "the school teacher" did fail. My mistake.

                         

                        ((?<![Hh]igh\s)(?<![Mm]iddle\s)(?<![Ee]lementary\s))([S|s]chool)\s(teacher) is correct.

                         

                        And yes, I can see that this would not be simple for the average user. 100+ lines of grep would be hard to generate by hand, and usually unless someone comes from a linux or programming background, they probably do not encounter too many regular expressions in the wild. It would probably be best to have a find/change list with a mostly-text mixture but watching out for exceptions using grep.

                         

                        If the user wants to generate text for FindChangeByList, they can easily do so with an excel sheet, then paste it into the plain text file relatively easily, as it's already tab-delimited. I'm not sure editing javascript code is easier for the end user versus a plaintext document, but one's mileage may vary.

                         

                        I think the deeper problem is that editing text for style is a complicated process that will need a human eye to catch most mistakes. A lot of the bulk work (and some of the tricky stuff, like double spaces and formatting) are best for scripts, but it's very hard to get one script to solve all problems.

                         

                        Thank you Trevor, and I have indeed figured some things out today.

                         

                        Nukleas

                         

                        P.S: We can avoid having to worry about breaking across paragraphs by just using a space instead of \s, but that would be a problem if the writer uses thin spaces (I don't see that being the case, though!)

                         

                        Double P.S: huh, the forum broke the tea cher for me too, peculiar!

                        • 9. Re: FindChangebyList with strings of text?
                          Trevorׅ Adobe Community Professional

                          Hi Nukleas,

                           

                          Me again

                           

                          To import a word list from an excel file save the file in excel as a tab deliniated text file and

                          instead of the lines

                          myChanges = 
                          [
                          'over-sized' , 'oversize',
                          '`pussy cat' , 'pussy', // Pussy cat will stay Pussy cat because of the ` tag
                          'CAT' , 'CAT®',
                          'school teacher' , 'schoolteacher',
                          'high schoolteacher' , 'high school teacher',
                          ';(never)\\-(?=\\S)' , '$1' // Because of the ; (semicolon) tag will be dealt with as a grep
                          ];
                          
                          

                           

                          Put

                           

                          var filePath= "c:/Word Change List.txt"; // change to correct file name and location
                          var txtfFile=new File(filePath);
                          txtfFile.open();
                          fileContent = txtfFile.read();
                          txtfFile.close();
                          var myArrayString=fileContent.replace(/'/g, "QtQeQn4").replace(/\t/g, "','").replace (/\n/g, "' , '");
                          myArrayString=myArrayString.slice(0,-3);
                          eval ("var myChanges = ['"+myArrayString+"];");
                          $.writeln(myChanges);
                          for (var c=0; c<myChanges.length-1; c++) myChanges[c]=myChanges[c].replace(/QtQeQn4/g, "'")


                           

                          I also notice that in my script I have app.findChangeTextOptions.caseSensitive = 0;

                          I meant to have app.findChangeTextOptions.caseSensitive = 1;

                           

                          Trevor

                           

                          P.s. Again the site is acting wacko, it's formatting my file snippet as a table

                          • 10. Re: FindChangebyList with strings of text?
                            Larry G. Schneider Adobe Community Professional & MVP

                            Trevor,

                             

                            Try using the Advanced editor (upper right) and then use the arrows to select the syntax highlighting you want.

                             

                            Screen shot 2012-08-09 at 9.10.24 AM.png

                            • 11. Re: FindChangebyList with strings of text?
                              Trevorׅ Adobe Community Professional

                              Hello Larry

                               

                              I'm not quite holding at the close to 4,000 post you have but this was not my 1st.

                               

                              I was using the advanced editor that's how the first snippet in the same post got formatted correctly, things seem to be a bit buggy on the forum lately see the tea cher bug that both Nekulus and myself had above.

                               

                              Saw some other post today were the word was split but with that one I can't know if it was a forum bug or a typo.

                               

                              Trevor

                              • 12. Re: FindChangebyList with strings of text?
                                Trevorׅ Adobe Community Professional

                                Just putting the script together  with instruction as I made reference to it somewhere else.

                                 

                                Instructions:

                                 

                                Make a find change list either in the script of more efficiently with a tab delimitated .txt excel file

                                Change the file path name in this line

                                var filePath= "c:/Word Change List.txt"; // CHANGE TO CORRECT FILE NAME
                                

                                to the correct path. Make sure to have the / in the right direction.

                                 

                                The normal search is semi-case sensitive i.e. will change if pussycat is the change from word then both pussycat and Pussycat would be changed PUSSYCAT or PussyCat would not.

                                If Pussycat was the change word then only Pussycat would be changed and not pussycat.

                                 

                                In other words the normal search will replace the word or the word with a capitol letter.

                                 

                                If you want only the word changed but not the capitol form i.e. pussycat but not pussy cat then add the ` symbol (above the tab key on my keyboard) like this `pussycat

                                 

                                If you want a non case sensitive find replace then add the ~ symbol like this ~pussycat this will change PUssycAt

                                 

                                For a grep change add the ; symbol to the beginning of the grep.

                                 

                                The excel file should be set up in this form

                                ScreenShot061.png

                                The file doesn't actually have to be made in excell as long as the words are sepertated by tabs and the rows by returns and the file saved as a tab delimitated .txt file

                                 

                                Enjoy

                                 

                                 

                                 

                                // Made by Trevor http://forums.adobe.com/message/4602248#4602248
                                
                                app.findTextPreferences = app.changeTextPreferences = null;
                                app.changeGrepPreferences = app.findGrepPreferences = null;
                                app.findChangeTextOptions.caseSensitive = 1;
                                myDoc = app.documents[0];
                                
                                /*  IF YOU DON'T WANT TO WORK WITH AN EXCEL FILE THEN DELETE THIS LINE !!!!!!!
                                myChanges = 
                                [
                                'over-sized' , 'oversize',
                                '`pussy cat' , 'pussy', // Pussy cat will stay Pussy cat because of the ` tag
                                'CAT' , 'CAT®',
                                'school teacher' , 'schoolteacher',
                                'high schoolteacher' , 'high school teacher',
                                ';(never)\\-(?=\\S)' , '$1' // Because of the ; (semicolon) tag will be dealt with as a grep
                                ];
                                 */ //  IF YOU DON'T WANT TO WORK WITH AN EXCEL FILE THEN DELETE THIS LINE !!!!!!!
                                
                                
                                // /* IF YOU DON'T WANT TO WORK WITH AN EXCEL FILE THEN DELETE THE // AT THE BEGINING OF THIS LINE !!!!!!!
                                
                                
                                    var filePath= "c:/Word Change List.txt"; // CHANGE TO CORRECT FILE NAME
                                
                                
                                    var txtfFile=new File(filePath);
                                    txtfFile.open();
                                    fileContent = txtfFile.read();
                                    txtfFile.close();
                                    var myArrayString=fileContent.replace(/'/g, "QtQeQn4").replace(/\t/g, "','").replace (/\n/g, "' , '");
                                    myArrayString=myArrayString.slice(0,-3);
                                    eval ("var myChanges = ['"+myArrayString+"];");
                                    $.writeln(myChanges);
                                    for (var c=0; c<myChanges.length-1; c++) myChanges[c]=myChanges[c].replace(/QtQeQn4/g, "'")
                                
                                // */ IF YOU DON'T WANT TO WORK WITH AN EXCEL FILE THEN DELETE THE // AT THE BEGINING OF THIS LINE !!!!!!!
                                
                                
                                
                                for (var c=0; c<myChanges.length;)
                                {
                                if  (myChanges[c][0] != "`" && myChanges[c][0] != ";" && myChanges[c][0] != "~")
                                {
                                    app.findChangeTextOptions.wholeWord = 1;
                                    app.findTextPreferences.findWhat = myChanges[c];
                                    app.changeTextPreferences.changeTo = myChanges[c+1];
                                    myDoc.changeText();
                                    capitalChangeFrom =  myChanges[c][0].toUpperCase() + myChanges[c].slice(1,myChanges[c].length);
                                    capitalChangeTo =  myChanges[c+1][0].toUpperCase() + myChanges[c+1].slice(1,myChanges[c+1].length);
                                    app.findTextPreferences.findWhat = capitalChangeFrom;
                                    app.changeTextPreferences.changeTo = capitalChangeTo;
                                    myDoc.changeText();
                                }
                                else if (myChanges[c][0] == "`")
                                {
                                    app.findChangeTextOptions.wholeWord = 1;
                                    app.findTextPreferences.findWhat = myChanges[c].slice(1,myChanges[c].length);
                                    app.changeTextPreferences.changeTo = myChanges[c+1];
                                    myDoc.changeText();
                                }
                                else if (myChanges[c][0] == "~")
                                {
                                    app.findChangeTextOptions.wholeWord = 0;
                                    app.findTextPreferences.findWhat = myChanges[c].slice(1,myChanges[c].length);
                                    app.changeTextPreferences.changeTo = myChanges[c+1];
                                    myDoc.changeText();
                                }
                                else
                                {
                                    app.findGrepPreferences.findWhat = myChanges[c].slice(1,myChanges[c].length);
                                    app.changeGrepPreferences.changeTo = myChanges[c+1];
                                    myDoc.changeGrep();
                                }
                                c+=2;
                                }
                                
                                • 13. Re: FindChangebyList with strings of text?
                                  SeanTurtle

                                  Hi Trevor

                                   

                                  Your script is exactly what I'm looking for (and will save me 400+ manual find and replaces), but when I run it, I get this error:

                                   

                                  Error number: 4

                                  Error string: Unterminated string constant

                                   

                                  Engine: main

                                  Line: 1

                                   

                                  Source: var myChanges = *and then it lists the tab-delimited file*

                                   

                                  I'd appreciate your help and time if you could clarify what I'm doing wrong.

                                   

                                  Thanks

                                   

                                  Sean

                                  • 14. Re: FindChangebyList with strings of text?
                                    Trevorׅ Adobe Community Professional

                                    Hi Sean,

                                     

                                    I'm not 100% sure on what you mean.

                                    I pressume that you changed the file location to the correct location and used forward slashes /

                                     

                                    If you send me a screan shot of the exact error message it might help

                                    • 15. Re: FindChangebyList with strings of text?
                                      celuloyd Level 1

                                      Folks,

                                       

                                      Most of you seem to know what you're talking about so I'll pose my problem/question here.

                                       

                                      We are using InDesign CS4 on Windows XP to create 12 catalogs bi-annually (24 total) with thousands of parts in each one. We now need to change all those part numbers to new ones. I have a spreadsheet that has the old numbers in one column and the corresponding new numbers in a second column. There are approximately 59,000 part numbers in the spreadsheet. I know nothing about scripting at all. Is there a way to reference the spreadsheet and find the old part number in the InDesign document then replace it with the new number? This would save weeks of work.

                                       

                                      I tried one custom script I found in an Adobe user forum but I had to place the info from the spreadsheet into InDesign, convert it to a table, select the table, then run the script. The problem was that it only changed the numbers in the table, not in my document.

                                       

                                      I've also read that the FindChangeByList script can be used (as long as the Excel file is converted to a .txt file), but I have no idea how to edit the script to suit what I need done.

                                       

                                      Any suggestions? Thanks,

                                      Lloyd

                                      • 16. Re: FindChangebyList with strings of text?
                                        nukleas Level 1

                                        HI Lloyd,

                                         

                                        If you would like to use a find change entry for each, you can do so easily using an excel sheet. That path is definitely a good way if you want to have all the options available to you, such as regular expressions or certain paragraph/style options.

                                         

                                         

                                        What's nice about excel is you can copy-paste the tables directly into notepad to create a tab-delimited text file, which can be used in some scripts.

                                         

                                         

                                        The following is a simple script that will do a simple find/change replace using just a text document with:

                                         

                                        text_to_find<TAB>text_to_replace

                                         

                                        And you can choose the scope of how far you want to take it.

                                         

                                         

                                         

                                         

                                        // Simple Find-Change with Range
                                        function myDisplayDialog() {
                                            "use strict";
                                                  var findChangeTarget, dialogWindow, diaColRows, targetRangeButtons;
                                                  dialogWindow = app.dialogs.add({name: "Find/Change"});
                                                  diaColRows = dialogWindow.dialogColumns.add().dialogRows.add(); // Just to shorten the line so it reads easier
                                                  diaColRows.staticTexts.add({staticLabel: "Search Range:"});
                                            targetRangeButtons = diaColRows.radiobuttonGroups.add();
                                                  targetRangeButtons.radiobuttonControls.add({staticLabel: "Document", checkedState: true});
                                                  targetRangeButtons.radiobuttonControls.add({staticLabel: "Selected Story"});
                                            // If you have a selection, target that.
                                            if (app.selection[0].contents !== "") {
                                                targetRangeButtons.radiobuttonControls.add({staticLabel: "Selection", checkedState: true});
                                            }
                                                  if (dialogWindow.show()) {
                                                            switch (targetRangeButtons.selectedButton) {
                                                      case 0:
                                                                      findChangeTarget = app.documents[0];
                                                                      break;
                                                            case 1:
                                                                      findChangeTarget = app.selection[0].parentStory;
                                                                      break;
                                                            case 2:
                                                                      findChangeTarget = app.selection[0];
                                                                      break;
                                                            }
                                                            dialogWindow.destroy();
                                                            return findChangeTarget;
                                                  }
                                                  dialogWindow.destroy();
                                        }
                                        
                                        
                                        
                                        
                                        function doFindChange(find_text, change_text, target) {
                                            "use strict";
                                            app.findTextPreferences.findWhat = find_text;
                                            // Setting whole word to true. You want this most of the time, I'd think, but feel free to change
                                            app.findTextPreferences.findWhat.wholeWord = true;
                                            app.changeTextPreferences.changeTo = change_text;
                                            // Perform find/change
                                            target.changeText();
                                            // Write a line to console for debugging
                                            $.writeln("Changed " + find_text + " to " + change_text);
                                            // Reset Find/Change
                                            app.changeTextPreferences = NothingEnum.nothing;
                                                  app.findTextPreferences = NothingEnum.nothing;
                                        }
                                        function openFile() {
                                            "use strict";
                                                  var filePath, open_file;
                                            /*
                                                Instead of a hard-coded path, I decided to just have a dialog.
                                                This is so you don't have to worry about changing the code too much.
                                            */
                                            filePath = File.openDialog("Choose the file containing your find/change list");
                                            if (filePath && filePath.open("r", undefined, undefined)) {
                                                open_file = new File(filePath);
                                                open_file.open("r", undefined, undefined);
                                                return open_file;
                                            }
                                            return false;
                                        }
                                        function parseFile(open_file) {
                                            "use strict";
                                            var line, findChangeArray = [];
                                            do {
                                                line = open_file.readln().split('\t');
                                                if (line.length > 1) {
                                                    findChangeArray.push([line[0], line[1]]);
                                                }
                                            } while (open_file.eof === false);
                                            return findChangeArray;
                                        }
                                        function main() {
                                            "use strict";
                                                  var open_file, findChangeArray, i, target;
                                            app.changeTextPreferences = NothingEnum.nothing;
                                                  app.findTextPreferences = NothingEnum.nothing;
                                            open_file = openFile();
                                            if (open_file) {
                                                target = myDisplayDialog();
                                                findChangeArray = parseFile(open_file);
                                                for (i = 0; i < findChangeArray.length; i += 1) {
                                                    doFindChange(findChangeArray[i][0], findChangeArray[i][1], target);
                                                }
                                            }
                                        }
                                        main();
                                        
                                        

                                         

                                        If this is mangled, you can get it at:

                                         

                                        https://gist.github.com/nukleas/4981456

                                         

                                        If you want to take a tab-delimited file and convert it to the way findChangeByList does it, you can use:

                                         

                                        https://gist.github.com/nukleas/4981435

                                         

                                        and then tweak as necessary!

                                        • 17. Re: FindChangebyList with strings of text?
                                          MrTIFF Level 3

                                          Very nice.

                                           

                                          Of course, the user has to be sure that no value in the 'changeTo' column exists in the 'findWhat' column ... otherwise you can get "double-changes". (for example, one line causes all 10's to be changed to 20's; the next line causes all 20's to be changed to 30's; so that the original 10's are changed to 30's, which I think is not what we want here.)

                                          • 18. Re: FindChangebyList with strings of text?
                                            celuloyd Level 1

                                            nukleas,

                                             

                                            I take it you didn't see the part where I said I know nothing about scripting. 

                                             

                                            I'll see what I can do with this. Thank you!

                                             

                                            Lloyd

                                            • 19. Re: FindChangebyList with strings of text?
                                              Trevorׅ Adobe Community Professional

                                              Lloyd

                                               

                                              I sent you a private message, it probably went to your junk mail.

                                               

                                              Trevor

                                              • 20. Re: FindChangebyList with strings of text?
                                                nukleas Level 1

                                                stephen0218 wrote:

                                                 

                                                Very nice.

                                                 

                                                Of course, the user has to be sure that no value in the 'changeTo' column exists in the 'findWhat' column ... otherwise you can get "double-changes". (for example, one line causes all 10's to be changed to 20's; the next line causes all 20's to be changed to 30's; so that the original 10's are changed to 30's, which I think is not what we want here.)

                                                That is indeed a problem! I wonder if there is a way to easily prevent such double-corrections from occuring. I'll see if I can come up with anything... Perhaps having the replace actually surround the text with some sort of identifier that is checked for and avoided in the find/replace.

                                                • 21. Re: FindChangebyList with strings of text?
                                                  MrTIFF Level 3

                                                  Yes, seems like that could work.

                                                   

                                                  Another approach that I was thinking about might be to skip InDesign's FindChange mechanisms and just walk through all the words in the document once, looking for things that look like ProductNumbers. Should be an easy parsing task. If a "lookup" Object is pre-loaded to use the "findWhat" productnumbers for keys and the "changeTo" productnumbers for the values, the replacement process should even be quite fast.