Skip to main content
K.Daube
Community Expert
Community Expert
September 25, 2018
Question

Find/Replace behaving erratically

  • September 25, 2018
  • 0 replies
  • 300 views

Dear friends and experts

In my script FM-biblio the following is a key task:

  • An RTF file contains lines with the search and the replace strings:

  {Daube 1989 #9}»(Daube 1989)

  The » denotes a TAB

  • For every line in the RTF:
    •   Set up the Find parameters (using the search string)
    •   Find and replace as long as successful (Russ Ward method)

The whole script was developed in FM-13 times (and you find a lot of discussion about it in this forum). Now with FM-14 the Find/Replace loop turns out to be a vabanque game.

My test document is just two pages with 18 search items (some occur multiple times) and i have 11 replace items in the RTF.

The first item in the RTF is often not replaced in the FM doc.

I can repeat the find-replace step of the script multiple times. Sometimes I need to do so 3 times until also the first item is processed (revert to saved between the trials).

➔ What can be the reason for this behaviour? Timing?

For my extensive test series I did not change anything on the script. It is located in %UserProfile%\Docuemnts\Adobe Scripts\

Starting with FM-15 I saved the document as MIF and did the tests 3 times.

FM-15:  Of 3 trials 1 successful; FM-14 3/1; FM-13 3/1; FM-12 3/2; FM-11 3/3; FM-10 3/3

These tests 'mifed down' the document from FM-14 to FM-10, hence removing a lot of not used stuff. And now I repeted the tests:

In all FM-versions up to FM-15 success is 3 of 3!

➔ The more complex the FM file, the less reliable the Find/Change function.

But something else bothered me during the tests: sometimes I got error messages in the log:

"undefined is not an object" on script line 193, which reads

  var inputFile, prompt, docFile;

Then I just restarted FrameMaker and tried agian: No message then...

➔ ExtendScript is not reliable at all.

➔ How to conquer such obstacles?

I have added here only the find/replace function and the function setting up the find parameters:

function FindAndReplaceString (activeDoc, findString, replaceString, loopMax) { //=================

// Replace string by another

// Function returns replacemtCounter

// Since we have collected only in doc.MainFlowInDoc, we replace only in this flow

// loopMax used as emergency back door - twice the # of initially found citations

// We do not have an initial TextSelection, hence start directly at the first paragraph

// Source: Russ Ward in https://forums.adobe.com/message/3888653

  giFMbib_LvlTrace += 1; ZTrace ("FindAndReplaceString");

  var tr = new TextRange();

  var restoreTR, frame = 0, loopCounter = 0, replacementCounter = 0;

  var findParams = new PropVals();

  var firstPgf = activeDoc.MainFlowInDoc.FirstTextFrameInFlow.FirstPgf;

 

  tr.beg.obj = tr.end.obj = firstPgf;             // set up the starting text range as the very beginning

  tr.beg.offset = tr.end.offset = 0;              // of the flow. We'll move straight from beginning to end.

  trSaved = tr                                    // to come back after work

//We don't need the find to wrap because we are controlling the flow from beginning to end.

  findParams = GetFindParams (findString);        // Get the find parameters for finding string, case sensitive

  InitFA_errno ();                                // reset - it is write protected

  tr = activeDoc.Find(tr.beg, findParams);        // and do an initial find to get started.

 

  while(FA_errno === Constants.FE_Success && loopCounter++ < 2*loopMax) { //find and replace loop as long as we keep finding

ZLog ("   Replacement = «" + replaceString + "»")

    activeDoc.TextSelection = tr;                 // set up the text range to clear the original text

    activeDoc.Clear(0);                           // clear it

    activeDoc.AddText(tr.beg, replaceString);     // insert the new text at the original beginning of the text range

    tr.beg.offset += replaceString.length;        // 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.

    if(FA_errno === Constants.FE_Success) {       // increment our return counter - does not work

      replacementCounter++;

    }

    InitFA_errno ();                              // to be used to track the progress of the find and replace

    tr = activeDoc.Find(tr.beg, findParams);      // something screwy happened while we were replacing text.

  }

  activeDoc.ScrollToText(trSaved);                // we're done. Restore the document to it's original area of display

  giFMbib_LvlTrace -= 1;

  return replacementCounter;

} // --- end FindAndReplaceString

function GetFindParams (string) { //===============================================================

// Get/set the find parameters

// Returns find parameters in the function

// Consider string, case;

// Source; Rick Quatro

  if (gbFMbib_Verbose) {giFMbib_LvlTrace += 1; ZTrace ("GetFindParams");}

  var findParams = AllocatePropVals (2); 

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

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

  findParams[0].propVal.sval = string; 

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

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

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

  if (gbFMbib_Verbose) {giFMbib_LvlTrace -= 1;}

  return findParams; 

} // --- end GetFindParams

This topic has been closed for replies.