Author Archive: sbhaskar

ExtendScript to print the word count in an FM book file

Find the script here.
To test the script:

  1. Create a book file with many chapters. Chapters must be added as files.
  2. Open the book file.
  3. Ensure that chapters are not opened.
  4. Run the script.
  5. Wait for the script to open all the chapters and then print the word count.
    (Note that the script doesn’t include the words inserted in tables.)

Developing a document checklist using ExtendScript

I developed a script that can be used as a document checklist for a FrameMaker 10 book. You can add questions such as, “Have you updated variables?” Running the script captures the question and the answer to a .txt file. See the comments in the script to know more details.

Download the script here.

Disabling ActiveX filtering

Flash Player does not work if ActiveX filtering is enabled on Internet Explorer 9. When you visit sites that have Flash content, “You need to upgrade your Flash Player to watch this video” error appears. To disable ActiveX filtering, click Tools > Safety > ActiveX Filtering as shown below:

Your Flash Player version

I see many comments from users about the Flash Player version they installed and the most updated version available from Adobe. The latest version of Flash Player is 11,0,1,152

I have developed a Flash movie to help you. If you have Flash Player installed, it shows the Flash Player version installed on your machine and your operating system. It also displays a link to the Flash Player uninstaller for your operating system. Means, if you are on Mac, the link will point to the uninstaller for Mac.

Note that if you don’t have Flash Player installed, you see “plug-in not found” error.

Compare the version available in your machine and the latest version. If needed, uninstall the existing version and get the latest installer from Adobe.

Adobe Flash Player on Mac Lion with Safari

I found many comments from users that Flash Player is not getting downloaded on this OS-browser combination. Please note that the Download window in Safari is invisible till you click the Download icon on the top-left side.

Developing ExtendScripts – Part 3

Let me repeat, if you are very new to ExtendScripts, see the first two entries in this series. Here we are going to see a bit more complex example. This is what we are going to accomplish: If a book file is opened, running the script opens all FrameMaker files (chapters) added to it. Based on a property that we set in the script, it shows or hides a conditional text and then creates a pdf file of the book.

Before trying out this example, ensure that you do the following:

  1. Create a FrameMaker book, myBook.book. And, save it in a directory, FM_script, in your C: drive. (Feel free to change the name and location of the file. In that case, update the bookFile property value in the script.)
  2. Add two chapters to the book.
  3. Open the first chapter.
  4. Add some texts and apply the conditional text, Comment. (Comment is a default conditional text added in all the FrameMaker files. Don’t ask me how to apply a conditional text. Google is your friend.)
  5. Do step 3 to 4 for the second chapter.

Let us prepare a logical order for what we are going to accomplish:

  1. Open the book file. (Let us do it by ourselves; we will not seek help of the script. :))
  2. Open the first chapter.
  3. Hide the conditional text, Comment.
  4. Open the second chapter and hide the conditional text, Comment.
  5. Save the book as a pdf in a specific name.

Let us write functions to code step 2 to 4. First we will write a function that opens all chapters in the book.

bookFile=”C:\\FM_script\\myBook.book”
openedBook = app.ActiveBook
openBookFiles(openedBook)
savePdf(openedBook,bookFile + “.pdf”)
function openBookFiles(openedBook)
{
var bookChapter=openedBook.FirstComponentInBook
var chapterId = bookChapter.id
while(chapterId)
{
var chapterName = bookChapter.Name
chapterId = openFile(chapterName)
ShowHide(chapterId, “Comment”, 1)
bookChapter = bookChapter.NextComponentInBook
chapterId = bookChapter.id;
}
}

The first line created an object of the active book. We decided to keep the book opened. We could have written a function to open the book by providing its path. This just a tutorial and I don’t want to complicate things!! OpenBookFiles() function is called by providing the book object. It detected the first chapter using the FirstComponentInBook property. It also detected the component ID. A while loop is added and it’s valid till we reach the last chapter in the book. We found the chapter name using the Name property and opened the chapter using the openFile() method. After each chapter is opened, it calls a function, showHide().

function openFile(chapterName)
{
openProp = GetOpenDefaultParams()
retParm = new PropVals()
fileOpen=Open(chapterName,openProp,retParm)
return fileOpen;
}

You can open a FrameMaker file using the open() method. It needs three arguments: the file name, PropVal objects, and return parameters. PropVal objects is an array of values for various FrameMaker setting. We created the default ProPValue objects using the GetOpenDefaultParams() method. Return parameters are created using the new PropVals() method. The function opens the file and then calls the showHide() method:

function ShowHide(chapterId, condTextName, showOrHide)
{
CondFmtId = chapterId.GetNamedCondFmt (condTextName)
if (showOrHide)
CondFmtId.CondFmtIsShown = 1
else
CondFmtId.CondFmtIsShown = 0
chapterId.ShowAll = 0
}

