InDesign Table of Contents Webinar – Thursday, January 28, 2016, 1:00 pm EST

I am conducting an informal Webinar titled: “Generating custom InDesign Tables of Contents using XML, XSLT, and Tagged Text”. Sometimes you need a complex table of contents or index that can’t be easily generated using InDesign’s built-in Table of Contents command. I will demonstrate a simple workflow using XML, XSLT, and InDesign Tagged Text. Here is the registration information:

Please register for InDesign Table of Contents Webinar on Jan 28, 2016 1:00 PM EST at:

Sometimes you need a complex table of contents or index that can’t be easily generated using InDesign’s built-in Table of Contents command. Rick Quatro, long-time automation expert, will demonstrate a simple workflow using XML, XSLT, and InDesign Tagged Text.

After registering, you will receive a confirmation email containing information about joining the webinar.

Here are the Webinar notes.

Solving Path Problems with PathChanger

Let’s face it, the FrameMaker documents that we work with rarely stand alone. They often have graphics imported by reference, text insets, and external cross-references, all pointing to files outside of the FrameMaker document. FrameMaker books point to book components that can be located just about anywhere. And when files get moved or renamed, we can end up with a combination of missing graphics, unresolved text insets, unresolved cross-references, or books with missing components.

A FrameMaker document or book stores paths internally for each of these items. PathChanger is a series of ExtendScript scripts that makes it easy to change these paths for a FrameMaker document or book. It has a command for extracting and writing these paths to a simple .csv file. This file can be opened with Excel where you can easily see and edit and change the paths. Once the paths are updated, another command applies them back to the FrameMaker document or book, quickly resolving the missing or unresolved objects. There are additional commands for writing and updating books and their paths to each book component.

Here is how it works for imported graphics, text insets, and external cross-references:

  1. Open the document or book that has paths that need to be updated.
  2. Choose File > Utilities > Write Paths to File. The script will write the path information to a paths.csv file in the same folder as the document or book.
  3. Open the paths.csv file with Excel and edit the Path column in any rows that you want to update. Do not change any of the information in the other columns. You can delete any rows from the csv file that you don’t want to update.
  4. Save the edited Excel file. The file must by saved as a csv file, not as a native xls or xlsx file.
  5. Choose File > Utilities > Update Paths.
  6. Choose the updated csv file that you saved in step 4. PathChanger will open the files listed in the csv file and update the paths.

The process is similar for updating book component paths:

  1. Open the book that has book component paths that need to be updated.
  2. Choose File > Utilities > Write Book Component Paths to File. The script will write the book component paths information to a book_components_paths.csv file and save it in the same folder as the book.
  3. Open the book_components_paths.csv file with Excel and edit the Path column in any rows that you want to update. Do not change any of the information in the other columns. You can delete any rows from the csv file that you don’t want to update.
  4. Save the edited Excel file. The file must by saved as a csv file, not as a native xls or xlsx file.
  5. Choose File > Utilities > Update Book Component Paths.
  6. Choose the updated csv file that you saved in step 4. PathChanger will update the book component paths in the book.

Download the documentation for more details on this powerful new program. Purchase PathChanger today for only $79 at our online store.


FindChangeFormatsBatch is an ExtendScript script for FrameMaker 10 and higher. It allows you to Find/Change hundreds of FrameMaker formats in a document or book with a single command. It is controlled by a simple FrameMaker table that you fill in with your find/change formats. You can change the following format types: paragraph, table, character, condition, master page, marker type, cross-reference, and user variable. You can also use FindChangeFormatsBatch to delete unwanted formats from your document or book. FindChangeFormatsBatch is available now for $79 US. For more information, view the documentation. To purchase it, go to our online store.

Introducing TableCleanerES

FrameMaker and Word have always had an awkward relationship to each other. Technical writers are often required to integrate Word content into their FrameMaker publications. They soon learn that there is not always a one-to-one correspondence between the programs’ features. TableCleaner was designed to help users format FrameMaker tables that were imported from Word. The original TableCleaner, released in 1999, focused on two tasks: removing custom ruling and shading from tables and converting body rows to heading rows.

Some tables originating in Word have custom ruling and shading applied to them and that prevents ruling and shading changes applied from the Table Designer from appearing. So TableCleaner gives you a quick way to remove custom ruling and shading from all of the tables in a document. (NOTE: Screenshots are from the latest version of TableCleaner.)


The second issue is heading rows; tables imported from Word do not have true FrameMaker header rows that repeat at the top of each new column and page. Manually converting the first row to a heading row is a multi-step process, so TableCleaner gives you a batch command for converting the first row in all of the tables in the document.


Over time, I added more goodies to TableCleaner that are useful regardless of where the tables originated from. One popular feature is the ability to resize multiple tables with a single command. This includes an option to resize “by example”; you resize a single table to your liking and then apply this sizing to a bunch of other tables with a single command.


TableCleaner was originally written as a FrameMaker plugin, but I have recently rewritten it in ExtendScript. ExtendScript is Adobe’s implementation of JavaScript and it is built into FrameMaker 10 and higher. There are two significant new features: batch commands can now be applied to all of the documents in a book. And the interface can now be localized through a simple XML file. TableCleanerES is available now for only $39 US. Check out the full documentation, or purchase it now at my online store.

PostScript Text Frames

We had our first informal FrameMaker webinar on December 10, 2015. It was graciously hosted by Vivek Kumar of Adobe Systems via Adobe Connect. The topic was PostScript Text Frames and it was presented by me, Rick Quatro. Here is a link to the recording:

During the webinar I mentioned some useful resources for further learning:

  • pdfmark Reference. This document explains pdfmark syntax, which is a PostScript language extension. pdfmark is used to produce Acrobat features, such as links, bookmarks, and buttons during the distilling process.
  • Microtype makes TimeSavers which is a fantastic program for adding Acrobat features with Hypertext markers instead of PostScript text frames. I have used this program for years and highly recommend it.
  • Summary by Klaus Daube. Klaus is FrameMaker’s unofficial historian and has documented the nooks and crannies of the FrameMaker world.

If you have any comments or questions about PostScript Text Frames, please leave a comment below. Let me know if you have suggestions for further webinars.

Listing graphics in order of appearance – Part 2

Since we want a list of graphics, there are a couple of ways to approach this. First, we can write our report at the same time as we are collecting the data. Or, we can collect all of the data first, and then write the report. I prefer the second approach because it tends to make the code simpler to understand.

What kind of data should we collect? It all depends on our needs but it usually doesn’t hurt to collect more than we need in case we need it later. Here is what I would suggest collecting:

  • The absolute path to the imported graphic.
  • The absolute path to the FrameMaker document containing the graphic.
  • The page number.
  • The unique ID of the anchored frame containing the graphic. This will allow us to build a hypertext link from the report to the graphic if desired.

Here is a function we can use to create a data structure to hold the graphic data. There are several ways that this could be done, but this approach uses a series of parallel lists to hold the data.

This function will show you how to add to the data structure for each anchored frame.

You will have to pass this oImageData object into your functions as you navigate the paragraphs and anchored frames in your document (or book). Let me backtrack and rework the code from the last post. I am just going to just post shells of the existing functions and point out what is different. See if you can put the pieces together.

See if you can put it all together from both posts and make it work. You can test it by adding this line after line 18 in the previous code listing:

This should display a list of the graphic names in a message box. Note that if you have a ton of graphics in your document, you might not see the entire dialog box. You should be able to press Enter or Escape to dismiss it if you can’t see the OK/Cancel buttons. Alternatively, you can write the list to the FrameMaker Console window by using this:

In another post, we can explore how to write the report. Comments or questions are welcome.

Listing graphics in order of appearance

Jonathan asked on the FrameScript list on yahoo groups about getting a list of graphic files in a document in order of appearance. I decided to answer it here so I can discuss it in some detail and because yahoo groups doesn’t format code listings very well. There are a couple of possibilities to consider. First, if you don’t have any graphics in tables, you can do something simple like this:

If you have anchored frames inside of tables, then things get a little more complicated. Here is a basic loop for processing all of the paragraphs in document order, including those in tables:

This is a general purpose script for processing paragraphs in document order. Lines 8, 24, 32, and 40 are where you do something with each paragraph. In this case, we can call a function on each of these lines to get any anchored frames that are in each paragraph. The function would be similar to the first code example, except that it would get any anchored frames in each paragraph instead of the entire main flow.

There are some unfinished pieces here, like how to query each anchored frame for imported graphic information. Also, you will need a way to collect the graphic data. But this will get you started. Questions and comments are welcome. If there is enough discussion generated, we can go further with this.

Adobe Webinar: FrameMaker ExtendScript Examples


Thanks to the generosity of many, Jason and I have reached our fundraising goals for the Ride! As a result, I am withdrawing the offer for the scripts. Thank you for your help!

If you attended the webinar on April 29, 2015, you saw some realistic examples of using ExtendScript to automate FrameMaker. The scripts are well-commented and ready for production work. If you are learning ExtendScript, you can use many of the functions and techniques in your own scripts.

Here is a PDF that describes each script.

Thank you for your generous support of a great cause!


For those that received the scripts by donating, or saw them during the webinar, I am interested in your questions and feedback. Please add a comment to this post, and I will start a new post to discuss your questions and comments.

FrameMaker 12 ExtendScript: The Object Model

In a recent Adobe webinar, I used a chm file for FrameMaker 12 ExtendScript’s object model. Here is a link to the web site. Scroll to the bottom and you will see the link. After you download the chm, right+click on it and choose Properties. Click the Unblock button and you will be able to use the chm file.

The chm file has the same content as the ExtendScript Object Model Viewer, but in my opinion, is much easier to use. If you prefer HTML, there is a link to an HTML version as well.

Automatically Saving to MIF

It is not unusual to have “mixed” FrameMaker workflows where members of a team are using different versions of FrameMaker. Documents saved in a lower version can be opened with higher versions, but you can’t open documents saved with a higher version with a lower version of FrameMaker. There are two solutions: First, you can use the higher version to “save down” to the lower version. However, you can only save down to the next lowest version, for example, from FrameMaker 12 to FrameMaker 11. Second, you can save the document to MIF (Maker Interchange Format) in which case you can open it with any lower version of FrameMaker.

The main sticking point with saving to MIF is that you have to remember to do it. But with ExtendScript, you can automate this. You can create a script that will automatically save the document to MIF whenever you choose File > Save or press Control+S. When you are ready to pass the MIF file onto another team member that may be using a lower FrameMaker version, you know that it will always reflect the latest saved changes.

Here is how to set up the script below:

  1. Copy the code below and paste it into an empty text file.
  2. Save the text file to a convenient location with the name “SaveAsMif_Event.jsx”.
  3. Quit FrameMaker if it is running.
  4. Copy the file to C:\Users\<UserName>\AppData\Roaming\Adobe\FrameMaker\<Version>\startup, where <UserName> is your Windows login name and <Version> is the FrameMaker version that you are using. If the startup folder does not exist, create it.
  5. Start FrameMaker and test the script. Open a document, make some changes to it, and save it. You should see a corresponding MIF file in the same folder as the document.

If you have any questions, problems, or comments, please post them in the comments section. Here is a link to a video that walks through the creation of the script.