Skip navigation
Currently Being Moderated

Grouped paths inside of compound paths screws up script

Oct 18, 2013 1:09 PM

Tags: #script #javascript #groups #compound_paths

I'm running into a scripting problem with Illustrator CS6—one that's been plaguing me for quite some time now:  Groups inside of Compound Paths.

 

 

I've got a script set up to extract all of the used colors in an Illustrator file, as well as halftone information, CMYK, etc.  It basically loops through every path in the file and looks at its fill color (if it has any), stroke color (if it has any), gradient stops (if any), etc.  If the item it's looking at is a group, it just dives into that group and looks at all of its components by recursively calling the same function.  Same for compound paths.  It's also set up to handle most raster images, reporting back if its a colorized bitmap or a CMYK image, etc.

 

 

Where the script fails, however, is when it runs into a compound path that contains a group.  Now, normally, this wouldn't even be possible in Illustrator.  If you try to create a group of two paths, then compound them, Illustrator just removes the grouping.  However, there are some programs that some people use which, when exporting to an EPS file from them, some of the paths end up being groups inside of compound paths.  Besides training all of my people here to look for these problem paths, is there anything I can do with the script?  Here is the the script I currently have:

 

 

/**
 * The main part of the script that will run in Illustrator, getting the text of the object we're looking for.
 *
 * @param {File} theFile The file object that will be opened in Illustrator and checked.
 */
function findInfo(theFile)
{
          var document = app.open(theFile);
          var prodInfo = new Array;
 
 
          // This first section of the Illustrator script will just get the template name of the current product.
          var templateName = new String;
 
 
          var templateLayer = document.layers[2];
          $.writeln(templateLayer.name);
          for (var i = templateLayer.pageItems.length - 1; i >= 0; i--)
          {
                    var pName = templateLayer.pageItems[i].name;
                    if (pName != "")
                    {
                              templateName = templateLayer.pageItems[i].name;
                    }
          }
 
 
          $.writeln("templateName (inside Illustrator Script) is " + templateName);
 
 
          // This second section of the Illustrator script will gather all of the used colors and store them in an array.
          var colorsArray = [];
          var bHalftones = false;
          var bFourCP = false;
          var bReg = false;
          colorsInUse(document.layers[0]);
 
 
          function colorsInUse(currPageItem) {
                    for (var i = 0; i < currPageItem.pageItems.length; i++) {
                              // Stepping through each item on the layer.
                              var currentItem = currPageItem.pageItems[i];
                              // $.writeln("current item is " + currentItem.typename);
                              // $.writeln("Does it have a fill color? " + currentItem.fillColor);
                              if (currentItem.typename === "GroupItem" && !currentItem.guides) {
                                        // If it's a group, dig into the group and start the function over.
                                        colorsInUse(currentItem);
                              } else if (currentItem.typename == "TextFrame") {
                                        var charAttrib = currentItem.textRange.characterAttributes;
                                        getColors(charAttrib, colorsArray);
                              } else if (currentItem.typename === "RasterItem") {
                                        if (currentItem.imageColorSpace === ImageColorSpace.CMYK) {
                                                  $.writeln("Four-color process image in artwork.");
                                        } else if (currentItem.channels > 1 || currentItem.imageColorSpace === ImageColorSpace.GrayScale) {
                                                  if (currentItem.colorants[0] === "Gray") {
                                                            if (colorsArray.toString().indexOf("Black") === -1) {
                                                                      colorsArray.push("Black");
                                                            }
                                                            alert("When this script is finished, please verify that the Ink/PMS table has the correct colors.");
                                                  } else {
                                                            if (colorsArray.toString().indexOf(currentItem.colorants[0]) === -1) {
                                                                      colorsArray.push(currentItem.colorants[0]);
                                                            }
                                                  }
                                        } else {
                                                  alert("The raster image in the art file must be a 1-channel bitmap and, thus, script cannot determine its color.");
                                        }
                              } else if ((currentItem.fillColor || currentItem.strokeColor) && !currentItem.guides) {
                                        // If the current object has either a fill or a stroke, continue.
                                        if (currentItem.pathPoints.length > 2 || (currentItem.pathPoints == 2 && currentItem.stroked && currentItem..strokeWidth >= 0.1))
                                        {
                                                  // If the current object has 2 points and a good stroke, or more than two points, continue.
                                                  getColors(currentItem, colorsArray);
                                        }
                              } else if (currentItem.typename === "CompoundPathItem") {
                                        for (var c = 0; c < currentItem.pathItems.length; c++) {
                                                  if (currentItem.pathItems[c].pathPoints.length > 2 || (currentItem.pathItems[c].pathPoints == 2 && currentItem.pathItems[c].stroked && currentItem.pathItems[c].strokeWidth >= 0.1))
                                                  {
                                                            // If the current object has 2 points and a good stroke, or more than two points, continue.
                                                            getColors(currentItem.pathItems[c], colorsArray);
                                                  }
                                        }
                              }
                    }
                    return;
          }
 
 
          function getColors(currentItem, colorsArray)
          {
                    try
                    {
                              var fillColorType = currentItem.fillColor.typename;
                              var strokeColorType = currentItem.strokeColor.typename;
                              $.writeln("fillColorType is " + fillColorType);
                              switch (fillColorType) {
                                        case "CMYKColor":
                                                  if (currentItem.fillColor.cyan === 0 && currentItem.fillColor.magenta === 0 && currentItem.fillColor.yellow === 0) {
                                                            if (currentItem.fillColor.black > 0) {
                                                                      if (colorsArray.toString().indexOf("Black") === -1) {
                                                                                colorsArray.push("Black");
                                                                      }
                                                                      if (currentItem.fillColor.black < 100) {bHalftones = true;}
                                                            }
                                                  } else {
                                                            // $.writeln("Four color process!");
                                                            bFourCP = true;
                                                            bHalftones = true;
                                                  }
                                                  break;
                                        case "GrayColor":
                                                  if (currentItem.fillColor.gray > 0) {
                                                            if (colorsArray.toString().indexOf("Black") === -1) {
                                                                      colorsArray.push("Black");
                                                            }
                                                            if (currentItem.fillColor.gray < 100) {bHalftones = true;}
                                                  }
                                                  break;
                                        case "SpotColor":
                                                  if (colorsArray.toString().indexOf(currentItem.fillColor.spot.name) === -1 && currentItem.fillColor.spot.name.toLowerCase().indexOf("white") === -1) {
                                                            colorsArray.push(currentItem.fillColor.spot.name);
                                                  }
                                                  if (currentItem.fillColor.tint < 100) {bHalftones = true;}
                                                  break;
                                        case "GradientColor":
                                                  bHalftones = true;
                                                  for (var j = 0; j < currentItem.fillColor.gradient.gradientStops.length; j++) {
                                                            var gStop = currentItem.fillColor.gradient.gradientStops[j].color;
                                                            switch (gStop.typename) {
                                                                      case "GrayColor":
                                                                                if (colorsArray.toString().indexOf("Black") === -1) {
                                                                                          colorsArray.push("Black");
                                                                                }
                                                                                break;
                                                                      case "SpotColor":
                                                                                if (colorsArray.toString().indexOf(gStop.spot.name) === -1) {
                                                                                          colorsArray.push(gStop.spot.name);
                                                                                }
                                                                                break;
                                                                      case "CMYKColor":
                                                                                if (gStop.cyan === 0 && gStop.magenta === 0 && gStop.yellow === 0 && gStop.black > 0) {
                                                                                          if (colorsArray.toString().indexOf("Black") === -1) {
                                                                                                    colorsArray.push("Black");
                                                                                          }
                                                                                          if (gStop.black < 100) {bHalftones = true;}
                                                                                } else if (gStop.cyan === 0 && gStop.magenta === 0 && gStop.yellow === 0 && gStop.black === 0) {
                                                                                          break;
                                                                                } else {
                                                                                          // $.writeln("Four color process.");
                                                                                          bFourCP = true;
                                                                                          bHalftones = true;
                                                                                }
                                                                                break;
                                                                      default:
                                                                                // $.writeln("Four color process?");
                                                                                bFourCP = true;
                                                                                bHalftones = true;
                                                            }
                                                  }
                                                  break;
                                        case "NoColor":
                                                  break;
                                        default:
                                                  // $.writeln("The fill color on object number " + i + " is of type " + fillColorType);
                              }
 
 
                              switch (strokeColorType) {
                                        case "CMYKColor":
                                                  if (currentItem.strokeColor.cyan === 0 && currentItem.strokeColor.magenta === 0 && currentItem.strokeColor.yellow === 0) {
                                                            if (currentItem.strokeColor.black > 0) {
                                                                      if (colorsArray.toString().indexOf("Black") === -1) {
                                                                                colorsArray.push("Black");
                                                                      }
                                                                      if (currentItem.strokeColor.black < 100) {bHalftones = true;}
                                                            }
                                                  } else {
                                                            // $.writeln("Four color process!");
                                                            bFourCP = true;
                                                            bHalftones = true;
                                                  }
                                                  break;
                                        case "GrayColor":
                                                  if (currentItem.strokeColor.gray > 0) {
                                                            if (colorsArray.toString().indexOf("Black") === -1) {
                                                                      colorsArray.push("Black");
                                                            }
                                                            if (currentItem.strokeColor.gray < 100) {bHalftones = true;}
                                                  }
                                                  break;
                                        case "SpotColor":
                                                  if (colorsArray.toString().indexOf(currentItem.strokeColor.spot.name) === -1) {
                                                            colorsArray.push(currentItem.strokeColor.spot.name);
                                                  }
                                                  if (currentItem.strokeColor.tint < 100) {bHalftones = true;}
                                                  break;
                                        case "GradientColor":
                                                  bHalftones = true;
                                                  for (var j = 0; j < currentItem.strokeColor.gradient.gradientStops.length; j++) {
                                                            var gStop = currentItem.strokeColor.gradient.gradientStops[j].color;
                                                            switch (gStop.typename) {
                                                                      case "GrayColor":
                                                                                if (colorsArray.toString().indexOf("Black") === -1) {
                                                                                          colorsArray.push("Black");
                                                                                }
                                                                                break;
                                                                      case "SpotColor":
                                                                                if (colorsArray.toString().indexOf(gStop.spot.name) === -1) {
                                                                                          colorsArray.push(gStop.spot.name);
                                                                                }
                                                                                break;
                                                                      case "CMYKColor":
                                                                                if (gStop.cyan === 0 && gStop.magenta === 0 && gStop.yellow === 0 && gStop.black > 0) {
                                                                                          if (colorsArray.toString().indexOf("Black") === -1) {
                                                                                                    colorsArray.push("Black");
                                                                                          }
                                                                                          if (gStop.black < 100) {bHalftones = true;}
                                                                                } else if (gStop.cyan === 0 && gStop.magenta === 0 && gStop.yellow === 0 && gStop.black === 0) {
                                                                                          break;
                                                                                } else {
                                                                                          // $.writeln("Four color process.");
                                                                                          bFourCP = true;
                                                                                          bHalftones = true;
                                                                                }
                                                                                break;
                                                                      default:
                                                                                // $.writeln("Four color process?");
                                                                                bFourCP = true;
                                                                                bHalftones = true;
                                                            }
                                                  }
                                                  break;
                                        case "NoColor":
                                                  break;
                                        default:
                                                  // $.writeln("The stroke color on object number " + i + " is of type " + strokeColorType);
                              }
                    }
                    catch (e) {/* If an error was found with the fill color and/or stroke color, then just skip this particular path item. */};
                    return;
          }
 
 
          document.close(SaveOptions.DONOTSAVECHANGES);
 
 
          // Now we combine the gathered items into a single array and return it.
          if ((colorsArray.length > 1 && !/HI/.test(templateName.substring(0, 2))) || bFourCP) {bReg = true;}
          prodInfo.push(templateName, colorsArray, bHalftones, bFourCP, bReg);
 
 
          return prodInfo.toSource();
};

 

