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.
your script can't see all pathItems 'cause your root is a layer, if you change
colorsInUse(document.layers[0]);
to
colorsInUse(document);
you'll see all pathItems, even this included inside a compoundPath