25 Replies Latest reply on Mar 21, 2014 8:47 AM by Laubender

    [JS] delete swatch without replacing

    AgainstTheWind Level 1

      Hello all,

      I'm trying to find how to delete color in swatch without replacing with black. When I use this:

       

      myDocument.colors.item("test").remove();

       

      then my "test" color is replaced with black. Is there any way to delete it by script without replacing (unnamed swatch)?

        • 1. Re: [JS] delete swatch without replacing
          Jump_Over Level 5

          Hi,

           

          use

           

          myDocument.colors.item("test").remove(myColor);
          

           

          to apply myColor to all objects instead of removed one.

          It could be [None] as well. It leads to black (default) if empty.

           

          Jarek

          • 2. Re: [JS] delete swatch without replacing
            Laubender Adobe Community Professional & MVP

            It could be [None] as well.

            @Jarek – there is a "problem" with that.

            Strokes will change their strokeWeight to 0, if [None] is applied.

             

            //myColor is present
            var myColor =  app.documents[0].colors.itemByName("myColor");
            
            //Would substitute "myColor" with swatch "None":
            myColor.remove("None"); //=> width of stroke will change to zero
            

             

            Before:

            Before_SwitchingToNone.png

             

            After:

             

            After_SwitchingToNone.png

             

             

            Uwe

            • 3. Re: [JS] delete swatch without replacing
              Jump_Over Level 5

              Hi @Uwe,

              Laubender wrote:


              .. there is a "problem" with that...

               

              It could be sometimes. StrokeAlignment.INSIDE_ALIGNMENT makes it safe.

               

              But we can be sure that it is NO WAY to replace color with "undefined", "unnamed" or so.

              Some properties have to be set - like text.appliedFont - and ID will always set this to default value if previous set is removed without control.

               

              Jarek

              • 4. Re: [JS] delete swatch without replacing
                Laubender Adobe Community Professional & MVP

                @Jarek – yes of course, but safe?

                 

                Well there is one thing one can do to make a color at least "invisible" without changing the layout. But that, unfortunately, will involve two steps:

                 

                1. Set all strokes and fills of all objects that color is applied to "overprint".

                2. Change the color to a definition that in effect is "white", not "[Paper]", in CMYK that would be [0,0,0,0].

                 

                SrokeWeight will not change with using "overprint" together with setting the view to Simulate Overprinting ticked. Effects like Drop Shadow will not change on the object.

                 

                Thinking about transparency settings and opacity:

                 

                If you'd change opacity on a stroke to value zero, a drop shadow applied to that object will vanish as well, even its color is different. So we can rule out changing opacity.

                 

                What is really missing in InDesign is the possibility to define a swatch with an alpha value.

                 

                That would involve new color models like:

                 

                aLAB

                aRGB

                aCMYK

                 

                where a defines opacity…

                 

                Uwe

                • 5. Re: [JS] delete swatch without replacing
                  Laubender Adobe Community Professional & MVP

                  Here two screens:

                   

                  1. View "Simulate Overptinting" off

                  Rectangle stroke is using swatch "myColor" set to "CMYK" [0,0,0,0]

                  Stroke is set to "overprint".

                   

                  View_SimulateOverprinting_OFF.png

                   

                   

                  2. View "Simulate Overptinting" on

                  View_SimulateOverprinting_ON.png

                   

                  Uwe

                  • 6. Re: [JS] delete swatch without replacing
                    AgainstTheWind Level 1

                    JAREK:

                    I don't want to apply any color instead of removed one. I need to remove swatch color and "replace" it with unnamed swatch (so color swatch won't be in swatches anymore but object will still be colored with this color). You can do it in InDesign when removing color swatch, choosing "Unnamed Swatch":

                    http://ptgmedia.pearsoncmg.com/images/chap05_0321503066/elementLinks/delete-1.jpg

                     

                    Exactly this I need to do by script.

                    • 7. Re: [JS] delete swatch without replacing
                      Laubender Adobe Community Professional & MVP

                      @AgainstTheWind – I think that cannot be done directly by scripting.
                      I tried a few things. To no avail.

                       

                      However, if you doing this in the UI and exporting an object filled with your named color to IDMS, you can check inside  the IDMS how this color is represented. Before and after the unnaming.

                       

                      Here an example with a color named "myNamedColor" in CMYK with colorValue [11,22,33,44]:

                       

                      An relevant excerpt of the IDMS before the UI command "Delete Swatch":

                       

                      <Color Self="Color/myNamedColor" Model="Process" Space="CMYK" ColorValue="11 22 33 44" ColorOverride="Normal" AlternateSpace="NoAlternateColor" AlternateColorValue="" Name="myNamedColor" ColorEditable="true" ColorRemovable="true" Visible="true" SwatchCreatorID="7937"/>
                      

                       

                      IDMS after "Delete Swatch/Remove and Replace with:" [x] Unnamed Swatch:

                       

                      <Color Self="Color/ud8" Model="Process" Space="CMYK" ColorValue="11 22 33 44" ColorOverride="Normal" AlternateSpace="NoAlternateColor" AlternateColorValue="" Name="$ID/" ColorEditable="true" ColorRemovable="true" Visible="false" SwatchCreatorID="7937"/>
                      

                       

                      So the values for Self and Name has changed.

                       

                      IDMS is an XML representation in text form, so the IDMS file could be opened and edited with ExtendScript.

                      The specific color is enclosed in an opening tag and an closing tag:

                       

                      <Color … />

                       

                      In between are the property names and their values. Note here: not all possible property/value pairs must be present. Some could be optional. In some way they resemble property/value pairs from the ExtendScript DOM. But some are unique to IDMS (or IDML) like: Visible="True" || Visible="False".

                       

                      Someone, might be John Hawkinson, once explained the value we see here in this example for Self "ud8" and the encoding principle behind that value system. Unfortunately I cannot tell. The value "ud8" for Color Self ="Color/…" might be a different one in your case.

                       

                      Ah, after some digging around I found the relevant post by John Hawkinson:

                       

                      http://forums.adobe.com/message/4047220#4047220

                       

                      The problem now would be to anticipate the right ID value and calculate the right representation form for IDMS, if we want to change a color from named to unnamed.

                       

                      The idea is now:

                      Export a rectangle filled with your color to IDMS, edit the IDMS file with ExtendScript, place the IDMS back in the same InDesign document. Now the unnamed color is there. It would be the one with the highest index number, because added as last one to the collection of colors. It has an unique ID you can get, so it would be possible to remove() and therefore change your color to the new unnamed one like that:

                       

                      var myID = app.documents[0].colors[app.documents[0].colors.length-1].id;
                      var myNewUnnamedColor = app.documents[0].colors.itemByID(myID);
                      app.documents[0].colors.itemByName("myNamedColor").remove(myNewUnnamedColor);
                      

                       

                       

                      Uwe

                      • 8. Re: [JS] delete swatch without replacing
                        Jump_Over Level 5

                        Hi,

                         

                        I can see another way... if can you assume that some of your doc's color is "unnamed" already (made initially, manually or came with app default set).

                        There is a workaround like this:

                        • find this color
                        • duplicate it
                        • change its properties
                        • remove the one you need and replace with hidden "unnamed" one.

                         

                        However the biggest question is about criteria which color is going to be removed.

                        You can't expect script to read selection made in Swatch Panel.

                        If criteria are clear... look into this example:

                         

                        var 
                                  mColors = app.activeDocument.colors.everyItem().name,
                                  len = mColors.length,
                                  mString = mColors.join(),
                                  idx = mString.slice(0, mString.search(",,")).split(",").length,
                                  mBaseColor = app.activeDocument.colors.item(idx),
                                  currColor,
                                  mModel, mSpace, mValue;
                        
                                  if (idx == mString.length) {
                                            alert ("Can't find unnamed color in this doc"); 
                                            exit();
                                            }
                        
                        //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
                        // Now there is a question about criteria - which color to remove?
                        // Let say each RGB has to be removed
                        while (len-->0) {
                                  currColor = app.activeDocument.colors.itemByName(mColors[len]);
                                  if (currColor.isValid && currColor.space == ColorSpace.RGB)
                                            remNOrep (currColor);
                                  }
                        //|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
                        
                        
                        function remNOrep (color) {
                                  with (color) {
                                            mModel = model;
                                            mSpace = space;
                                            mValue = colorValue;
                                            }
                                  var mTargetColor = mBaseColor.duplicate();
                                  with (mTargetColor) {
                                            model = mModel;
                                            space = mSpace;
                                            colorValue = mValue;
                                            }
                                  color.remove(mTargetColor);
                                  }
                        

                         

                        Jarek

                        • 9. Re: [JS] delete swatch without replacing
                          [Jongware] Most Valuable Participant

                          Hmm .. Jarek, I think I tried this same route as well. I got it to work .. except that it changed *all* "unnamed" colors at the same time -- whatever their color! (I think I did this through a Snippet, exporting and then importing it again, essentially what Uwe is proposing above.)

                           

                          Handling unnamed colors has been asked before lots of times, no good solution appeared as yet. The built-in functionality is just not exposed to scripting.

                          • 10. Re: [JS] delete swatch without replacing
                            Trevorׅ Adobe Community Professional

                            You have probably (Jongware, definitely) all seen this thread (over 20,000 views reflects the lackingness of the feature).  Harb's solution might be helpful

                            • 11. Re: [JS] delete swatch without replacing
                              Trevorׅ Adobe Community Professional

                              Mean't to say this thread

                              • 12. Re: [JS] delete swatch without replacing
                                Laubender Adobe Community Professional & MVP

                                Jarek wrote:

                                I can see another way... if can you assume that some of your doc's color is "unnamed" already (made initially, manually or came with app default set).

                                @Jarek – well, I'll never make that assumption. It's a big one…

                                Constructing a unnamed color, as far as I know, is only possible with IDMS or IDML.

                                 

                                FWIW speaking in IDML or IDMS terms there is this property "Visible" you can set to "false".

                                If you'll do this  to a named color without changing its name, you cannot reveal it by using the UI command "Add unnamed Color". Theoretically, me practically by testing, one can add an invisible color by changing the attribute in a snippet.

                                 

                                Also possible wirh IDML/IDMS setting a swatch to locked ;-) or to editable (false) ;-)
                                Scripting provides no means to these properties.

                                 

                                Jarek wrote:

                                You have probably (Jongware, definitely) all seen this thread (over 20,000 views reflects the lackingness of the feature).

                                Thank you for that hint. Shame on me, I missed this thread back then…

                                 

                                Ok. Well, back to the drawing board.

                                I think, did not tested that very well, I have a solution without using a IDMS snippet file.

                                 

                                You hear from me in some minutes…

                                 

                                Uwe

                                • 13. Re: [JS] delete swatch without replacing
                                  Jump_Over Level 5

                                  Laubender wrote:

                                   

                                  @Jarek – well, I'll never make that assumption. It's a big one…

                                  Constructing a unnamed color, as far as I know, is only possible with IDMS or IDML.

                                   

                                  Well, not so big, I think.

                                  If your Color Panel is touched with no doc opened (Color not Swatch) each new doc has at least one "unnamed" color.

                                  I am going to find it by name.length == 0 since one can't add a color with empty name's property.

                                  You can create unnamed manually as well, using UI remove menu and choosing "unnamed" option. Starting from this point script should manage the goal...

                                   

                                  Shame on me as well, I am the one who missed Trevor's post too.

                                  Currently I am trying to reach Jongware's weird catch...

                                   

                                  Jarek

                                  • 14. Re: [JS] delete swatch without replacing
                                    Laubender Adobe Community Professional & MVP

                                    Just to outline my idea and the base for this.

                                     

                                    If you add a fresh new document and remove all swatches you can remove, you'll end up with some named swatches together with some unnamed ones.

                                     

                                    The code below gets the result:

                                     

                                    var myDoc = app.documents.add();
                                    
                                    //Remove all unused ones with a name that can be removed:
                                    
                                    var myColors = myDoc.colors;
                                    
                                    for(var n=myColors.length-1;n>=0;n--){
                                        if(myColors[n].name !=""){
                                            try{
                                                myColors[n].remove();
                                                }catch(e){};
                                            };
                                        };
                                    
                                    //GET ALL COLORS OF CURRENT DOCUMENT:
                                    
                                    var myEssentialColors = myDoc.colors;
                                    for(var n=0;n<myEssentialColors.length;n++){
                                        $.writeln(n+"\t"+myEssentialColors[n].id+"\t"+myEssentialColors[n].name+"\t"+myEssentialColors[n].colorValue.toString());
                                        };
                                    
                                    //RESULT with a fresh document (print related) with all swatches removed one can remove:
                                    /*
                                    0    11    Black    0,0,0,100
                                    1    12    Cyan    100,0,0,0
                                    2    13    Magenta    0,100,0,0
                                    3    15    Paper    0,0,0,0
                                    4    16    Registration    100,100,100,100
                                    5    17    Yellow    0,0,100,0
                                    6    133        0,0,0,100
                                    7    135        0,0,0,0
                                    */
                                    
                                    var myID = myDoc.colors.lastItem().id;
                                    var myUnnamedColor = myDoc.colors.itemByID(myID);
                                    
                                    var myNewColor = myUnnamedColor.duplicate();
                                    myNewColor.properties = {colorValue:[100,0,0,0]};
                                    
                                    var myColors = myDoc.colors;
                                    for(var n=0;n<myColors.length;n++){
                                        $.writeln(n+"\t"+myColors[n].id+"\t"+myColors[n].name+"\t"+myColors[n].colorValue.toString());
                                        };
                                    
                                    //RESULT AFTER DUPLICATING THE LAST UNNAMED COLOR:
                                    /*
                                    0    11    Black    0,0,0,100
                                    1    12    Cyan    100,0,0,0
                                    2    13    Magenta    0,100,0,0
                                    3    15    Paper    0,0,0,0
                                    4    16    Registration    100,100,100,100
                                    5    17    Yellow    0,0,100,0
                                    6    133        0,0,0,100
                                    7    135        0,0,0,0
                                    8    212        100,0,0,0
                                    */
                                    var newRectangleWithUnnamedColor = myDoc.rectangles.add({geometricBounds:[0,0,100,100],fillColor:myNewColor});
                                    

                                     

                                    Here the screen grab with the result:

                                     

                                    After duplicating the last unnamed color, that is always present (assumption!), changing its colorValue, adding a rectangle and assigning the new unnamed color to fillColor:

                                     

                                    After-DuplicatingLastUnnamedColorChangingColorValue.png

                                     

                                    Here the proof that we could make it to a new named swatch:

                                     

                                    AddingUnnamedColorToSwatchesPanel.png

                                     

                                    After-AddingUnnamedColorToSwatchesPanel.png

                                     

                                    Without adding this new color to the Swatches Panel, we can omit the IDMS thing altogether and using this new rectangle for the task.

                                     

                                    Uwe

                                    • 15. Re: [JS] delete swatch without replacing
                                      Laubender Adobe Community Professional & MVP

                                      Uwe wrote:

                                      Constructing a unnamed color, as far as I know, is only possible with IDMS or IDML.

                                       

                                      I love contradicting myself! :-)

                                       

                                      Ok. It is possible constructing a unnamed color by duplicating a standard unnamed one!

                                       

                                      Uwe

                                      • 16. Re: [JS] delete swatch without replacing
                                        Trevorׅ Adobe Community Professional

                                        Well done Uwe

                                         

                                        Excellent! So it seems that there are always colors in a document

                                        In which case it doesn't matter for our purposes if they are named are not.

                                        So we can just do a 2 liner (not including the rectangle), no IDML, XML PDFs or who knows what.

                                        Just plain and simple dead easy

                                         

                                        var myUnnamedColor = app.activeDocument.colors[-1].duplicate();
                                        myUnnamedColor.properties = {colorValue:[10,50,70,0]}; // space, model etc.
                                        var newRectangleWithUnnamedColor = app.activeDocument.rectangles.add({geometricBounds:[0,0,100,100],fillColor:myUnnamedColor});
                                        

                                         

                                        The swatch won't be added just the unnamed color

                                        I shall add that to the above mentioned thread.

                                         

                                        Trevor

                                        • 17. Re: [JS] delete swatch without replacing
                                          Laubender Adobe Community Professional & MVP

                                          @Jarek EDIT: @Trevor, of course, sorry! – Your simple code is working well.

                                          Cool. Good collaboration, I think!

                                           

                                          And here the solution to this all (not tested well):

                                           

                                          var myNamedColor = app.documents[0].colors.itemByName("myNamedColor");
                                          
                                          var myUnnamedColor = app.activeDocument.colors[-1].duplicate();
                                          myUnnamedColor.properties = myNamedColor.properties;
                                          myNamedColor.remove(myUnnamedColor);
                                          

                                           

                                           

                                          Uwe

                                           

                                          Message was edited by: Laubender

                                          • 18. Re: [JS] delete swatch without replacing
                                            Trevorׅ Adobe Community Professional

                                            Now to answer the OP's question

                                            Instead of using remove use zapSwatch.

                                             

                                             

                                            app.selection[0] && zapSwatch (app.selection[0].fillColor);
                                            
                                            function zapSwatch (byeByeSwatch) {
                                                var parentDoc = byeByeSwatch.parent; // the doc
                                                var byeByeSwatchID = byeByeSwatch.id;
                                                byeByeSwatch = parentDoc.swatches.itemByID(byeByeSwatchID); // use this to make sure that byeByeSwatch is a swatch and not just a color
                                                if (!byeByeSwatch.isValid) return; // fill color is not a swatch so nothing to do.
                                                try {if (byeByeSwatch.model == 1936748404 /* Spot */) byeByeSwatch.model = 1886548851 /* Process */} catch (e) {return} // change color model to process if needed
                                                var unNamedColor =parentDoc.colors[-1].duplicate();
                                                unNamedColor.properties = byeByeSwatch.properties;
                                                try {byeByeSwatch.remove(unNamedColor);} catch (e) {}; // incase swatch is readonly.
                                            }
                                            

                                             

                                            Message was edited by: Trevorׅ Added the line try {if (byeByeSwatch.model == 1936748404 /* Spot */) byeByeSwatch.model = 1886548851 /* Process */} catch (e) {return} So the script works for spots

                                            • 19. Re: [JS] delete swatch without replacing
                                              Laubender Adobe Community Professional & MVP

                                              @AgainstTheWind – here a variation of that snippet working on a selected pageItem filled with the color you want to change from named to unnamed:

                                               

                                              //ChangeNamedColorToUnnamed_USING_fillColor_WITH_SELECTED-PAGEITEM.jsx
                                              
                                              var myName = app.selection[0].fillColor.name;
                                              var myNamedColor = app.documents[0].colors.itemByName(myName);
                                              
                                              var myUnnamedColor = app.activeDocument.colors[-1].duplicate();
                                              myUnnamedColor.properties = myNamedColor.properties;
                                              try{
                                              myNamedColor.remove(myUnnamedColor);
                                              }catch(e){};
                                              

                                               

                                              Let's see, if that will work on all color models and color values.

                                              I can foresee, this is not working as expected with the standard colors in brackets […] and with tints.

                                               

                                              Uwe

                                              • 20. Re: [JS] delete swatch without replacing
                                                Trevorׅ Adobe Community Professional

                                                Uwe, I beat you by less than 2 minutes

                                                Trevor

                                                 

                                                Message was edited by: Trevorׅ Didn't see 17 above so I'm not so sure of my comment

                                                • 21. Re: [JS] delete swatch without replacing
                                                  Laubender Adobe Community Professional & MVP

                                                  Now, we need a catch for a Tint. The UI menu is working correctly on that. Our scripts are ignoring the fact that a pageItem could be filled with a tint as well.

                                                   

                                                  Or with a Gradient, or a MixedInk…

                                                   

                                                  Uwe

                                                  • 22. Re: [JS] delete swatch without replacing
                                                    Laubender Adobe Community Professional & MVP

                                                    Something new.

                                                    We cannot always assume, that colors[-1] will work as expected for duplication.

                                                    In length I described this in the other thread:

                                                     

                                                    Trevorׅ

                                                    Coloring a Font with a RGB etc. without adding the color to the document swatches.

                                                    21.09.2011 15:50

                                                     

                                                    Answer #20 | Uwe Laubender

                                                    http://forums.adobe.com/message/6220993#6220993

                                                     

                                                    Here some files to download where using colors[-1] for duplicating is critcal:

                                                     

                                                    https://www.dropbox.com/s/pl1za6fw9v3bc04/AddingUnnamedColorDoesNotWork.zip

                                                     

                                                    AddingUnnamedColorDoesNotWork.zip

                                                        AddingUnnamedColorDoesNotWork_TREVOR-SNIPPET.idml

                                                        AddingUnnamedColorDoesNotWork_TREVOR-SNIPPET.indd

                                                     

                                                    The InDesign file is CS 5.5.

                                                     

                                                    Uwe

                                                     

                                                    Message was edited by: Laubender

                                                    • 23. Re: [JS] delete swatch without replacing
                                                      Trevorׅ Adobe Community Professional

                                                      Hi Uwe,

                                                       

                                                      It looks like one can't have a spot unnamed color which I think has some logic to it.

                                                      So as in our case we are looking to zap the swatch if one fist changes the swatch to process then it will work in the vast majority of cases (I think).

                                                      See my edit to 18 above.

                                                      I think the cases where it would fail is if colors[-1] is a mixed ink etc.

                                                       

                                                      I haven't found a fail case yet but I have no doubt that you will

                                                       

                                                      Trevor

                                                      • 24. Re: [JS] delete swatch without replacing
                                                        Trevorׅ Adobe Community Professional

                                                        This I think will work in all cases

                                                         

                                                        app.selection[0] && zapSwatch (app.selection[0].fillColor);
                                                        
                                                        function zapSwatch (byeByeSwatch) {
                                                            if (!(byeByeSwatch instanceof Object) || byeByeSwatch.constructor.name != "Color" || !byeByeSwatch.isValid || byeByeSwatch.name in {'Black': 1, 'Cyan': 1, 'Magenta': 1, 'Paper': 1, 'Registration': 1, 'Yellow': 1}) return false; // fill color is not a swatch or is readonly so nothing to do.
                                                            var tempDoc, PARENT;
                                                            tempDoc = PARENT= byeByeSwatch.parent; // the doc / application
                                                            if (byeByeSwatch.model !== 1886548851 /* Process */) byeByeSwatch.model = 1886548851; // change color model to process if needed
                                                            var lastSwatch = PARENT.colors[-1];
                                                            var unNamedColor;
                                                            app.doScript (
                                                                """
                                                                if (lastSwatch.name == "") unNamedColor = PARENT.colors[-1].duplicate();
                                                                else unNamedColor = taggedColor();
                                                                unNamedColor.properties = byeByeSwatch.properties;    
                                                                byeByeSwatch.remove(unNamedColor);
                                                                if (tempDoc != PARENT) tempDoc.close(SaveOptions.NO);
                                                                """,
                                                                ScriptLanguage.javascript,
                                                                undefined,
                                                                UndoModes.FAST_ENTIRE_SCRIPT
                                                            );
                                                            return PARENT.colors[-1];
                                                                 function taggedColor() { // need to use this if no unnamed exists
                                                                     var tagString = "<ASCII-" + ($.os[0] == "M" ? "MAC>\r " : "WIN>\r ") + "<cColor:COLOR\:CMYK\:Process\:0.1\,0.95\,0.3\,0.0><cColor:>"; // would make more sense to apply the correct value in the tagged text file but I can't be bothered !
                                                                     var tempFile = new File (Folder (Folder.temp) + "/ " + (new Date).getTime() + ".txt");
                                                                     tempFile.open('w');
                                                                     tempFile.write(tagString);
                                                                     tempFile.close();
                                                                     tempDoc = (PARENT == app) ? app.documents.add(false) : PARENT;
                                                                     var tempFrame = tempDoc.pages[-1].textFrames.add();
                                                                     $.sleep(200);
                                                                     tempFrame.place(tempFile);
                                                                     tempFrame.remove();
                                                                     tempFile.remove();         
                                                                 return tempDoc.colors[-1];         
                                                             }
                                                        }
                                                        
                                                        • 25. Re: [JS] delete swatch without replacing
                                                          Laubender Adobe Community Professional & MVP

                                                          @All – something on colors and swatches:


                                                          Marc Autret

                                                          InDesign Scripting Forum Roundup #3

                                                           

                                                          2/ Graphics, Colors and Geometry

                                                          Anonymous and/or Unused Swatches

                                                          http://www.indiscripts.com/post/2012/07/indesign-scripting-forum-roundup-3#hd2sb2

                                                           

                                                          Uwe