Nehmen wir mal an, wir haben ein Layout-Dokument mit 50 Bildrahmen. In jedem Bildrahmen ist ein JPEG-Bild verknüpft.
Allerdings bekommt man von der Litho 50 TIFF-Dateien, die man nun allesamt neu verknüpfen muss.

"Ganz einfach über die Verknüpfungs-Palette!" ...werden manche sagen.
Das funktioniert leider nicht immer. Also bei mir eigentlich nie. Entweder, weil mir schon die dazugehörigen JPEG-Bilder nicht vorliegen oder weil das InDesign-Dokument in einem Redaktions-System liegt und ich keine lokale InDesign-Datei habe, die ich mal in den Links-Ordner mit rein legen könnte, so dass InDesign weiß, wo es denn nach den Bildern suchen soll.

Zum Glück gibt es Skripte!

Auf dieser Seite habe ich ein Skript gefunden, welches eigentlich genau das tut, was ich will:
Alle Links neu verknüpfen und dabei...

  • ...in einem gewünschten Ordner nach Bildern suchen
  • ...es mit den Bildnamen nicht so genau nehmen (z.B. Datei-Endung .tif statt .jpg)

Dass man, um den alternativ zu suchenden Dateinamen zu spezifizieren, auf den Text-Suchen-und-Ersetzen-Dialog von InDesign zurückgreifen muss, fand' ich allerdings nicht arg benutzerfreundlich und intuitiv gelöst, so habe ich eine eigene Lösung gebastelt.

Relinker Plus.jsx (Version 1.1)
#targetengine 'replacePlus';

if (app.documents.length == 0) {  
  alert("Es ist kein Dokument ge\u00F6ffnet.");
  exit();  
  }

var gDoc    = app.activeDocument;  
var gLinks  = gDoc.links;  
var counter = 0;
var gesamt  = 0;

if (gLinks.length == 0) {  
  alert("Dieses Dokument scheint keine Bilder zu enthalten.");
  exit();  
  }

// Start-Dialog
var findReplace = {dothat:false, suchen:null, ersetzen:null, alt:true, andere:true};
if (!startwerte())
  exit();

// Pfad zum Ordner wählen, der die Bilder enthalten sollte
var pfad = Folder.selectDialog("Ordner, die Bilddaten enth\u00e4lt, zu denen neu verkn\u00fcpft werden soll", "");
if (pfad == null)
  exit();  

// Progress-Bar
var w = new Window("palette", "Bilder des Dokumentes pr\u00fcfen", undefined, {closeButton:false});
var pbarTxt  = w.add ("statictext", undefined, gLinks.length+" Bilder...");
var progress = w.add ("progressbar", undefined, 1, gLinks.length);
progress.preferredSize = [300,20];
w.show();

// Ergebnis-Palette
var resultWin = new Window ('palette', "Gefundene Bilder", undefined, {closeButton:true});
resultWin.alignChildren = 'left';
var tpanel = resultWin.add ('tabbedpanel');
tpanel.alignChildren = ['fill', 'fill'];
if (parseInt (app.version.split('.')[0], 10) >= 9) { tpanel.maximumSize.width = 720; }
var myTabs = [];
var itemsPerTab = ($.screens[0].bottom - $.screens[0].top >= 864) ? 25 : 15;
var currentTabIndex = -1;
var myMatchingFilesMenu = {};
var myMatchingFilesList = [];
// Alle Bilder durchgehen
for (var i = gLinks.length-1; i >= 0; i--) {  
   progress.value++;
    var currentLink = gLinks[i];  
    if (currentLink.name.indexOf(".wcml") != -1) continue; // Woodwing-Artikel
    gesamt++;
    if (findReplace.dothat && !findReplace.andere && !currentLink.name.match(findReplace.suchen)) continue; // Dateien ignorieren, die nicht dem Suchen-/Ersetzen-Schema entsprechen
    var newName = findReplace.dothat ? currentLink.name.replace(findReplace.suchen, findReplace.ersetzen) : currentLink.name;
    var newFile = new File(pfad+"/"+newName);
    if (!newFile.exists && findReplace.dothat && !findReplace.alt) {
        newFile = new File(pfad+"/"+currentLink.name);
        newName = currentLink.name;
        }
    if (newFile.exists) {
        // Datei im gewählten Ordner gefunden
        // Ggf. neuen Tab hinzufügen?
        if (currentTabIndex < 0 || myTabs[currentTabIndex].children.length >= itemsPerTab) {
            currentTabIndex++;
            myTabs[currentTabIndex] = tpanel.add ('tab', undefined, currentTabIndex+1);
            myTabs[currentTabIndex].alignChildren = 'left';
            }
        // Item hinzufügen
        var idl = currentLink.id;
        myMatchingFilesList[idl] = newFile;
        myMatchingFilesMenu[idl] = myTabs[currentTabIndex].add('group');
        myMatchingFilesMenu[idl].ID = idl;
        myMatchingFilesMenu[idl].cb = myMatchingFilesMenu[idl].add('checkbox', undefined, currentLink.name);
        myMatchingFilesMenu[idl].cb.helpTip = "Diesen Link beim Klick auf 'Alle ersetzen' mit einbeziehen";
        myMatchingFilesMenu[idl].cb.value = true;
        myMatchingFilesMenu[idl].neu = myMatchingFilesMenu[idl].add ('statictext', undefined, newName);
        myMatchingFilesMenu[idl].sel = myMatchingFilesMenu[idl].add ('button', undefined, "G");
        myMatchingFilesMenu[idl].sel.size = [20, 20];
        myMatchingFilesMenu[idl].sel.helpTip = "Gehe zu Verkn\u00fcpfung";
        myMatchingFilesMenu[idl].sel.onClick = function() { try { gDoc.links.itemByID(Number(this.parent.ID)).parent.select(); } catch (e) { alert (e); } };
        myMatchingFilesMenu[idl].rep = myMatchingFilesMenu[idl].add ('button', undefined, "V");
        myMatchingFilesMenu[idl].rep.size = [20, 20];
        myMatchingFilesMenu[idl].rep.helpTip = "Neu verkn\u00fcpfen (nur diese eine hier)";
        myMatchingFilesMenu[idl].rep.onClick = function() {
            try {
                gDoc.links.itemByID(Number(this.parent.ID)).relink(myMatchingFilesList[Number(this.parent.ID)]);
                this.parent.cb.value = false;
                this.parent.cb.hide();
                this.parent.neu.hide();
                this.hide();
                this.parent.sel.onClick();
                this.parent.sel.hide();
                delete myMatchingFilesMenu[this.parent.ID];
                if (myMatchingFilesMenu.length == 0) resultWin.close();
            } catch(e) { alert(e); }
            };
        counter++;
        }
    }
