Create a Book Packager using ExtendScript


You all must be familiar with the great power that lies in ExtendScript. With the scripting support in FrameMaker 10 you can easily automate time-consuming and repetitive tasks.

This Archive or Packager, which I am going to describe here, is one such utility developed using FrameMaker Scripting support.


It copies a book to a target folder, given by the user, and gathers all the assets for that book and its chapters into this archive directory. All references in the documents are then made to point to these files. Once a book has been archived, you can zip the directory to create a compressed self-contained archive of your book. It handles all components of hierarchical books i.e. Folders, Groups, Folder Templates and nested books. Works on structured and unstructured documents as well.

Components that are archived:

  • Book Chapters
  • Referenced Graphics, multimedia and flash content
  • Poster files applied on multimedia
  • External cross-references
  • Text insets


  • Open the book or document you want to archive.
  • Choose File -> Script -> Run and select the script Archive.jsx. This will create a new menu item Archive.
  • Choose the menu command:
    File > Utilities > Archive Book (if a book file is active)
    File > Utilities > Archive Document (if a document file is active)

Code Snippets

It essentially performs the following steps (script attached, original script can be found here):

  1. Create a menu “Archive” inside the File -> Utility menu:

    var bookMenu = app.GetNamedMenu("BookUtilitiesMenu");
    var newCmd=DefineCommand(1,"Archive" ,"Archive","");
    var newCmd1=bookMenu.AddCommandToMenu(newCmd);
  2. It opens the Browse Folder dialog where the user can select the folder to be used to Archive his files. He can also create a new folder. In the directory you choose, the Archive plugin will create a subdirectory “Insets” to hold the referenced graphics and text insets

    folderPath= ChooseFile("Select Archive Folder","","",Constants.FV_ChooseOpenDir,"");
    insetPath = folderPath.concat("\\","Insets");
    newFolder=new Folder (insetPath);
  3. It silently opens all the chapter files in the book, finds all the referenced files in those files, copies all referenced files to Insets folder, changes the document references, saves them, and silently closes all the files. The book, with the new component paths, is then saved at the Archive directory.

    var inset=docId.FirstGraphicInDoc;
        //copy inset to the new folder
        var oldPath=inset.InsetFile;
        var fullPath=getNewPathForInsets(oldPath); //user-defined function that creates new paths for the insets
  4. At the end of operation it gives an Alert informing the user about the completion of the operation and the archived location.

    Alert("Your achive is ready at \n" + folderPath ,Constants.FF_ALERT_CONTINUE_NOTE);

For further details see the attached script.

You can develop and use such similar utilities to eliminate manual effort and increase productivity. Do try the script and let us know your valuable feedback!


With best regards,
Adobe FrameMaker Engineering Team

ExtendScript, FrameMaker, Products, RoboHelp

Posted on 07-15-2011


  • By Ronny - 11:11 AM on March 31, 2014   Reply

    Thank you, thank you!!!

    • By Tom Gier - 3:34 PM on April 7, 2016   Reply

      Hi all, I know this is rather old but I would like to use this script for archiving my books. I tried it and it works somehow. What caught my eye is that the script copies chapters to the insets directory as soon as there’s an xref from another chapter to this chapter. In my opinion it should only copy graphics and files that are not book chapters to the insets directory.

      I tried to figure out what’s going on in the code but my scripting knowledge is not very well developed. I found some code that checks potential insets whether they are book chapters or not but I must admit that don’t really understand what’s going on there. I think something in there is not working as intended.

      I don’t know if someone more capable of scripting than I am is willing to look into this. It would be great, in any case 🙂

      Thanks a lot
      Tom Gier

  • By JD - 7:16 PM on February 25, 2014   Reply

    I’ve downloaded the ArchiveV2.jsx file and can’t seem to make it work. What am I doing wrong? How/where do I install it to make it work? I need to identify all the files (images) used in my book and eliminate the unused legacy files (about 1300+). HELP!!??

  • By DH - 3:58 PM on February 24, 2014   Reply

    I’ve tried the script. There are 2 issues I encounter. The first issue is that it does not copy or recreate the reference pages. The second issue is that it didn’t fix the links to the graphics. I get the missing file dialog box. It is looking in the Inset folder, but it doesn’t give you the file name that it’s looking for. I have over 300 graphic files that have been referenced so I can’t relink the graphics if I don’t know which one it is looking for. Any clues?

    I also don’t see the link to the script, much less a v2.

    • By DH - 9:31 PM on February 24, 2014   Reply

      Version 2 is working great!

  • By Mike Wickham - 5:49 PM on December 11, 2013   Reply

    (script attached, original script can be found here):

    Please note that there are two script links in the page above. The “original script” link, as I recall, had a bug which was fixed in v2. The “script attached” link gets v2 of the script. The way the two are on the page, it almost looks like a single link and a person may click the wrong link. I would suggest deleting the old v1 script.

  • By MJenn - 2:54 PM on May 31, 2013   Reply

    I like the script but it is copying files into to the inserts folder but they are just xrefs between chapters in the book. How can I stop this?

  • By Olivera Stojanovic - 2:13 PM on April 22, 2013   Reply

    Until today I have no problems with this script. But today something runs wrong. After the run of the script my graphics are gone. And I also can not put it again to the document. Can somebody help me? What can I do on this way. Thx.

  • By erilot - 7:33 PM on November 13, 2012   Reply

    This is outstanding. Is there anything here that would break in FM11? I’ll run some tests with it to verify, but curious if there are edge cases I should be aware of.

    I’ll post the results of FM11 testing. Thanks again — this is exactly the tool we were looking for.

    • By anarora - 11:50 AM on November 15, 2012   Reply

      Thanks for the encouraging feedback.
      Ideally there is no change in FM11 that can cause this script to break. You can give it a try n your files and share your results with us.


  • By GBtechwriter - 11:52 PM on November 5, 2012   Reply

    I can’t seem to create a folder for the book archive under the folder I created to hold the book archives. I just get “NewFolder”, “NewFolder(2)”, etc. I’m using a WinXP machine that meets all the requirements for Frame.

    What are the proper steps to create a new folder under a folder (directory)?

    And the script doesn’t copy the referenced insets twice, it included any referenced book file (cross-reference) in the Insets folder.

    • By anarora - 8:42 AM on November 7, 2012   Reply

      When you click Archive menu, you must be getting a Browse For Folder dialog. Browse to your archive directory and click on Make New Folder, then rename it to your desired name and click on OK. This should archive your book in the selected folder.
      This is working for me in Win XP as well as Vista.

      As regarding the script not copying the insets twice, this was a requirement from some of the users of the script (in comments below), hence I made an enhancement to handle it.

  • By Victoria - 7:48 PM on September 20, 2012   Reply

    Why can’t I view any of the comments on this page?

  • By Serge Menard - 11:23 PM on July 26, 2012   Reply

    Hi, thanks for this excellent script. A great time saver. However I should report that it copies the referenced insets twice: in the user specified archive directory then in the Insets sub-directory. Can this be corrected easily? Thanks again.

    • By - 5:35 PM on January 17, 2013   Reply

      It does more than that (and this is also a problem). It also (at least at times), puts copies of files in a book into the Insets folder and then uses those as the targets for Cross-References. I had to delete these files, make MIFs of the affected files in the main directory and do a find/replace in the MIFs:

      find: <XRefSrcFile `Insets

      replace: <XRefSrcFile `

      Maybe a function to do this can be added to the script to fix this problem.

  • By Pia Karlson - 10:05 AM on May 25, 2012   Reply

    Thank you from the bottom of my heart!! This saved med hours of work finding about 300 images.

  • By Tom Schenck - 7:16 PM on February 2, 2012   Reply

    Hi Anchal,

    Thanks for replying!

    I package the book to send to translators, and then get the translated FrameMaker files back.

    It’s not that the files are not usable, but the duplicated FrameMaker files add cost to the total translation project. Also the files in the insets folder make it difficult for my Help Authoring Tool to process them and create output. The HAT uses the cross references and other markers to create hyperlinks in the electronic output. Exporting to PDF has the same issues, the cross references are looking for files in the \Insets\ which does not exist in the PDF output.

    So, All of the FrameMaker files need to be in one folder.

    Graphic files are just replaced with new files in the correct languages, so they can be in a separate folder and just imported by reference.

  • By Anh Gauthier - 7:34 PM on January 6, 2012   Reply

    Hi Anchal,

    I have the updated script. When I run it for a book, FrameMaker tells me there is an error in line 177.

    • By Anchal - 5:49 AM on January 9, 2012   Reply

      Hi Anh,

      You will get this error in case the function call proceeds without getting a valid docid. This is not a generic problem. You will have to debug the script for that purpose or you can share your book file so that I can debug and know the cause.

      • By Anh Gauthier - 7:31 PM on January 10, 2012   Reply

        Thanks for replying. I will give debugging a shot.

  • By Tom Schenck - 6:36 PM on November 29, 2011   Reply

    Hi Anchal,
    I have the 10/17/11 version of this script. In archiving a book file, It is still updating the cross references to other FrameMaker files to the copied FrameMaker files in the \Insets\ directory. This makes the arcived set of files unusable.

    Otherwise, this is a great script, thanks!!

    • By Anchal - 5:47 AM on January 9, 2012   Reply

      Hi Tom,

      This is the way the script is supposed to work. The referenced FrameMaker files will be copied into Insets folder and the reference will be changed accordingly. I didn’t understand why will this make the files unusable.
      In case the references are to some chapter files of the same book, then instead of copying the file I am just updating the references to avoid duplicates.
      Let me know where you are facing the problem.

  • By JLGTechPubs - 8:00 PM on November 4, 2011   Reply

    We are trying to get this script to change the name of the folder once it archives the files, right now it creates a folder called “Inserts” inside the archive folder; however, we would like it to say “Graphics”. Does anyone know how to do this? I tried changing lines 19 and 119 of the script to say “\\”, “Graphics”. I can get it to create the graphics folder, but it does not populate it with any illustrations.


    • By Anchal Arora - 9:17 AM on November 5, 2011   Reply

      Just changing these 2 lines is sufficient for this purpose. See if you can run the script successfully on your book file without making any changes in the script.

      • By JLGTechPubs - 2:01 PM on November 5, 2011   Reply


        Thank you for the quick response.

        Yes, if I run the script without making any changes, it will create a new folder, archive all of the section files and the book file. It will then create a folder called “insets” and place all the illustrations used in that book inside that folder. The problem we have is all of our files reference the “Graphics” folder for our illustrations and we didn’t want to lose that reference each time we archived a book. So I tried to modify the coding to change the output folder from “insets” to “Graphics”, which is why I tried to change lines 19 & 119.

        Here is what happens when I change lines 19 and 119.

        Line 19 – Changed / Line 119 – Unchanged
        insetPath = folderPath.concat(“\\”,”Insets”) to insetPath = folderPath.concat(“\\”,”Graphics”)

        When I do this, it will archive all the document files and the book file, create a folder called Graphics; however, it does not populate it with any illustrations.

        Line 19 – Unchanged / Line 119 – Changed
        var fileName = folderPath.concat(“\\”,”Insests”,”\\”,name) to
        var fileName = folderPath.concat(“\\”,”Graphics”,”\\”,name)

        When I do this, it does not create the graphics folder, it creates an insets folder and populates it with 1/4 of the illustrations.

        Line 19 – Changed / Line 119 – Changed
        When I change both lines, it creates a Graphics folder and populates it with 1/4 of the illustrations.

        • By Anchal - 5:56 AM on January 9, 2012   Reply


          Firstly, you will have to change both the lines for it to work.
          Secondly, I cannot come up with any case in which only 1/4th of the graphics shall get copied. May be its because they are imported by copy and not reference?
          P.S. this works fine at my end. See if you can share your files with me so that i can reproduce the issue and fix it.

  • By anarora - 1:48 PM on October 17, 2011   Reply

    Hi all,
    I am attaching an updated script for book packager. This contains some bug fixes for issues mentioned above and few enhancements.
    1) Bug fix for graphics imported by copy. Now, there will be no effect on embedded graphics
    2) In case of external cross-references in chapters pointing to other book chapters, references will be updated to the new path of the chapter and not inside Insets folder
    3) Some changes in book traversal
    4) Also, added support for maps

  • By Anchal Arora - 7:37 AM on October 11, 2011   Reply

    Hi Tom,

    Here is some information which I hope will be of help to you.

    1) UpdateMenus(): Updates the top order menu set. For example, when a new menu file is read, or when a view only, book menu, quick menu or similar is loaded, this updates the newly read menus (in case of menu file) or different top menu bar (in case of view only, book and quick menus). Must be called if script has been run through ESTK, redundant otherwise.
    This is a FrameMaker Global method and need not be defined anywhere in your script. In this script, you can remove the call.

    2) The Command function is equivalent to F_ApiCommand(command) in FDK. This is a callback function called on clicking any menu item added through DefineAndAddCommand or AddCommandToMenu methods.


  • By Tom Deering - 7:08 PM on October 6, 2011   Reply

    JavaScript newbie here. I’ve successfully made tweaks to the script to customize it for our situation, but there are a couple of basic things I don’t understand:

    1) UpdateMenus doesn’t seem to be defined anywhere.
    2) The Command function doesn’t seem to be called anywhere.

    So it’s a mystery to me why the script should work in the first place. It’s as if UpdateMenus and Command are magic in some way, and I don’t see any reference to them in any of the Help files. What gives?

  • By Roman - 12:09 PM on September 22, 2011   Reply

    A good idea, but a badly written script. By default it creates the Inset folder, and removes graphics from the framemaker files. The files then become unusable.

    Have you tested it before making publicly available :-(?

    • By anarora - 12:42 PM on September 22, 2011   Reply

      Hi Roman,

      I think you had some problem in using the script. The graphics are not removed from the FrameMaker files but are updated to the new path ( inside Insets folder). This makes sure that all graphics reside at one place.
      You can try closing and reopening your doc. There can be a refresh issue.

      • By Roman - 11:09 AM on September 26, 2011   Reply


        My graphics is embedded inside the FM files and I don’t want the script to extract the graphics and put it in a separate folder without asking if I want to. In fact, the insets folder remains empty, and the graphics disappears from the FM files.

        • By Michael Müller-Hillebrand - 7:24 AM on September 29, 2011   Reply


          As Anchal said above, the script is just an example that things can be done, you’d have to adapt it to your own processes. In other words: It is just not useful the way it is.

          The script assumes that every graphic is referenced and ignores the fact that some graphics may be copied into a document. For those graphics the empty file path is replace by a folder path… oops.

          To be fair, creating such a script that handles text insets, graphics and cross-references (including those between text insets) is not an easy task.

          – Michael

  • By Arnis Gubins - 4:07 PM on July 15, 2011   Reply


    For those of use getting to know Extendscript better, it would be a quite beneficial if you could expand this script to have the fonts used in the FM documents included as well. This would make the utility more useful for users (on par with InDesign’s Package tool) and would also provide additional programming examples of collecting files at the system level.

    • By anarora - 12:43 PM on September 22, 2011   Reply

      Thanks for the suggestion Arnis. We will see how to work on it.

  • By Michael Müller-Hillebrand - 2:04 PM on July 15, 2011   Reply

    @Mike: The ZIP file is OK, it must be your firewall blocking *.jsx files.


    I have to say the script as present needs some more work. The concept to simply copy each file used as the source for a cross-file cross-reference to the Insets folder is far from perfect.

    If you have cross-references between book components, they end up twice in the archive folder: in the root and in the Insets subfolder. And worse: the cross-references point into the Insets subfolder…

    This is a work-in-progress, I have to say.

    – Michael

    • By anarora - 12:48 PM on September 22, 2011   Reply

      Hi Michael,

      The script can be enhanced to fit one’s needs. The main motive here was to highlight what all and how easily things can be done.
      As far as cross-references are concerned, they do end up twice but i think a simple check can avoid files getting copied multiple times. This won’t require much effort.

  • By Rick Quatro - 1:21 PM on July 15, 2011   Reply

    I had trouble opening the archive with WinZip. However, 7-Zip was able to open it.

  • By Mike Wickham - 1:19 PM on July 15, 2011   Reply

    The ZIP file containing the script will not open. “Cannot open file; it does not appear to be a valid archive.” It appears to be a RAR file instead. When I changed the extension, it opened fine.

  • By Mike Nelson - 12:32 PM on July 15, 2011   Reply

    This is just what I’ve been waiting for! Bruce Foster’s Archive plug-in provided this functionality in earlier versions of FrameMaker. Sadly, he recently passed away.

    When I downloaded the script, I’m unable to unzip it. Could you please check the file? If it’s OK, then perhaps my company’s firewall is blocking the contents.

    Mike Nelson
    KVH Industries, Inc.

Reply to anarora