Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

jmckenzie

macrumors member
Original poster
Oct 31, 2022
53
94
I can't launch the latest version of Art Files on Ventura — I get a message saying the app is incompatible. Dropped a line to the developer a while back, heard nothing, which is odd.

This is an indispensible little utility for design studios... Yes, Illustrator has a basic collection facility built in, but Art Files has always been easier, especially for remote work, as you don't have to open an .ai file to locate all the placed images you need.

Anyone have any intel about an update to this app?

thanks.
 
That site only indicates compatibility through macOS 11, Code Line's online store appears to be dead, and their company website has a copyright date of 2014 in the footer.
I think you should look for an alternative solution. These guys seem to have packed up shop a while back unfortunately.
 
This script will help
Note:
you need Illsutartor and Indesign 2022 (for collecting fonts)

Code:
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;
      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;
          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.name); // Store the source file name

          var sourceDoc = app.open(sourceFiles); // 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 + " - " + placedItem.name);
                }
              }
            } catch (e) {
              missingLinks.push("Linked item with no associated file: " + sourceFileNames + " - " + 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
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.