6 Replies Latest reply on Dec 10, 2012 7:09 AM by Russ Ward

    Book level - import master pages and formats

    ionbond_mueller

      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[i].propVal.ival=Constants.FV_DoOK

       

      i=GetPropIndex(openProp,Constants.FS_FontNotFoundInCatalog)

      openProp[i].propVal.ival=Constants.FV_DoOK

       

      i=GetPropIndex(openProp,Constants.FS_FontNotFoundInDoc)

      openProp[i].propVal.ival=Constants.FV_DoOK

       

      i=GetPropIndex(openProp,Constants.FS_FileIsInUse)

      openProp[i].propVal.ival=Constants.FV_DoCancel

       

      i=GetPropIndex(openProp,Constants.FS_AlertUserAboutFailure)

      openProp[i].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

        • 1. Re: Book level - import master pages and formats
          4everJang Level 3

          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[i].propVal.ival = Constants.FV_DoOK;

           

           

                    i = GetPropIndex(oaOpenProps,Constants.FS_FontNotFoundInCatalog);

                    oaOpenProps[i].propVal.ival = Constants.FV_DoOK;

           

           

                    i = GetPropIndex(oaOpenProps,Constants.FS_FontNotFoundInDoc);

                    oaOpenProps[i].propVal.ival = Constants.FV_DoOK;

           

           

                    i = GetPropIndex(oaOpenProps,Constants.FS_RefFileNotFound);

                    oaOpenProps[i].propVal.ival = Constants.FV_AllowAllRefFilesUnFindable;

           

           

                    i = GetPropIndex(oaOpenProps,Constants.FS_UpdateTextReferences);

                    oaOpenProps[i].propVal.ival = Constants.FV_DoNo;

           

           

                    i = GetPropIndex(oaOpenProps,Constants.FS_UpdateXRefs);

                    oaOpenProps[i].propVal.ival = Constants.FV_DoNo;

           

           

                    i = GetPropIndex(oaOpenProps,Constants.FS_FileIsInUse);

                    oaOpenProps[i].propVal.ival = Constants.FV_DoShowDialog;

           

           

                    i = GetPropIndex(oaOpenProps,Constants.FS_AlertUserAboutFailure);

                    oaOpenProps[i].propVal.ival = Constants.FV_DoNo;

           

           

                    i = GetPropIndex(oaOpenProps,Constants.FS_UseRecoverFile);

                    oaOpenProps[i].propVal.ival = Constants.FV_DoNo;

           

           

                    i = GetPropIndex(oaOpenProps,Constants.FS_MakeVisible);

                    oaOpenProps[i].propVal.ival = Constants.FV_DoYes;

           

           

                    oaRetParms = new PropVals();

                    oDocOpen = Open(sFilename,oaOpenProps,oaRetParms);

                    return oDocOpen;

          }

          • 2. Re: Book level - import master pages and formats
            ionbond_mueller Level 1

            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

            • 3. Re: Book level - import master pages and formats
              Russ Ward Level 4

              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[i].propVal.ival=Constants.FV_DoOK;

               

                  i=GetPropIndex(openProp,Constants.FS_FontNotFoundInCatalog);

                  openProp[i].propVal.ival=Constants.FV_DoOK;

               

                  i=GetPropIndex(openProp,Constants.FS_FontNotFoundInDoc);

                  openProp[i].propVal.ival=Constants.FV_DoOK;

               

                  i=GetPropIndex(openProp,Constants.FS_FileIsInUse);

                  openProp[i].propVal.ival=Constants.FV_DoCancel;

               

                  i=GetPropIndex(openProp,Constants.FS_AlertUserAboutFailure);

                  openProp[i].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();

              }

              • 4. Re: Book level - import master pages and formats
                ionbond_mueller Level 1

                Hey Russ!

                 

                Wow, I'm overwhelmed by the helpfulness!

                 

                In fact, I like both of them. The only thing I prefer is that in Jang_fishbone's script all the fm files were closed at the end. But that's a detail; both of them do what I wanted perfectly.

                 

                So thanks a million to both of you! I can also learn a lot from your work.

                 

                One more thing (or maybe this is too much to ask). Is it possible to add a UI element that lets me select which formats to import? Just like in the traditional File > Import > Format menu? I'm not expecting a ready made solution again, guys. I think you've done enough for me already ;-)

                 

                Just give me a hint, maybe..?

                 

                Thanks a lot again!

                Matthias

                • 5. Re: Book level - import master pages and formats
                  ionbond_mueller Level 1

                  And I wanted to mark both answers as correct. Apparently this is not possible..so one of you pulled the shorter straw..sorry.

                  • 6. Re: Book level - import master pages and formats
                    Russ Ward Level 4

                    Hi Matthias,

                     

                    You could have marked Jang's answer as correct... he got to the finish line first   And besides, it is a costly 8-hour plane ride between us, so it's not likely we will get rough about it.

                     

                    Anyway, to answer your question about a UI control, yes it is absolutely possible. You can make this as elegant, sophisticated, and/or complex as you want. To make this sort of control, you would use the concept of ExtendScript "forms," which are described in the "JavaScript Tools Guide," which you can access from the script editor by selecting Help > JavaScript Tools Guide. You can build any kind of dialog box you want, really.

                     

                    It would be a bit much for me to work up an example of this at the moment. Perhaps later, but no promises. There might me an example of forms and UI controls out there somewhere, but I'm not sure where that might be.

                     

                    Russ