Plane Wryter
Plane Wryter

Reputation: 1379

How to Code Bulk Image Placement in InDesign Using .jsx or .idjs?

InDesign Coding N00B, here.

Seeking guidance as to practicality and approach to writing .idjs or .jsx code to place ~300 .png image files in an InDesign-based "coffee table book."

BACKGROUND

Using exiftool, each affected .png has been updated with an "xmp-dc:Description" tag that contains the image's caption.

In a single image test via InDesign's PLACE command, InDesign's Caption Setup | Generate Live Caption recognizes and displays the ("Description") Caption just fine.

All images are listed in a .csv that contains:

  1. The full macOS path of the image, and
  2. The page number where the image is to be placed.

(At the moment, the author just wants each image placed on their designated page...with intentions of manually repositioning & resizing them later.)

Example CSV entries:

REQUEST for YOUR EXPERTISE

Is there a practical way(s) to write a .jsx or .idjs script that can:

When done looping through the .csv: close the .indd and exit InDesign?

IDEAL for AUTOMATION? Or...?

If the above process is ideal for automation (.idjs or .jsx), then hints for this N00B as to how to approach coding a solution would be greatly appreciated.

Or, should I abandon the idea of automating this task--and ~300 times--manually place the images on their page, embed the link, apply Caption Setup, activate Generate Live Caption, et cetera?

Suggestions and insights are invited and welcomed!

With great gratitude from someone that is dreading 300 mind-numbing & repetitive and repetitive & mind-numbing PLACEments, et cetera.

Many thanks,

Plane Wryter

Upvotes: 2

Views: 537

Answers (1)

Yuri Khristich
Yuri Khristich

Reputation: 14537

Basically this simple script can do it:

app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.FAST_ENTIRE_SCRIPT, 'Place images');

function main() {
    var doc = app.activeDocument;
    var images = get_list_of_images_from_csv();
    var frames = [];

    // place images on the pages
    for (var i=0; i<images.length; i++) {
        var image = images[i];
        var page = doc.pages.itemByName(image.page);

        // UPDATED LINES
        var pic = page.place(image.path)[0];
        resize(pic, 432);
        frames.push(pic.parent);
    }

    // align frames by center of pages, why not?
    for (var i=0; i<frames.length; i++) {
        var frame = frames[i];
        doc.align(frame, AlignOptions.HORIZONTAL_CENTERS, AlignDistributeBounds.PAGE_BOUNDS);
        doc.align(frame, AlignOptions.VERTICAL_CENTERS, AlignDistributeBounds.PAGE_BOUNDS);
    }

    // add captions to the placed images
    // it uses the caption settings of the current document
    // I don't know if you can change the settings via a srcipt
    for (var i = 0; i < frames.length; i++) {
        app.selection = frames[i];
        try {
            app.menuActions.item('$ID/Generate Live Caption').invoke();
        } catch(e) {}
    }
}

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

function get_list_of_images_from_csv() {
    var doc = app.activeDocument;
    var csv_file = doc.filePath.getFiles('*.csv')[0] || doc.fullName;
    csv_file = csv_file.openDlg("Select CSV file");
    if (!csv_file) exit();

    csv_file.encoding = 'UTF-8';
    csv_file.open('r');
    var contents = csv_file.read().split('\n');
    csv_file.close();

    var images = []; // the array of objects [{path, page}, {path, page}, ...]
    while (contents.length) {
        var row = contents.shift().split(','); // a path shouldn't contain comma!
        if (row.length == 0 || row[0] == '' || row[1] == '') continue;
        var path = row[0].replace(/"/g,''); // remove quote marks
        var page = row[1].replace(/"/g,''); // remove quote marks
        images.push({path: path, page: page});
    }

    return images;
}

// function to resize an image by height (px)
function resize(pic, target_height) {
    var doc = app.activeDocument;
    // save doc units
    var vert_units = doc.viewPreferences.verticalMeasurementUnits;
    var horiz_units = doc.viewPreferences.horizontalMeasurementUnits;

    // change doc units to px
    doc.viewPreferences.verticalMeasurementUnits = MeasurementUnits.PIXELS
    doc.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.PIXELS

    // change size of the picture
    var pic_height = pic.geometricBounds[2] - pic.geometricBounds[1];
    pic.horizontalScale = 100 * target_height / pic_height;
    pic.verticalScale = 100 * target_height / pic_height;
    pic.parent.geometricBounds = pic.geometricBounds; // resize the frame

    // restore original doc units
    doc.viewPreferences.verticalMeasurementUnits = vert_units;
    doc.viewPreferences.horizontalMeasurementUnits = horiz_units;
}

It takes CSV file like this (note: if a path contains a comma , there will be an error):

"/Users/me/Documents/test/001.tif","1"
"/Users/me/Documents/test/011.tif","3"
"/Users/me/Documents/test/012.tif","4"

And puts the images on the pages of current open document:

enter image description here

It adds the captions with the caption settings of the current document. It doesn't change the settings. I don't know if it's possible to change the settings via a script.

Upvotes: 2

Related Questions