Skip to main content
Participating Frequently
December 10, 2012
Answered

Book level - import master pages and formats

  • December 10, 2012
  • 1 reply
  • 1619 views

Dear all,

I am very new at scripting for framemaker (and a complete novice at JavaScripting) and I find it a bit hard to find information in an environment I'm not familiar in. Maybe you can help me out.

What I would like to do:

I would like to be able to modify the master pages, page layouts, paragraph formats and character formats in the first document of a book and then initiate the script, which will

  1. import the master pages and formats from the first document into all the other documents (just like if you go via File > Import > Format),
  2. update the book.

In the example scripts folder in the installation folder, I have found an example script that goes through all the documents in a book:

book=app.ActiveBook;

comp=book.FirstComponentInBook;

while(comp.ObjectValid())

{

        open(comp.Name);

        nextComp=comp.NextBookComponentInDFSOrder;

        prevComp=comp.PrevBookComponentInDFSOrder;

        compType=comp.BookComponentFileType;

        Log("BookComponent.log", "CompName-"+comp.Name);

        Log("BookComponent.log", "comp File Type-"+compType);

        Log("BookComponent.log", "Component Type(Fldr,Grp,file)-"+comp.ComponentType);

        Log("BookComponent.log", "PreviousCompName-"+prevComp.Name);

        Log("BookComponent.log", "nextCompName-"+nextComp.Name);

        Log("BookComponent.log", "---------------------------------");

        //process component here//

        comp=nextComp;

    }

function open(filename)

{

openProp = GetOpenDefaultParams()

i=GetPropIndex(openProp,Constants.FS_FileIsOldVersion)

openProp.propVal.ival=Constants.FV_DoOK

i=GetPropIndex(openProp,Constants.FS_FontNotFoundInCatalog)

openProp.propVal.ival=Constants.FV_DoOK

i=GetPropIndex(openProp,Constants.FS_FontNotFoundInDoc)

openProp.propVal.ival=Constants.FV_DoOK

i=GetPropIndex(openProp,Constants.FS_FileIsInUse)

openProp.propVal.ival=Constants.FV_DoCancel

i=GetPropIndex(openProp,Constants.FS_AlertUserAboutFailure)

openProp.propVal.ival=Constants.FV_DoCancel

retParm = new PropVals()

docOpen=Open(filename,openProp,retParm);

return docOpen;

}

function Log(logFile,textLine)

{

    file=new File ("C:\\ESLog\\"+logFile);

    file.open("a+", "TEXT", "????");

    file.write(textLine+"\r");

    file.close();

    }

That gets me started a bit. I have also seen the line //process component here//, and I am a bit familiar with programming and scripting. I somehow see how this works in principle. But then I am at a loss.

I know that there's a lot of documentation on FrameMaker scripting (I have the scripting guide). But I find it hard to find the corresponding information without spending hours of learning.

Could someone help me out?

Immense gratitude in advance!

Matthias

This topic has been closed for replies.
Correct answer Russ Ward

Hi Matthias,

While Jang was cooking up a script, I was too, So here is my version... let the dueling begin!

A key point regarding your original post... that sample script was almost there, all you needed to add was:

- A line to remember the first document in the book. You'll see that in Jang's script where he defines 'sourceDoc' and in my script where I define 'firstDoc'

- A call to SimpleImportFormats() on each document to import formats from that first document. You'll see that in both scripts.

Also, the sample script included a lot of logging that really wasn't relevant to the task you were looking to complete, so I streamlined the logging to be more applicable. You may not want logging at all... in which case you could just lose the Log() lines. It was just something handy that the sample showed how to do.

Jang's script includes a function to look for a currently-open document before attempting to open it from the file system. I think that is good practice and something I would implement myself in a script like this.

My script includes a check for an open book file, in case the book window isn't currently active. You may or may not want this. I put that in a lot because it's often a pain to have to remember that the book window needs to be active.

