9 Replies Latest reply on Jan 24, 2016 1:20 PM by trondk

    Convert an ExtendScript to FDK

    trondk

      Hi All.

       

      I have never used FrameMaker until today so this is my first post here. :-)

       

      I have combined a file-reading script and Ian Proudfoot's Search and Replace script into a script that reads comma separated values from a file, and then searches the FrameMaker file for the first string in the array and if found replaces that string with the second string in the array. Making it possible to e.g. loop through a list of old product numbers and replacing them with new ones.

       

      It does actually work, but the thing is that the people who are going to use this script are still using FrameMaker 9.So I need to convert this script to a FDK script. And i need to inform them how to run this script in FrameMaker 9.

       

      So does anyone know if there are any easy ways of converting this ExtendScript to a FDK script to be used in FM9. And could anyone please help me understand how such a script would be run in FrameMaker 9?

       

      Here's "my" script:

       

      //initializing variables

      var activeDoc = app.ActiveDoc;

      var flow = activeDoc.MainFlowInDoc;

      var findString = '';

      var replaceString = '';

      var considerCase = 0;

       

       

      // telling FrameMaker which file to open

      var csvFile = File.openDialog('Select a CSV File','comma-separated-values(*.csv):*.csv;'); 

       

       

      if (csvFile != null)

      {

          sarArray = readInCSV(csvFile);  //read the file into the Search And Replace (sar) array using the readInCSV function

      }

       

       

      for (var i=0, len=sarArray.length; i < len; i++) { //loop through the array and do a search and replace for each collection of elements in the array

          findString = sarArray[i][0];  //the find string is the first element in the current collection

          replaceString = sarArray[i][1] //the replace string is the second element in the current collection

          FindAndReplaceString(activeDoc, flow, findString, replaceString, considerCase)  //the actual search and replace routine

      }

       

       

       

       

      function readInCSV(fileObj)

      {

           var sarArray = new Array(); //creating the array

           fileObj.open('r');  //open the file for reading

           fileObj.seek(0, 0);  //go to the beginning of the file

           while(!fileObj.eof)  //as long as end of file has not been reached

           {

                var thisLine = fileObj.readln(); //read each line

                var csvArray = thisLine.split(';'); //split the line in two at the ; character

                sarArray.push(csvArray); //insert each value into the array

           }

           fileObj.close();  //close the file

           return sarArray; //and return an array full of search and replace strings

      }

       

       

      function FindAndReplaceString(activeDoc, flow, findString, replaceString, considerCase) {

          var tr = new TextRange();

          var restoreTR, frame = 0;

          var loopCounter = 0, replacementCounter = 0;

          var findParams = new PropVals();

       

       

          //if the flow object is not valid, assume the main flow

          if(activeDoc.ObjectValid() && !flow.ObjectValid()){

              flow = activeDoc.MainFlowInDoc;

          }

       

       

          //get the first text frame in the flow, a starting point to

          //find the first paragraph

          if(flow.ObjectValid()){

              frame = flow.FirstTextFrameInFlow;

          }

       

       

          //At this point, if we don't have a frame object, might as well abort.

          if(!frame.ObjectValid()){

              Alert("Could not find a starting point for the search. Cannot continue." , Constants.FF_ALERT_CONTINUE_WARN);

          return replacementCounter;

          }

       

       

          //store the original text selection as an amenity to restore after the action.

          restoreTR = activeDoc.TextSelection;

       

       

          //now, set up the starting text range as the very beginning

          //of the flow. We'll move straight from beginning to end.

          tr.beg.obj = tr.end.obj = frame.FirstPgf;

          tr.beg.offset = tr.end.offset = 0;

       

       

          //set up our find parameters. We want to configure it to look

          //for a string and perhaps be case sensitive. We don't need

          //the find to wrap because we are controlling the flow from

          //beginning to end.

          findParams = AllocatePropVals(2);

       

       

          findParams[0].propIdent.num = Constants.FS_FindText;

          findParams[0].propVal.valType = Constants.FT_String;

          findParams[0].propVal.sval = findString;

       

       

          findParams[1].propIdent.num = Constants.FS_FindCustomizationFlags;

          findParams[1].propVal.valType = Constants.FT_Integer;

          if(considerCase){

              findParams[1].propVal.ival = Constants.FF_FIND_CONSIDER_CASE;

          }

          else{

              findParams[1].propVal.ival = 0;

          }

       

       

          //initialize the errno global, which will be used to

          //track the progress of the find and replace

          FA_errno = Constants.FE_Success;

       

       

          //and do an initial find to get started.

          tr = activeDoc.Find(tr.beg, findParams);

       

       

          //now, run the find and replace loop as long as we keep finding things.

          //The loop counter is just an emergency back door in case something

          //goes critically wrong and causes an endless loop.

          while(FA_errno === Constants.FE_Success && loopCounter++ < 1500){

          //set up the text range to clear the original text

              activeDoc.TextSelection = tr;

              //clear it

              activeDoc.Clear(0);

       

       

              //insert the new text. We should be able to use the

              //original beginning of the text range where the old text was

              //found.

              activeDoc.AddText(tr.beg, replaceString);

       

       

              //now, lets jimmy the text range in memory to place it directly

              //after the string we just inserted, so the find picks back up after that.

              tr.beg.offset += replaceString.length;

       

       

              //increment our return counter

              if(FA_errno === Constants.FE_Success){

                  replacementCounter++;

              }

       

       

              //...and find the next instance. We'll reset FA_errno again just in case

              //something screwy happened while we were replacing text.

              FA_errno = Constants.FE_Success;

              tr = activeDoc.Find(tr.beg, findParams);

          }

          //we're done. Restore the document to it's original area of display

          activeDoc.TextSelection = restoreTR;

          activeDoc.ScrollToText(restoreTR);

          return replacementCounter;

      }

        • 1. Re: Convert an ExtendScript to FDK
          frameexpert Level 4

          There is no "converter" to go from ExtendScript to FDK code. The FDK is C/C++ based. Your best bet is to download the FDK docs and see if you can recode it with C. You will need a MS compiler to work with the FDK.

           

          Another alternative for FrameMaker 9 would be FrameScript (http://www.framescript.com). There is no direct conversion, but like ExtendScript, it is a scripting language. I have been using FrameScript since 1998 and it is very good and reasonably priced.

          • 2. Re: Convert an ExtendScript to FDK
            trondk Level 1

            Thank you very much for your swift response, Rick.

             

            As you understand, Im not new to scripting, but I am new to FrameMaker. Will FrameScript be able to pull off the same thing as this ExtendScript? And how does FrameScript handle the search parameters and constants?

             

            Another important question is whether FrameScript needs to be installed on the computer running FrameMaker 9, or is it enough that it is installed on our computer.

             

            Best regards

            Trond

            • 3. Re: Convert an ExtendScript to FDK
              frameexpert Level 4

              Hi Trond, Yes, FrameScript will need to be installed on each computer that has to run the script. They use an activation scheme to ensure unique licenses on each FrameMaker installation. FrameScript can do what your ExtendScript script can do. -Rick

              • 4. Re: Convert an ExtendScript to FDK
                Russ Ward Level 4

                Trond,

                 

                I recognized that code sample right away because of the word "jimmy" in the comments. I should use more standard English, indeed.

                 

                Anyway, I guess you found this in the following post:

                 

                Re: Find/Replace?

                 

                If you look above the Ian's ExtendScript code, you see the original FDK sample for the find and replace function. Maybe that will help. I don't mean to hijack Rick's conversation here, but I will note that FrameScript must be installed on every machine where a script needs to run. The FDK is free, as is Visual C++ Express Edition which can compile the code. It is no simple matter to set up the project, though, as the documentation is not very good. Having said that, you likely could get some help here.

                 

                Russ

                • 5. Re: Convert an ExtendScript to FDK
                  frameexpert Level 4

                  No problem hijacking; the more discussion the better. ExtendScript code will be easier to "translate" to FDK code because of their similarities. However, if you prefer scripting, then FrameScript is a good option for FrameMaker 9 and below.

                  • 6. Re: Convert an ExtendScript to FDK
                    trondk Level 1

                    Russ,

                     

                    Yes, that's the post Google sent me to.

                     

                    So I will download the FDK, but is the 2015 FDK compatible with the FM9 developer's kit? Are there any good documentation links to be found anywhere, or would learning by doing wrong again be just as quick?

                     

                    Must add that since FrameMaker is soon to be phased out by our sub-supplier, investing in even the low-cost FrameScript is more or less out of the question.

                     

                    Best regards

                    Trond

                    • 7. Re: Convert an ExtendScript to FDK
                      Wiedenmaier Level 3

                      Trond,

                      you can find FDK9 here Framemaker Developer Center | Adobe Developer Connection. (at the end of the page (Other Downloads).

                      There is an FDK Developer Guide and FDK Reference in doc folder.

                      Plan some time for getting started. There are a lot of Stones at the beginning, where you will stumble

                      Using FrameScript with FM9 or ExtendScript with higher versions is not a bad idea, if you need a quick solution

                      Markus

                      • 8. Re: Convert an ExtendScript to FDK
                        Russ Ward Level 4

                        Trond, if you do get Visual C++ installed and also the FDK9, I may be able to provide an empty solution fileset to get you started.

                         

                        Russ

                        • 9. Re: Convert an ExtendScript to FDK
                          trondk Level 1

                          Hi Markus and Russ.

                           

                          Thanks for all the great help in this case. We took the easy solution, We got our sub-supplier to send us the FrameMaker files so that I could run the ExtendScript in my trial version of FrameMaker. Then I exported the files to PDF and assembled them anew in an updated manual. So at the end of the day there was no need for the FDK, this time.

                           

                          But it certainly was fun to do exactly what our sub-supplier claimed could not be done.....

                           

                          Once again, thanks for all the help. You guys are awesome!

                           

                          Best regards

                          Trond