Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Indesign Script to automatically match layers in Illustrator

Explorer ,
Apr 05, 2025 Apr 05, 2025

Hi!

I was hoping one of the scripting geniuses around here could lend a hand. I stumbled on the Script below in another forum and it almost does exactly what I need. Essentially if I have an Indesign document with Layers A, B, and C, the script will look through the linked .psd and if there is a Layer with the matching name in the .psd it will turn on that layer. This is perfect but I'm usually using .ai files more often than .psd so I was curious if anyone knew how to modify it to do the same thing in Illustrator. My coding knowledge is basically non existent for reference haha.

Best,

Matt

 

Original Link: https://creativepro.com/topic/automate-change-object-layer-option/

 

// Select an InDesign layer. Check for any Photoshop images on that layer in the document.
// If so, if the PSD file has a layer with the same name, set it visible
// set all other PSD layers that match with other InDesign layer names invisible
// Any non-matching layer name in PSD remains untouched (which usually includes the Background layer)
//
// Hence on ID layers X,Y,Z the Photoshop files have layer X visible and Y,Z invisible on the ID X layer if X layer is selected
// ,, Y X,Z Y Y
// ,, Z X,Y Z Z
//
// A n additional radiobutton allows all InDesign layers to be checked

main();
exit();

//--------------------------------------------------------------------------------------------------------------------------
function main()
{
var myDoc = app.activeDocument;
var myLayers = myDoc.layers;
var selectedLayer; // list of layers to process. Can be one or all
var numChanges;

// ask what layer to use to modify images
selectedLayer = selectLayer(myLayers);

numChanges = 0;
for (var i=0;i<selectedLayer.length;i++){
numChanges = + setPSDlayerVisible(selectedLayer[i])
};
alert ("Finished. \r Changed " + numChanges + " image layer visibility settings on " + selectedLayer.length + " InDesign layers");
exit();
}

//--------------------------------------------------------------------------------------------------------------------------

function setPSDlayerVisible(selectedLayer){

// go through all pages of the document, select the layer indicated, open all images if PhotoShop made
// and set all layers invisbile except for layer with same name as selected layer
// Return the number of changed visibility properties in the Photoshop files in the specified document layer

var links, placedFile, PSDlayer, numChanges;

// store all layers in InDesign document
var docLayers = app.activeDocument.layers;

// start with no modifications
numChanges = 0;

// only look for images that have their roots in external files, i.e. have links
links = app.activeDocument.links;
for (var i = 0; i < links.length; i++){

// get the file info from the link: stored as "parent" of the link
placedFile = links[i].parent;

// file must be an image, not null (not embedded) and made by Photoshop
if (placedFile.constructor.name == "Image" && placedFile.itemLink != null && placedFile.itemLink.linkType == "Photoshop" ){
//$.writeln ("1 found: "+ placedFile.itemLink.filePath + " on ID layer " + placedFile.itemLayer.name);

imageChange = false;
//$.write ("2 PSD file on selected layer " );
if (placedFile.itemLayer == selectedLayer){
//$.writeln (" - Yes");

// check if Photoshop file has a layer by the same name as one of the InDesign layers.
// If it does not exist, the layer will be invalid, if it does, check if the psd layer name matches an InDesign layer name.
// If that is so, set visibility true only for the layer with the same name as the selectedLayer, otherwise set layer invisible
for (var n = 0; n < docLayers.length;n++){
placedFile = links[i].parent; // after any modification of a linked object, it is replaced, so reset it to use the old object at its new location
layer = placedFile.graphicLayerOptions.graphicLayers.item(docLayers[n].name);

if (layer.isValid){
if (layer.name == selectedLayer.name){
if (layer.currentVisibility != true){
//$.writeln("psd/InDesign layer names the same - layer set visible");
layer.currentVisibility = true;
imageChange = true;
}
else{
//$.writeln("psd/InDesign layer names the same - layer already visible");
}
}
else{
if (layer.currentVisibility != false){
//$.writeln("psd/InDesign layer names different - layer set invisible");
layer.currentVisibility = false;
imageChange = true;
}
else{
//$.writeln("psd/InDesign layer names different - layer already invisible");
}
}

// count the number of changes made
if (imageChange){
numChanges++;
}
else{
}
}
else{
//$.writeln ("Layer invalid (not found)");
}
} // next docLayer
}
else{
//$.writeln (" - No");
}
}
else{
//$.writeln ("No photoshop file");
}
} // next linked file

return numChanges;
}

