Wednesday, March 14, 2012

Opening Files Off Screen

If you are processing a large number of files without user interaction, consider opening those files off screen. This allow your script to work faster (as there is no need to update the display) and to do its work without screen fireworks.

Use Open() and set the open parameter Constants.FS_MakeVisible to False to open a file off screen. Files opened this way can be modified in exactly the same way as files that are on screen.

If you work with files in this way, keep in mind is that your script must take total responsibility for managing off screen files. When a script is done with an off screen file, it must save (if changes are to be retained) and close the file. Failing to do so leaves the file locked and open but inaccessible to an end user.

There may be a case where you want to open a file off screen, work with that file, and then make it visible to users. To do so, set the document property, FS_MakeVisible to True when you are ready to reveal the file to users. 

Tuesday, March 13, 2012

Opening Book Files when there are Issues

If you use SimpleOpen() to open book files non-interactively, files with missing graphics, missing fonts, or other issues will not open. Use Open() with an appropriate set of parameters to solve this problem.

The following function sets up open preferences that allow files of the following types to open without user interaction:
  • Files which reference missing files.
  • Files that are in an old FM version.
  • Files with missing font issues.
  • Files that are locked.
function getOpenPrefs() {
    var params, i;
    params = GetOpenDefaultParams();
    i = GetPropIndex(params, Constants.FS_RefFileNotFound);
    params[i].propVal.ival =
    i = GetPropIndex(params, Constants.FS_FileIsOldVersion);
    params[i].propVal.ival = Constants.FV_DoOK;
    i = GetPropIndex(params, Constants.FS_FontChangedMetric);
    params[i].propVal.ival = Constants.FV_DoOK;  
    i = GetPropIndex(params, Constants.FS_FontNotFoundInCatalog);
    params[i].propVal.ival = Constants.FV_DoOK;   
    i = GetPropIndex(params, Constants.FS_FontNotFoundInDoc);
    params[i].propVal.ival = Constants.FV_DoOK;   
    i = GetPropIndex(params, Constants.FS_LockCantBeReset);
    params[i].propVal.ival = Constants.FV_DoOK;       
    i = GetPropIndex(params, Constants.FS_FileIsInUse);
    params[i].propVal.ival = Constants.FV_OpenViewOnly;     
    return (params);
The function to open the book using these parameters is shown here:

function openBookFiles(book) {
    var doc, component, compName;
    var openParams, openReturnParams;
    openParams = getOpenPrefs ();
    openReturnParams =  new PropVals();

    component =book.FirstComponentInBook;
    while(component.ObjectValid() ){    
        compName = component.Name;
        doc = Open(compName, openParams, openReturnParams);
        component =  component.NextComponentInBook;

Monday, March 12, 2012

Saving FM Binary in Old Version

If you have ever needed to revert FrameMaker files to an older version, the following script does so automatically. It works on the active document but you could convert it to work on a book or a directory of files.

The key to the script is the Save() method which allows you to set the file type as desired. I have chosen FrameMaker 9 (FV_SaveFmtBinary90) but you can  go as far back as FrameMaker 6 (FV_SaveFmtBinary60).

I chose not to change the file name. I end the script by closing the FM 10 version of the file without saving it. The FM9 version is already on disk.

var doc,  name, saveParams, i;

doc = app.ActiveDoc;
name = doc.Name;

saveParams = GetSaveDefaultParams();
returnParams = new PropVals();
i = GetPropIndex(saveParams, Constants.FS_FileType);
saveParams[i].propVal.ival =Constants.FV_SaveFmtBinary90;
doc.Save(name, saveParams, returnParams);

After running the script, I opened the test file just to convince myself this really works.

Sunday, March 11, 2012

Using SimpleOpen() without User Interaction

SimpleOpen() can be called interactively or without user interaction. This distinction makes a difference if you are dealing with files that have issues.

If you are calling SimpleOpen() interactively, the user decides what to do when there are missing fonts, locked files, or other problematic situations.

If you call SimpleOpen() without user interaction FrameMaker defaults to very conservative behavior.
I created a simple a test to demonstrate this behavior. I cobbled together a set of files, each with a distinct issue, and put those files into a FrameMaker book. Each of my four files has one of the following issues:
  • It is locked.
  • It contains missing graphics.
  • It uses unavailable fonts.
  • It is in an older FrameMaker version.
Opening these files from the user interface brings up a dialog that allow the user to proceed or abort the open. Opening these files using the following code produces no user interaction and only one of the files opens: the locked file is opened in view only mode.

doc = SimpleOpen(compName, false);