1

I have a lot of .ai files which they need to be sent to publisher, packaging them one by one is a pain!

There is some sharewares for mac, but I'm on windows 10, and prefer a free script, plugin or third-party.

But even a simpler script could work, as if it get an input and output path with a bunch of checkboxes to tell script what kind of things need to be saved and an output path to save AI packages into separate folders.

4
  • 1
    ermm....... helpx.adobe.com/illustrator/using/package-files.html -- although that page states it's available since CS6.. it's not. CC+
    – Scott
    Aug 3, 2021 at 5:28
  • Yes, It's a feature that is in File menu, I know this, but it works for current open document only, not for multiple files. I'm looking for a way to batch package multiple files in-a-go.
    – Roozbeh E
    Aug 3, 2021 at 5:31
  • Is a ZIP useless in this case? It's a simple way to make a bunch of files to one for transmission.
    – user82991
    Aug 3, 2021 at 8:16
  • For sure it's useless! each file contains Links which they placed in a bunch of folders scattered through system. Package feature is an option to find these Links, Copy them into a "Links" folder beside .ai file and relink-ing them automatically to that-new-made folder, also Packaging copies the Fonts used in .ai file into a "Font" folder which is an another Pain-in-the-ass-manually-to-be-done thing!
    – Roozbeh E
    Aug 4, 2021 at 4:32

2 Answers 2

1

Try this:

  1. In Illustrator, open a blank document, and begin recording a new Action

  2. Click on the tiny Action menu at the top right of the Actions panel, and choose Insert Menu Item. Type "package", then Find, and click OK to insert it into your Action

enter image description here

  1. Stop the Action recording. You should end up with something like this:

enter image description here

  1. Apply the action to a batch of AI files contained in one folder, by clicking on the menu at the top of the Actions panel, and choose Batch. Select the Action you just recorded. Set a source and destination folder. Hit OK.

enter image description here

  1. The first time the Package dialog appears, make sure to also set the output folder to one inside your destination folder (same as the one in the Batch dialog). Here for example I named it packages, which will be located inside the Packages folder.

enter image description here

Note: You will have to click through a couple of dialogs each time the Package command is executed. I don't know how to suppress that. But it's still quicker than doing it on individual files separately.

4
  • Aha! I did it before! my AI version is CC2019 - 23.0.3, what's yours? I get "Save as" recorded. This Recordable Package thing most be for a newer version! Also Thank you so much, it was good to know. If I'll be sure that is a version feature, maybe I update soon.
    – Roozbeh E
    Aug 6, 2021 at 18:23
  • 1
    @RoozbehE Actually, I'm still on CC2018, so it's older than your copy. Of course they may have changed the name, I'm not sure. I should update too, but haven't had the time.
    – Billy Kerr
    Aug 6, 2021 at 22:40
  • 1
    @RoozbehE - note this is not a normal operation, you have to go into it via the Actions menu, click Insert Menu Item, then type "package", then click Find to see it, then you can insert it into your Action. It won't record the action normally as you would with other operations. I've added a screenshot to step 2 in the answer.
    – Billy Kerr
    Aug 6, 2021 at 22:51
  • Thank you so much! Now at least I know a new thing. Yes I found that in "Insert menu Item". While it is not what I'm looking for exactly, it maybe facilitate the procedure of multiple files need to be packaged.
    – Roozbeh E
    Aug 7, 2021 at 5:39
1

This script will help Note: you need Illsutartor and Indesign 2022 (for collecting fonts)

function getUsedFonts(doc) { var xml = new XML(doc.XMPString), names = xml.descendants('stFnt:fontName'), files = xml.descendants('stFnt:fontFileName'), ln = names.length(), m = 0, arr = []; for (; m < ln; m++) { var fontName = names[m].toString(); var fontFile = files[m].toString();

  // Exclude embedded fonts and font names containing "+Courier"
  if (fontFile.indexOf('Document Fonts') === -1 && fontName.indexOf('+Courier') === -1) {
    arr.push([fontName, fontFile]);
  }
}
return arr;

}

// Package fonts function packageFonts(arr, oFolder) { Array.prototype.indexOf = function (obj, start) { for (var m = (start || 0), s = this.length; m < s; m++) { if (this[m] === obj) { return m; } } return -1; };

var oFile, oName, fontInfo, fontName, fontFiles, index, q,
  psNameArr = String(app.fonts.everyItem().postscriptName).split(','),
  arr = arr.split('###'),
  ln = arr.length,
  m = 0;

for (; m < ln; m++) {
  fontInfo = arr[m].split(',');
  fontName = fontInfo[0];
  fontFiles = fontInfo[1].split('; ');
  index = psNameArr.indexOf(fontName);
  oPath = File(app.fonts[index].location).parent;

  for (q = 0; q < fontFiles.length; q++) {
    oFile = File(oPath + '/' + fontFiles[q]);
    oName = oFolder + '/' + fontFiles[q];
    try {
      oFile.copy(File(oName), true);
    } catch (e) {}
  }
}

}

function activateFonts() { var fonts = app.textFonts; for (var i = 0; i < fonts.length; i++) { var font = fonts[i]; font.available = true; } }

function getProjectNumberFromLayers() { //var filename = app.activeDocument.name; var filename =app.documents[0].name; var underscoreIndex = filename.indexOf("_");

if (underscoreIndex !== -1) {
  var parts = filename.split("_");
  var firstPart = parts[0];
  var lastPart = parts[parts.length - 1].split(".")[0];

  if (/^\d/.test(firstPart)) {
    return firstPart;
  } else if (/^\d/.test(lastPart)) {
    return lastPart;
  }
}

return null;

}

