/*
SearchReplaceLinkPaths.jsx
With the help of this time saving script, you can replace the paths of all linked objects with new ones.
This function is especially helpful if you use an existing InDesign project as a template for a new project, copy it to a new directory,
but the paths for InDesign will not change, relatively.
Tip: In this case, simply rename the old path to the linked objects after copying
so that InDesign does not mistakenly continue to use the old objects. You will then get the warnings in the link panels, instead.
The linked objects can even be located in any nested subdirectories.
The script UI: A dialogue box shows up in the sense of "Search and Replace". You search for and enter the text expression that is to change in all paths, equally.
Note: The paths will only be replaced if the files do actually exist in the new directories.
Paths that do not match the search-replace condition remain unaffected.
Example 1:
Original Path, search for:
"B:\5.3_Cornerstone\Release_7.1"
New Path, replace with:
"D:\2.1.2_Cornerstone\Release_7.2"
Example 2:
Original Path:
"B:\5.3_Cornerstone\Release_7.1\Media..."
New Path:
"B:\5.3_Cornerstone\Release_7.2\Media..."
Search for: "7.1"
Replace by: "7.2"
And: I am not a programmer.
The only thing that annoys me is the poor comfort with the cumbersome handling of file paths in InDesign's Link Panel, as 1000 others on the Internet have been complaining for years.
Feedback and improvements are very welcome!
*/
// the following 4 lines declare variables
// usually I declare all vars at the beginning of the function
// when you declare a variable with var, you limit its scope to the function
// (making them local),
// otherwise the scope is global which may cause you problems
// a rule-of-thumb is to use global vars only you really need them
var i, link, newFile, AbsolutePath;
var NumMatches = 0; // counter of how many file paths actually were found that match the replacement condition
var NumUpdates = 0; // counter of how many files paths were actually updated
var NumOpen = 0; // number of files that still do not exist in the new directories
doc = app.activeDocument; // set variable doc to the front most document
links = doc.links; // set variable links to collection of all links
// call the dialoge window
var shownWindow = setConfigWindow();
// Clicked on Ok = true
if(shownWindow.result == true){
// alert ('Ok!');
alert ('Searching for:\t'+shownWindow.StrSearch+'\n'+
'To be replaced by:\t'+shownWindow.StrReplace);
for (i = links.length-1; i >= 0; i--) { // loop through all links backwards
link = links[i]; // set the variable link to the current link
AbsolutePath = link.filePath;
if (AbsolutePath != AbsolutePath.replace(shownWindow.StrSearch,shownWindow.StrReplace)) {
NumMatches = NumMatches+1;
// alert (AbsolutePath+'\n\n'+AbsolutePath.replace(shownWindow.StrSearch,shownWindow.StrReplace));
// create file object:
newFile = new File(AbsolutePath.replace(shownWindow.StrSearch,shownWindow.StrReplace));
if (newFile.exists){
NumUpdates = NumUpdates+1;
link.relink(newFile); // relink only if the file exists
// I use try-catch block to make the script compatible with CS3 and above
// In other words, if an error occurs here, skip it over and go on
try {
link.update();
}
catch(err) {}
}
}
}
NumOpen = NumMatches - NumUpdates;
alert ('Number of cases that matched the replacement condition:\t'+ NumMatches +
'\nNumber of relinked objects:\t\t\t\t' + NumUpdates +
'\nNumber of files missing in new folders:\t\t\t' + NumOpen);
}
// Clicked on Cancel = if false
else {
alert ('The action was canceled');
}
// provides dialog box as a function
function setConfigWindow() {
// Create dialog box
var configWindow = new Window('dialog','Updating Paths for Linked Objects');
// Adding a display column (siehe auch Adobe JavaScript Tools Guide)
configWindow.column01 = configWindow.add ('group {orientation: "column"}');
// Add framing with "Title"
configWindow.column01.gridPanel = configWindow.column01.add ('panel', undefined,
'Differentiating strings as part of the absolute paths');
// Do the following with the "inside" of the frame...
with(configWindow.column01.gridPanel){
// Set "orientation" of the "frame" to the left
aligment = 'left';
// Add display group for 1st input
var SearchGroup = add('group');
// Add "input label" (statictext) & input field (edittext)
SearchGroup.add('statictext', [0,0,80,15], 'Search for:');
var SearchInputField = SearchGroup.add('edittext', [0,0,150,24], 'A:\\');
// Add display group for 2nd input
var ReplaceGroup = add('group');
// Add "input label" (statictext) & input field (edittext)
ReplaceGroup.add('statictext', [0,0,80,15], 'Replace with:');
var ReplaceInputField = ReplaceGroup.add('edittext', [0,0,150,24], 'B:\\');
}
// Add buttons in the "Display column" but outside the "Frame"
configWindow.column01.btnGrp = configWindow.add('group');
configWindow.column01.btnGrp.add('button', undefined, 'Ok');
configWindow.column01.btnGrp.add('button', undefined, 'Cancel');
// View windows in Adobe InDesign
var usrAction = configWindow.show();
// Return three objects
return {
result: usrAction,
StrSearch: SearchInputField.text,
StrReplace: ReplaceInputField.text
}
}