by Willam van Weelden

Willam van Weelden

Created

28 October 2012

Requirements

Prerequisite knowledge

To follow this article, you should have a basic understanding of:

JavaScript

User level

All

One of the most powerful and perhaps one of the most neglected features of RoboHelp is scripting. Scripting allows you to automate repetitive tasks and can save you many hours of dull work. A script can reset image dimensions, convert text to variables, add index entries, create context sensitivity, count the words in your project, and so on.

And scripting is not limited to automating repetitive tasks. The new RoboHelp 9 ePub output is also created using RoboHelp's scripting engine. If you are using Technical Communication Suite 3, you can even create scripts that utilize both RoboHelp and FrameMaker functionality.

In this article, I will give you an introduction to RoboHelp Object Model, which is the way to access all the resources in your project. I assume that you know how to run and open scripts using the RoboHelp Script Explorer pod. If you want to know how to run scripts in RoboHelp, watch John Daigle's excellent tutorial on how to run scripts in RoboHelp: Automating tasks with built-in scripting.

When you start working with ExtendScript in RoboHelp, you will need the RoboHelp scripting guide. This scripting guide describes the available classes and methods created specifically for RoboHelp. You can also use the Help of the ExtendScript toolkit, which has the RoboHelp scripting guide integrated in its Help system.

JavaScript: Extended

The ExtendScript toolkit allows you to work with several scripting languages. Some scripting languages, such as VBScript, can be used only on specific operating systems. Fortunately, you can also use JavaScript, the commonly used scripting language for the web.

Adobe added extra features to JavaScript so the scripts can interact with Adobe programs. This extended version of JavaScript is called ExtendScript. The difference between JavaScript and ExtendScript is not relevant for this article.

RoboHelp Object Model: Resources, classes, and methods

The first step to writing a script is to learn how to access the resources of a RoboHelp project. These resources are all the files, map IDs, variables, and other elements of your project. You access these resources using RoboHelp Object Model, which is similar to Document Object Model (DOM) in JavaScript.

RoboHelp Object Model, or ROM in short, is split into three main branches or classes: TokenManager, Project, and the constants, such as SSLLayoutType and TagType.

TokenManager is the class for reading and editing the contents of (X)HTML and XML files. These can be files from your project, such as topics, or files from outside a project. TokenManager breaks a file into sizable chunks for you to work with. You can also use the ExtendScript File object to access files, but that method is outside the scope of this article.

The constants (the right branch of ROM) are predefined values you use to check the properties of tokens, topics, files, and so on. You access a constant by defining the RoboHelp object, then the correct constant class, followed by the constant you want to use. If you want to check if the language of a topic is set to UK English, you can use the following code:

if(topic.language == RoboHelp.Language.ENGLISHUK) //Do something for UK English topics

The variable 'topic' in this example is a topic resource. To check whether the topic is UK English, the constant ENGLISHUK is used by calling the RoboHelp object, followed by the class Language. You can then use the available constants in the Language class.

The main branch of ROM is Project. The Project branch gives you access to all resources of the current project, such as topics, master pages, linked FrameMaker files, variables, and so on. The Project branch is the main branch that you use when executing scripts for a project.

Accessing project resources

Accessing project resources is a two-step process. First, you need to access the project class (the branch of ROM you need) and the class of the resource you want to use. Note that all classes are case sensitive.

Note: In the scripts, specify the Project class as RoboHelp.project.

Then you can access the resources by looping through the resource class. For example, to access all the topics in the current project, you first need to define a variable that references the TopicManager class and then you can loop through the class to access the individual topics.

For instance, if you want to print the title of all the topics in your project to the Output View pod, you must first define the TopicManager class. Then you can access the topics using a loop:

//Load the TopicManager into the variable ‘topicmngr’ //Note the lowercase for the project class. var topicmngr = RoboHelp.project.TopicManager; //Loop through all the topics in the TopicManager for(var i =1;i<=topicmngr.count;i++) { //Get the topic by invoking the method item() var topic = topicmngr.item(i); //Write an output message with the topic title RoboHelp.project.outputMessage(topic.name+"\n"); }

The different resource classes inside the project class are arrays holding the resources. (The ReportManager class and the MapIDManager class are exceptions.) The resource classes are not regular arrays. For example, the first key in the array is 1 and not 0 like in regular arrays. Secondly, you cannot use the length method to get the number of objects in the array. ROM provides you with the count method to get the number of objects in the resource class.

This means that to implement a for loop, you start counting from 1 and the loop continues until the counter is larger than the count of the resource class. You can see this implementation in the code example above that loops through the topics in a project. When you cycle through a regular array, you still use the length method and start counting with 0.