progress.parent.close();

var b_run = resultWin.add ('button', undefined, "Alle gew\u00e4hlten Verkn\u00fcpfungen ersetzen");
b_run.alignment='right';
b_run.onClick = function (){
    try {
        app.doScript(function() { relinkAll(); },
                ScriptLanguage.JAVASCRIPT,
                undefined,
                UndoModes.ENTIRE_SCRIPT,
                b_run.text
                );
        } catch(e) { alert(e); }
    };

if (counter == 0) {
    alert("Es wurden keine passenden Bilder im gew\u00e4hlten Verzeichnis gefunden");
    exit();
    }

resultWin.show();

function relinkAll() {
  resultWin.close();
  var replacedLinksCount = 0;
  for (var idm in myMatchingFilesMenu) {
    if (! myMatchingFilesMenu[idm].cb.value) { continue; }
    var myOldLink;
    try {
      myOldLink = gDoc.links.itemByID(Number(idm));
      if (! myOldLink) { throw new Error; }
      if (! myOldLink.isValid) { throw new Error; }
    } catch(e) {
      continue;
      }
    var myNewLinkFile = myMatchingFilesList[Number(idm)];
    myOldLink.relink(myNewLinkFile);
    replacedLinksCount++;
    }
  alert (replacedLinksCount + " Link"+((replacedLinksCount==1)?"":"s")+" ersetzt");
  }