Anyway, with that, enjoy!

Russ

var doc, firstDoc = null;

var counter = 0;

//Set this to some text file on your computer

//where you want logging to be written.

//The folder has to exist but the file

//will be created automatically.

var logFile = "C:\\temp\\delete\\import_formats.log";

book=app.ActiveBook;

if(!book.ObjectValid())

{

    //If no book window is currently active,

    //look for any open book, then prompt

    //whether we really want to use that one.

    book = app.FirstOpenBook;

   

    if(book.ObjectValid())

    {

        //If the user does not want to use the first open book,

        //reset the book variable to the invalid object so that

        //future processing does not take place.

        if(!confirm("No book is currently active. " +

            "Would you like to process " + book.Name + "?"))

                book = app.ActiveBook;

    }

}

Log(logFile, "");

Log(logFile, "---------------------------------------------");

date = new Date();

Log(logFile, date.getMonth() + "/" +

    date.getDate() + "/" +

    date.getFullYear() + " - " +

    date.getHours() + ":" +

    date.getMinutes() + ":" +

    date.getSeconds());

Log(logFile, "Beginning format importer script...");

//do the processing. If there is no valid book at this

//point, we'll never get a valid comp and therefore this will

//all be skipped.

comp=book.FirstComponentInBook;

while(comp.ObjectValid())

{

    //get the document associated with the component, opening

    //it if necessary. If we are at the first one, store the object

    //because that's the one from which we are importing the

    //formats

    doc = open(comp.Name);

    if(firstDoc == null) firstDoc = doc;

    //check the component type. No need to bother with folders and groups.

    compType=comp.BookComponentFileType;

    if(compType != Constants.FV_BK_FOLDER && compType != Constants.FV_BK_GROUP)

    {

        //process component here//

        Log(logFile, "Importing to: " + comp.Name);

        //Import formats from the first document

        doc.SimpleImportFormats(firstDoc,

            Constants.FF_UFF_PAGE | Constants.FF_UFF_PGF| Constants.FF_UFF_FONT);

           

        counter++;

       

    }

    //iterate to the next component, if there is one.

    comp = comp.NextBookComponentInDFSOrder;

}

Log(logFile, "Total files processed: " + counter);

Log(logFile, "---------------------------------------------");

function open(filename)

{

    openProp = GetOpenDefaultParams();

    i=GetPropIndex(openProp,Constants.FS_FileIsOldVersion);

    openProp.propVal.ival=Constants.FV_DoOK;

    i=GetPropIndex(openProp,Constants.FS_FontNotFoundInCatalog);

    openProp.propVal.ival=Constants.FV_DoOK;

    i=GetPropIndex(openProp,Constants.FS_FontNotFoundInDoc);

    openProp.propVal.ival=Constants.FV_DoOK;

    i=GetPropIndex(openProp,Constants.FS_FileIsInUse);

    openProp.propVal.ival=Constants.FV_DoCancel;

    i=GetPropIndex(openProp,Constants.FS_AlertUserAboutFailure);

    openProp.propVal.ival=Constants.FV_DoCancel;

    retParm = new PropVals();

    docOpen=Open(filename,openProp,retParm);

    return docOpen;

}

function Log(logFile,textLine)

{

    file=new File (logFile);

    file.open("a+", "TEXT", "????");

    file.write(textLine+"\r");

    file.close();

}

1 reply

4everJang
Legend
December 10, 2012

Hello Matthias,

Here's a script that does what you need. I thought that script might come in handy for myself, so I went ahead and created one. It

book = app.ActiveBook;

if (book.ObjectValid())