function main() { var sourceFiles = File.openDialog("Select Illustrator files to process", "*.ai", true); if (sourceFiles != null) { if (sourceFiles != null) { for (var i = 0; i < sourceFiles.length; i++) { var sourceFile = sourceFiles[i]; var doc = app.open(sourceFile); var layerName = getProjectNumberFromLayers(); if (layerName) { var destFolder = new Folder('~/Desktop/' + layerName);

      } else {
        alert("Project name not found in the layers structure. Please try again.");
      }
    }
  }
  if (destFolder != null) {
    var fontSet = {}; // Custom set-like object
    var linkedPaths = []; // Array to store linked file paths
    var missingLinks = []; // Array to store missing link paths
    var sourceFileNames = []; // Array to store source file names

    for (var i = 0; i < sourceFiles.length; i++) {
      sourceFileNames.push(sourceFiles[i].name); // Store the source file name

      var sourceDoc = app.open(sourceFiles[i]); // Open the Illustrator file

      var timeoutStart = new Date().getTime();
      var timeoutDuration = 10000; // Timeout duration in milliseconds (adjust as needed)
      while (!sourceDoc.active) {
        var currentTime = new Date().getTime();
        if (currentTime - timeoutStart > timeoutDuration) {
          break; // Break the loop if timeout duration is exceeded
        }
      }

      activateFonts();

      var doc = sourceDoc;

      var arr = getUsedFonts(doc);

      // Collect the font names
      for (var j = 0; j < arr.length; j++) {
        var fontName = arr[j][0];
        var fontFile = arr[j][1];

        // Exclude embedded fonts
        if (fontFile.indexOf('Document Fonts') === -1) {
          fontSet[fontName] = true; // Use object properties to add unique font names
        }
      }

      var oFolder = new Folder(destFolder + '/Document Fonts');
      var bt;

      oFolder.create();
      bt = new BridgeTalk();
      bt.target = "indesign";
      bt.body = packageFonts.toSource() + '("' + arr.join('###') + '", "' + oFolder + '")';
      bt.send();

      // Copy the opened Illustrator file to the new folder
      var newAiFile = new File(destFolder);
      var saveOptions = new IllustratorSaveOptions();
      saveOptions.embedICCProfile = true;
      saveOptions.colorConversionID = ColorConversion.None;
      sourceDoc.saveAs(newAiFile, saveOptions);

      // Copy only linked PSD files to the "Links" folder
      var linksFolder = new Folder(destFolder+ "/Links");
      linksFolder.create();
      var copiedFiles = {}; // Object to store copied file names

      // Collect linked file paths in the current document
      var placedItems = app.activeDocument.placedItems;
      for (var j = 0; j < placedItems.length; j++) {
        var placedItem = placedItems[j];
        try {
          var linkedFile = new File(placedItem.file.fullName);
          var linkedExtension = linkedFile.name.match(/\.([^\.]+)$/)[1]; // Get the file extension
          if (linkedExtension.toLowerCase() === "psd") {
            var linkedFileName = linkedFile.name;
            var linkedFileCopy = new File(linksFolder.fsName + "/" + linkedFileName);
            try {
              linkedFile.copy(linkedFileCopy);
              copiedFiles[linkedFileName] = true;
              linkedPaths.push(linkedFile.fsName); // Store the linked file path
            } catch (e) {
              missingLinks.push("Linked item with no associated file: " + sourceFileNames[i] + " - " + placedItem.name);
            }
          }
        } catch (e) {
          missingLinks.push("Linked item with no associated file: " + sourceFileNames[i] + " - " + placedItem.name);
        }
      }
      sourceDoc.close(SaveOptions.DONOTSAVECHANGES);
    }

    // Save linked file paths to a text file
    var linkedFilesText = linkedPaths.join("\n");
    var linkedFilesTextFile = new File(destFolder + "/linked_files.txt");
    linkedFilesTextFile.open("w");
    linkedFilesTextFile.write(linkedFilesText);
    linkedFilesTextFile.close();
    if (linkedFilesTextFile.length === 0) {
        linkedFilesTextFile.remove();
      }

    // Save missing link paths to a text file
    if (missingLinks.length > 0) {
      var missingLinksText = missingLinks.join("\n");
      var missingLinksFile = new File(destFolder + "/missing_links.txt");
      missingLinksFile.open("w");
      missingLinksFile.write(missingLinksText);
      missingLinksFile.close();
    }

    // Get the font list by extracting keys from the object
    var fontList = [];
    for (var fontName in fontSet) {
      if (fontSet.hasOwnProperty(fontName)) {
        fontList.push(fontName);
      }
    }

    // Output the font list
    var textFile = new File(destFolder + "/font_list.txt");
    textFile.open("w");
    textFile.write(fontList.join("\n"));
    textFile.close();
    if (textFile.length === 0) {
        textFile.remove();
      }
  }
}
var linksFolder = new Folder(destFolder + "/Links");
if (linksFolder.exists && linksFolder.getFiles().length === 0) {
  linksFolder.remove();
}

var documentFontsFolder = new Folder(destFolder + "/Document Fonts"); var fontListFile = new File(destFolder + "/font_list.txt"); if (documentFontsFolder.exists && documentFontsFolder.getFiles().length === 0 && !fontListFile.exists) { documentFontsFolder.remove(); }

// Add an alert when the script completes alert("Script completed!"); }

app.userInteractionLevel = UserInteractionLevel.DONTDISPLAYALERTS; // Disable alerts main(); app.userInteractionLevel = UserInteractionLevel.DISPLAYALERTS; // Restore alert settings

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.