Copy link to clipboard
Copied
The ultimate goal of this script is to create a sort of plain black text version of a copy layer (with text that sometimes has various effects/appearances applied).
I've got a multi-part script I'm trying to write that will do a few things in order. I've got a few bits cobbled together from other scripts, but it's not entirely working and there's some bits of functionality I don't know how to fit in there. It's actually a bit of a mess and I'm sure there must be a more efficient way to go about it. Could anybody take a look and either point me in the right direction or (if someone had the time) create a more efficient version of this.
What I need the script to do:
1. Lock all Layers
2. Duplicate Layer "SOURCE"
3. Rename duped layer to "SOURCE APPROVAL" & hide all other layers
4. Move "SOURCE APPROVAL" layer to below "SOURCE" layer in layers palette
5. Outline all text on "SOURCE APPROVAL" layer
6. Select everything, remove all strokes, and change the Fill color of all objects (whether regular items or compound paths or grouped) to black (only on "SOURCE APPROVAL" layer)
What I've got so far is a giant mess that does some things, but not others. I haven't been able to get the layers to move to a specific point in the layers palette and I can't seem to affect compound paths to change their color or remove their strokes.
var docRef = app.activeDocument;
var myLayers = docRef.layers;
var layer = app.activeDocument.activeLayer;
var flatBlack= new CMYKColor()
flatBlack.black=100;
for (a=0; a<myLayers.length; a++){
myLayer = myLayers;
myLayer.locked = true;
}
#target illustrator
var ln = 'SOURCE';
var ol = docRef.layers.getByName(ln);
var nl = docRef.layers.add();
nl.name = ln+' APPROVAL';
for (var a = ol.pageItems.length-1; a >= 0; a--) {
ol.pageItems.duplicate(nl, ElementPlacement.PLACEATBEGINNING);
}
app.executeMenuCommand("selectall");
app.executeMenuCommand("ungroup");
app.executeMenuCommand("outline");
// Iterate through all path items
for (var i = 0; i < nl.pathItems.length; i++) {
with (nl.pathItems) {
if (filled == true) {
// If black exceeds maxBlack clip it to flat black (100%K)
fillColor = flatBlack;
}
if (stroked == true) {
stroked = false;
}
}
}
Thanks for the test file.
Like this?
...#target illustrator
(function () {
var docRef = app.activeDocument,
myLayers = docRef.layers,
layer = app.activeDocument.activeLayer,
flatBlack = new CMYKColor(),
ln = 'SOURCE',
nln = ln + ' APPROVAL',
ol = docRef.layers.getByName(ln),
nl = docRef.layers.add(),
pathItem,
i,
max;
function isContainedInApprovalLayer(target) {
if (target.parent.typename === "Document") {
Copy link to clipboard
Copied
Hello, paddirn.
Please try this and read the explanation in the code.
// #target illustrator
(function () {
var docRef = app.activeDocument,
myLayers = docRef.layers,
layer = app.activeDocument.activeLayer,
flatBlack = new CMYKColor(),
ln = 'SOURCE',
ol = docRef.layers.getByName(ln),
nl = docRef.layers.add(),
myPathItem,
i;
function dismantleCompoundPathItem() {
app.executeMenuCommand("selectall");
app.executeMenuCommand("noCompoundPath");
}
function ungroup() {
app.executeMenuCommand("selectall");
app.executeMenuCommand("releaseMask");
app.executeMenuCommand("ungroup");
}
nl.name = ln + ' APPROVAL';
flatBlack.black = 100;
// (When the layer and the relativeObject are locked, the layer can't move.)
// >> 4. Move "SOURCE APPROVAL" layer to below "SOURCE" layer in layers palette
nl.move(ol, ElementPlacement.PLACEAFTER);
for (i = ol.pageItems.length - 1; i >= 0; i -= 1) {
// (change "ElementPlacement.PLACEATBEGINNING" to "ElementPlacement.INSIDE".)
ol.pageItems.duplicate(nl, ElementPlacement.INSIDE);
}
for (i = 0; i < myLayers.length; i += 1) {
myLayers.locked = true;
}
// unlock to edit objects in "nl" layer.
nl.locked = false;
// >> 3. ... hide all other layers
for (i = 0; i < myLayers.length; i += 1) {
myLayers.visible = false;
}
nl.visible = true;
app.executeMenuCommand("selectall");
app.executeMenuCommand("outline");
// dismantle compoundpathitems
if (0 < nl.compoundPathItems.length) {
dismantleCompoundPathItem();
}
// clear clipping path and ungroup
while (0 < nl.groupItems.length) {
ungroup();
}
for (i = 0; i < nl.pathItems.length; i += 1) {
myPathItem = nl.pathItems;
if (myPathItem.filled === true) {
myPathItem.fillColor = flatBlack;
}
if (myPathItem.stroked === true) {
myPathItem.stroked = false;
}
}
// >> 1. Lock all Layers
nl.locked = true;
}());
Copy link to clipboard
Copied
Thanks for taking a look at it, that code looks alot better than the junk I was try to cludge together. I ran the script and it does do a good portion, but it's still getting stuck on a part of the problem I've been having with it. I probably didn't explain it well enough. I'm trying to get it to outline/fill with Black a variety of type styles/appearances that may be setup in our files.
So the test file I'm running it on looks like this:
After I ran your script, it ends up looking like this:
So all the copy is outlined and some paths change to black/lose strokes, which is what I needed, but the outlined text itself doesn't change color and some of the strokes on the text doesn't actually lose it's stroke. It also didn't touch the invisible objects, which is a good thing.
I tried adjusting the last portion of it that adds the fill and removes the strokes, but that didn't seem to do it either:
while (0 < nl.groupItems.length) {
ungroup();
}
for (i = 0; i < nl.pathItems.length; i += 1) {
myPathItem = nl.pathItems;
myCompoundPathItem = nl.compoundPathItems;
if (myPathItem.filled === true) {
myPathItem.fillColor = flatBlack;
}
if (myPathItem.stroked === true) {
myPathItem.stroked = false;
}
if (myCompoundPathItem.filled === true) {
myCompoundPathItem.fillColor = flatBlack;
}
if (myCompoundPathItem.stroked === true) {
myCompoundPathItem.stroked = false;
}
}
Copy link to clipboard
Copied
Sorry. nl layer don't have compound item due to dismantleCompoundPathItem().
Could you attach that test file ?
Copy link to clipboard
Copied
Sure thing, Not quite sure how to attach things on here, but here's a link: https://www.dropbox.com/s/qebzffy85rg40h4/TextStylesTest.ai?dl=0
The test file is meant to simulate many of the likely scenarios we might come across working on our files. To give some background, alot of times we pull art forward and make minor changes, but because so many different people have been in and out of the files over the years, files can get weird sometimes. Some of the designers we've had just do things differently or got sloppy files from an agency and didn't clean up the files afterwards. So we're constantly having to keep a lookout for booby traps (even in how the text is constructed). For proofreading purposes, we're wanting to submit a black and white document to proofreaders and other departments to verify the accuracy of the info and to avoid them getting distracted by any other visual elements, thus the need for this script to quickly output a "plain text" proofreading document.
Also, I recreated the file at home on CS6, whereas we use CC2017 at work. Not sure if anything in AI scripting changed between the two.
Copy link to clipboard
Copied
Thanks for the test file.
Like this?
#target illustrator
(function () {
var docRef = app.activeDocument,
myLayers = docRef.layers,
layer = app.activeDocument.activeLayer,
flatBlack = new CMYKColor(),
ln = 'SOURCE',
nln = ln + ' APPROVAL',
ol = docRef.layers.getByName(ln),
nl = docRef.layers.add(),
pathItem,
i,
max;
function isContainedInApprovalLayer(target) {
if (target.parent.typename === "Document") {
if (target.name === nln) {
return true;
}
return false;
}
return isContainedInApprovalLayer(target.parent);
}
nl.name = nln;
flatBlack.black = 100;
nl.move(ol, ElementPlacement.PLACEAFTER);
for (i = ol.pageItems.length - 1; i >= 0; i -= 1) {
ol.pageItems.duplicate(nl, ElementPlacement.INSIDE);
}
for (i = 0, max = myLayers.length; i < max; i += 1) {
myLayers.locked = true;
}
nl.locked = false;
for (i = 0, max = myLayers.length; i < max; i += 1) {
myLayers.visible = false;
}
nl.visible = true;
docRef.selection = null;
for (i = 0, max = nl.symbolItems.length; i < max; i += 1) {
nl.symbolItems.selected = true;
}
// expand symbol item.
app.executeMenuCommand('Expand3');
app.executeMenuCommand('selectall');
app.executeMenuCommand('outline');
docRef.selection = null;
for (i = 0, max = nl.groupItems.length; i < max; i += 1) {
nl.groupItems.selected = true;
}
// Register action to "Clear Appearance" only in advance.
// ("Clear Appearance" in the menu of Appearance panel)
app.doScript("myAction", "myActionSet");
for (i = 0, max = docRef.pathItems.length; i < max; i += 1) {
pathItem = docRef.pathItems;
if (isContainedInApprovalLayer(pathItem) && pathItem.locked === false && pathItem.hidden === false) {
if (pathItem.filled === true) {
pathItem.fillColor = flatBlack;
}
if (pathItem.stroked === true) {
pathItem.stroked = false;
}
}
}
nl.locked = true;
}());
Copy link to clipboard
Copied
Thank you very much! Didn't catch what it meant with the "// Register action to..." line at first and assumed it was something the script was supposed to be doing (instead of on my end), but then figured it out and got it working. This does absolutely everything we needed it to do, that's fantastic. Thank you very much sir, this is awesome!