6 Replies Latest reply on Dec 8, 2008 7:59 AM by Tom Tomasko

    Can findText find two different objects at once?

    Tom Tomasko Level 1
      I have written a script that finds all italicized words, then compares them to a character style that italicizes characters. If there are any italicized words that do not use the character style, the user is alerted.

      Of course, not all fonts use a fontStyle that equals "Italic." Some use a fontStyle called "Oblique."

      I was trying to figure out how the findText function could find two fontStyles at the same time. My solution was to realize that each find is an array. So I made two finds and the concatenated the arrays. The resultant array (here called myFoundItems) elements can be searched through to find any that do not have the correct character style applied.

      My question is if the findText function can find more than two different objects at once or are we stuck with concatenating arrays?

      Below is part of the script:

      var myDoc = app.activeDocument;
      initFindReplace(); [This function zeros out anything left in the find/change preferences]
      app.findTextPreferences.fontStyle = "Italic";
      var myFoundItems1 = myDoc.findText();
      initFindReplace();
      app.findTextPreferences.fontStyle = "Oblique";
      var myFoundItems2 = myDoc.findText();
      initFindReplace();
      var myFoundItems = myFoundItems1.concat(myFoundItems2);

      Thanks,
      Tom
        • 1. Re: Can findText find two different objects at once?
          Roy McCoy Level 1
          Tom Tomasko wrote:

          > Of course, not all fonts use a fontStyle that equals "Italic." Some
          > use a fontStyle called "Oblique."

          I was surprised the other day when InDesign treated the two as
          identical. That is, I requested something related to Italic and it did
          it to Oblique also (or the other way around - I don't remember).
          Perhaps you can take advantage of this.


          Roy McCoy
          Rotterdam, NL
          • 2. Re: Can findText find two different objects at once?
            Peter Kahrel Adobe Community Professional & MVP
            > or are we stuck with concatenating arrays?

            We are.

            Peter
            • 3. Re: Can findText find two different objects at once?
              Tom Tomasko Level 1
              Peter,

              Thanks for that clarification. Armed with that knowledge, that we have to concatenate arrays, I figured why not make a function that would iterate through all of the font style names used in a document, compare them to a regular expression for "italics" and "oblique" (because some font style names are "46 Light Italic" or "Bold Oblique" etc.) and then spit out one array of word and TextStyleRange objects that are italicized?

              Below is such a function. However it returns only the last iteration, not array of all the iterations. What am I doing wrong?

              And sorry for the bad formatting. Isn't there a way to format this by wrapping the code in [CODE] brackets?

              Tom

              var myDoc = app.activeDocument;
              var arrFontStyles = myDoc.fonts.everyItem().fontStyleName;
              findFontStyle();
              //main:
              function findFontStyle(){
              ]var myFoundItems2 = new Array;
              ]for(var k = 0; k<= arrFontStyles.length; k++){
              ]]var testFontStyleItal =/italic/i;
              ]]var testFontStyleObl =/oblique/i;
              ]]var testedFontStyleItal = testFontStyleItal.test(arrFontStyles[k]);
              ]]var testedFontStyleObl = testFontStyleObl.test(arrFontStyles[k]);
              ]]]if(testedFontStyleItal == true||testedFontStyleObl == true){
              ]]]app.findTextPreferences = NothingEnum.NOTHING;
              ]]]app.changeTextPreferences = NothingEnum.NOTHING;
              ]]]app.findTextPreferences.fontStyle = arrFontStyles[k];
              ]]]var myFoundItems1 = myDoc.findText();
              ]]]var allMyFoundItems = myFoundItems2.concat(myFoundItems1);

              }//end if
              }//end for k
              return allMyFoundItems;
              }// end function findFontStyle
              • 4. Re: Can findText find two different objects at once?
                Tom Tomasko Level 1
                I solved the problem.<br /><br />The function below iterates through all of the font style names in a document and finds any variation of "italics" or "oblique." It makes an array called "aa" which is an array of arrays of objects such as Words, TextStyleRange, Paragraphs and Characters.<br /><br />I have no idea why it creates an array of arrays. Hopefully someone can explain that. But no matter, the X and Y For statements creates an array called reallyAllMyFoundItems that contains all the objects as equal elements.<br /><br />I can then iterate through those objects to find which ones have the correct character style applied to them. I haven't shown that part of the script.<br /><br />Tom<br /><br />var myDoc = app.activeDocument;<br />var arrFontStyles = myDoc.fonts.everyItem().fontStyleName;<br />var aa = findFontStyle();<br />//main:<br />function findFontStyle(){<br />     var allMyFoundItems = new Array;<br />     var myFoundItems2 = new Array;<br />     for(var k = 0; k<= arrFontStyles.length; k++){<br />          var testFontStyleItal =/italic/i;<br />          var testFontStyleObl =/oblique/i;<br />          var testedFontStyleItal = testFontStyleItal.test(arrFontStyles[k]);<br />          var testedFontStyleObl = testFontStyleObl.test(arrFontStyles[k]);<br />          if(testedFontStyleItal == true||testedFontStyleObl == true){<br />               app.findTextPreferences = NothingEnum.NOTHING;<br />               app.changeTextPreferences = NothingEnum.NOTHING;<br />               app.findTextPreferences.fontStyle =  arrFontStyles[k];<br />               var myFoundItems = myDoc.findText();     <br />               allMyFoundItems.push(myFoundItems);<br />                    }//end if<br />               //var allMyFoundItems = myFoundItems2.concat(myFoundItems1);<br />          }//end for k<br />     return allMyFoundItems;<br />     }//end findFontStyle function<br />var reallyAllMyFoundItems = new Array;<br />for ( var x=0; x<aa.length; x++) {<br />    for (var y=0; y<aa[x].length; y++) {<br />       reallyAllMyFoundItems.push(aa[x][y]);<br />    }//end for y<br />}//end for x<br />reallyAllMyFoundItems;
                • 5. Re: Can findText find two different objects at once?
                  Peter Kahrel Adobe Community Professional & MVP
                  Tom,

                  The reason why you end up with an array of arrays is this: you define an array allMyFoundItems, then you iteratively collect other arrays using findText and insert ("push") these arrays into allMyFoundItems. Instead, you should use concatenate:

                  var allMyFoundItems = new Array;
                  
                  . . .
                  for (. . .
                     var myFoundItems = myDoc.findText();
                     allMyFoundItems = allMyFoundItems.concat (myFoundItems)


                  If you'll allow me a further comment, you could formulate your test to check whether a fontstyle name contains oblique or italic in one line:
                  >if (arrFontStyles[k].search (/(italic|oblique)/i) > -1)

                  And as the script searches but doesn't change anything, there's no need to set the ChangeTextPreferences. Your script could then be stated as follows:

                  var myDoc = app.activeDocument;
                  
                  var arrFontStyles = myDoc.fonts.everyItem().fontStyleName;
                  aa = findFontStyle (arrFontStyles);

                  function findFontStyle (arrFontStyles)
                     {
                     var allMyFoundItems = new Array;
                     var myFoundItems2 = new Array;
                     app.findTextPreferences = NothingEnum.NOTHING;
                     for(var k = 0; k < arrFontStyles.length; k++)
                        {
                        if (arrFontStyles[k].search (/(italic|oblique)/i) > -1)
                           {
                           app.findTextPreferences.fontStyle = arrFontStyles[k];
                           var myFoundItems = myDoc.findText();
                           allMyFoundItems = allMyFoundItems.concat (myFoundItems);
                           }//end if
                        }//end for k
                     return allMyFoundItems;
                     }//end findFontStyle function


                  As to formatting scripts in the forum, you can do this by wrapping your code in <pre> and </pre>. Also replace < with &lt; (< causes all lines of code to be displayed on one line). You should also replace curly quotes with straight codes, and tabs with (non-breaking) spaces. I use the following script for that:

                  tf = app.documents.add().textFrames.add ({geometricBounds: [0,0,'700pt','500pt']})
                  
                  tf.insertionPoints[0].select();
                  app.activeDocument.textPreferences.typographersQuotes = false;
                  app.paste();
                  app.findGrepPreferences = app.changeGrepPreferences = null;
                  sara (tf, '&', '&amp;');
                  sara (tf, '<', '&lt;');
                  sara (tf, '\\t', '   ');
                  sara (tf, "'", "'");
                  sara (tf, '"', '"');
                  tf.parentStory.insertionPoints[0].contents = '<pre>';
                  tf.parentStory.insertionPoints[-1].contents = '</pre>';

                  function sara (tf, f, r)
                     {
                     app.findGrepPreferences.findWhat = f;
                     app.changeGrepPreferences.changeTo = r;
                     tf.parentStory.changeGrep ()
                     }


                  Copy the text of the script you want to prepare for posting, then run this above script. It creates a new InDesign document, pastes your script into it, and makes all the necessary changes. Then copy that and paste it into the forum.

                  Peter
                  • 6. Re: Can findText find two different objects at once?
                    Tom Tomasko Level 1
                    Yes, Peter, all this was very helpful. Thanks!
                    Tom