{

          comp = book.FirstComponentInBook;

          sourceDoc = FindOpenDoc(comp.Name);

          if (sourceDoc == null)

                    sourceDoc = OpenDoc(comp.Name);

          if (sourceDoc.ObjectValid())

          {

                    comp = comp.NextBookComponentInDFSOrder;

                    while(comp.ObjectValid())

                    {

                              targetDoc = FindOpenDoc(comp.Name);

                              if (targetDoc == null)

                                        targetDoc = OpenDoc(comp.Name);

                              if (targetDoc.ObjectValid())

                              {

                                        targetDoc.SimpleImportFormats(sourceDoc,Constants.FF_UFF_FONT | Constants.FF_UFF_PGF | Constants.FF_UFF_PAGE);

                                        targetDoc.SimpleSave(targetDoc.Name,false);

                                        targetDoc.Close(1);

                              } else

                                        alert("Cannot open "+comp.Name);

                              comp = comp.NextBookComponentInDFSOrder;

                    }

                    sourceDoc.SimpleSave(sourceDoc.Name,false);

                    sourceDoc.Close(1);

                    alert("Done");

          } else

                    alert("Cannot open first chapter.");

} else

          alert("Activate the book first.");

function FindOpenDoc(sFileName)

{

          var oTheDoc = app.FirstOpenDoc;

          while (oTheDoc.ObjectValid())

          {

                    if (oTheDoc.Name == sFileName)

                              return oTheDoc;

                    oTheDoc = oTheDoc.NextOpenDocInSession;

          }

          return null;

}

function OpenDoc(sFilename)

{

          var oaOpenProps = GetOpenDefaultParams();

          i = GetPropIndex(oaOpenProps,Constants.FS_FileIsOldVersion);

          oaOpenProps.propVal.ival = Constants.FV_DoOK;

          i = GetPropIndex(oaOpenProps,Constants.FS_FontNotFoundInCatalog);

          oaOpenProps.propVal.ival = Constants.FV_DoOK;

          i = GetPropIndex(oaOpenProps,Constants.FS_FontNotFoundInDoc);

          oaOpenProps.propVal.ival = Constants.FV_DoOK;

          i = GetPropIndex(oaOpenProps,Constants.FS_RefFileNotFound);

          oaOpenProps.propVal.ival = Constants.FV_AllowAllRefFilesUnFindable;

          i = GetPropIndex(oaOpenProps,Constants.FS_UpdateTextReferences);

          oaOpenProps.propVal.ival = Constants.FV_DoNo;

          i = GetPropIndex(oaOpenProps,Constants.FS_UpdateXRefs);

          oaOpenProps.propVal.ival = Constants.FV_DoNo;

          i = GetPropIndex(oaOpenProps,Constants.FS_FileIsInUse);

          oaOpenProps.propVal.ival = Constants.FV_DoShowDialog;

          i = GetPropIndex(oaOpenProps,Constants.FS_AlertUserAboutFailure);

          oaOpenProps.propVal.ival = Constants.FV_DoNo;

          i = GetPropIndex(oaOpenProps,Constants.FS_UseRecoverFile);

          oaOpenProps.propVal.ival = Constants.FV_DoNo;

          i = GetPropIndex(oaOpenProps,Constants.FS_MakeVisible);

          oaOpenProps.propVal.ival = Constants.FV_DoYes;

          oaRetParms = new PropVals();

          oDocOpen = Open(sFilename,oaOpenProps,oaRetParms);

          return oDocOpen;

}

Participating Frequently
December 10, 2012

Hi Jang_fishbone

Thank you so much. I didn't expect to be served with a ready made solution ;-) But thank you!

I will try it out as soon as I can spare a minute.

Best,

Matthias

Russ WardCorrect answer
Legend
December 10, 2012

Hi Matthias,

While Jang was cooking up a script, I was too, So here is my version... let the dueling begin!

A key point regarding your original post... that sample script was almost there, all you needed to add was:

- A line to remember the first document in the book. You'll see that in Jang's script where he defines 'sourceDoc' and in my script where I define 'firstDoc'

- A call to SimpleImportFormats() on each document to import formats from that first document. You'll see that in both scripts.

