Skip to main content
Inspiring
May 13, 2025
Answered

Scripting for layer activation/deactivation, colour change and export of PDF

  • May 13, 2025
  • 1 reply
  • 1356 views

I am new to scripting and have no idea what I am doing... I seek help with developing a script to do the following (if it is possible):

 

  1. Activate a particular layer. (e.g. "Black")
  2. Deactivate a particular layer. (e.g. "CMYK")
  3. Find/replace all instances of a swatch used as a fill in tables (e.g. Find "Yellow" change to "Grey")
  4. Export book to PDF (so the dialogue box is shown and I can choose the appropriate options).

 

Some background on the project...

I have an ID book that contains 40 chapters. Each chapter is one INDD file. Each chapter has a layer named "CMYK" and another "Black". The respective layers contain different versions of artwork as well as background designs that are used in the colour version and the black and white version of the PDF..

 

Rather than manually activating and deactivating layers on 40 different INDD files, and then running a find/replace colour operation, I would like to be able to streamline the process and run a script where all the changes are made in the background and I am presented with a dialogue box to choose the appropriate export settings for the PDF. Is this possible?

 

Thank you to community members in advance. This really is not my area of expertise.

Correct answer exuberant_luminary6979

Final script that incorporates suggestions by @Eugene Tyson and @Manan Joshi

 

#target indesign

// ask for book file
var bookFile = File.openDialog("Select the Book file (.indb)", "*.indb");
if (!bookFile) {
    alert("No book selected.");
    exit();
}

// open the book
var book = app.open(File(bookFile));
var bookDocs = book.bookContents;

// Loop through book
for (var i = 0; i < bookDocs.length; i++) {
    var docPath = bookDocs[i].fullName;
    if (!File(docPath).exists) continue; // skip missing files

    // Open invisible
    var doc = app.open(File(docPath), false);

    // Toggle layers
    toggleLayers(doc, "Black", "CMYK");

    // Find/replace swatch in cells
    replaceTableCellFill(doc, "Yellow copy", "Grey");

    doc.save();
    doc.close();
}

// Save the book
book.save();

alert("All done!");

// --- FUNctions ---
function toggleLayers(doc, activateLayerName, deactivateLayerName) {
    doc.layers.itemByName(activateLayerName).visible = true
    doc.layers.itemByName(deactivateLayerName).visible = false
}

function replaceTableCellFill(doc, findSwatchName, changeSwatchName) {
    var findSwatch = doc.swatches.itemByName(findSwatchName);
    var changeSwatch = doc.swatches.itemByName(changeSwatchName);

    if (!findSwatch.isValid || !changeSwatch.isValid) {
        alert("Swatch '" + findSwatchName + "' or '" + changeSwatchName + "' not found.");
        return;
    }

    var tables = doc.stories.everyItem().tables.everyItem().getElements();
    for (var i = 0; i < tables.length; i++) {
        var cells = tables[i].cells;
        for (var j = 0; j < cells.length; j++) {
            if (cells[j].fillColor == findSwatch) {
                cells[j].fillColor = changeSwatch;
            }
        }
    }
}

  

1 reply

Community Expert
May 13, 2025

Hello - new to scripting too so maybe we can both learn here. 

I'm no way the best scripter and there probably is a better method. But I managed to put something together that worked for my test files. 

I can get it to make a PDF but I cannot get the PDF dialog box to open work - never could

But you can export the PDF after it's finished doing the work.

So here was can blind open the documents in the book and toggle the layers as you said 

 

And there's a line here - so you put in tyour swatch colours (I can't use Yellow for some reason it's locked to the App so I made one called Yellow copy.

Replace these colours with your own names

replaceTableCellFill(doc, "Yellow copy", "Grey");

 

With no documents open - go to Window>Utilities>Scripts and run it - it will ask you to open the book file

then it should cycle the changes - I tested on a very basic document.

 

If it's not wroking the way you want could you please drop a few files for testing. Thanks.

 

TEST ON A DUPLICATE BOOK FILE (back up your book and all files first)

 

#target indesign

// ask for book file
var bookFile = File.openDialog("Select the Book file (.indb)", "*.indb");
if (!bookFile) {
    alert("No book selected.");
    exit();
}

// open the book
var book = app.open(File(bookFile));
var bookDocs = book.bookContents;

// Loop through book
for (var i = 0; i < bookDocs.length; i++) {
    var docPath = bookDocs[i].fullName;
    if (!File(docPath).exists) continue; // skip missing files

    // Open invisible
    var doc = app.open(File(docPath), false);

    // Toggle layers
    toggleLayers(doc, "Black", "CMYK");

    // Find/replace swatch in cells
    replaceTableCellFill(doc, "Yellow copy", "Grey");

    doc.save();
    doc.close();
}

// Save the book
book.save();

alert("All done!");

// --- FUNctions ---
function toggleLayers(doc, activateLayerName, deactivateLayerName) {
    var layers = doc.layers;
    for (var i = 0; i < layers.length; i++) {
        if (layers[i].name == activateLayerName) {
            layers[i].visible = true;
        }
        if (layers[i].name == deactivateLayerName) {
            layers[i].visible = false;
        }
    }
}

function replaceTableCellFill(doc, findSwatchName, changeSwatchName) {
    var findSwatch = doc.swatches.itemByName(findSwatchName);
    var changeSwatch = doc.swatches.itemByName(changeSwatchName);

    if (!findSwatch.isValid || !changeSwatch.isValid) {
        alert("Swatch '" + findSwatchName + "' or '" + changeSwatchName + "' not found.");
        return;
    }

    var tables = doc.stories.everyItem().tables.everyItem().getElements();
    for (var i = 0; i < tables.length; i++) {
        var cells = tables[i].cells;
        for (var j = 0; j < cells.length; j++) {
            if (cells[j].fillColor == findSwatch) {
                cells[j].fillColor = changeSwatch;
            }
        }
    }
}

 

 

 

Community Expert
May 14, 2025

@Eugene Tyson, great take on the problem. I list some pointers that I feel could improve the script more. We could directly change the layer property with something like the following and avoid the loop. This way the code is more optimised.

function toggleLayers(doc, activateLayerName, deactivateLayerName) {
    doc.layers.itemByName(activateLayerName).visible = true
    doc.layers.itemByName(deactivateLayerName).visible = true
}

 Also if you still want to use the loop you should keep a check to break the loop once both the layers have been found and changed, this would speed things up in some cases. For example if there are 50 layers and you find your layers to change in the first 5 iterations only then there is no point iterating the remaining 45 layers.

 

For swatch change maybe we can use the FindChange color. That would again help us avoid the loop and do the change in a single go.

-Manan

-Manan
Community Expert
May 14, 2025

@Manan Joshi 

Thank you so much for this - amazing!

 

I thought about the FindChange for colour but wouldn't that change all colours in text and other things? - I was under the impression it was just the fill of a cell in tables from Yellow to Grey - I was reluctant for a global change colour in case other colours changed beside cell fills. 

 

The other part is next level scripting that I didn't consider. 

 

Interesting, I only tried on a 2 doc indesign file with about 6 pages total, with random tables (2 min setup) and it was pretty quick - obviously.