A special resource class is the FileManager class. The FileManager class lets you handle all the files in the open project. This includes topics, snippets, style sheets, and RoboHelp control files, such as the XPJ file. Modifying the control files may be useful on some occasions but can also seriously wreck a project. Some files, such as style sheets, can only be accessed through the FileManager class.

Resource properties and resource methods

Every class, resource class, and resource in the ROM has several properties and methods. All available properties and methods are listed in RoboHelp Scripting Guide and the Object Model Viewer in the ExtendScript toolkit.

Methods are actions you can use on a resource. For instance, you can delete a topic, check out a file from source control, or create a new snippet.

Properties provide you with information about a resource, such as the title of a topic or the synchronization status of a FrameMaker file. Some properties, such as the synchronization status of a FrameMaker file, are read-only. Other properties, such as a topic title, can be changed. If you want to know whether a property can be changed, check RoboHelp Scripting Guide.

Reading and editing resources with TokenManager

In many scripts, you may want to read and edit the contents of resources, such as topics and snippets. To do this, you need to load the resource into TokenManager.

TokenManager breaks up the files you read into small chunks: tokens. This allows you to identify the pieces of the file you need and modify those pieces according to your requirements. When you want to use scripts to perform tasks as inserting text or changing paragraph styles, you need to open the files, find the correct element, and save the modifications.

A token is the smallest possible chunk of related information. For topics, this means either a single HTML tag or a piece of text. A token is always a single element. In the case of an HTML tag, this is only the start tag with its attributes. A simple paragraph is therefore split up in three tokens: the start tag, the paragraph text, and the end tag:

<p class="note">This is a warning.</p>

The above paragraph is transformed into the following three tokens:

· <p class="note"> · This is a warning. · </p>

To load a file into TokenManager, you use the RoboHelp method getTokenManager():

var topicmngr = RoboHelp.project.TopicManager; for(var i =1;i<=topicmngr.count;i++) { var topic = topicmngr.item(i); //Load the resource in the TokenManager var tokens = RoboHelp.getTokenManager(topic.path); }

The script above loads the topic as tokens into the variable tokens. To load a resource into TokenManager, you need to provide the complete path of the resource. You can do this by providing the path property of the resource you want to load.

You can now cycle through the tokens. For example, if you want to apply the class note to all paragraphs in all topics, you can use the following script:

var topicmngr = RoboHelp.project.TopicManager; for(var i =1;i<=topicmngr.count;i++) { var topic = topicmngr.item(i); //Load the resource in the TokenManager var tokens = RoboHelp.getTokenManager(topic.path); //Check to see that the TokenManager is defined if(typeof(tokens) != "undefined") { //Check that the file is not empty if(tokens.count>0) { //Define the first token var token = tokens.item(1); //Loop through all the tokens while(typeof(token)!="undefined") { //Check that the token is a HTML paragraph tag if(token.tagType== RoboHelp.TagType.TAGPARAGRAPH) { //Set the class of the paragraph to ‘note’. token.setAttribute("class", "note"); } //Next token token = token.next; } //Save the file tokens.save(); } } }

The above script loads all topics into TokenManager. The script then checks to see if the file was correctly loaded. If the file is loaded, the script checks that there are more than zero tokens. A file with zero tokens is empty.

When there are tokens, each token is loaded into the variable token. The while loop ensures that the script runs until all the tokens are parsed. In the loop, the script checks whether the current token is an HTML paragraph tag. If the token is a paragraph tag, the script gives the attribute class the value note. Last, the variable token is changed to the next token. When there are no more tokens, the variable token gets the type undefined. This ends the while loop. The file is saved and automatically closed.

Theory to test: Example script

For this article, I created a small example script to show you the structure of a complete script (CleanProjectExample.jsx) inside the sample files for this article:

robohelp-extendscript.zip

Download the example script and open the script in the ExtendScript toolkit or any text editor you like.

The example script shows you how to parse the topics in your project and to remove all inline styling. The script is commented and illustrates the explanations in this article.

Warning: Run this script in a test project. This script will remove all inline styling and may produce unwanted results in your production projects.

Summary

In this article, I have introduced you to RoboHelp Object Model. With RoboHelp Object Model, you can start creating your own scripts. When you want to create your own scripts, be sure to look at the example scripts provided by Adobe. Those scripts show how the programmers at Adobe use ExtendScript to enhance RoboHelp.

Using ExtendScript allows you to use RoboHelp Object Model together with specific ExtendScript options such as advanced file creation, graphical interface creation, and more. Be sure to check the documentation included with the Adobe ExtendScript Toolkit for a complete overview of all possibilities.

Script resources

Some sites on the web host scripts for RoboHelp. You can use the scripts found through the following links in your own projects and as examples:

Where to go from here

Read my latest article on using the new RoboHelp 10 scripting events.