Skip to main content
April 14, 2010
Question

Script to change links for many files

  • April 14, 2010
  • 3 replies
  • 5312 views

Does anyone have any suggestions or pointers to a solution for changing the file path for links in an Illustrator document?

For example, let's say my Illustrator document is stored at:

/Volumes/Storage/Projects/Client/AAA001/designs/concept1.ai

and I have placed 2 linked visuals:

/Volumes/Storage/Projects/Client/AAA001/visuals/big_retouch.psd

/Volumes/Storage/Projects/Client/AAA001/visuals/flattened.jpg

When I open the .AI I noticed that the reference to the visuals is under a %DocumentFiles section:

%%DocumentFiles:/Volumes/Storage/Projects/Client/AAA001/visuals/retouched.psd

%%+/Volumes/Storage/Projects/Client/AAA001/visuals/flattened.jpg

I need to replace "/Volumes/Storage/Projects" with "/Volumes/Projects". (There are some more complex replacements I need, but let's start here.)

Any suggestions please?

Kind regards

Craig.

This topic has been closed for replies.

3 replies

Participant
November 15, 2013

I think all the proposed solutions suffer from the same, problem, there is no file object assosiated with the placedItem if the link is broken when the .ai is first opened in illustrator. To fix links, you have to inspect the XMP meta data, transform the file path string assosiated with each linked file, and used the transformed file name to recreate the file object assosiated with each placed item. I have a hacky script below that works only for me, but gives an idea of how this could be done, more professionally.

//bring in some environment variables

var labdir = $.getenv("LABDIR")

var labdir_smsg = $.getenv("LABDIR_smsg")

var labdir_lenovo = $.getenv("LABDIR_lenovo")

var labdir_old = $.getenv("LABDIR_old")

 

if ( app.documents.length > 0 ) {

var fileReferences = new Array();

}

var sourceDoc = app.activeDocument;

// load the library

if (ExternalObject.AdobeXMPScript == undefined) {

    ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript');

}

var xmp = new XMPMeta(sourceDoc.XMPString);

var placedFiles = new Array();

       

for (i = 1; i <= xmp.countArrayItems(XMPConst.NS_XMP_MM, "Manifest"); i++){

    var path_name = "xmpMM:Manifest[".concat(i.toFixed(0),"]/stMfs:reference/stRef:filePath");

    var t = xmp.getProperty(XMPConst.NS_XMP_MM, path_name);

    var new_path = t.value;

    if (t.value.indexOf(labdir_lenovo)!=-1){

          new_path = t.value.replace(labdir_lenovo, labdir);

          placedFiles.push(new_path);

          }

    if (t.value.indexOf(labdir_old)!=-1){

        new_path = t.value.replace(labdir_old, labdir);

          placedFiles.push(new_path);

        }

    if (t.value.indexOf(labdir_smsg)!=-1){

        new_path = t.value.replace(labdir_smsg, labdir);

          placedFiles.push(new_path);

        }

}

for ( i = 0; i < sourceDoc.placedItems.length; i++ ) {

    sourceDoc.placedItems.file = new File(placedFiles);

}

April 15, 2010

Thanks both for your response.

The broader picture includes traversing a folder, opening all .AI files and replacing every placed link reference with its new path which can be predetermined as we are reorganising by removing one folder and adding another.

So going back to my first question, original path is (under /Volumes directory on Mac OS X):

Storage

     Projects
          Client

               AAA001

                    Visuals

                         big_retouch.psd

and the new path...

Projects

      Client

          Brand

               AAA001

                     Visuals

                         big_retouch.psd

So I can replace "/Volumes/Storage/Projects" universally with "/Volumes/Projects".

However, I will be adding a Brand for client projects, which I could look up from a stored array, but don't know how.

Any help on traversing hierarchy and performing string replacements would be hugely appreciated.

artchrome
Inspiring
April 15, 2010

Hi,

Sorry but i'm not sure to understand :

summary:

at begining you said you haved two linked files 1 psd and 1 jpeg

/Volumes/Storage/Projects/Client/AAA001/visuals/big_retouch.psd

/Volumes/Storage/Projects/Client/AAA001/visuals/flattened.jpg

Do you want

/Volumes/Projects/Client/Brand/AAA001/visuals/big_retouch.psd

for PSD files  and

/Volumes/Projects/Client/AAA001/visuals/flattened.jpg

for JPEG files ?

sorry, could you clarify ? (some screen shoot can help also)

Ciao, art.chrome

April 15, 2010

Sorry I should have used just one placed file as an example to keep things simple.

What I was trying to say is that the current path of:

/Volumes/Storage/Projects/Client/AAA001/visuals/big_retouch.psd

will become

/Volumes/Projects/Client/Brand/AAA001/visuals/flattened.jpg

So, the Volume name is currently "Storage" and will change to "Projects", but also we will introduce a folder called Brand.

---

Here is a detailed example which intros the design folder for .AI files:

We did 2 projects for ACME corp, one for concrete and one for oil products.

These are stored at present as follows:

/Volumes/Storage/Projects/ACME/AAA001 Concrete/visuals/mixed_conrete.psd

/Volumes/Storage/Projects/ACME/AAA001 Concrete/design/concrete_bag.ai  (which has mixed_conrete.psd placed within)

/Volumes/Storage/Projects/ACME/AAA002 Oil/visuals/drum.psd

/Volumes/Storage/Projects/ACME/AAA002 Oil/design/oil.ai  (which has drum.psd placed within)

In reorganising our files I would like them to be relocated as follows:

/Volumes/Projects/ACME/Concrete/AAA001 Concrete/visuals/mixed_conrete.psd

/Volumes/Projects/ACME/Concrete/AAA001 Concrete/design/concrete_bag.ai  (which has mixed_conrete.psd placed within)

/Volumes/Projects/ACME/Oil/AAA002 Oil/visuals/drum.psd

/Volumes/Projects/ACME/Oil/AAA002 Oil/design/oil.ai  (which has drum.psd placed within)

I hope this is clear and sorry for any waste of your time as I really do appreciate any help on this while I get my head around CS scripting.
Kind regards
Craig.

artchrome
Inspiring
April 14, 2010

Hi,

Some times , i have same problem.

Fisrt i don't use PSD file but EPS files, and i hope that my way works for you:

Manually:

(sorry for this french dialog box)
1) i'm breaking the link by rename or delete old folder (i want that illustrator ask me for file)

