8 Replies Latest reply on May 2, 2008 11:47 AM by (Todd_Robinson)

    [JS CS2] How to replace Documents in Books (after moving folders...)

    pp06
      Hello

      I need to replace the Documents referred to by a Book.

      I was expecting using something like
      app.books[0].bookContents.item(i).replace( File( myNewFullName ) ) ;

      but after many retries to find a correct form for myNewFullName (absoluteURI, ...)... ID always stops.

      Would somebody have a working example for the replace() function applied to a bookContent ? Or a nice advice for a beginner in JS and InDesign ?

      Note : I'm with ID CS2 under Windows XP SP2.

      Thanks !
        • 1. Re: [JS CS2] How to replace Documents in Books (after moving folders...)
          Peter Kahrel Adobe Community Professional & MVP
          myNewFullName should be a string, so if you try something like

          app.books[0].bookContents.item(i).replace( File( '/d/docs/exx.indd' ));

          will work.

          Peter
          • 2. Re: [JS CS2] How to replace Documents in Books (after moving folders...)
            pp06 Level 1
            Hi Peter

            Thanks for your answer; I agree, this *should* work.
            I wonder what I do wrong. (New files to point to, designated that way exist, of course). Just worrying a little bit...

            Patrick
            • 3. Re: [JS CS2] How to replace Documents in Books (after moving folders...)
              Peter Kahrel Adobe Community Professional & MVP
              What exactly is myNewFullName, where does it come from? Can you show us some more code?

              Peter
              • 4. Re: [JS CS2] How to replace Documents in Books (after moving folders...)
                Level 1
                Have you tried this in the UI? There are problems, I believe, in the underlying functionality that might be the cause of your script failing. I ran into this the other day when I changed the names of some folders holding parts of my book. Getting the Book to update to the newly named (but actually the same documents) was a royal pain -- in the end, I had to delete the documents and then add them again. It could be that a script would have to do the same, simply because of the way the feature works (or doesn't, depending on how you look at it).

                Dave
                • 5. Re: [JS CS2] How to replace Documents in Books (after moving folders...)
                  Peter Kahrel Adobe Community Professional & MVP
                  This works fine for me:

                  new_folder = '/d/benj/';
                  
                  bb = app.books[0].bookContents;

                  app.scriptPreferences.userInteractionLevel =
                     UserInteractionLevels.neverInteract;

                  for (i = 0; i < bb.length; i++)
                     bb[i].replace (File (new_folder+bb[i].fullName.name));
                   
                   
                  app.scriptPreferences.userInteractionLevel =
                     UserInteractionLevels.interactWithAll;


                  There are two problems. The first is that the script (or ID) wants to open a document before replacing it in the book. But the book contents doesn't exist any longer where the book thinks it is, so the script produces an error. This is suppressed by the userInteractionLeve statement.

                  The second problem, which may have thrown Patrick, is that the fullName property of bookContents gives you the full name but is an object of type File containing the full pathname. fullName.name gives you the name of the document as a string.

                  Peter
                  • 6. Re: [JS CS2] How to replace Documents in Books (after moving folders...)
                    pp06 Level 1
                    Hi Peter and Dave,

                    Thanks for your prompt replies and your help. I still had no chance with the replace() function, even following Peter's advice (see below), what I could do with the UI.

                    I suppose it is a matter of version and there is nothing to do (Version 4.0.5, French version, no update available)

                    Sample code : at the end I wrote very simple test code
                    As I had some difficulties with the replace() function and I wanted to be sure with simple paths as string constants,
                    I created a simple folder structure figuring 2 "modules" and 1 book

                    D:\test\A\bookA.indb
                    D:\test\A\1\A1.indd
                    D:\test\A\2\A2.indd

                    Than I copied id to a second "B" folder and renamed bookA.indb as bookB.indb
                    D:\test\B\bookB.indb -> as it is a copy, it still points to modules in the D:\test\A folder
                    D:\test\B\1\A1.indd
                    D:\test\B\2\A2.indd

                    >>> No issue with the UI at replacing the modules "by hand and mouse" <<<<br />
                    ------ Simple test -------------------------------
                    app.books[0].bookContents.item(0).replace( File('/d/test/B/1/A1.indd') ) ;
                    app.books[0].bookContents.item(1).replace( File('/d/test/B/2/A2.indd') ) ;
                    // NOK. InDesign stops at the first line. ESTK engine backs to "ExtendScript Toolkit".

                    // ------------------------------------------------------------

                    // Suggested by Peter Kahrel, use fullName.name on the original bookContents.item(i) rather than fullName
                    new_folder = '/d/test/B/';
                    bb = app.books[0].bookContents;
                    ...
                    for (i = 0; i < bb.length; i++) {
                    $.writeln(new_folder+bb[i].fullName.name) ;
                    // Javascript Console : /d/test/B/undefined
                    // With a Document, myDocument.fullName.name provides the short name. (with extension)
                    bb[i].replace (File (new_folder+bb[i].fullName.name));
                    // InDesign stops here for i = 0. ESTK engine backs to "ExtendScript Toolkit".
                    }
                    // ----------------------------------------------------------

                    Maybe ".fullName.name" is in newer models of newer version of InDesign ? Anyway. I forget replace(). I wrote a new script to create a new book and add() copyied indd files in it, with absolute paths based on current book path and effective indd files locations in the sub-folders.
                    It is quite long to run for a script, with yesterday 20 files indd involved, but it works !
                    Doing the same thing by hand would clearly be a royal pain,as you write, Dave. Here is the code. It would need to be completed to set some book and bookContent properties as they were in the original, this would rather be in another script. The script that works for me :

                    // ----------------------------------------------------
                    //
                    //
                    // After copying an ID book and catalog modules to a new folder, the point is the book
                    // keeps its pointers to original modules - absolute paths to folders and files -
                    // This script intends to establish paths to modules under *this* folder.
                    //
                    // This script supposes there is 1 opened book : books[0] and only one.
                    //
                    var oldBook ;
                    var newBookPath ;
                    var myFullModuleName ;

                    // try finding an initial book
                    try {
                    oldBook = app.books[0] ;
                    } catch (e) {
                    alert(e+" : the initial book must be open") ;
                    exit() ;
                    }

                    // check if the book is not empty, then determine the new path to the book
                    if ( oldBook.bookContents.length > 0 ) {
                    newBookPath = oldBook.filePath ;
                    $.writeln("New module path : "+ newBookPath+"\n");
                    } else {
                    alert("The initial book should not be empty") ;
                    exit() ;
                    }

                    // create a new-temporary book to receive references to modules
                    try {
                    var newBook = app.books.add(File(newBookPath+'/tmp.indb')) ;
                    } catch(e) {
                    alert(e+" Couldn't create a temporary book") ;
                    exit() ;
                    }

                    app.scriptPreferences.userInteractionLevel = UserInteractionLevels.neverInteract;

                    // for each document file in the original book
                    for ( var i = 0; i < oldBook.bookContents.length; i++) {
                    var bb = app.books[0].bookContents.item(i) ;
                    myFullModuleName = bb.fullName ;

                    // regenerate the /sub-folder/module.indd path
                    var splittedName = myFullModuleName.split("\\") ;
                    var myShortModuleName = '/'+splittedName[splittedName.length-2]+'/'+splittedName[splittedName.length-1] ;
                    $.writeln(newBookPath+myShortModuleName) ;

                    // put the module in new book
                    app.books[1].bookContents.add( File(newBookPath+myShortModuleName) ) ;
                    }

                    app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll;

                    exit() ;
                    // Note. The new book is not saved at this stage so the file on the disk is for an empty book,
                    // and the original book is still existing.
                    • 7. Re: [JS CS2] How to replace Documents in Books (after moving folders...)
                      Peter Kahrel Adobe Community Professional & MVP
                      Patrick,

                      I do apologise for misleading you about the nature of fullName: I was talking about CS3 and rereading your original post, only now notice that you use CS2. The difference is relevant as in CS2, bookContents[0].fullName returns a string (in CS3, a file object). Here is the script working in CS2:

                      #target indesign
                      

                      new_folder = '/d/test/';
                      bb = app.books[0].bookContents;

                      app.scriptPreferences.userInteractionLevel =
                         UserInteractionLevels.neverInteract;

                      for (i = 0; i < bb.length; i++)
                         {
                         try
                            {
                            new_name = new_folder + File(bb[i].fullName).name;
                            bb[i].replace (File (new_name));
                            $.writeln (new_name)
                            }
                         catch(_){}
                         }
                        
                      app.scriptPreferences.userInteractionLevel =
                         UserInteractionLevels.interactWithAll;


                      bb[i].fullName is a string containing the full path. You need just the filename, and the easiest way to get that out of the string is to convert the string into a file object and use the name property: File (bbi.fullName).name (I'm writing this up, feebly hoping that I'll remember it). This approach is a bit clearer than your "regenerate the /sub-folder/module.indd path" (I used something similar before I found the File (xxx).name method; File(xxx).path gives you the path part of a string by the way).

                      The try-catch construction is there to ensure that the script doesn't break when a document can't be found or because of any other situation. As the script is painfully slow, it may be best to run it from ESTK and let it print each document's name as it is replaced. On very small files it takes ages (well, just over a second), so larger files may take their time. Maybe disabling automatic pagination speeds up the script, may be worth a try:

                      app.books[0].automaticPagination = false;

                      But maybe your approach of creating a new book is quicker.

                      Peter
                      • 8. Re: [JS CS2] How to replace Documents in Books (after moving folders...)
                        I am trying to figure out the same this except i don't really know anything about javascript and i'm very new to using scripts in ID. Can some please help me? i'm trying to make back up copies, but when a change is made to the original, the backups all change as well. and i would like them to remain unchanged.