7 Replies Latest reply on Jun 5, 2013 8:02 PM by Shonkyin

    How to getFiles from subdirectories as well

    caglyph

      Hello all,

       

      I am using a modified version of tomaxxi's script as seen here (yes I know it is an old thread): http://forums.adobe.com/message/3168013

       

      I know he has a new script, but neither of them can do all indesign files in subfolders as well as the parent folder.  I am wondering how I can adjust the following script so that it will pull all .indd files in subfolders of the selected folder.

       

      Additionally, if there is another plugin that does the same thing that would work and has this functionality, I am all ears.

       

      Array.prototype.unique = function (){var i, a = {},r = [],n = this.length;for( i=0 ; i<n ; ++i ) a[this[i]]=1;for( i in a ) r.push(i);return r;}
      
      
      if(app.documents.length == 0){
          fontReporter();
      }else{
          alert("Please close all documents!","Font Report Creator");
      }
      
      
      function fontReporter(){
      app.scriptPreferences.userInteractionLevel = UserInteractionLevels.NEVER_INTERACT;
      // write report to file
      var writeReport = function(myData, myFile){myFile.open ('w'); myFile.encoding = 'UTF-8'; for(var d = 0; d < myData.length; d++)myFile.write (myData[d]); myFile.close (); }
      // collect info from document
      var createFontReport = function(){
          var myDoc = app.documents[0];
          var myDocFonts = myDoc.fonts;
          var myDocName = myDoc.name;
          myFonts.push("//// Font report for file: [ " + myDocName + " ] ////\r\r");
          for(var f = 0; f < myDocFonts.length; f++){var myString = myDocFonts[f].fontFamily + "\t" + myDocFonts[f].fontStyleName + "\t" + myDocFonts[f].location + "\r"; myFonts.push(myString); myFontsAll.push(myString);}
          //myFonts.sort();
          myFonts.push("\r//// Fonts used count: " + f + " ////\r\r\r");
      
      
      }
      
      
          var myFonts = [];
          var myFontsAll = [];
      
      
          // open/report/close
          var myFolder = Folder.selectDialog("Please select a folder containing the InDesign files.");
          if(myFolder == null){alert("No folder selected!","Font Report Creator"); exit();}
      
      
          var myFolderContents = myFolder.getFiles("*.indd");
          if(myFolderContents.length == 0){alert("No InDesign files in folder!","Font Report Creator"); exit();}
      
      
          for (var i = 0; i < myFolderContents.length; i++) {
              app.open(File(myFolderContents[i]), false);
              if(app.documents[0].saved == true)createFontReport();
              app.documents[0].close(SaveOptions.no);
          }
      
      
          var myReportFile = File(myFolder + "/" + "Separate document report - Font Report.txt");
          writeReport(myFonts, myReportFile);
      
      
          // complete report
          myFontsAll = myFontsAll.unique();
          myFontsAll.sort();
          myFontsAll.unshift("//// Font report for folder: [ " + myFolder + " ]////\r\r");
          myFontsAll.push("\r//// Fonts used count: " + (myFontsAll.length - 1) + " ////");
          myReportFile = File(myFolder + "/All [INDD] Documents Font Report.txt");
          writeReport(myFontsAll, myReportFile);
      
      
      app.scriptPreferences.userInteractionLevel = UserInteractionLevels.INTERACT_WITH_ALL;
      
      
      alert("Font reports created!","Font Report Creator");
      }
      
        • 1. Re: How to getFiles from subdirectories as well
          dln385

          If the code you posted works correctly for the documents in the selected folder, then the code below should work correctly for all documents in the selected folder and subfolders.

           

           

          Array.prototype.unique = function unique() {
            var i, a = {}, r = [], n = this.length;
            for (i = 0; i < n; ++i) {
              a[this[i]] = 1;
            }
            for (i in a) {
              r.push(i);
            }
            return r;
          }
          
          
          if (app.documents.length == 0) {
            fontReporter();
          } else {
            alert("Please close all documents!", "Font Report Creator");
          }
          
          
          function fontReporter() {
            app.scriptPreferences.userInteractionLevel = UserInteractionLevels.NEVER_INTERACT;
          
            // write report to file
            var writeReport = function writeReport(myData, myFile) {
              myFile.open('w');
              myFile.encoding = 'UTF-8';
              for (var d = 0; d < myData.length; d++) {
                myFile.write(myData[d]);
              }
              myFile.close();
            }
          
            // collect info from document
            var createFontReport = function createFontReport(myDoc) {
              var myDocFonts = myDoc.fonts;
              var myDocName = myDoc.name;
              myFonts.push("//// Font report for file: [ " + myDocName + " ] ////\r\r");
              for(var f = 0; f < myDocFonts.length; f++) {
                var myString = myDocFonts[f].fontFamily + "\t" + myDocFonts[f].fontStyleName + "\t" + myDocFonts[f].location + "\r"; myFonts.push(myString);
                myFontsAll.push(myString);
              }
              //myFonts.sort();
              myFonts.push("\r//// Fonts used count: " + f + " ////\r\r\r");
            }
          
          
            /**
             * Calls the callback function for each descendant file of the specified folder.
             * The callback should accept a single argument that is a File object.
             * 
             * @param {Folder} folder The folder to search in.
             * @param {Function} callback The function to call for each file.
             */
            var forEachDescendantFile = function forEachDescendantFile(folder, callback) {
              var aChildren = folder.getFiles();
              for (var i = 0; i < aChildren.length; i++) {
                var child = aChildren[i];
                if (child instanceof File) {
                  callback(child);
                }
                else if (child instanceof Folder) {
                  this.forEachDescendantFile(child, callback);
                }
                else {
                  throw new Error("The object at \"" + child.fullName + "\" is a child of a folder and yet is not a file or folder.");
                }
              }
            }
          
          
            /**
             * Returns true if the name of the given file ends in the given extension. Case insensitive.
             *
             * @param {File} iFile
             * @param {String} sExtension The extension to match, not including the dot. Case insensitive.
             * @return {boolean}
             */
            var matchExtension = function matchExtension(iFile, sExtension) {
              sExtension = "." + sExtension.toLowerCase();
              var displayName = iFile.displayName.toLowerCase();
              if (displayName.length < sExtension.length) {
                return false;
              }
              return displayName.slice(-sExtension.length) === sExtension;
            }
          
            var openIfDocument = function openIfDocument(oFile) {
              if (matchExtension(oFile, "indd")) {
                var document = app.open(oFile, false);
                try {
                  if (document.saved == true) {
                    createFontReport(document);
                  }
                }
                finally {
                  document.close(SaveOptions.no);
                }
              }
            }
          
            var myFonts = [];
            var myFontsAll = [];
          
          
            // open/report/close
            var myFolder = Folder.selectDialog("Please select a folder containing the InDesign files.");
            if (myFolder == null) {
              alert("No folder selected!", "Font Report Creator");
              exit();
            }
          
          
            forEachDescendantFile(myFolder, openIfDocument);
          
          
            var myReportFile = File(myFolder + "/" + "Separate document report - Font Report.txt");
            writeReport(myFonts, myReportFile);
          
          
            // complete report
            myFontsAll = myFontsAll.unique();
            myFontsAll.sort();
            myFontsAll.unshift("//// Font report for folder: [ " + myFolder + " ]////\r\r");
            myFontsAll.push("\r//// Fonts used count: " + (myFontsAll.length - 1) + " ////");
            myReportFile = File(myFolder + "/All [INDD] Documents Font Report.txt");
            writeReport(myFontsAll, myReportFile);
          
          
            app.scriptPreferences.userInteractionLevel = UserInteractionLevels.INTERACT_WITH_ALL;
          
          
            alert("Font reports created!", "Font Report Creator");
          }
          
          
          

           

          The code you posted calls createFontReport() for each document in the selected folder. I replaced that with forEachDescendantFile(myFolder, openIfDocument);, which should call  createFontReport() for each decendant document in the selected folder.

          • 2. Re: How to getFiles from subdirectories as well
            caglyph Level 1

            Thanks for the quick reply.  I get the following error:

             

            Error Number: 24

            Error String: this.forEachDescendantFile is not a function

             

            Engine: main

             

            Line: 62

            Source: this.forEachDescendantFile(child,callback);

             

            I am trying to figure it out myself, but any suggestions would be great!

             

            Thanks.

            dln385 <mailto:forums_noreply@adobe.com>

            May 29, 2013 9:43 PM

             

            >

                  Re: How to getFiles from subdirectories as well

             

            created by dln385 <http://forums.adobe.com/people/dln385> in /InDesign

            Scripting/ - View the full discussion

            <http://forums.adobe.com/message/5364012#5364012

             

            • 3. Re: How to getFiles from subdirectories as well
              dln385 Level 2

              Oops, forgot to change that when I copy-pasted. The line this.forEachDescendantFile(child, callback); shouldn't have "this". It should be forEachDescendantFile(child, callback);

              1 person found this helpful
              • 4. Re: How to getFiles from subdirectories as well
                caglyph Level 1

                Brilliant!  Thanks!

                 

                This time it ran but the reports it created were blank so it must not

                have actually pulled the files, strange.  Not sure how to pinpoint the

                error from here...

                • 5. Re: How to getFiles from subdirectories as well
                  Shonkyin Level 3

                  You can try this script.

                   

                  Thanks,

                  Shonky

                  1 person found this helpful
                  • 6. Re: How to getFiles from subdirectories as well
                    caglyph Level 1

                    Thanks Shonky!  This is awesome.  However, seems to have one problem:  If I do not have one of the required fonts, it fails with an error.  One of the whole reasons I am trying to run this kind of report is to find missing fonts/generate a list of missing fonts over a range of multiple documents.

                     

                    Is there anyway to modify this script to print an error, indicating the missing fonts, rather than just failing?

                     

                    Thanks!!

                    • 7. Re: How to getFiles from subdirectories as well
                      Shonkyin Level 3

                      I have tried to run on different type of Indesign files with missing fonts but I have not got any error with this script. Can you please share some screenshot of error or InDesign file which resulting error. I'll fix it quickly and provide you updated script.

                       

                      Thanks,

                      Shonky