2) when illustrator ask me for file, check "apply to all" and "Correct"

3) Choose new folder

4) Save doc

By script: (tested on CS4)

#target illustrator
var newFolder="/Volumes/aFolder/new folder/"; // <-Here your NEW FOLDER PATH
if ( app.documents.length > 0 ) { // if  1 document is open

var sourceDoc = app.activeDocument;  // the active doc

for ( i = 0; i < sourceDoc.pageItems.length; i++ ) {  //  all layers
artItem = sourceDoc.pageItems
switch ( artItem.typename ) {  // check for type
case "PlacedItem":  // your Imported item
//alert ("PlacedItem: "+artItem.file.fsName+"\r"+artItem.name);
artItem.file=new File (newFolder+artItem.name); // replace by newfolder and same PSD name
break; 
}
}
sourceDoc.save(); // save it

}

ciao, art.chrome

Muppet_Mark-QAl63s
Inspiring
April 14, 2010

Almost the same thing but heres my take anyhow…

#target illustrator function linkReplacer() {      var orginalUIL = app.userInteractionLevel;      app.userInteractionLevel = UserInteractionLevel.DONTDISPLAYALERTS;            if (app.documents.length == 0) {           alert('Please have an "Illustrator" document open before running this script.');           return;      } else {           docRef = app.activeDocument;      }      var defaultFolder = new Folder ('~/Desktop');      var psdFolder = defaultFolder.selectDlg('Please select the folder of your replacement files?');      if (psdFolder == null) return;            with (docRef) {           var placedFiles = new Array();           for (var i = 0; i < placedItems.length; i++) {                placedFiles.push(placedItems.file.name);           }                      for (var j = 0; j < placedItems.length; j++) {                var rePlace = new File(psdFolder.fsName + '/' + placedFiles);                if (rePlace.exists) {                     placedItems.file = rePlace;                } else {                     alert('File "' + placedFiles + '" is missing?');                }           }      }      app.userInteractionLevel = orginalUIL; } linkReplacer();

April 15, 2010

Mark

Your script gives me an error:

"Error 9062: There is no file associated with this item

Line: 21

->     placedFiles.push(placedItems.file.name);"

I looked at documents but don't know enough yet to determine the cause. I am using CS4 on OSX10.6.2.

Any ideas please?