19 Replies Latest reply on Nov 4, 2015 8:25 AM by kungxiong5

    plug-in or script to print unrelated, multiple InDesign files

    Carina Marano Level 1

      Does anyone know of a plug-in or script that allows you to print unrelated, multiple InDesign files? Using a book does not work as each InDesign file has it's own print settings.


      I'm looking for something similar to Zevrix's Batch Output, but for only the print feature. It allows you to print each InDesign file with the last print settings used for that file.


      I greatly appreciate any help. Thank you.

        • 1. Re: plug-in or script to print unrelated, multiple InDesign files
          John Hawkinson Level 5

          This is certainly easy to script. Untested (so it probably needs a little help):

          var folder = new Folder("/path/to/folder-of-files");
          
          var i, f, files, uil;
          
          uil = app.scriptPreferences.userInteractionLevel;
          app.scriptPreferneces.userInteractionLevel =
            UserInteractionLevels.neverIntact;
          
          try {
            files = folder.getFiles("*.indd");
            app.print(files);
          } catch (e) {
            alert("Caught error:" + e);
          } finally {
            app.scriptPreferences.userInteractionLevel = uil;
          }
          

           

          Since allegedly app.print() takes an array of files, it might well be the case that you're better off looping through the array of files and printing each one at a time, since that way you can find out when something goes wrong. Or possibly even opening the files and then printing them and closing them, one by one. But each of those is more work. So try the above.

           

          It, of course, expects the files to be in a folder of their own, /path/to/folder-of-files. So change that.

          1 person found this helpful
          • 2. Re: plug-in or script to print unrelated, multiple InDesign files
            John Hawkinson Level 5

            Oh yes. You're new, so you probably need instructions on how to install a script (this is in JavaScript).

            Try the directions at http://indesignsecrets.com/how-to-install-scripts-in-indesign.php (from Anne-Marie Concepcion), or for more florid graphical detail, see http://www.danrodney.com/scripts/directions-installingscripts.html. Maybe we should have a link on the side in this forum.

            • 3. Re: plug-in or script to print unrelated, multiple InDesign files
              Carina Marano Level 1

              Thank you. Once I corrected a couple of spelling errors and figured out that I needed to replace "/path/to/folder-of-files" with the path to the actual folder with the .indd files, it worked like a charm. This will save me so much time. I greatly appreciate it.

              • 4. Re: plug-in or script to print unrelated, multiple InDesign files
                John Hawkinson Level 5

                Great. Sorry about the typo(s).

                I sort of wonder if that script was too defensive. I suppose you could maybe have just run:

                 

                app.print((new Folder("/path/to/folder-of-files")
                  )
                .getFiles("*.indd"));

                 

                and maybe it would all just work .

                • 5. Re: plug-in or script to print unrelated, multiple InDesign files
                  Carina Marano Level 1

                  So, I've tried adding a few things to the script to make it a little more user friendly. I don't know anything about scripting so I've been piecing it together from another script.

                   

                  i've added a dialog box to search for the folder. And then added a dialog if there's nothing in the folder.

                   

                  I'm trying to add a Go/Quit dialog, but I don't know how to make the "go" button move the script along.

                   

                  Also, if possible, I'd love to be able to have a progress bar going as the files are printing.

                   

                  Any help is appreciated. Thank you.

                   

                   

                  var myInDesignVersion = Number(String(app.version).split(".")[0]);

                   

                  var myFolder = Folder.selectDialog();
                  if (myFolder == null) exit();
                  var myFilelist = [];
                  var myAllFilesList = myFolder.getFiles();

                   

                  for (var f = 0; f < myAllFilesList.length; f++) {
                      var myFile = myAllFilesList[f];
                      if (myFile instanceof File && myFile.name.match(/\.indd$/i)) {
                          myFilelist.push(myFile);
                      }
                  }

                   

                  if (myFilelist.length == 0) {
                      alert("No files to print.");
                      exit();
                  }

                   

                  var myDialogResult = CreateDialog();
                  if (myDialogResult == undefined) {
                      exit();
                  }

                   

                  var i, f, files, uil;

                  uil = app.scriptPreferences.userInteractionLevel;
                  app.scriptPreferences.userInteractionLevel =
                    UserInteractionLevels.neverInteract;

                  try {
                    files = myFolder.getFiles("*.indd");
                    app.print(files);
                  } catch (e) {
                    alert("Caught error:" + e);
                  } finally {
                    app.scriptPreferences.userInteractionLevel = uil;
                  }

                   


                  function CreateDialog() {
                      var myDialog = new Window('dialog', 'Package for Archive');
                      myDialog.orientation = 'column';
                      myDialog.alignChildren = 'top';
                     
                      var myFolderPanel = myDialog.add('panel', undefined, 'Folder to package:');
                      myFolderPanel.alignment = 'fill';
                      var myFolderPanelStTxt1 = myFolderPanel.add('statictext', undefined, myFolder.fsName.replace("/Volumes/", ""));
                      var myFolderPanelStTxt2 = myFolderPanel.add('statictext', undefined, '(Found ' + myFilelist.length + ' files)');
                     
                      var myOkCancelGroup = myDialog.add('group');
                      myOkCancelGroup.orientation = 'row';
                      myOkCancelGroup.alignment = 'center';
                      var myOkBtn = myOkCancelGroup.add('button', undefined, 'Go', {name:'ok'});
                      var myCancelBtn = myOkCancelGroup.add('button', undefined, 'Quit', {name:'cancel'});
                     
                      var myShowDialog = myDialog.show();   
                      }

                  • 6. Re: plug-in or script to print unrelated, multiple InDesign files
                    [Jongware]-9BC6tI Level 4

                    Your myDialog.show returns the 'button pressed' -- in your case, OK or Cancel. You store this returned value in a variable, but forget to return it to your main program

                     

                    From Peter Kahrel's ScriptUI Guide (and it's also somewhere in Adobe's own Javascript reference):

                     

                    The window's behaviour is this: if the user presses OK, the line myWindow.show ( ) returns 1, if they press Esc, that line returns 2. We capture this as follows ...

                     

                    so add this at the bottom of your CreateDialog function:

                     

                     var myShowDialog = myDialog.show();
                      return myShowDialog;
                    }
                    

                     

                    or change it to

                     

                    return myDialog.show();

                     

                    to return the result to the rest of your code.

                    1 person found this helpful
                    • 7. Re: plug-in or script to print unrelated, multiple InDesign files
                      [Jongware]-9BC6tI Level 4

                      Oh, by the way:

                       

                      So, I've tried adding a few things to the script to make it a little more user friendly. I don't know anything about scripting so I've been piecing it together from another script.

                       

                      That's great! It's a good way to get started. I'd be lost without my, what?, 200?, "old" scripts that I no longer really use; but I keep them to copy snippets of working code.

                      • 8. Re: plug-in or script to print unrelated, multiple InDesign files
                        Carina Marano Level 1

                        This is so close. The dialog box comes up, but whether I hit "go" or "quit", or even if I try escape, the script proceeds anyway. Kind of defeating the point of the dialog box.

                         

                        I tried adding in an if satement like the one from the PDF, but it freezes up at the dialog box and hitting "go" or "quit" does nothing, and I cannot escape out fo the script.

                         

                        if (myDialog.show() ==1)
                        var myShowDialog = myDialog.show();

                        return myShowDialog;

                         

                        I'm thinking it should be something besides "myDialog.show" but i'm not sure what.

                        • 9. Re: plug-in or script to print unrelated, multiple InDesign files
                          [Jongware]-9BC6tI Level 4

                          .. each time you call myDialog.show(), the dialog pops up. So don't use it twice! Perhaps poor InDesign is getting confused there, and that's why it blocks.

                           

                          As for quitting, use this. The dialog returns '1' for OK, '2' for Cancel, right? Then test it like this:

                           

                          var myDialogResult = CreateDialog();  // use the value returned by myDialog.show() here
                          if (myDialogResult == 2) {  // Cancelled?
                              exit();
                          }
                          
                          .. rest of your script ..
                          
                          • 10. Re: plug-in or script to print unrelated, multiple InDesign files
                            John Hawkinson Level 5

                            Wow, Carina! You put a lot of work into this. I admit, I figured you just needed a canned solution. It's great that you want to learn more.

                             

                            So, several recommendations.

                             

                            First, when posting Javascript to this forum, please use the Java syntax highlighting option:http://forums.adobe.com/servlet/JiveServlet/showImage/2-2703004-23715/Screen+shot+2010-03-31+at+9.24.11+AM.png

                             

                            It makes your code much easier to read, and of course, easy-to-read code is the code that gets good feedback.

                             

                            Also, I suspect you're new to JavaScript (apologies if not!). If so, it's best to learn good habits from the start. We're often sloppy in scripting, but JavaScript has a bunch of language "gotchas" that are good to avoid, especially if you ever end up doing JavaScript programming in other environments. ExtendScript is pretty decent, but other environments (e.g. browsers) are often not so forgiving. An excellent reference is Douglas Crockford's

                            JavaScript: The Good Parts (amazon link) and his excellent code-quality tool JSLint.

                             

                            So, going through your code:

                             

                            . JavaScript uses function scope for local variables, only. Not block scope (inside curly braces). So generally speaking, you should declare all your variables at the top of a function, once. When you write this:

                             

                            for (var f = 0; f < myAllFilesList.length; f++)
                            

                             

                            You think that f is a local variable that exists only inside your for loop, but actually it's not. It's part of the entire enclosing function! And since all this stuff is not inside a function at all, it's actually a global variable. As your program gets longer and more complicated, this is a recipe for disaster!

                             

                            Crockford's good advice is to put all your var declarations in one spot at the top of your function, and it's good advice.

                             


                            . In JavaScript, unlike Java, what look like constructors don't actually behave that way, especially if you don't include the new operator. There's no reason to write:

                            var myInDesignVersion = Number(String(app.version).split(".")[0]);
                            

                            when you can just write:

                            var InDesignVersion=app.version.split("."][0]
                            

                            (If you really want it as a number, you're supposed to call parseint(foo,10) on it. But why bother making it a number?)

                            Also, I guess a lot of people will disgree with me, but there's no reason for you to put "my" in front of your variable names. Personally I find it a klunky style that doesn't serve any purpose.

                             

                            No reason to write "if (myFolder == null)" when you can just write "if (!myFolder)".

                             

                            In my original example, I showed you "myAllFilesList.getFiles("*.indd")". Why convert to this? It is much less readible and more errorprone:

                            for (var f = 0; f < myAllFilesList.length; f++) {
                                var myFile = myAllFilesList[f];
                                if (myFile instanceof File && myFile.name.match(/\.indd$/i)) {
                                    myFilelist.push(myFile);
                                }
                            }
                            

                             

                            I suppose in your case yours would successfully exclude folders that were named ".indd" but that seems a really unlikely case.

                            Javascript is loosely typed, and the benefit of that is you don't need to run aroudn checking types. There's really nothing to be gained by making sure that myFile instanceof File is true. Just match against myFile.name.

                             

                            In JavaScript, because 0 is a "falsy" value, "if (myFilelist.length == 0) {" is better written as "if (!myFilelist.length) {".

                            Similarly, checking against "undefined" is bad style and error prone. Just check and see "if (!myDialogResult)". As JongWare points out, your CreateDialog function (at least the original version) doesn't return a value, so checking it's value is never going to work.

                             

                            My sample script had some leftover variable declarations that I never ended up using: "var i, f, files, uil;". i and f were never used. Of course, you later used f. But never i.

                             

                            Using a CreateDialog() function is great! More functions is almost always better and clearer. Best to declare the variables all at the top, though. Yes, it doesn't really matter here, but it's good style and if you learn good habits early, you'll be set later on. So:

                             

                             

                            function CreateDialog() {
                                 var myDialog, myFolderPanel, myFolderPanelStTxt1, myFolderPanelStTxt2, myOkCancelGroup,
                                   myOkBtn, myCancelBtn, myShowDialog;
                                   
                                myDialog = new Window('dialog', 'Package for Archive');
                                myDialog.orientation = 'column';
                                myDialog.alignChildren = 'top';
                               
                                myFolderPanel = myDialog.add('panel', undefined, 'Folder to package:');
                                myFolderPanel.alignment = 'fill';
                                myFolderPanelStTxt1 = myFolderPanel.add('statictext', undefined, myFolder.fsName.replace("/Volumes/", ""));
                                myFolderPanelStTxt2 = myFolderPanel.add('statictext', undefined, '(Found ' + myFilelist.length + ' files)');
                               
                                myOkCancelGroup = myDialog.add('group');
                                myOkCancelGroup.orientation = 'row';
                                myOkCancelGroup.alignment = 'center';
                                myOkBtn = myOkCancelGroup.add('button', undefined, 'Go', {name:'ok'});
                                myCancelBtn = myOkCancelGroup.add('button', undefined, 'Quit', {name:'cancel'});
                               
                                myShowDialog = myDialog.show();   
                                }
                            

                             

                            Though, really, please drop the "my"s. You could also write this without quite so many variables by using the resource specification format.

                             

                            Whoops, gotta run. More later.

                            • 11. Re: plug-in or script to print unrelated, multiple InDesign files
                              Carina Marano Level 1

                              So,

                               

                              I think I've cleaned this up pretty good with all the suggestions, except getting rid of the "my"s (which I'll gladly attempt if I ever write something from scratch or if I attempt to rewrite this thing).

                               

                              So far I've got this:

                               

                                   function CreateDialog() {
                                   var myDialog, myFolderPanel, myFolderPanelStTxt1, myFolderPanelStTxt2, myOkCancelGroup,
                                     myOkBtn, myCancelBtn, myShowDialog;
                                     
                                  myDialog = new Window('dialog', 'Multiple Print');
                                  myDialog.orientation = 'column';
                                  myDialog.alignChildren = 'top';
                                 
                                  myFolderPanel = myDialog.add('panel', undefined, 'Files to Print');
                                  myFolderPanel.alignment = 'fill';
                                  myFolderPanelStTxt1 = myFolderPanel.add('statictext', undefined, myFolder.fsName.replace("/Volumes/", ""));
                                  myFolderPanelStTxt2 = myFolderPanel.add('statictext', undefined, '(Found ' + myAllFilesList.length + ' files)');
                                 
                                  myOkCancelGroup = myDialog.add('group');
                                  myOkCancelGroup.orientation = 'row';
                                  myOkCancelGroup.alignment = 'center';
                                  myOkBtn = myOkCancelGroup.add('button', undefined, 'Go', {name:'ok'});
                                  myCancelBtn = myOkCancelGroup.add('button', undefined, 'Quit', {name:'cancel'});
                                 
                                  myShowDialog = myDialog.show();   
                                  }
                              
                              var InDesignVersion=app.version.split(".")[0]
                              
                              var myFolder = Folder.selectDialog();
                              if (!myFolder) exit();
                              var myAllFilesList = myFolder.getFiles("*.indd");
                              
                              if (!myAllFilesList.length) {
                                   alert("No files to print.");
                                   exit();
                              }
                              
                              var myDialogResult = CreateDialog();
                              if (myDialogResult == 2) {
                                   exit();
                              }
                              
                              var i, f, files, uil;
                               
                              uil = app.scriptPreferences.userInteractionLevel;
                              app.scriptPreferences.userInteractionLevel =
                                UserInteractionLevels.neverInteract;
                               
                              try {
                                files = myFolder.getFiles("*.indd");
                                app.print(files);
                              } catch (e) {
                                alert("Caught error:" + e);
                              } finally {
                                app.scriptPreferences.userInteractionLevel = uil;
                              }
                              

                               

                              But I don't think the CreateDialog is doing its job. Because from there either "Go" or "Quit" have no effect and the script proceeds.

                               

                              Thank you both, so much, for your help.

                              • 12. Re: plug-in or script to print unrelated, multiple InDesign files
                                John Hawkinson Level 5

                                I'll be back with more later.

                                 

                                But I don't think the CreateDialog is doing its job. Because from there either "Go" or "Quit" have no effect and the script proceeds.

                                 

                                Indeed. This is because you don't return a value from CreateDialog. You probably want it to return the result of dialog.show().

                                 

                                Some small nits:

                                 

                                1. It's not a good idea to name functions with an initial capital letter -- in JavaScript style, that means your function is a constructor that returns a new Object. So instead please call it "createDialog."

                                 

                                2. Your createDialog function is using global variables to get the folder and file list name. That's usually a bad idea, both for modularity and code reuse. Try passing in arguments. E.g.:

                                 

                                function createDialog(folder, allFilesList) {
                                     var dialog, folderPanel, folderPanelStTxt1, folderPanelStTxt2, okCancelGroup,
                                          okBtn, cancelBtn, showDialog;
                                //...
                                    showDialog = dialog.show();
                                    $.writeln("s"+showDialog);
                                    return showDialog;
                                }
                                

                                 

                                ($.writeln() is a great tool to print out the value of variables and understand whether things are working as you would like them to.

                                 

                                3. I forget (3). Oops, more later!

                                 

                                Edit: added missing return;

                                • 13. Re: plug-in or script to print unrelated, multiple InDesign files
                                  John Hawkinson Level 5

                                  So, here's how I'd write your createDialog function.

                                   

                                  Of course, here's where I go off the deep end, since I don't like to have an extra variable for each UI element, so I'd

                                  use a resource specification. (And I do this horribly ugly thing with multiple strings in an array and joining them to

                                  avoid using line continuations that don't work in all JavaScript compilers. But of course they work fine in ExtendScript...)

                                   

                                  I like to use a short variable (like 'd' instead of 'myDialog'), since you have to type it so often.

                                  Also, why replace the /Volumes? Just use .fullName instead.

                                   

                                  I admit, I don't know how to make the buttons be defaultElements or cancelElements without either adding them seperately with the .add method, or doing something like "d.defaultElement = d.okCancelGroup.ok;" so I just add them later, along with the text... You could also interpolate the

                                  StaticText into the resource spec if you wanted to...

                                   

                                   

                                  function createDialog(folder, allFilesList) {
                                       var d, showDialog, winspec;
                                  
                                       winspec = [
                                       "dialog { orientation: 'column', alignChildren: 'top', text: 'Multiple Print',",
                                       "  folderPanel: Panel {",
                                       "    name: 'Files to Print',",
                                       "    alignment: 'fill',",
                                       "    StText1: StaticText { },",
                                       "    StText2: StaticText { }",
                                       " }, okCancelGroup: Group {",
                                      "   orientation: 'row', alignment: 'center',",
                                       " } ",
                                       "}"].join("");
                                   
                                      d = new Window(winspec);
                                       d.folderPanel.StText1.text = folder.fullName;
                                       d.folderPanel.StText2.text = '(Found ' + allFilesList.length + ' files)';
                                       d.okCancelGroup.add('button', undefined, 'Go', { name: 'ok' } );
                                       d.okCancelGroup.add('button', undefined, 'Cancel', { name: 'cancel' } );
                                  
                                      showDialog = d.show();
                                       $.writeln("s"+showDialog);
                                       return showDialog;
                                  }
                                  
                                  • 14. Re: plug-in or script to print unrelated, multiple InDesign files
                                    John Hawkinson Level 5
                                    Also, if possible, I'd love to be able to have a progress bar going as the files are printing.

                                    So, obviously that won't work if you hand an array to app.print().

                                    But it's easy enough if you break it up:

                                     

                                    var w, winspec;
                                    
                                    files=folder.getFiles("*.indd");
                                    
                                    winspec = [
                                         "window { name: 'Progress',",
                                         "pb: Progressbar {",
                                         "  value: 0, size: [300, 40]",
                                         "} }"].join("");
                                    w = new Window(winspec);
                                    w.pb.stop = files.length;
                                    w.show();
                                    
                                    for (i=0; i<files.length; i++) {
                                         f = files[i]
                                         w.pb.value++;
                                         app.print(f);
                                    }
                                    

                                     

                                    So, we just set the stop size of the progressbar to the length of our files, and then we loop over all the files and we increment the progress bar and then app.print() each one. It might be cleverer to report the name of the file currently being printed. Or perhaps to save the output to a file in case the whole thing crashes and burns. Both left as an exercise to the reader .

                                    • 15. Re: plug-in or script to print unrelated, multiple InDesign files
                                      Carina Marano Level 1

                                      Screen shot 2011-02-21 at 5.40.21 PM.png

                                      Not sure what it's asking for at this point.

                                      • 16. Re: plug-in or script to print unrelated, multiple InDesign files
                                        John Hawkinson Level 5

                                        It probably doesn't like my folder.fullName because you actually have myFolder.fullName or something...Sorry

                                         

                                        BTW, the progress bar and spec could have been more compact, with a one line spec:

                                        var w;
                                        w = new Window("window { pb: Progressbar { } }", "Progress");
                                        
                                        • 17. Re: plug-in or script to print unrelated, multiple InDesign files
                                          John Hawkinson Level 5

                                          Also: if you run from the ExtendScript Toolkit, when it stops with an error, you can type JavaScript expressions into the JavaScript console and try to figure out what's wrong. So you can figure out what is invalid, what is valid, and maybe try a few things you might have otherwise typed.

                                          • 18. Re: plug-in or script to print unrelated, multiple InDesign files
                                            Carina Marano Level 1

                                            So I just wanted to post this script as is b/c it works now. It still lacks a progress bar. And if I'm able, I'll post a revised version with a progress bar. But this will print multiple, separate InDesign files with their last saved print preset.

                                            function createDialog(folder, allFilesList) {
                                                 var d, showDialog, winspec;
                                             
                                                 winspec = [
                                                 "dialog { orientation: 'column', alignChildren: 'top', text: 'Multiple Print',",
                                                 "  folderPanel: Panel {",
                                                 "    name: 'Files to Print',",
                                                 "    alignment: 'fill',",
                                                 "    StText1: StaticText { },",
                                                 "    StText2: StaticText { }",
                                                 " }, okCancelGroup: Group {",
                                                "   orientation: 'row', alignment: 'center',",
                                                 " } ",
                                                 "}"].join("");
                                             
                                                d = new Window(winspec);
                                                 d.folderPanel.StText1.text = myFolder.fullName;
                                                 d.folderPanel.StText2.text = '(Found ' + myAllFilesList.length + ' files)';
                                                 d.okCancelGroup.add('button', undefined, 'Go', { name: 'ok' } );
                                                 d.okCancelGroup.add('button', undefined, 'Cancel', { name: 'cancel' } );
                                             
                                                showDialog = d.show();
                                                 $.writeln("s"+showDialog);
                                                 return showDialog;
                                            }
                                            
                                            var InDesignVersion=app.version.split(".")[0]
                                            
                                            var myFolder = Folder.selectDialog();
                                            if (!myFolder) exit();
                                            var myAllFilesList = myFolder.getFiles("*.indd");
                                            
                                            if (!myAllFilesList.length) {
                                                 alert("No files to print.");
                                                 exit();
                                            }
                                            
                                            var myDialogResult = createDialog();
                                            if (myDialogResult == 2) {
                                                 exit();
                                            }
                                            
                                            var i, f, files, uil;
                                             
                                            suil = app.scriptPreferences.userInteractionLevel;
                                            app.scriptPreferences.userInteractionLevel =
                                              UserInteractionLevels.neverInteract;
                                             
                                            try {
                                              files = myFolder.getFiles("*.indd");
                                              app.print(files);
                                            } catch (e) {
                                              alert("Caught error:" + e);
                                            } finally {
                                              app.scriptPreferences.userInteractionLevel = uil;
                                            }
                                            
                                            • 19. Re: plug-in or script to print unrelated, multiple InDesign files
                                              kungxiong5 Level 1

                                              This is actually a very useful script but when I use the script it doesn't print in the order it is in the folder.

                                               

                                              For example. I would have these documents below. It would print document 1, 10 and then 2-9. Would there be an additional line where I would place in the script to make it work?

                                              Document1

                                              Document2

                                              Document3

                                              Document4

                                              Document5

                                              Document6

                                              Document7

                                              Document8

                                              Document9

                                              Document10