13 Replies Latest reply on Mar 12, 2009 6:18 AM by Andreas Jansson

    [CS3 JS] Question about collecting overridden style settings

    Andreas Jansson Level 2
      Hi!

      I can use the styleOverridden to check every item in a textStyleRange for overrides. But is there a smart way to collect the attributes actually overridden? (The attributes showing up neatly in the tooltip when you hold the mouse cursor over an overridden style name.)

      My script needs to add a clean character style for every overridden style, recreating the behaviour of the add new character style dialogue, creating the new style based on the overrides.

      Kind regards,
      Andreas
        • 1. Re: [CS3 JS] Question about collecting overridden style settings
          Andreas Jansson Level 2
          Or... is there a way for a script to mimic the way of the user:

          When manually adding a new style in InDesign the "new style" window shows up with the style attributes of the selected text as "presets" for the new style.

          Can a new style be created from the styles of a textStyleRange (including its overrides) or in a similar way, from script code?

          I hope I've made my question clear enough. Anyone?
          • 2. Re: [CS3 JS] Question about collecting overridden style settings
            Peter Kahrel Adobe Community Professional & MVP
            Andreas,

            Dave Saunders has a few scripts that reposrt some features of paragraph styles. I don't know if they deal with overrides, but do check his web sites(s).

            Peter
            • 3. Re: [CS3 JS] Question about collecting overridden style settings
              Andreas Jansson Level 2
              Thanks for the suggestion, Peter. I've found one example of a script dealing with "Italic", "Bold" and "Bold Italic" (which might originate from David Saunders, I'm not sure).
              It's described as "Preserve Local Formatting" and looks for ranges without a character style (i.e. with "noCharStyle") but with those specific fontStyles, creating Italic etc, as character styles, and applies them on the text.

              These are very specific fontStyle attributes and would not deal with the font size being changed, or the character spacing set to another number between two words etc.

              I need to create a more generic code to create character styles for all overridden textstyle ranges in a text.

              And now I'm also a bit confused about the nature of the textStyleRange object as well. Looking at its properties some of them have the same names as properties of a characterStyle object, but of different type:

              myTextStyleRange.appliedFont.constructor.name
              Result: Font

              While

              myNewCharacterStyle.appliedFont.constructor.name
              Result: String

              Meaning that I can't directly assign the attributes of the textStyleRange with the overridden styles, to a newly created character style, or is there a way?

              Andreas
              • 4. Re: [CS3 JS] Question about collecting overridden style settings
                Peter Kahrel Adobe Community Professional & MVP
                You needn't worry too much about the difference in constructors. In many cases you can apply a font using either a string or an object:

                myNewCharacterStyle.appliedFont = "Times";
                myNewCharacterStyle.appliedFont = app.fonts.item ("Times");

                The second one always works, so it's good practice to assign objects rather than strings (that goes for all objects, not just strings). So you should be able to do this:

                myNewCharacterStyle.appliedFont = myTextStyleRange.appliedFont

                Peter
                • 5. Re: [CS3 JS] Question about collecting overridden style settings
                  Andreas Jansson Level 2
                  Ah, it looks like it's beginning to work now :-)
                  I thought I had tried some of these things before, but obviously not. Thanks Peter, for your assistance. Now even assigning the whole properties collection of the TextStyleRange objects to the new character style object works! There's a lot of properties created, which I'd really would have preferred not to show up (in the summary of the character style dialogue box), since they are (as far as I can see) the default values, but I like the easy code this approach results in:

                  var selText = app.selection;
                  var srs = selText[0].textStyleRanges;

                  for (var iTSR=srs.length-1; iTSR>=0; iTSR--){
                  ]if (srs[iTSR].styleOverridden){
                  ]]// This is an overridden style we need to create a style for
                  ]]var ch = srs[iTSR];
                  ]]newStyle = app.activeDocument.characterStyles.add(ch.properties);
                  ]]if (app.activeDocument.characterStyles.item('newstyle'+iTSR.toString())!=null) app.activeDocument.characterStyles.item('newstyle'+iTSR.toString()).remove();
                  ]]newStyle.name = 'newstyle'+iTSR.toString();
                  ]}

                  }

                  I'm not yet quite clear on how to treat overridden paragraph styles. Perhaps I need to check whether the properties of the new character style are already the same as the ones of an possibly applied paragraph style, and if so, not assign (or remove) that property from the new character style.

                  Also... possible need to name all uniquley auto-generated styles and find a way to apply the same style again (not to risk creating a large number of character styles just setting "bold").

                  Andreas
                  • 6. Re: [CS3 JS] Question about collecting overridden style settings
                    Peter Kahrel Adobe Community Professional & MVP
                    You could get the properties of the textStyleRange and those of the containing paragraph by using toResource(). You then have two objects that can be compared fairly easily. Collect the differences and set those to the new paragraph style.

                    If you store these settings (in a variable, array, object -- whatever), you can use them to check whether another textStyleRange differs and decide not to create a new char. style but use one that already exists with those same settings.

                    Peter
                    • 7. Re: [CS3 JS] Question about collecting overridden style settings
                      Andreas Jansson Level 2
                      I guess you mean the toSource() method, but I don't follow quite here, how the properties could be compared - or rather how toSource() can be helpful.

                      "sr" being the TextStyleRange, the following statement ...
                      > sr.properties.toSource()

                      and the one from its paragraphstyle ...

                      > sr.paragraphs[0].appliedParagraphStyle.properties.toSource()

                      ... returns partly different things,
                      obviously since the TextStyleRange contains properties from character styles as well as from paragraph style (and perhaps some of its own). Only the "clean" paragraph style properties would match - can toSource() be helpful making such a comparison?

                      I guess I could try and make use of the complete toSource() strings of the properties of the paragraph styles as keys (property names) in an associative array (if they are allowed as such - they do get very long), to be able to check for the exact same paragraph style.

                      But getting the differing style properties only, wouldn't that require checking each property from the text style range object against the corresponding one in the containing paragraph, individually?

                      (
                      I also noticed a bug in CS3 - when there is no paragraph style (not the Basic Paragraph but NO paragraph style at all), InD craches when you try to do something with the "properties" object of that TextStyleRange object, such as
                      ] var srProperties = sr.properties;

                      )

                      Andreas
                      • 8. Re: [CS3 JS] Question about collecting overridden style settings
                        Peter Kahrel Adobe Community Professional & MVP
                        >But getting the differing style properties only, wouldn't that require checking each property from the text style range object against the corresponding one in the containing paragraph, individually?

                        It would, and the resource string can be pretty long, but it's all text and processing them is very quick.

                        Peter
                        • 9. Re: [CS3 JS] Question about collecting overridden style settings
                          Dirk Becker  Level 4
                          Some building blocks:

                          To iterate the members of an object
                          for( n in props ) { alert(props[n]); }

                          To check whether another object has such a member:
                          if( other[n]!=undefined ) ...

                          To remove a named member:
                          delete other[n];

                          I wonder though how you would detect differences caused by nested styles.

                          Regarding toSource(), you could use that as a key in an associative array.
                          var styleMap = [];
                          var props = myStyle.properties;
                          delete props.name;
                          delete props.otherIgnoredAttribute;
                          var key = props.toSource();
                          var found = styleMap[key];
                          if( found!=undefined ) alert("Hey, we have a similar style"+ found.name);
                          else styleMap[key] = myStyle;

                          Dirk
                          • 10. Re: [CS3 JS] Question about collecting overridden style settings
                            Andreas Jansson Level 2
                            Great! I have some other work to do first, but this looks very good, and I will continue this script and make use of your input. Thanks!
                            Andreas.
                            • 11. Re: [CS3 JS] Question about collecting overridden style settings
                              Andreas Jansson Level 2
                              Hi!

                              My script now works fine with fresh data...
                              But making a new override (manually), such as colorizing a couple of letters red, in a paragraph with an already applied auto-generated paragraph style
                              ... and running the script again, then the script engine / InDesign no longer accepts that my code tries to use the properties collection of the StyleRange object.
                              The result is a crashing appliction.

                              The context of the error is this:

                              for (var iTSR=srs.length-1; iTSR>=0; iTSR--){
                              ]var sr = srs[iTSR];
                              ]if (sr.styleOverridden){
                              ]]var srProps = sr.properties; // Crash at this line
                              ]]...

                              The same fatal error ocurrs when trying to access "sr.properties" in the JavaScript console as well.

                              I really need to solve this so I hope that someone else has encountered a similar problem and knows the cause and a workaround.
                              How can it be that the properties collection of the StyleRange suddenly is not available and crashes InDesign?

                              Best regards,
                              Andreas

                              ( InDesign crashes " at location 0x78138aa0 ".
                              AppName: indesign.exe AppVer: 5.0.4.682 ModName: text.rpln
                              ModVer: 5.0.4.682 Offset: 00182bbb )
                              • 12. Re: [CS3 JS] Question about collecting overridden style settings
                                Andreas Jansson Level 2
                                A bit closer to the error - dropCapStyle was automatically assigned (copied) and when it exists in the properties collection, InDesign shuts down (when accessing the "properties" property).
                                There seems to be similar problems with nested styles properties. Will try and remove more properties from the ones being handled, trying to make it work.

                                Also, InDesign CS4 has no difficulties in handling the same script. (The error/bug is in CS3.)

                                Andreas
                                • 13. Re: [CS3 JS] Question about collecting overridden style settings
                                  Harbs. Level 6
                                  FWIW, I came across a similar crash some time ago on a certain file when
                                  iterating through character properties. I never got to the bottom of it
                                  (although I didn't spend a lot of time trying...).

                                  --
                                  Harbs
                                  http://www.in-tools.com