Also, the sample script included a lot of logging that really wasn't relevant to the task you were looking to complete, so I streamlined the logging to be more applicable. You may not want logging at all... in which case you could just lose the Log() lines. It was just something handy that the sample showed how to do.

Jang's script includes a function to look for a currently-open document before attempting to open it from the file system. I think that is good practice and something I would implement myself in a script like this.

My script includes a check for an open book file, in case the book window isn't currently active. You may or may not want this. I put that in a lot because it's often a pain to have to remember that the book window needs to be active.

Anyway, with that, enjoy!

Russ

var doc, firstDoc = null;

var counter = 0;

//Set this to some text file on your computer

//where you want logging to be written.

//The folder has to exist but the file

//will be created automatically.

var logFile = "C:\\temp\\delete\\import_formats.log";

book=app.ActiveBook;

if(!book.ObjectValid())

{

    //If no book window is currently active,

    //look for any open book, then prompt

    //whether we really want to use that one.

    book = app.FirstOpenBook;

   

    if(book.ObjectValid())

    {

        //If the user does not want to use the first open book,

        //reset the book variable to the invalid object so that

        //future processing does not take place.

        if(!confirm("No book is currently active. " +

            "Would you like to process " + book.Name + "?"))

                book = app.ActiveBook;

    }

}

Log(logFile, "");

Log(logFile, "---------------------------------------------");

date = new Date();

Log(logFile, date.getMonth() + "/" +

    date.getDate() + "/" +

    date.getFullYear() + " - " +

    date.getHours() + ":" +

    date.getMinutes() + ":" +

    date.getSeconds());

Log(logFile, "Beginning format importer script...");

//do the processing. If there is no valid book at this

//point, we'll never get a valid comp and therefore this will

//all be skipped.

comp=book.FirstComponentInBook;

while(comp.ObjectValid())

{

    //get the document associated with the component, opening

    //it if necessary. If we are at the first one, store the object

    //because that's the one from which we are importing the

    //formats

    doc = open(comp.Name);

    if(firstDoc == null) firstDoc = doc;

    //check the component type. No need to bother with folders and groups.

    compType=comp.BookComponentFileType;

    if(compType != Constants.FV_BK_FOLDER && compType != Constants.FV_BK_GROUP)

    {

        //process component here//

        Log(logFile, "Importing to: " + comp.Name);

        //Import formats from the first document

        doc.SimpleImportFormats(firstDoc,

            Constants.FF_UFF_PAGE | Constants.FF_UFF_PGF| Constants.FF_UFF_FONT);

           

        counter++;

       

    }

    //iterate to the next component, if there is one.

    comp = comp.NextBookComponentInDFSOrder;

}

Log(logFile, "Total files processed: " + counter);

Log(logFile, "---------------------------------------------");

function open(filename)

{

    openProp = GetOpenDefaultParams();

    i=GetPropIndex(openProp,Constants.FS_FileIsOldVersion);

    openProp.propVal.ival=Constants.FV_DoOK;

    i=GetPropIndex(openProp,Constants.FS_FontNotFoundInCatalog);

    openProp.propVal.ival=Constants.FV_DoOK;

    i=GetPropIndex(openProp,Constants.FS_FontNotFoundInDoc);

    openProp.propVal.ival=Constants.FV_DoOK;

    i=GetPropIndex(openProp,Constants.FS_FileIsInUse);

    openProp.propVal.ival=Constants.FV_DoCancel;

    i=GetPropIndex(openProp,Constants.FS_AlertUserAboutFailure);

    openProp.propVal.ival=Constants.FV_DoCancel;

    retParm = new PropVals();

    docOpen=Open(filename,openProp,retParm);

    return docOpen;

}

function Log(logFile,textLine)

{

    file=new File (logFile);

    file.open("a+", "TEXT", "????");

    file.write(textLine+"\r");

    file.close();

}