Large Format Saves

Script for Adobe Illustrator

This script was created to speed up, and make consistent, saving art and cut files for large format output. I grew tired of hiding the cut layer to save the art, then deleting the art to save the cut file. And often getting it wrong. The script ensures the correct layers are configured, and adds saving all open documents or all in a folder.

This solution also inspired an Adobe Script Tutorial describing how to build the script. The original script was specific to one client. I altered the code to allow updating the layer and PDF preset names, so it's easy to adapt to other uses.

  • Process active document
  • Process open documents
  • Process folder of documents
  • Save art and/or cut files
  • Adapt open source to customize or create other scripts
Download
Large Format Saves
Help me keep making new scripts by supporting my work. Click the PayPal button to contribute any amount you choose. Thank you. William Campbell

How-to Video

How to use the script

The interface has two sections: Process, and Options. Set options as desired and click OK to begin.

Section 1: Process

Active Document — saves the document, outputs art and/or cut files with specified suffix to the document location, and closes the document.

Open documents — for every open document, the steps for active document are performed.

Folder — select a folder and for each Illustrator file found in the folder, art and/or cut files are output with specified suffix to the document location. Only files with the extension .ai are processed.

Include subfolders — if enabled, documents in all subfolders are also processed.

Suffix for art files and suffix for cut files are specified in the script code and are editable.

Section 2: Options

Save art file — the document cut and crease layers are hidden and the file is saved using the PDF preset for art files.

Save cut file — all layers that are not marks, cut, or crease layers are removed, and the file is saved using the PDF preset for cut files.

Layer names and PDF preset names are specified in the script code and are editable.

Source code

(download button below)

/*

Large Format Saves
Copyright 2023 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.

*/

