19 Replies Latest reply on Feb 20, 2013 1:06 PM by wokoman1234

    [FM10] Some support needed with book save as XML


      Hi there,


      I'm in a process to convert loads of old non structured FM manuals into structured formats, and though it all works fine there is a lot of repetition involved I'd like to get rid off. I'm having a bit of experience with extendscript for indesign, but the documentation for FM is rather poor. So if someone can get me started or provide some codesnippets to make my job a bit more pleasant it would be highly appreciated :-)


      My processes :


      First I open a book, and for each file I run the 'Generate conversion Table' command. The missing paragraph tags need to be added to an existing Conversion table called 'conversion_table'.


      Question 1 : Can I use some code to do this automatically ? So all fm files in the book get opened (silent or not does not really matter) , missing tags are added to the existing table, and fm file is closed again.


      Second : I clean up the conversion table so output is a bit streamlined. That's a manual process anyway so no issues


      Third : I structure the book using the table. Pretty straight forward also so no problem here


      Last step : I save all fm files as docbook 2.1 format, but again this requires me to open all fm files one by one, select 'save as XML', select docbook as format and save the file itself.


      Question 2 : Can I also here use some code so all fm files in the book are opened, saved as XML using docbook format , and closed again with me leaning back and looking at my PC doing the dirty job for me. To push my luck it would be great if I could also integrate step 3



      I guess all of this would be rather simple for a seasoned programmer, but I'm cracking my teeth on it. Therefore anybody that can point me in the right direction or provide some code that could get me running would make my day for sure


      Thanks in advance!


        • 1. Re: [FM10] Some support needed with book save as XML
          Russ Ward Level 4

          Hi K,


          Since nobody has responded, I thought I would add a little something, although probably not what you are asking for. Your requirements are well-suited for ExtendScript automation; however, they represent a fairly advanced usage of it. It could take some time to develop these scripts, more time than somebody can likely give you on a simple user-to-user forum post. So, I think that might be why you are having trouble getting responses.


          This is a good place to ask specific questions about ES code, but yours is quite broad. I'm almost sure you would need to pay someone to write all that code. My suggestion is to back up a bit and start learning about ES at a lower level, then maybe  the way forward will eventually start to make more sense to you.



          • 2. Re: [FM10] Some support needed with book save as XML
            frameexpert Level 4

            I agree with Russ; you have a lot going on. I would suggest splitting your question into multiple posts, one for each step in the process. Most of us like to help, but I do this for a living so I can't spend too much time posting complete solutions for free. But here is some code that will automate your third step:


            CallClient ("Structure Generator",  "InputDocId " + inputId);
            CallClient ("Structure Generator",  "RuleDocId " + convId);
            CallClient ("Structure Generator",  "StructureDoc");


            The inputId and convId variables are the id properties of the input document and the conversion table document, respectively. For example, if you are structuring the active document, you would do this to get the inputId:


            var inputId = app.ActiveDoc.id;


            There are also commands to add new entries to an existing conversion table. The best place to get this information is in the FDK manuals. You will have to "translate" the information from C to ExtendScript, but at least you have something to start with. I don't think any of the Structure Generator information is in the ExtendScript documentation.



            • 3. Re: [FM10] Some support needed with book save as XML
              wokoman1234 Level 1

              Thanks both,


              Fully understand and agree that I probably pushed my luck a bit :-)


              Let's try again on some part already. I'm able to run a script to save it as XML, and I probably can figure outhow to get it done on booklevel with the examples available, but I'm still struggling with the structured save part. Saving as XML works fine, and I found some example for the SDK, but I can't find the right syntax to do it on the extendscript Toolkit as that's a bit less intimidating for me.


              This is what I have now :


              var doc,  name, saveParams, i;


              doc = app.ActiveDoc;

              name = doc.Name;

              fullName = name.replace(".fm",".xml");


              saveParams = GetSaveDefaultParams();

              returnParams = new PropVals();


              i = GetPropIndex(saveParams, Constants.FS_FileType);

              saveParams[i].propVal.ival =Constants.FV_SaveFmtXml;


              i = GetPropIndex(saveParams, Constants.FS_StructuredSaveApplication);

              saveParams.val[i].propVal.ival = "XDocBook"; <- this doesnt'work, any advice on what the exact syntax would be ?


              doc.Save(fullName, saveParams, returnParams);





              • 4. Re: [FM10] Some support needed with book save as XML
                frameexpert Level 4

                Since XDocBook is a string, it is probably .sval:


                saveParams.val[i].propVal.sval = "XDocBook";
                • 5. Re: [FM10] Some support needed with book save as XML
                  wokoman1234 Level 1

                  Actualy I was too fast with copy paste activity from c to extend, so after some tweeking I got this to work :


                  saveParams[i].propVal.sval = "XDocBook";


                  After some further playing around I got a full flow working now for the save as xml part, all files of the book are now opened silently, each document is saved with structured fomat and closed. Below full working code in case someone could use it also




                  // Save all compontents as XML


                  bookTraverse ();


                  // Traverse through book components and save them when valid, thanks to the original creator !

                  function bookTraverse ()


                  var book = app.ActiveBook


                      if (!book.ObjectValid() )


                         // kind reminder to select the book before we get started

                          Alert ("Select book first" ,Constants.FF_ALERT_CONTINUE_WARN)




                  // Quick warning up front...   

                  var ret = Alert ("All files in this book will be saved as XML: Press <OK> to continue or <cancel> to abort",Constants.FF_ALERT_OK_DEFAULT)

                  if (ret == -1)




                  var compBook = book.FirstComponentInBook

                  while(compBook.ObjectValid() )


                      var compName = compBook.Name

                      var compType = compBook.BookComponentFileType

                      var doc = open(compName)


                      if (compType == Constants.FV_BK_BOOK)


                          bookTraverse (doc)


                    if (doc.ObjectValid() )


                       // component is valid so we save as XML   

                       saveDocAsXML (doc, doc.Name)

                      doc.Close (1)


                      compBook = compBook.NextBookComponentInDFSOrder


                  Alert ("All are saved" ,Constants.FF_ALERT_CONTINUE_WARN)



                  function open(filename)


                  var openProp = GetOpenDefaultParams()


                  var i=GetPropIndex(openProp,Constants.FS_FileIsOldVersion)






















                  var retParm = new PropVals()

                  var fileObj=Open(filename,openProp,retParm);

                  return fileObj




                  function saveDocAsXML(doc,name) {


                  var fullName = name.replace(".fm",".xml");

                  var saveParams = GetSaveDefaultParams();

                  var returnParams = new PropVals();


                  var i = GetPropIndex(saveParams, Constants.FS_FileType);

                  saveParams[i].propVal.ival =Constants.FV_SaveFmtXml;


                  i = GetPropIndex(saveParams, Constants.FS_StructuredSaveApplication);

                  saveParams[i].propVal.sval = "DocBook 2.1";


                  doc.Save(fullName, saveParams, returnParams);



                  • 6. Re: [FM10] Some support needed with book save as XML
                    Russ Ward Level 4



                    You've done well! I think maybe you didn't really need help at all, maybe you just wanted to talk to somebody



                    • 7. Re: [FM10] Some support needed with book save as XML
                      wokoman1234 Level 1

                      Thanks Rick, this helped me quite a lot.


                      I was able to figure out how to add the missing entries to my conversion table using below mentioned booktraverser in combination with following :


                      function UpdateConvTable(doc,name,ConvTableID ){


                      // get current doc id

                      var docId = doc.id;


                      // add missing tags to conversion table

                      CallClient("Structure Generator", "SourceDocId " + docId);

                      CallClient("Structure Generator", "UpdateTable " + ConvTableID );


                      // and save the documents so it's up to date with latest version

                      var params = GetSaveDefaultParams();

                      var returnParamsp =new PropVals();

                      var i = GetPropIndex(params, Constants.FS_FileType);

                      params[i].propVal.ival =Constants.FV_SaveFmtBinary;


                      doc.Save(name, params, returnParamsp)




                      It does nicely what I want, it opens all the bookcomponents, adds the missing ones to my conversion table, saves the component and does all of this without nagging me with errors etc.




                      I got the id of my conversion table by opening it, giving it the scope, and then retrieving the app.ActiveDoc.id. But this is a bit of unreliable method, for starters I'm not even sure if this id is unique and fixed, or can just be changed over time. What would therefore be a better to get the id of the conversion table, rather than having it hardcoded as I did now ?


                      Scenario I am thinking of is as follows


                      Book is selected, and script starts

                      -> if page with name "conversion_table" is not opened (using IsOnScreen ?), open the page (located at "C:\\conversion_table.fm)

                      -> if opened get the id , and run all code magic on all the book components (above function)


                      seems like fairly simple, but i can't find back any examples on how to use IsOnScreen, or opening a single document (my conversion table) without losing focus on selected book. Any advice / support would be welcome.

                      • 8. Re: [FM10] Some support needed with book save as XML
                        wokoman1234 Level 1

                        Yeah, sometimes just thinking out loud get's you started also :-)

                        • 9. Re: [FM10] Some support needed with book save as XML
                          frameexpert Level 4

                          This may not be the best approach, but you could loop through the open documents and test its name to see if it is the conversion table. You should probably put this in a function.


                          var doc = app.FirstOpenDoc;
                          while (doc.ObjectValid() === 1) {
                              if (/Conversion/.test(doc.Name) === true) {
                                  var convId = doc.id;
                              doc = doc.NextOpenDocInSession;



                          • 10. Re: [FM10] Some support needed with book save as XML
                            wokoman1234 Level 1

                            Thanks again Rick, it looks like a good alternative, but I'm not familiar with the /conversion/.test syntax.

                            I've tried a few things with above code, but it didn't give me results. Playing with the script I can get the name of the open docs etc, but the test thing puzzles me.


                            What would I need to change in (/Conversion/.test(doc.Name) === true) to make it work ? Assume I would have a document called conversion_table.fm, located at C:/folder/conversion_table.fm

                            • 11. Re: [FM10] Some support needed with book save as XML
                              frameexpert Level 4

                              This is where you get into core JavaScript versus FrameMaker ExtendScript. /Conversion/ is a JavaScript regular expression that matches the literal string "Conversion" somewhere in the file path or name. You can use /Conversion/i.test to give you a case-insensitive search; this is probably why it is failing for you. JavaScript has other ways of matching strings that you may find more convenient. I like the test method because it returns true or false.



                              1 person found this helpful
                              • 12. Re: [FM10] Some support needed with book save as XML
                                wokoman1234 Level 1

                                ah, brilliant... the case insentive did the trick indeed.

                                • 13. Re: [FM10] Some support needed with book save as XML
                                  wokoman1234 Level 1

                                  Hi Expert,


                                  I've tried above scripts, and thought it works great when updating the conversion table, it doesn't seem to do much when I want to structure my book. Below is the script I have, and I think i'm overlooking something obvious, as I believe that in theory it should work


                                  function structureBook(){


                                       var bookID = app.ActiveBook.id;

                                       var bookName = app.ActiveBook.Name;


                                      //set path to current folder, and add struc

                                      var x=bookName.lastIndexOf("\\");

                                      var dirPath=bookName.substring(0, x )

                                      dirPath += "\\struc"


                                      //If no convTableId get it





                                      //alert(convTableId + " - " + bookID  + " - "  + dirPath)


                                      //Structure current book using above values

                                      CallClient("Structure Generator", "InputBookId " + bookID);

                                      CallClient("Structure Generator", "RuleDocId " + convTableId);

                                      CallClient("Structure Generator", "OutputDirName " + dirPath);

                                      CallClient("Structure Generator", "GenerateBook");




                                  I get all my inputs correctly (book ID, Conversion table ID), the folder where I'd like to save the structured content does exist etc (anyway, commenting the outputdir part doesn't make a difference).


                                  Yet nothing seems to happen, the script runs and gives no failure, but also no output. Any idea on what i might have missed (or how I could check where things go wrong ?)


                                  Thanks again !

                                  • 14. Re: [FM10] Some support needed with book save as XML
                                    Russ Ward Level 4



                                    I could be wrong, but I don't think there is any such command as InputBookId. I think you need to go document-by-document with InputDocId.



                                    • 15. Re: [FM10] Some support needed with book save as XML
                                      wokoman1234 Level 1

                                      Hi Russ, I found it in the FDK reference :


                                      F_ApiCallClient() calls to structure a book

                                      F_ApiCallClient("Structure Generator", "InputBookId objectID");

                                      where objectID is the ID of the input book.


                                      I know I can do it on document base, but then i need to generate the book again if i want to keep my original files, so it would be nice if i could get the book thing running

                                      • 16. Re: [FM10] Some support needed with book save as XML
                                        Russ Ward Level 4

                                        Interesting. Never knew about that... I guess I never had a need. I've done it a single document at a time and it works.


                                        Here is an idea, but it is a long shot. In some older versions of the FDK doc, there was a mistake where it said "GenerateDoc" instead of "StructureDoc", which caused the single doc conversion to fail. I see that the latest version of the FDK doc has fixed that, but it still says "GenerateBook" for the book conversion. I wonder if there is any chance that it should actually be "StructureBook"?  Maybe give that a try. If that doesn't work, I don't have any other suggestions at the moment. I'm a bit tied up to try it myself right now.

                                        1 person found this helpful
                                        • 17. Re: [FM10] Some support needed with book save as XML
                                          wokoman1234 Level 1

                                          Haha, brilliant !  Using StructureBook indeed did the trick. Thanks a lot Russ

                                          • 18. Re: [FM10] Some support needed with book save as XML
                                            Russ Ward Level 4

                                            Maybe not so brilliant, just that I've been around too long. Has it been that long?


                                            Thanks for marking my answer as correct, but Rick definately deserves more credit. He was originally much more helpful than me.

                                            • 19. Re: [FM10] Some support needed with book save as XML
                                              wokoman1234 Level 1

                                              Yeah, it's a small annoyance of the system that you can't mark more than one correct answer. But you sure both helped me a lot !