function selectLayer(allLayers, nrLayers){
// present all layer names in document. Allow selection of a single one or all.
// The selection is returned as an array with only 1 element or as many as there are levels.
// Each element is added to the array by push and filled with a layer object

var result=[];

// create dialog
var myDialog = app.dialogs.add({name:"Select document layer (with PSD images) ", canCancel:true});

// within the dialog box it all happens in its columns - create a radiobutton group for a series of radiobuttons
// - one button for each layer plus a button for "all layers".
// Only one button can be selected at any time. The buttongroup will obtain its value.
// Set the first button as the initially selected layer.

with (myDialog.dialogColumns.add () ){
with (borderPanels.add() ){
staticTexts.add({staticLabel:"Specify InDesign layer to sync Photoshop image layers:"});
var myRadioButtonGroup = radiobuttonGroups.add();
with(myRadioButtonGroup){
for (var i=0; i< allLayers.length; i++){
radiobuttonControls.add({staticLabel: allLayers[i].name});
}
radiobuttonControls.add({staticLabel: "All InDesign layers"});
radiobuttonControls[0].properties=({checkedState:true});
}
}
};

// show the box
var myResult = myDialog.show();

// check for OK or Cancel
if (myResult == true){
// make a difference between a single selected layer or all layers (selected button (last) then length-1 since buttons start to count from 0)
with (myDialog.dialogColumns[0].borderPanels[0].radiobuttonGroups[0]){
if(radiobuttonControls.length-1== myRadioButtonGroup.selectedButton ){
for (var i=0;i<allLayers.length;i++){
result.push(allLayers[i]);
}
}
else{ // array has a single element :the one selected layer
result.push (allLayers[myRadioButtonGroup.selectedButton]);
}
}
}
else {
result = [];
}

// delete dialog box
myDialog.destroy;
if (result == []){
alert ("Operation cancelled");
exit();
}
else{
return result;
}
}

 

TOPICS
Scripting
113
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Apr 05, 2025 Apr 05, 2025

@Little_Matty 

 

You're welcome.

 

This should work for BOTH cases - Images and PDFs/AIs - without the need for two separate scripts:

 