The showHide() function accepts the following parameters:

chapterId – The reference to the FM file that is opened.
condTextName – The name of the conditional text. That is Comment.
showOrHide – It can be 0 or 1. If it is 1, the conditional text is visible in the pdf. If it’s 0, conditional text is hidden.
Using the GetNamedCondFmt() function, it finds the conditional text ID of Comment, and based on showorHide value, it makes it visible or hidden by setting the CondFmtIsShown property to 1 or 0. After conditional texts are set, the script calls the savePdf() method to save the file as a pdf.

function savePdf(openedBook,pdfName)
{
var params = GetSaveDefaultParams()
var returnParamsp =new PropVals()
var i = GetPropIndex(params, FS_FileType)
params[i].propVal.ival =FV_SaveFmtPdf
openedBook.Save(pdfName, params, returnParamsp)
return
}

The function accepts reference to the book file and pdf name as the arguments. Using the GetSaveDefaultParams() method it gets all the default parameters of FrameMaker. It finds the File Type index, a unique value for FrameMaker using the GetPropIndex method. In the parameter’s array, it changes the file type to pdf using the params[i].propVal.ival =FV_SaveFmtPdf method. Then, it saves the file as a pdf using the Save() method.

You can also download the script here. Let me know if you find any issues.

Try to improve the code. For example, if you have a folder added to the book, you may notice that the files in the folder are not getting opened. As I mentioned earlier, my intention was to give you an overview!! It is yours now. All the best!!

Developing ExtendScripts – Part 2

If you are very new to ESTK, I suggest you to read the first blog entry in this series. In the first blog entry, we didn’t use any functions that are specific to any TCS component. In this blog entry we will. Let us develop a script that changes the DPI setting of all the images inserted in a FrameMaker document that is already opened. Before we start, let us logically divide our requirement:

The script should:

  1. refer to the currently active FrameMaker document.
  2. detect the first graphic in the document.
  3. change the DPI setting of the graphic.
  4. detect the next graphic.
  5. change the DPI setting of the graphic.
  6. continue step 4 and 5 until the script detects the last graphic.

Open FrameMaker, and then open ESTK. In ESTK, select FrameMaker from the drop-down list displayed on the upper-left corner. We didn’t do it when we created the script that displayed an alert, because the functions that we used to display an alert have nothing to do with any of the TCS component. Here, we are going to write a script that automates a task in FrameMaker. So, we will use some methods that are related to FrameMaker. Observe the green icon displayed. It represents that a FrameMaker session is alive. If we didn’t have opened FrameMaker, the icon would have displayed in red.

Let us start coding. First, we will refer to the active FrameMaker document. The code for this is:

document =app.Activedocument

The code creates a document variable pointing to the active FrameMaker document. app.Activedocument represents the currently active document. Now, let me introduce Object Model Viewer that comes handy when you develop scripts using ESTK. Press F1 or click Help > Object Model Viewer.

Click Browser, and then select FrameMaker 10 from the drop-down list beneath it. You will see all the TCS components you installed in this drop-down list. We selected FrameMaker 10, because we are trying to get information about a method in FrameMaker, app.Activedocument. Type the same in the text box displayed on the upper-left corner, and click Search. From the search results, clicking the link provides information about the method you clicked. This information is very helpful when you develop scripts. You can select the specific TCS component on which you need information and search for information.

Let us go back to coding. I am not going to explain each line of code, because I assume that you know the basics of scripting.

document =app.Activedocument
gobj = document.FirstGraphicIndocument;
  while(gobj.ObjectValid())
    {
       gobj = gobj.NextGraphicIndocument;
       if(gobj.type == FO_Inset)
         {
            name = gobj.InsetFile;
            gobj.InsetDpi=200;
         }
   }

To summarize, this is what the script does:

The code first creates a reference to the active document. Then, creates a reference to the first graphic in the document using the document.FirstGraphicIndocument method. It uses a while loop to detect all graphics in the document. The reference move to the next available graphic using the NextGraphicIndocument method and it continues till it reaches the last graphic. It uses the InsetDpi property of the graphic reference to set the DPI value.

Save the file and close ESTK. (Don’t ask me how.)

Let us run the script separately. We have already seen how to run the script in ESTK. Let us not run the script in ESTK. We will run the script through FrameMaker, because in real-time, you need not be the programmer who actually does the coding. So, you don’t need ESTK to run it. From FrameMaker, click File > Script > Run. Select the file we saved and click Open.

That’s it. To recap whatever we learned:

- Object Model Viewer helps you to get information about the methods that you can use in ExtendScripts.
- You don’t need to have ESTK to run ExtendScripts.

Developing ExtendScripts – Part 1

