Copy link to clipboard
Copied
I'm trying to write a script that selects all items on the layer "Text Layer" and then run pathfinder subtract. Here is what I have but it continue to error out. Any help would be appreciated.
I'm getting Error Number: 1287
Error String: Cannot determine the spread this object is on. It might be an anchored object the is in overset or uncomposed text
Line: 5
Sourc: textLayer.pageItems.everyItem().select();
var doc = app.activeDocument;
var textLayer = doc.layers.itemByName("Text Layer");
textLayer.pageItems.everyItem().select();
app.executeMenuCommand("Minus Front");
Copy link to clipboard
Copied
If the items are on multiple pages, select won't work. Instead iterate through the items and select individually.
Copy link to clipboard
Copied
Is there a way to do that with a script? I'm outlining all the text on that layer and then I want it to select all items. In this case there are 3 items, first name last name and a white box below those. We're hoping that we can select all those items and then apply the pathfinder subtract so it creates a mask essentially.
Copy link to clipboard
Copied
I'm not JS guy so can't give you working code, but you need to iterate through the collection of PageItems, push all that are on the same page and same layer and then use what you've found for selection.
Copy link to clipboard
Copied
As Brian and Robert mentioned, you need to work page by page. On each page get the frames on the text layer, then use InDesign's subtractPath() method:
function textLayerFrames (page) {
var f = page.pageItems.everyItem().getElements();
var a = [];
for (var i = 0; i < f.length; i++) {
if (f[i].itemLayer.name === 'Text Layer') {
a.push (f[i]);
}
}
return a;
}
pages = app.documents[0].pages.everyItem().getElements();
for (i = 0; i < pages.length; i++) {
frames = textLayerFrames (pages[i]);
frames[0].subtractPath (frames);
}
You're not working with any selection here. Working with selections should really be avoided as much as possible, working with script functions such as subtractPath() are much more robust.
P.
Copy link to clipboard
Copied
Peter,
Thanks for this. It seems to be almost doing what I would like, just in reverse. I've attached images of the goal vs what is happening once I run the script. Pervious to this I outline all the text in the doc.
This image is where we start. The outlined text are compound objects then the white box.
This image is if I select the three items on the Text Layer (ctrl-a) and then run pathfinder subtract. This is the final look we are trying to achieve across the entire document.
This is the result I'm getting when I run the script.
Copy link to clipboard
Copied
Because script have no idea which object should be used as a reference.
And it probably should combine TextObjects first then cut it from the white box.
Copy link to clipboard
Copied
Robert is probably right: it's a matter of the stacking order of the objects and how a script orders the objects. Can you show the content of the text layer? Is the image on that layer or somewhere else? Maybe post your document (or a small representative sample).
Actually, try replacing subtractPath with excludeOverlapPath and see whether makes a difference.
Copy link to clipboard
Copied
After some test, i think that the problem is the order of the elements of the array.
Given three objects (Rectangle (white frame), polygon (outlined text), textFrame) it doesn’t matter how they are stacked in the ‘Text Layer’, their order in the array is always the same: rectangle, polygon, textframe.
You have to rearrange the array and then the script works.
function textLayerFrames (page) {
var f = page.pageItems.everyItem().getElements();
var a = [];
for (var i = 0; i < f.length; i++) {
if (f[i].itemLayer.name === 'Text Layer') {
a.push (f[i]);
}
}
alert(a);
var b = [];
b.push(a[2]);
b.push(a[1]);
b.push(a[0]);
alert(b);
return b;
}
pages = app.documents[0].pages.everyItem().getElements();
for (i = 0; i < pages.length; i++) {
frames = textLayerFrames (pages[i]);
frames[0].subtractPath (frames);
}
Copy link to clipboard
Copied
Elements in the collection are always ordered by the creation order.
To be honest I don't understand why the script works - maybe InDesign is simply ignoring the fact that in your array you have the same object that you are using as the "reference" point - would be much safer - and correct - if your array won't contain white rectangle at all - just the outlined text and TF.
Copy link to clipboard
Copied
Hi @Robert Tkaczyk.
As you can see in the 3 cols. image, it doesn't matter the creation order (in my case, copy and paste).
Array 'a' has always the same order: rectangle, polygon, text frame.
I don't know why.
Copy link to clipboard
Copied
Stacking order is elusive. It was discussed in this forum some years ago, and its behaviour changed at some stage. An experiment now shows that pageItems and allPageItems show different behaviour w.r.t. stacking order. Take this situation:
Two rectangles and two text frames. The 0 and 1 suffixes denote the order of creation. The frames in the screenshot were moved around a bit (order of creation was texxt frame 0, text frame 1, rectangle 0, rectangle 1).
This script:
items = app.documents[0].pageItems.everyItem().getElements();
for (i = 0; i < items.length; i++) {
$.writeln (items[i].name + ' -- ' + items[i].index);
}
prints this in the console:
rectangle 1 -- 0
rectangle 0 -- 1
text frame 0 -- 0
text frame 1 -- 1
That is, no matter the creation order, the order is the order in the Layers panel but grouped by item type: rectangles before text frames.
However, this script
items = app.documents[0].allPageItems;
for (i = 0; i < items.length; i++) {
$.writeln (items[i].name + ' -- ' + items[i].index);
}
prints the items in the order shown in the Layers panel:
text frame 0 -- 0
rectangle 1 -- 0
text frame 1 -- 1
rectangle 0 -- 1
Copy link to clipboard
Copied
@Peter Kahrel thank you for the explanation.
Copy link to clipboard
Copied
So, what happens if you replace
var f = page.pageItems.everyItem().getElements();
with
var f = page.allPageItems;
in the script above? If you see the reverse of what you expect, then reverse the array by using unshift() instead of push(): replace
a.push (f[i]);
with
a.unshift (f[i]);
Which of course is pretty whacky. You could also try a different pathfinder method (minusBack(), intersectPath(), etc.).
P.