// file must be an image, not null (not embedded) and made by Photoshop
if ((placedFile.constructor.name == "Image" && placedFile.itemLink != null && placedFile.itemLink.linkType == "Photoshop" ) || (placedFile.constructor.name == "PDF" && placedFile.itemLink != null && placedFile.itemLink.linkType == "Adobe Portable Document Format (PDF)" )){

 

But then, for c

...
Translate
Community Expert ,
Apr 05, 2025 Apr 05, 2025

Sorry, I don't have time to analyze the whole code - but you'll most likely need to change this line:

 

// file must be an image, not null (not embedded) and made by Photoshop
if (placedFile.constructor.name == "Image" && placedFile.itemLink != null && placedFile.itemLink.linkType == "Photoshop" ){

to:

// file must be an image, not null (not embedded) and made by Photoshop
if (placedFile.constructor.name == "PDF" && placedFile.itemLink != null && placedFile.itemLink.linkType == "Adobe Portable Document Format (PDF)" ){

 

 

Marked in green is value for "placedFile.constructor.name".

Marked in red is value for "placedFile.itemLink.linkType".

 

RobertatIDTasker_1-1743892625720.png

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 05, 2025 Apr 05, 2025

Worked perfectly, thank you!

For anyone wondering, here is the complete script. Forums like these have been invaluable for me so I just wanted to pass the along the good will.

-Matt

 

//
// Select an InDesign layer. Check for any Photoshop images on that layer in the document.
// If so, if the PSD file has a layer with the same name, set it visible
// set all other PSD layers that match with other InDesign layer names invisible
// Any non-matching layer name in PSD remains untouched (which usually includes the Background layer)
//
// Hence on ID layers X,Y,Z the Photoshop files have layer X visible and Y,Z invisible on the ID X layer if X layer is selected
// ,, Y X,Z Y Y
// ,, Z X,Y Z Z
//
// A n additional radiobutton allows all InDesign layers to be checked

main();
exit();

//--------------------------------------------------------------------------------------------------------------------------
function main()
{
var myDoc = app.activeDocument;
var myLayers = myDoc.layers;
var selectedLayer; // list of layers to process. Can be one or all
var numChanges;

// ask what layer to use to modify images
selectedLayer = selectLayer(myLayers);

numChanges = 0;
for (var i=0;i<selectedLayer.length;i++){
numChanges = + setPSDlayerVisible(selectedLayer[i])
};
alert ("Finished. \r Changed " + numChanges + " image layer visibility settings on " + selectedLayer.length + " InDesign layers");
exit();
}

//--------------------------------------------------------------------------------------------------------------------------

function setPSDlayerVisible(selectedLayer){

// go through all pages of the document, select the layer indicated, open all images if PhotoShop made
// and set all layers invisbile except for layer with same name as selected layer
// Return the number of changed visibility properties in the Photoshop files in the specified document layer

var links, placedFile, PSDlayer, numChanges;

// store all layers in InDesign document
var docLayers = app.activeDocument.layers;

// start with no modifications
numChanges = 0;

// only look for images that have their roots in external files, i.e. have links
links = app.activeDocument.links;
for (var i = 0; i < links.length; i++){

// get the file info from the link: stored as "parent" of the link
placedFile = links[i].parent;

// file must be an image, not null (not embedded) and made by Photoshop
if (placedFile.constructor.name == "PDF" && placedFile.itemLink != null && placedFile.itemLink.linkType == "Adobe Portable Document Format (PDF)" ){
//$.writeln ("1 found: "+ placedFile.itemLink.filePath + " on ID layer " + placedFile.itemLayer.name);

imageChange = false;
//$.write ("2 PSD file on selected layer " );
if (placedFile.itemLayer == selectedLayer){
//$.writeln (" - Yes");

// check if Photoshop file has a layer by the same name as one of the InDesign layers.
// If it does not exist, the layer will be invalid, if it does, check if the psd layer name matches an InDesign layer name.
// If that is so, set visibility true only for the layer with the same name as the selectedLayer, otherwise set layer invisible
for (var n = 0; n < docLayers.length;n++){
placedFile = links[i].parent; // after any modification of a linked object, it is replaced, so reset it to use the old object at its new location
layer = placedFile.graphicLayerOptions.graphicLayers.item(docLayers[n].name);

if (layer.isValid){
if (layer.name == selectedLayer.name){
if (layer.currentVisibility != true){
//$.writeln("psd/InDesign layer names the same - layer set visible");
layer.currentVisibility = true;
imageChange = true;
}
else{
//$.writeln("psd/InDesign layer names the same - layer already visible");
}
}
else{
if (layer.currentVisibility != false){
//$.writeln("psd/InDesign layer names different - layer set invisible");
layer.currentVisibility = false;
imageChange = true;
}
else{
//$.writeln("psd/InDesign layer names different - layer already invisible");
}
}

// count the number of changes made
if (imageChange){
numChanges++;
}
else{
}
}
else{
//$.writeln ("Layer invalid (not found)");
}
} // next docLayer
}
else{
//$.writeln (" - No");
}
}
else{
//$.writeln ("No photoshop file");
}
} // next linked file

return numChanges;
}

function selectLayer(allLayers, nrLayers){
// present all layer names in document. Allow selection of a single one or all.
// The selection is returned as an array with only 1 element or as many as there are levels.
// Each element is added to the array by push and filled with a layer object

var result=[];

// create dialog
var myDialog = app.dialogs.add({name:"Select document layer (with PSD images) ", canCancel:true});

// within the dialog box it all happens in its columns - create a radiobutton group for a series of radiobuttons
// - one button for each layer plus a button for "all layers".
// Only one button can be selected at any time. The buttongroup will obtain its value.
// Set the first button as the initially selected layer.

with (myDialog.dialogColumns.add () ){
with (borderPanels.add() ){
staticTexts.add({staticLabel:"Specify InDesign layer to sync Photoshop image layers:"});
var myRadioButtonGroup = radiobuttonGroups.add();
with(myRadioButtonGroup){
for (var i=0; i< allLayers.length; i++){
radiobuttonControls.add({staticLabel: allLayers[i].name});
}
radiobuttonControls.add({staticLabel: "All InDesign layers"});
radiobuttonControls[0].properties=({checkedState:true});
}
}
};

// show the box
var myResult = myDialog.show();

// check for OK or Cancel
if (myResult == true){
// make a difference between a single selected layer or all layers (selected button (last) then length-1 since buttons start to count from 0)
with (myDialog.dialogColumns[0].borderPanels[0].radiobuttonGroups[0]){
if(radiobuttonControls.length-1== myRadioButtonGroup.selectedButton ){
for (var i=0;i<allLayers.length;i++){
result.push(allLayers[i]);
}
}
else{ // array has a single element :the one selected layer
result.push (allLayers[myRadioButtonGroup.selectedButton]);
}
}
}
else {
result = [];
}

// delete dialog box
myDialog.destroy;
if (result == []){
alert ("Operation cancelled");
exit();
}
else{
return result;
}
}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 05, 2025 Apr 05, 2025
LATEST

@Little_Matty 

 

You're welcome.

 

This should work for BOTH cases - Images and PDFs/AIs - without the need for two separate scripts:

 

// file must be an image, not null (not embedded) and made by Photoshop
if ((placedFile.constructor.name == "Image" && placedFile.itemLink != null && placedFile.itemLink.linkType == "Photoshop" ) || (placedFile.constructor.name == "PDF" && placedFile.itemLink != null && placedFile.itemLink.linkType == "Adobe Portable Document Format (PDF)" )){

 

But then, for clarity, you can edit all the comments where Photoshop is mentioned 😉

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines