• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

First found item not replaced - random behaviour

Community Expert ,
Jul 07, 2015 Jul 07, 2015

Copy link to clipboard

Copied

Dear friends and experts

In my project I use a (minor) modification of Ian Proudfoot's find/replace script.
The find- and replace-strings are taken from global arrays (which are filled from an RTF file).
Randomly the first call of the function FindAndReplaceString does not find/replace the item in question.
A trace of the function calls gives these results (first few items only):

~~~~ReplaceInDoc
~~~~~~FindAndReplaceString
find = >{Bartels, 1981 #14}< replace = >[1]<
~~~~~~FindAndReplaceString
find = >{Daube, 1989 #6}< replace = >[2]<
   success
~~~~~~FindAndReplaceString
find = >{Daube, 2005 #15}< replace = >[3]<
   success

Since the whole script is far to long for a justification of the problem, I have set up a testprogram which defines the findreplce stings directly (the test file is here😞

/* use test file t-find-replace.fm
There must be a subtle differene to the real script environment:
This test exhanges all occurrances
In FM-bilbio.jsx only the secont-to-last item is found and replaced.
*/
var doc = app.ActiveDoc;
var flow = doc.MainFlowInDoc;             // collection would have been failed, if flow/frame invalid
var inString = ["{Daube, 2005 #15}", "{Müller, 1925 #13}", "{Sèsíüs,  #26}"];
var outString = ["[15]", "[19]", "[23]"];

for (j = 0; j < 3; j += 1) {
  FindAndReplaceString (doc, inString, outString, 100);
}


function FindAndReplaceString (activeDoc, findString, replaceString, loopMax) {
// FindText, ConsiderCase; Function returns replacemtCounter
// Since we have collected only in doc.MainFlowInDoc, we replace only in this flow
// loopMax used as emrgency back door - twice the # of initially found citations
// We do not have an initial TextSelection, hence start directly at the first para
// Source: https://forums.adobe.com/message/3888653#3888653 by Ian Proudfoot
Console ("find = >" + findString + "< replace = >" + replaceString + "<");
  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
//Set up 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;
  findParams[1].propVal.ival = Constants.FF_FIND_CONSIDER_CASE;

  FA_errno = Constants.FE_Success;                // errno global, to be used to track the progress of the find and replace
  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
    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
      replacementCounter++;
Console ("   success"); // <=== debugging ====================
    }
    FA_errno = Constants.FE_Success;              // ...  find the next instance. We'll reset FA_errno again just in case
    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
  return replacementCounter;
} // --- end FindAndReplaceString

And guess what?

  • opening the test-doc and running script => First item not found/replaced
  • opening the test-doc and running script => OK (all 3 items found/replaced)
  • opening the test-doc and running script => OK
  • opening the test-doc, efresh script in catalogue, run script => OK
  • opening the test-doc and running script => OK
  • opening the test-doc and running script => OK
  • After 3h of testing I'm tired now

I have not the slightest idea what may cause the random behaviour. Do You have any (the highest temparature sensed on the main board is 50°C  (122°F) - not that alarming).

TOPICS
Scripting

Views

227

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
no replies

Have something to add?

Join the conversation