8 Replies Latest reply on Jun 29, 2017 1:09 AM by vinny38

    Checking if a para style is based on [Basic Paragraph]

    vinny38 Level 4

      Hi community

      I'd like to implement a small script that would allow to tell me if there is any para style that is based on [Basic]

      And more (and that's where I'm stuck), loop through any other para which would be based on para based on [Basic].

       

      Please see below my code:

      I can reach para A which is based on [basic]

      I can reach para B which is based on [basic]

      But what for C based on B or D based on C... and so on.

       

      It's basically a loop "problem", that my poor JS skills can't solve.

      Thanks a lot for your help.

      Vinny

       

       

      var myPstyles = app.activeDocument.allParagraphStyles;
      var myBasic = '[Paragraphe standard]' // Change this according to your language (be careful: Upper/Lower case matters)
      
      
      for (i = 1; i < myPstyles.length; i++) {
        if (myPstyles[i].basedOn.name === myBasic) {
          alert(myPstyles[i].name + ' is based on ' + myBasic);
          for (j = 1; j < myPstyles.length; j++) {
            if (myPstyles[j].basedOn.name === myPstyles[i].name) {
              alert(myPstyles[j].name + ' is based on ' + myPstyles[i].name + ' which is based on ' + myBasic);
            }
          }
        }
      }
      
        • 1. Re: Checking if a para style is based on [Basic Paragraph]
          Chinnadk Level 4

          Try this,

           

          Array.prototype.contains = function(obj)
          {
                  for(var i =0;i<this.length;i++)
                  {
                          if(this[i] === obj)
                          {
                                  return true;
                              }
                      }
                  return false;
              }
          var doc = app.activeDocument;
          var pstyles = doc.allParagraphStyles;
          var basic = "[Basic Paragraph]";
          var basedOnBasicStyles = [];
          
          
          for(var i=2;i<pstyles.length;i++)
          {
                  if(pstyles[i].basedOn.name == basic || basedOnBasicStyles.contains(pstyles[i].basedOn.name))
                  {
                          $.write(pstyles[i].name + "\r");
                          basedOnBasicStyles.push(pstyles[i].name);
                      }
              }
          
          • 2. Re: Checking if a para style is based on [Basic Paragraph]
            vinny38 Level 4

            Hey. Thanks for your answer.

            I'll try this om Monday, week end time now^^, but it's looking great

            1 person found this helpful
            • 3. Re: Checking if a para style is based on [Basic Paragraph]
              Laubender Adobe Community Professional & MVP

              Chinnadk  wrote

               

              Try this,

              Hi,

              thank you for sharing your snippet.

               

              Hm, maybe it's better to keep compatibility with localized versions of InDesign—like my German InDesign—by changing line 14 to that:

               

              var basic = doc.paragraphStyles[1].name;
              

               

              I think, storing the name of a style is not sufficient, because several paragraph styles sharing the same name can recide in different style groups.

              For easier access I would store the style in the result array, not its name.

               

              I also wonder why you are adding a prototype to Array…

              You loop through the allParagraphStyles array. Every entry in this array is unique.

              What would you expect from array.contains() ?

               

              So in effect something like the snippet below would work as explained.

              One could do a report of the style group a found item is stored as well:

               

              var doc = app.activeDocument;  
              var pstyles = doc.allParagraphStyles;  
              var basic = doc.paragraphStyles[1].name;
              
              var basedOnBasicStyles = [];  
                
              for(var i=2;i<pstyles.length;i++)  
              {  
                  if(pstyles[i].basedOn.name == basic )  
                  {  
                      var styleGroups = [];
                      var parent = pstyles[i].parent;
                      
                      while( parent.constructor.name !== "Document")
                      {
                          styleGroups[styleGroups.length++] = parent.name ;
                          parent = parent.parent ;
                      }
                  
                      if( styleGroups.length == 0 )
                      {
                          $.writeln( pstyles[i].name ) ;
                      }
                      else
                      {
                          $.writeln( styleGroups.reverse().join("\t")+"\t"+pstyles[i].name );
                      };
                      
                      basedOnBasicStyles[basedOnBasicStyles.length++] = pstyles[i];
                  }  
              };
              
              // Then loop through the basedOnBasicStyles array, if you want to do something with the found styles
              

               

              Here an example output from the $.writeln() where two paragraph styles share the same name: "Style 1".
              One style is in the "root" and one is in the deeper nested style group named "Group 2", that itself is nested in a style group named "Group 1":

               

              /*
              Style 1
              Group 1    Group 2    Style 1
              */
              

               

              Another question would be:
              Would we like to detect a style that is indirectly based on the Basic Paragraph Style?

              Because the style it is based on is based on the Basic Paragraph Style?

               

              You can show dependencies like that this with Harbs' wonderful script:

              Show Paragraph Based-on Script | in-tools.com

               

              Also see this screenshot where my snippet above does not reflect that there is a "Style 3"  that is based on "Style 2"  that is based on "Style 1" and finally that is based on the Basic Paragraph Style:

               

              ShowBasedOn-ParagraphStyles-Harbs.png

               

              As you can see above with my little example:


              All styles are directly or indirectly based on [No Paragraph Styles] ( [Kein Absatzformat] ).

              Only two styles here are directly based on [No Paragraph Styles] :

              "[Einf. Abs.]" and "Style 4".

               

              Two styles are directly based on [Basic Paragraph Style] ( [Einf. Abs.] ) :

              "Style 1" and "Style 1".

               

              Two are indirectly based on [Basic Paragraph Style] :

              "Style 2" and "Style 3". Where "Style 3" is directly based on "Style 2".

               

              Regards,
              Uwe

              1 person found this helpful
              • 4. Re: Checking if a para style is based on [Basic Paragraph]
                vinny38 Level 4

                Thanks to you two.

                Both answers were very helpful.

                As far as I understand (and tested), Chinndk script catches "indirectly based on" [basic], as well as styles with same name, put in different groups.

                 

                Apart from the smart idea of defining var basic = doc.paragraphStyles[1].name;

                I don't really understand your explanation Uwe: far too technical for me I'm afraid.

                I don't the .prototype part either, but I'll look into that.

                 

                Thanks!

                • 5. Re: Checking if a para style is based on [Basic Paragraph]
                  Laubender Adobe Community Professional & MVP

                  vinny38  wrote

                   

                  … As far as I understand (and tested), Chinndk script catches "indirectly based on" [basic], as well as styles with same name, put in different groups. …

                  Hi Vinny,
                  I will test Chinndk's script again, but I thought it gave an incomplete output when I tested the first time with CS6 on my Mac.

                   

                  Regards,
                  Uwe

                  • 6. Re: Checking if a para style is based on [Basic Paragraph]
                    Laubender Adobe Community Professional & MVP

                    Hi Vinny,

                    now that I tested again Chinna's snippet on my sample you are seeing in the screenshot #3 I see that the snippet's output is:

                     

                    Style 1

                    Style 2

                    Style 1

                     

                    "Style 3" is missing in the list.

                    It is based on "Style 2" that is based on "Style 1" that is based on "[Basic Paragraph Style]".

                     

                    The if statement in the loop is not sufficient to see that "Style 3" is indirectly based on "[Basic Paragraph Style]".

                     

                    As I said earlier: All paragraph styles are indirectly based on paragraphStyles[0].

                    We can do a while loop to travel in the hierarchy of based-on-styles from the current investigated paragraph style in the loop up to paragraphStyles[0]. If "[Basic Paragraph Style]" is found on the way the current style should be saved with the output array.

                     

                    Harbs has it right by showing the hierarchy of dependencies with his script "Based on Styles".

                    Did you try Harbs' script?

                     

                    Below my script that is using a while loop to see into dependencies with basedOn.

                    Now all four styles are correctly recognized with my sample document.

                     

                    One little obstacle writing this:

                    basedOn returns a string and no paragraphStyle object if a style is based on paragraphStyles[0]—the "[No Paragraph Style]" style.

                    Don't ask me why. I knew it, but nearly forgot about it.

                     

                    var doc = app.activeDocument; 
                    var pstyles = doc.allParagraphStyles;
                    var pstylesLength = pstyles.length;
                    
                    var basedOnBasicStyleNames = [];
                    var basedOnBasicStyleStyles = [];
                    
                    var noParagraphStyle = doc.paragraphStyles[1].basedOn;
                    var basicParagraphStyle = doc.paragraphStyles[1];
                    
                    for(var n=2;n<pstylesLength;n++) 
                    { 
                      var currentStyle = pstyles[n];
                      var basedOnStyle = currentStyle.basedOn;
                    
                      while( basedOnStyle !== noParagraphStyle )
                      {
                        if( basedOnStyle == basicParagraphStyle )
                        {
                          // If you want the names only:
                          basedOnBasicStyleNames[basedOnBasicStyleNames.length++] =
                          currentStyle.name;
                    
                          // If you want the styles:
                          basedOnBasicStyleStyles[basedOnBasicStyleStyles.length++] =
                          currentStyle;
                    
                          break
                        }
                        basedOnStyle = basedOnStyle.basedOn;
                    
                      };
                    
                    };
                    
                    
                    // Output in index order of allParagraphStyles
                    
                    // Names:
                    $.writeln( basedOnBasicStyleNames.join("\r") );
                    
                    // Paragraph styles listed:
                    $.writeln( basedOnBasicStyleStyles.join("\r") );
                    
                    // FWIW: Showing also IDs from the pageItem class of document and paragraph styles:
                    $.writeln( basedOnBasicStyleStyles.toSource().replace(/,/g,"\r") );
                    
                    // You can loop now the basedOnBasicStyleStyles array
                    // to do something with the styles directly.
                    

                     

                    Regards,
                    Uwe

                    • 7. Re: Checking if a para style is based on [Basic Paragraph]
                      Chinnadk Level 4

                      Hi Vinny,

                       

                      Laubender is correct. Please make Laubender's answer as correct answer. Here is my modified code.

                       

                      var doc = app.activeDocument;  
                      var pstyles = doc.allParagraphStyles;  
                      var basic = "[Basic Paragraph]";  
                      var basedOnBasicStyles = [];  
                      findBasedOnBasicStyle(basic);
                      function findBasedOnBasicStyle(basic)
                      {
                              for(var i=2;i<pstyles.length;i++)
                              {
                                      if(pstyles[i].basedOn.name == basic)
                                      {
                                              var stylename = "";
                                              if(pstyles[i].parent.constructor.name === "ParagraphStyleGroup")
                                              {
                                                      stylename = pstyles[i].parent.name +"-" + pstyles[i].name;
                                                  }
                                              else
                                              {
                                                      stylename = pstyles[i].name;
                                                  }
                                              $.write(stylename + "\r");
                                              basedOnBasicStyles.push(stylename);
                                              findBasedOnBasicStyle(stylename);
                                          }
                                  }
                          }
                      
                      • 8. Re: Checking if a para style is based on [Basic Paragraph]
                        vinny38 Level 4

                        Thanks Uwe

                        you were right, styles in subgroups were not caught.

                        Your script works perfectly.