ExtendScripts automate tasks that you do in any of the TCS components. ExtendScripts are saved as .jsx file and are similar to JavaScript. TCS provides you with ExtendedScript ToolKit (ESTK) support to develop ExtendScripts. ESTK is a development environment that makes the script development simpler. In this first blog entry, I will familiarize you with ESTK. We will develop a simple JavaScript function using ESTK.

I am not teaching you JavaScript here. I assume that many of you are familiar with JavaScript. It doesn’t mean that you should have JavaScript development experience to code in ExtendedScript. However, that will help. I will not touch any TCS-specific codes here. This blog entry is just an introduction to ESTK.

Start

Open ESTK. (See the documentation if you do not know how to open ESTK.)

You see a blank screen titled, Source1. That’s your first file. You can start typing the code. You don’t need to save this file to run the code. (We will save the file later.)

Let us start with a very simple example – a code that generates an alert. You know what an alert is, right? The pop-up that appears when you do something on a web page.

Start typing ‘alert’ in ESTK. Before you reach ‘l’ in ‘alert,’ you see a pop-up window that gives you a suggestion on what you are trying to type. It also provides you with an argument list that an alert statement takes.

Double-click it. The following entry is inserted:

alert (message, title, errorIcon)

Run

Now, let’s run the code. It’s simple. Click the Play button displayed on the top-right corner. Oops!! You see that the code is highlighted in red. Observe that left-bottom corner displays a message saying, “message is undefined.” All JavaScript experts got the point. We have not defined the variable, “message.” So is the case with other variables – “title” and “errorIcon.” ESTK provided you the error the moment it detected “message.” It is yet to verify the other variables.

Fix

What to do next? Put all those variables in double quotes, so that ESTK knows they are just strings, not variables. Observe that the script has not completed execution. Click the Stop button in ESTK, and then insert the double quotes:

alert (“message”, “title”, “errorIcon”)

Now run it again. You got it right this time!!

Explore

Now let us make the alert statement a function and call it.

function showAlert(message, title, errorIcon)
{
alert (message, title, errorIcon)
}
showAlert(“It’s a message!!”, “Alert Title”, “errorIcon”)

We created a function showAlert that accepts three arguments. We called the function with the arguments. Run the script and you will see the output.

Summarize

That’s it. Let me summarize what we learned here:

- ExtendScripts are like JavaScripts.

- ESTK provides an environment for developing, debugging, and running ExtendedScript.

Accessing the StageWebView object

Recently, for one of my articles on StageWebView, a reader has commented that he gets an error while calling a stage object through a preperationComplete event. I must say that while preparing the article, I never thought about that kind of a scenario. This blog entry is to explain how to sort this issue out.
This was the example that I provided:

==
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:local="*" creationComplete="init()">
 <fx:Declarations>
  <!-- Place non-visual elements (e.g., services, value objects) here -->
 </fx:Declarations>
<fx:Script>
 <![CDATA[
  import flash.geom.Rectangle;
  import flash.media.StageWebView;
  import flash.net.*;
  import flash.net.URLRequest;
  public var webView:StageWebView = new StageWebView();
  public function init():void
  {
   webView.stage = this.stage;
   webView.viewPort = new Rectangle( 0, 0, stage.stageWidth, stage.stageHeight );
   webView.loadURL("http://www.bbc.com");
  }
 ]]>
</fx:Script>  

</s:WindowedApplication>

===
Compiling the code generates the following error: “Cannot access a property or method of a null object reference.” When a creationComplete event fires, the stage is still null. It is not initialized yet. The stage property acquires a value only after the display object has been added to the stage’s display list. Here, we don’t have any display object added to the stage. If you are accessing the function through another component, say a button, you don’t find this issue.

One solution is to wait for the addedToStage event. This event gets fired whenever the stage is initialized and obtains a value. The issue I explained above has nothing to do with the StageWebView api. See the code below. Using the creationComplete event, I called in the init() function which listens for the addedToStage event. After it’s fired, the target function accesses the stage object.

The following code works without any issues:

==
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:local="*" creationComplete="init()">
 <fx:Declarations>
  <!-- Place non-visual elements (e.g., services, value objects) here -->
 </fx:Declarations>
<fx:Script>
 <![CDATA[
  import flash.geom.Rectangle;
  import flash.media.StageWebView;
  import flash.net.*;
  import flash.net.URLRequest;
  public var webView:StageWebView = new StageWebView();
  public function init():void
  {
   this.addEventListener(Event.ADDED_TO_STAGE , handleLoad );
  }
  public function handleLoad(e:Event):void
  {
   webView.stage = this.stage;
   webView.viewPort = new Rectangle( 0, 0, stage.stageWidth, stage.stageHeight );
   webView.loadURL("http://www.bbc.com");
  }
 ]]>
</fx:Script>  

</s:WindowedApplication>
==