Run a Script in Response to a Command

Here is a question from the Adobe FrameMaker ExtendScript forum: “I wonder if there is there a way to make [a] script event-driven, so that it will be triggered after importing formats from another file?” This post describes how to do this with an ExtendScript script.

First, some terminology: When something happens in FrameMaker, it is called an event. You want your script to listen for one or more events to occur. In ExtendScript, you want to tell FrameMaker to notify to you when one or more events has occurred.

You can set this up in your script with a couple of functions. You first have to tell the script which events you want it to listen for.

function setupNotifications () {

  // Set up a notification for after a book is updated.
  Notification (Constants.FA_Note_PostGenerate, true);
}

Here, we are telling FrameMaker to notify us after a book is updated. This is sometimes referred to as registering the event. You can register as many events as you want in this function.

NOTE: There are no specific notifications when importing formats, but we will show you how to handle this shortly.

You will call this function at the beginning of your script.

setupNotifications ();

Now you need a function that will listen for the notifications (or events) that you specified. FrameMaker ExtendScript has a built-in function for this:

function Notify (note, object, sparam, iparam) {

  // Test for the event type.
  switch (note) {
    case Constants.FA_Note_PostGenerate :
    // Do something here (respond to the event).
    break;
  }
}

The Notify function will receive four arguments:

  • note: This is the event that was triggered. We usually use a JavaScript switch statement to test for the event, because we may want to test for more than one event.
  • object: This is the relevant object that was in play when the event occurred. In the above example, this will be the Book object of the book that was updated.
  • sparam: This will be a relevant string value or null, depending on the event.
  • iparam: This will be a relevant integer value or null, depending on the event.

Once you receive the correct notification in the Notify function, you can call the appropriate code in your script.

Let’s go back to the forum question. FrameMaker ExtendScript has a bunch of built-in notifications, many of them in a “Pre” and “Post” format. For example, FA_Note_PreGenerate is triggered just before a book is updated and FA_Note_PostGenerate happens just after a book is updated. However, there are no specific notifications that occur before or after importing formats. To handle this, we can use the generic FA_Note_PostFunction notification, which gets triggered after nearly every FrameMaker event. When this notification calls the Notify function, the iparam value will be the unique number of the function. To find the number for a particular command, run the following code, then run the desired command in FrameMaker.

#target framemaker

setupNotifications ();

function setupNotifications () {
    
    // Set the notification for after a book is updated.
    Notification(Constants.FA_Note_PostFunction , true);

}

function Notify (note, object, sparam, iparam) {
    
    // Handle the generate book event.
    switch (note) {
        case Constants.FA_Note_PostFunction :
        // Display the command number.
        alert (iparam);
        break;
    }
}

After running the script and importing formats, you should see the number 790 displayed in the alert dialog box. You probably saw a lot of other numbers if you performed other FrameMaker operations before importing formats! Now that you have the number you need, uninstall the script above or quit and restart FrameMaker.

Now we can go back and edit the Notify function that we added to our script. We will test for the Import Formats command by using the command number.

function Notify (note, object, sparam, iparam) {

  // Test for the event type.
  switch (note) {
    case Constants.FA_Note_PostFunction :
      if (iparam === 790) { // Formats were imported.
        // Do something here.
      }
    break;
  }
}

There are a couple of things to note about this particular example. If you cancel the Import Formats dialog box, the event is still triggered and the Notify event is called. If you go ahead with the Import Formats command, the Notify event is actually called twice. At this point, I am not sure how to work around this. In any case, always test Notify event carefully to ensure that your code gets called exactly when it is needed.

Leave a Reply

Your email address will not be published. Required fields are marked *