TransWikia.com

InDesign Script new layer naming by page number

Graphic Design Asked by Duncan on October 27, 2021

I’ve got an odd query where I need to take all the objects on a certain layer and put them each on a separate new layer so they can be exported as individual PDFs (and converted to png). I’ve found a script that does this:

var doc = app.activeDocument;
var myLayer = doc.layers.item("Answers");
 
for (var i = myLayer.pageItems.length - 1; i >= 1; i--) {
  var newLayer = doc.layers.add();
  myLayer.pageItems[i].itemLayer = newLayer;
}

This works great, but the layers are just named sequentially. I’m wondering if it’s possible to have the new layers named with the page number that the object is on so instead of

Layer 1
Layer 2
etc.

I get:

Page1-1
Page1-2
Page1-3
Page2-1
Page2-2
etc

Is that doable? I’ve tried finding scripts to get the page number but I can’t get it to work (I wish I knew more about Javascript!).

I’m using PageExporterUtility to export all the individual layers as PDFs but because there are many pages that have nothing on a lot of the new layers, I’m getting a lot of blank pages created which I have to sort through and delete manually. I’m thinking if the layers are named with the page numbers I can export just the layers I need for a given page.

I know it’s a weird request, any help would be much appreciated.

Thanks,
Duncan

Edit:
The export process I’m currently using with this is Page Exporter Utility 5.0.1 (here). This exports each layer in the doc as a separate PDF per page. Then I run a Photoshop batch to make them 5500px wide and a png, which is what I need.

2 Answers

Ok, here is a solution that should solve your issue or at the very least send you on your way. As I described in the comments below the post, this sets up a layer that is dedicated for exporting, duplicates one item after the other to this layer, exports and removes the element again:

// set the preferences for the PNG export
var pngPrefs = app.pngExportPreferences;

pngPrefs.pngExportRange = PNGExportRangeEnum.EXPORT_RANGE;
pngPrefs.pngQuality = PNGQualityEnum.MAXIMUM;
pngPrefs.exportResolution = 300;
// etc.; for all possible settings see
// https://www.indesignjs.de/extendscriptAPI/indesign8/#PNGExportPreference.html

var doc = app.activeDocument;

// loop over all layers and make them non-printable

for (var i = 0; i < doc.layers.length; i++) {
  doc.layers[i].printable = false;
}


// set up layers
var exportLayer = doc.layers.add();
var sourceLayer = doc.layers.item("Answers");


// loop over each page item, duplicate it to the export layer and then export it

for (var i = 0; i < sourceLayer.pageItems.length; i++) {
  var pageItem = sourceLayer.pageItems[i];

  // duplicate the page item
  var dupItem = pageItem.duplicate(exportLayer);

  // set up export file
  var expFile = File('~/Desktop/output/page' +
      pageItem.parentPage.name + '-' + i + '.png');

  // set which page to export
  pngPrefs.pageString = pageItem.parentPage.name;

  // export the document
  doc.exportFile(ExportFormat.PNG_FORMAT, expFile);

  // remove the duplicate item
  dupItem.remove();
}

Edit: To avoid the error with page items on the pastboard, you can quickly check, if the item has a valid parent page. You could add this snippet below the var pageItem ... line:

if(!pageItem.parentPage) continue;

This basically tells the script to skip the current page item and continue with the next.

Answered by mdomino on October 27, 2021

How about just adding as many new layers as the maximum number of items on a page? That way no page would have empty layers.

// main function
function distributeItemsToLayers() {
    // active document
    var doc = app.activeDocument;
    // source layer
    var sourceLayer = doc.layers.item("source layer name");
    // array for new layers
    var newLayers = [];
    // loop through pages
    for (var i = 0; i < doc.pages.length; i++) {
        // page
        var page = doc.pages[i];
        // array for items on page in the source layer
        var items = [];
        // loop through items on page
        for (var j = 0; j < page.pageItems.length; j++) {
            // item on page
            var item = page.pageItems[j];
            // check if item is on source layer
            if (item.itemLayer === sourceLayer) {
                // add item to array of items on source layer
                items.push(item);
            }
        }
        // loop through items on source layer
        for (var j = 0; j < items.length; j++) {
            // item on source layer
            var item = items[j];
            // check if a new layer exists for this number
            if (newLayers.length < j + 1) {
                // add new layer for this number
                newLayers.push(doc.layers.add());
            }
            // set item layer to corresponding new layer
            item.itemLayer = newLayers[j]; 
        }        
    }
}
// run main function as one undoable action
app.doScript(distributeItemsToLayers, ScriptLanguage.javascript, undefined, UndoModes.ENTIRE_SCRIPT, 'Distribute Items To Layers');

Answered by Wolff on October 27, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP