Create a Book Packager using Extendscript

Friday, July 15 2011 @ 10:30 AM, By anarora

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.

Archive or Packager, that I am going to describe here, is one such utility developed using FrameMaker scripting support.

Description: 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 these steps (script attached, original script can be found here):

1. Creates 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


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

    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.

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

    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 Rick Quatro - 1:21 PM on July 15, 2011  

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

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

    @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  

      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 Arnis Gubins - 4:07 PM on July 15, 2011  


    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  

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

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

    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  

      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  


        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  


          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 Tom Deering - 7:08 PM on October 6, 2011  

    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 Anchal Arora - 7:37 AM on October 11, 2011  

    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 anarora - 1:48 PM on October 17, 2011  

    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 JLGTechPubs - 8:00 PM on November 4, 2011  

    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  

      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  


        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  


          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 Tom Schenck - 6:36 PM on November 29, 2011  

    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  

      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 Anh Gauthier - 7:34 PM on January 6, 2012  

    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  

      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  

        Thanks for replying. I will give debugging a shot.

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

    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 Pia Karlson - 10:05 AM on May 25, 2012  

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

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

    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  

      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 Victoria - 7:48 PM on September 20, 2012  

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

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

    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  

      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 erilot - 7:33 PM on November 13, 2012  

    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  

      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 Olivera Stojanovic - 2:13 PM on April 22, 2013  

    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 MJenn - 2:54 PM on May 31, 2013  

    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 Mike Wickham - 5:49 PM on December 11, 2013  

    (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 DH - 3:58 PM on February 24, 2014  

    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  

      Version 2 is working great!

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

    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 Ronny - 11:11 AM on March 31, 2014  

    Thank you, thank you!!!

  • Categories

  • Archives

  • Authors

  • Useful Links

  • Recent Comments

    • Dieter Gust: So I found it out myself: C:\Program Files (x86)\Adobe\AdobeFrameMaker201 5\fminit\ditafm\DITA-OT\doc...
    • Dieter Gust: In the DITA-OT 2.1 version a rudimentary HTML5 output is included. Add the following entries in...
    • Dieter Gust: Which fonts do you recommend for Thai and Farsi? As far as I can see special Adobe fonts for these...
    • Bjørn Smalbro: Hi Welcome aboard to the new folks! I do have a couple of questions; 1: I have every sent in my...
    • Dieter Gust: Kapil How can I check the DITA-OT version which is installed with FrameMaker?