Links GREP Rename

JavaScript for Adobe InDesign

Use GREP (regular expressions) to change the file names of existing links and update each link.

For files already renamed, use the script Links GREP Relink.

  • Rename links and update using GREP pattern replacement
  • Option to ignore letter case
  • Adapt open source to create other scripts
Links GREP Rename screen
Download
Links GREP Rename

You decide. Reward the author an
amount the solution is worth to you.

How-to Video

How to use the script

The interface has one section: Link file name. Set the GREP pattern and replacement, then click the OK button to begin. A progress bar is displayed as links are processed.

Section 1: Link file name

Find what — the GREP pattern to match. Works the same as when using the InDesign Find/Change dialog. For each link in the document, the file’s base name (file name without extension) is tested against the pattern. By excluding extension, GREP patterns never change the file type to which a graphic is linked.

Change to — the GREP replacement to use when the pattern above is matched. Works the same as when using the InDesign Find/Change dialog. For each link that matches the find pattern, the file’s base name (file name without extension) is renamed using the change value, and then the file is relinked.

Ignore case — adds the “i” switch to the regular expression, making it case-insensivive.

Source code

(download button below)

/*

Links GREP Rename
Copyright 2021 William Campbell
All Rights Reserved
https://www.marspremedia.com/contact

Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

*/

//@target indesign

(function () {

    var title = "Links GREP Rename";

    var count = 0;
    var doc; // Document

    // Reusable UI variables.
    var g1; // group
    var g2; // group
    var p; // panel
    var w; // window

    // Permanent UI variables.
    // Prefixes:
    //   btn  = "button"
    //   cb   = "checkbox"
    //   txt  = "statictext"
    //   inp  = "edittext"
    //   list = "dropdownlist"
    //   rb   = "radiobutton"
    var btnCancel;
    var btnOk;
    var cbIgnoreCase;
    var inpFind;
    var inpChange;

    // SETUP

    // Check for valid doc.
    if (!app.documents.length) {
        alert("Open a document.", title, false);
        return;
    }
    doc = app.activeDocument;

    // CREATE USER INTERFACE

    w = new Window("dialog", title);
    w.alignChildren = "fill";

    // Search/Replace.
    p = w.add("panel", undefined, "Link file name");
    p.alignChildren = "left";
    p.margins = [24, 24, 24, 18];
    p.spacing = 24;

    g1 = p.add("group");
    g2 = g1.add("group");
    g2.alignChildren = "left";
    g2.orientation = "column";
    // Preferred size set on next two to match height of inputs in next column.
    g2.add("statictext", undefined, "Find what:").preferredSize = [-1, 23];
    g2.add("statictext", undefined, "Change to:").preferredSize = [-1, 23];
    g2 = g1.add("group");
    g2.alignChildren = "left";
    g2.orientation = "column";
    inpFind = g2.add("edittext");
    inpFind.characters = 38;
    inpChange = g2.add("edittext");
    inpChange.characters = 38;

    cbIgnoreCase = p.add("checkbox", undefined, "Ignore case");

    // Action Buttons
    g1 = w.add("group");
    g1.alignment = "center";
    btnOk = g1.add("button", undefined, "OK");
    btnCancel = g1.add("button", undefined, "Cancel");

    // UI ELEMENT EVENT HANDLERS

    btnOk.onClick = function () {
        if (!inpFind.text) {
            alert("Enter a value for 'Find what'");
            return;
        }
        if (!confirm("WARNING!\nFiles on disk will be renamed and this cannot be undone. Make backup copies of files before proceeding. Are you sure you want to continue?", true, title)) {
            return;
        }
        w.close(1);
    };

    btnCancel.onClick = function () {
        w.close(0);
    };

    // DISPLAY THE DIALOG

    if (w.show() == 1) {
        try {
            process();
            alert(count + " links renamed", title, false);
        } catch (e) {
            alert("An error has occurred.\nLine " + e.line + ": " + e.message, title, true);
        }
    }

    //====================================================================
    //               END PROGRAM EXECUTION, BEGIN FUNCTIONS
    //====================================================================

    function process() {
        var extension;
        var file;
        var fileNew;
        var fileVersion;
        var i;
        var link;
        var name;
        var nameBase;
        var nameBaseChanged;
        var nameNew;
        var pattern;

        try {
            progress(doc.links.length);
            pattern = new RegExp(inpFind.text, "g" + (cbIgnoreCase.value ? "i" : ""));
            for (i = 0; i < doc.links.length; i++) {
                link = doc.links[i];
                file = new File(link.filePath);
                name = link.name;
                progress.message(name);
                // Split filename into base name and extension.
                nameBase = name.replace(/.[^.]+$/, "");
                extension = name.replace(/^.*\./, "");
                nameBaseChanged = nameBase.replace(pattern, inpChange.text);
                // Did name change?
                if (nameBaseChanged !== nameBase) {
                    // Test if file with name exists.
                    nameNew = nameBaseChanged + "." + extension;
                    fileVersion = 0;
                    fileNew = new File(file.path + "/" + nameNew);
                    while (fileNew.exists) {
                        // File exists. Add version suffix.
                        fileVersion++;
                        nameNew = nameBaseChanged + "~" + fileVersion + "." + extension;
                        fileNew = new File(file.path + "/" + nameNew);
                    }
                    // Rename and relink.
                    if (file.exists) {
                        progress.message(name + " -> " + nameNew);
                        file.rename(nameNew);
                        link.relink(file);
                        link.update();
                        count++;
                    }
                }
                progress.increment();
            }
        } finally {
            progress.close();
        }
    }

    function progress(steps) {
        var b;
        var t;
        var w;
        w = new Window("palette", "Progress", undefined, {
            closeButton: false
        });
        t = w.add("statictext");
        t.preferredSize = [450, -1]; // 450 pixels wide, default height.
        if (steps) {
            b = w.add("progressbar", undefined, 0, steps);
            b.preferredSize = [450, -1]; // 450 pixels wide, default height.
        }
        progress.close = function () {
            w.close();
        };
        progress.increment = function () {
            b.value++;
        };
        progress.message = function (message) {
            t.text = message;
            w.update();
        };
        w.show();
    }

})();
Download
Links GREP Rename

License details included in download

For help installing scripts, see How to Install and Use Scripts in Adobe Creative Cloud Applications.

IMPORTANT: by downloading the script you agree that the software is provided without any warranty, express or implied. USE AT YOUR OWN RISK. Always make backups of important data.