I know it's kinda messy right now, with a lot of `$.writeln`s for debugging purposes, some of which are even commented out because they caused errors.  Anyway, I would be immensely grateful for any help with this issue.

 
Replies
  • Currently Being Moderated
    Oct 18, 2013 1:47 PM   in reply to Sturm359

    what happens when you have a group inside a compound path? do you get errors or the paths inside the group just get ignored? if so then you could just traverse the groups inside the cp

     

    from this

    } else if (currentItem.typename === "CompoundPathItem") {
                                            for (var c = 0; c < currentItem.pathItems.length; c++) {
                                                 .
                                                 .
                                            }
    

     

     

    to this

    } else if (currentItem.typename === "CompoundPathItem") {
                                            for (var c = 0; c < currentItem.pathItems.length; c++) {
                                                 .
                                                 .
                                            }
                                            for (var d = 0; d < currentItem.groupItems.length; d++) {
                                                 colorsInUse(currentItem.groupItems[d]);
                                                 .
                                            }
    
     
    |
    Mark as:
  • Currently Being Moderated
    Oct 21, 2013 9:29 AM   in reply to Sturm359

    can you share a file with a troubled compoundPath?

     
    |
    Mark as:
  • Currently Being Moderated
    Oct 21, 2013 10:12 AM   in reply to Sturm359

    can you save it down to CS5 please?

     
    |
    Mark as:
  • Currently Being Moderated
    Oct 21, 2013 11:29 AM   in reply to Sturm359

    the only thing I can think of, is to go through all the items at the Document level, instead of at the Layer level, that way the script will see all paths

     

    change this

    colorsInUse(document.layers[0]);

     

    to this

    colorsInUse(document);

     
    |
    Mark as:
  • Currently Being Moderated
    Oct 21, 2013 11:50 AM   in reply to Sturm359

    it'll take more time but it will probably be unnoticeable, check for the Layer property of each item, if it is other than your target layer...ignore.

     

    the difference is, at the Layer level, the script only sees main pageItems, for instance if you only have 2 path items (grouped) in a layer, you won't be able to access them directly, you only see 1 group item, you'll have to explicitly go inside the group to access those two path items.

     

    alert(document.pathItems.length); // returns 2
     
    alert(document.layers[0].pathItems.length; // returns 0
    
     
    |
    Mark as:
  • Currently Being Moderated
    Oct 21, 2013 1:37 PM   in reply to Sturm359

    you're welcome,

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (1)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points