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?
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).
Have something to add?