(function () {

    // PREFERENCES; update to your own values.
    var pdfPresetArt = "Large Format";
    var pdfPresetCut = "Large Format Cut File";
    var layerArt = "Art Layer";
    var layerCrease = "Crease Layer";
    var layerCut = "Cut Layer";
    var layerMarks = "Regmarks";
    var suffixArt = "_Color";
    var suffixCut = "_CF";

    var title = "Large Format Saves";

    if (!/illustrator/i.test(app.name)) {
        alert("Script for Illustrator", title, false);
        return;
    }

    // Script variables
    var doneMessage;
    var error;
    var folderInput;
    var progress;

    // Reusable UI variables
    var g; // group
    var p; // panel
    var w; // window

    // Permanent UI variables
    var btnCancel;
    var btnFolderInput;
    var btnOk;
    var cbSaveArt;
    var cbSaveCut;
    var cbSubfolders;
    var grpFolderInput;
    var rbProcessActiveDoc;
    var rbProcessFolder;
    var rbProcessOpenDocs;
    var txtFolderInput;

    // CREATE PROGRESS WINDOW

    progress = new Window("palette", "Progress", undefined, {
        "closeButton": false
    });
    progress.t = progress.add("statictext");
    progress.t.preferredSize.width = 450;
    progress.b = progress.add("progressbar");
    progress.b.preferredSize.width = 450;
    progress.display = function (message) {
        message && (this.t.text = message);
        this.show();
        this.update();
    };
    progress.increment = function () {
        this.b.value++;
    };
    progress.set = function (steps) {
        this.b.value = 0;
        this.b.minvalue = 0;
        this.b.maxvalue = steps;
    };

    // CREATE USER INTERFACE

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

    // Panel 'Process'
    p = w.add("panel", undefined, "Process");
    p.alignChildren = "left";
    p.margins = [24, 24, 24, 18];
    g = p.add("group");
    rbProcessActiveDoc = g.add("radiobutton", undefined, "Active document");
    rbProcessOpenDocs = g.add("radiobutton", undefined, "Open documents");
    rbProcessFolder = g.add("radiobutton", undefined, "Folder");
    grpFolderInput = p.add("group");
    btnFolderInput = grpFolderInput.add("button", undefined, "Folder...");
    txtFolderInput = grpFolderInput.add("statictext", undefined, "", {
        truncate: "middle"
    });
    txtFolderInput.preferredSize.width = 350;
    cbSubfolders = p.add("checkbox", undefined, "Include subfolders");

    // Panel 'Options'
    p = w.add("panel", undefined, "Options");
    p.alignChildren = "left";
    p.margins = [24, 24, 24, 18];
    g = p.add("group");
    cbSaveArt = g.add("checkbox", undefined, "Save art file");
    cbSaveCut = g.add("checkbox", undefined, "Save cut file");

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

    // Panel Copyright
    p = w.add("panel");
    p.add("statictext", undefined, "Copyright 2023 William Campbell");

    // SET DEFAULTS

    rbProcessActiveDoc.enabled = false;
    rbProcessOpenDocs.enabled = false;
    rbProcessFolder.value = true;
    if (app.documents.length > 0) {
        rbProcessActiveDoc.enabled = true;
        rbProcessActiveDoc.value = true;
        rbProcessFolder.value = false;
        if (app.documents.length > 1) {
            rbProcessOpenDocs.enabled = true;
        }
    }
    cbSaveArt.value = true;
    cbSaveCut.value = true;
    configureUi();

    // UI EVENT HANDLERS

    // Panel 'Process'
    rbProcessActiveDoc.onClick = configureUi;
    rbProcessOpenDocs.onClick = configureUi;
    rbProcessFolder.onClick = configureUi;
    btnFolderInput.onClick = function () {
        var f = Folder.selectDialog("Select folder to process", txtFolderInput.text);
        if (f) {
            txtFolderInput.text = Folder.decode(f.fullName);
        }
    };

    // Action Buttons
    btnOk.onClick = function () {
        if (rbProcessFolder.value) {
            folderInput = new Folder(txtFolderInput.text);
            if (!(folderInput && folderInput.exists)) {
                alert("Select folder to process", " ", false);
                return;
            }
        }
        w.close(1);
    };

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

    // SHOW THE WINDOW

    if (w.show() == 1) {
        doneMessage = "";
        try {
            process();
            doneMessage = doneMessage || "Done";
        } catch (e) {
            error = error || e;
            doneMessage = "An error has occurred.\nLine " + error.line + ": " + error.message;
        }
        progress.close();
        doneMessage && alert(doneMessage, title, error);
    }

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

    function configureUi() {
        if (rbProcessActiveDoc.value) {
            // Process active document.
            rbProcessOpenDocs.value = false;
            rbProcessFolder.value = false;
            grpFolderInput.enabled = false;
            cbSubfolders.enabled = false;
            cbSubfolders.value = false;
        } else if (rbProcessOpenDocs.value) {
            // Process open documents.
            rbProcessActiveDoc.value = false;
            rbProcessFolder.value = false;
            grpFolderInput.enabled = false;
            cbSubfolders.enabled = false;
            cbSubfolders.value = false;
        } else if (rbProcessFolder.value) {
            // Process folder.
            rbProcessActiveDoc.value = false;
            rbProcessOpenDocs.value = false;
            grpFolderInput.enabled = true;
            cbSubfolders.enabled = true;
        }
    }

    function getFiles(folder, subfolders, extensions) {
        // folder = folder object, not folder name.
        // subfolders = true to include subfolders.
        // extensions = string, extensions to include.
        // Combine multiple extensions with RegExp OR i.e. jpg|psd|tif
        // extensions case-insensitive.
        // extensions undefined = any.
        // Ignores hidden files and folders.
        var f;
        var files;
        var i;
        var pattern;
        var results = [];
        if (extensions) {
            pattern = new RegExp("\." + extensions + "$", "i");
        } else {
            // Any extension.
            pattern = new RegExp(".*");
        }
        files = folder.getFiles();
        for (i = 0; i < files.length; i++) {
            f = files[i];
            if (!f.hidden) {
                if (f instanceof Folder && subfolders) {
                    // Recursive (function calls itself).
                    results = results.concat(getFiles(f, subfolders, extensions));
                } else if (f instanceof File && pattern.test(f.name)) {
                    results.push(f);
                }
            }
        }
        return results;
    }

    function getLayer(doc, name) {
        var i;
        for (i = 0; i < doc.layers.length; i++) {
            if (doc.layers[i].name == name) {
                return doc.layers[i];
            }
        }
        return null;
    }

    function process() {
        progress.display("Working... Please wait...");
        if (rbProcessActiveDoc.value) {
            app.activeDocument.save();
            processDoc(app.activeDocument);
        } else if (rbProcessOpenDocs.value) {
            processOpenDocs();
        } else if (rbProcessFolder.value) {
            processFolder();
        }
    }

    function processDoc(doc) {
        var baseName;
        var fileArt;
        var fileCut;
        var i;
        var layer1;
        var layer2;
        var saveOptions;
        baseName = doc.fullName.fullName.replace(/\.ai$/i, "");
        fileArt = new File(baseName + suffixArt + ".pdf");
        fileCut = new File(baseName + suffixCut + ".pdf");
        saveOptions = new PDFSaveOptions();
        if (cbSaveArt.value) {
            // Hide cut layer.
            layer1 = getLayer(doc, layerCut);
            layer1.visible = false;
            // Hide crease layer.
            layer2 = getLayer(doc, layerCrease);
            if (layer2) {
                layer2.visible = false;
            }
            // Save.
            saveOptions.pDFPreset = pdfPresetArt;
            doc.saveAs(fileArt, saveOptions);
            // Show layers.
            layer1.visible = true;
            if (layer2) {
                layer2.visible = true;
            }
        }
        if (cbSaveCut.value) {
            // Remove all layers except marks, cut, and crease layers.
            // Lock marks, cut, and crease layers.
            // Loop backwards because removing items.
            for (i = doc.layers.length - 1; i > -1; i--) {
                layer1 = doc.layers[i];
                if (layer1.name == layerMarks ||
                    layer1.name == layerCut ||
                    layer1.name == layerCrease
                ) {
                    layer1.visible = true;
                    layer1.locked = true;
                    continue;
                }
                layer1.locked = false;
                layer1.remove();
            }
            // Save.
            saveOptions.pDFPreset = pdfPresetCut;
            doc.saveAs(fileCut, saveOptions);
        }
        doc.close(SaveOptions.DONOTSAVECHANGES);
    }

    function processFolder() {
        var doc;
        var file;
        var files;
        var i;
        progress.display("Reading folder...");
        files = getFiles(folderInput, cbSubfolders.value, "ai");
        if (!files.length) {
            doneMessage = "No files found in selected folder";
            return;
        }
        progress.set(files.length);
        for (i = 0; i < files.length; i++) {
            file = files[i];
            progress.increment();
            progress.display(File.decode(file.name));
            doc = app.open(file);
            if (getLayer(doc, layerMarks) &&
                getLayer(doc, layerCut) &&
                getLayer(doc, layerArt)
            ) {
                processDoc(doc);
            } else {
                // Ignore files missing required layers.
                doc.close(SaveOptions.DONOTSAVECHANGES);
            }
        }
    }

    function processOpenDocs() {
        var doc;
        var i;
        progress.set(app.documents.length);
        // Loop backwards because docs are being closed.
        for (i = app.documents.length - 1; i > -1; i--) {
            doc = app.documents[i];
            progress.increment();
            progress.display(doc.name);
            doc.save();
            processDoc(doc);
        }
    }

})();
Help me keep making new scripts by supporting my work. Click the PayPal button to contribute any amount you choose. Thank you. William Campbell
Download
Large Format Saves
Download
PDF Presets

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

IMPORTANT: scripts are developed for the latest Adobe Creative Cloud applications. Many scripts work in CC 2018 and later, even some as far back as CS6, but may not perform as expected, or run at all, when used in versions prior to 2018. Photoshop features Select Subject and Preserve Details 2.0 definitely fail prior to CC 2018 (version 19) as the features do not exist in earlier versions. For best results use the latest versions of Adobe Creative Cloud applications.

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

IMPORTANT: fees paid for software products are the purchase of a non-exclusive license to use the software product and do not grant the purchaser any degree of ownership of the software code. Author of the intellectual property and copyright holder William Campbell retains 100% ownership of all code used in all software products regardless of the inspiration for the software product design or functionality.