// Startdialog
function startwerte() {
    var w = new Window("dialog", "", undefined, {closeButton:false});
  w.spacing = 0;
    w.add ("statictext", [0,0,600,50], "Dieses Skript verkn\u00fcpft alle Bilder des Dokumentes neu zu Dateien aus dem Ordner, den Sie im folgenden Schritt w\u00e4hlen k\u00F6nnen.", {multiline: true});
    var wPanel = w.add ('panel {text: "Dateinamen-Variation"}'); wPanel.alignment = "left";  wPanel.margins.top = 20;
    wPanel.add ("statictext", [0,0,600,25], "Bitte geben Sie hier an, ob nach einer Variation des Dateinamens gesucht werden soll.", {multiline: true});
    var wgrpSuchen = wPanel.add ('group');
    wgrpSuchen.add ('statictext {text: "Suchen:", characters: 8}');
    wgrpSuchen.alignment = "left";
    var wTxtSuchen = wgrpSuchen.add ('edittext {characters: 18, active: true}');
    var wgrpErsetzen = wPanel.add ('group');
    wgrpErsetzen.alignment = "left";
    wgrpErsetzen.add ('statictext {text: "Ersetzen: ", characters: 8}');
    var wTxtErsetzen = wgrpErsetzen.add ('edittext {characters: 18, active: false}');
   
  var regexChk = wPanel.add ("checkbox", [0,0,600,20], "Verwende RegEx (Bitte \\ escapen => \\\\)");
  regexChk.value = false;
  regexChk.alignment = "fill";
    var altChk = wPanel.add ("checkbox", [0,0,600,20], "Falls neuen Dateinamen nicht gefunden, nach altem Dateinamen suchen");
  altChk.value = true;
  altChk.alignment = "fill";
    var andereChk = wPanel.add ("checkbox", [0,0,600,30], "Auch nach Dateien in dem Verzeichnis suchen,\ndie nicht diesem Suchen/Ersetzen-Schema entsprechen");
  andereChk.value = true;
  andereChk.alignment = "fill";
    var wTxt3  = wPanel.add ("statictext", [0,0,600,60], "Beispiel:\nSuchen: .JPG Ersetzen: .tif\nVerknüpfung bild.JPG wird durch bild.tif ersetzt (falls in Ordner gefunden)\n"+
                                                    "Lassen Sie die beiden Felder leer, wenn nach den originalen Dateinamen gesucht werden soll.", {multiline: true});
  wTxt3.graphics.font = "dialog:10";
   
    var wBtn    = w.add("group"); wBtn.alignment = "right";  wBtn.margins.top = 20;
    var wCancel = wBtn.add("button", undefined, "Abbruch",  {name:"Cancel"});
    var wOK     = wBtn.add("button", undefined, "Fortfahren", {name:"OK"});

    if (w.show() == 1) {
        if (wTxtSuchen.text == "") {
            findReplace.dothat = false;
         } else {
            findReplace.dothat   = true;            
            findReplace.suchen   = regexChk.value ? new RegExp(wTxtSuchen.text, "gi") : wTxtSuchen.text;
            findReplace.ersetzen = wTxtErsetzen.text;
            findReplace.alt      = altChk.value;
            findReplace.andere   = andereChk.value;
            }      
        return true;
        }
    else return false;
    }

Skript in eine neue Textdatei einfügen, im InDesign-Programmeordner, Unterordner Scripts/Scripts Panel abspeichern und dann über die Fenster > Hilfsprogramme > Skripte-Palette starten.

Danach wird man vom rechts gezeigten Dialog begrüßt.
Man kann nichts eingeben und einfach nur auf "Fortfahren" klicken, so erscheint als nächstes ein Verzeichnis-Wahldialog. Hier den Ordner wählen, der die Verknüpfungen enthält. Klickt man anschließend auf "Alle gewählten Verknüpfungen ersetzen", werden alle Bildrahmen im Dokument mit den Dateien im eben gewählten Verzeichnis neu verknüpft (sofern eine gleichnamige Datei gefunden wurde).
 
Der Start-Dialog eignet sich aber auch dazu, Bilder eines bestimmten Dateityps gegen andere Bilder auszutauschen. Also zum Beispiel für die Problematik "Im Dokument als .jpg verknüpft, mir liegen allerdings .tif-Dateien vor".
Dank Regular Expressions sind wir hier sehr flexibel, was die zu ersetzenden Dateien angeht. Wichtig für's Verständnis ist nur: Durch die Suchen & Ersetzen-Funktion entsteht ein fester Dateiname, welchen das Skript im gewählten Ordner zu finden sucht. Wird der Dateiname nicht gefunden, wird außerdem versucht, eine Datei des originalen Dateinamens zu finden.

Neu in Version 1.1: Zwei weitere Checkboxen (Nicht in den Screenshots zu sehen)

  • Falls neuen Dateinamen nicht gefunden, nach altem Dateinamen suchen – Falls bei bild.jpg .jpg durch .tif ersetzt werden soll, bild.tif aber nicht gefunden werden kann, nach dem ursprünglichen bild.jpg suchen
  • Auch nach Dateien in dem Verzeichnis suchen, die nicht diesem Suchen/Ersetzen-Schema entsprechen – Falls .jpg durch .tif ersetzt werden soll, in dem gewählten Verzeichnis auch nach Bildern suchen, die z.B. anderesbild.tif heißen

Gefundene Dateien werden nicht sofort neu ersetzt – es erscheint erst ein Fenster zum Ãœberprüfen der gefundenen Dateien.
Hier ist der aktuelle im Dokument erwartete Dateiname und der Name der im gewählten Verzeichnis gefundenen Datei zu finden (sofern die Suchen & Ersetzen-Funktion verwendet wurde, können diese beiden Namen voneinander abweichen).
Möchte man einen Link nicht aktualisieren: Haken vor dem Dateinamen entfernen und alle restlichen Links mit dem Button "Alle gewählten Verknüpfungen ersetzen" aktualisieren.

Man kann außerdem mit dem "V"-Button nur diesen einen Link aktualisieren oder mit dem "G"-Button zu dem Link im Dokument springen (wie die "Gehe zur Verknüpfung" und "Verknüpfung aktualisieren"-Buttons in der Verknüpfungs-Palette).

Da es wohl ein Problem mit längeren scrollbaren Listen gibt, werden die gefundenen Dateien hinter mehreren Tabs zum Durchblättern gelistet.
Im oberen Beispiel gibt es nur eine Seite.