Copy link to clipboard
Copied
I build an array of acronyms in the document's acronym glossary and use the getFind function below to search the document to see if the acronym is used and how many times it's used (findCtr++). I'm running into some cases where the getFind function goes into an endless loop looking for specific words in specific documents. This might happen with just four words in a document, or sometimes dozens of words. The loop is 100% repeatable. I believe I need to move the textRange.beg to the end of the "find" word each time a match is found, but I'm not familiar enough with ranges to know how to do it. Appreciate any suggestions.
function getFind(findString, considerCase, docName) {
doc=app.ActiveDoc; //sets the active document as the object
docStart = doc.MainFlowInDoc.FirstTextFrameInFlow.FirstPgf;
textRange = app.ActiveDoc.TextSelection;
findParams = AllocatePropVals (5);
propVal = new PropVal ();
propVal.propIdent.num = Constants.FS_FindText;
propVal.propVal.valType = Constants.FT_String;
propVal.propVal.sval = findString;
findParams[0] = propVal;
propVal = new PropVal ();
propVal.propIdent.num = Constants.FS_FindCustomizationFlags;
propVal.propVal.valType = Constants.FT_Integer;
if (considerCase) {
propVal.propVal.ival = Constants.FF_FIND_CONSIDER_CASE;
} else {
propVal.propVal.ival = 0; }
findParams[1] = propVal;
propVal = new PropVal ();
propVal.propIdent.num = Constants.FS_FindCustomizationFlags;
propVal.propVal.valType = Constants.FT_Integer;
propVal.propVal.ival = 16; // Regular expressions (per RQ)
findParams[2] = propVal;
propVal = new PropVal ();
propVal.propIdent.num = Constants.FS_FindWrap;
propVal.propVal.valType = Constants.FT_Integer;
propVal.propVal.ival=0;
findParams[3] = propVal;
propVal = new PropVal ();
propVal.propIdent.num = Constants.FS_RegexFlavour;
propVal.propVal.valType = Constants.FT_Integer;
propVal.propVal.ival = Constants.FR_USE_PERL; //1;
findParams[4] = propVal;
textRange = doc.Find(textRange.beg, findParams);
checkAcronyms();
}
function checkAcronyms() {
while (textRange.beg.obj.ObjectValid() && FA_errno == Constants.FE_Success) {
var find = getText (textRange, doc) // Matching acronym found
if (find.length > 0) {
findCtr++; // Count times word is found
}
textRange = doc.Find(textRange.beg, findParams);
}
return;
}
I used to see this when I first started scripting with FrameScript. So I never felt comfortable trusting the Find method. My way of doing it is to loop through the body page paragaphs, and for each paragraph, get the text and use a regular expression to search the text. If I actually need to manipulate the text, then I use doc.Find (), starting with a TextLoc of the paragraph and offset of the found text. I don't have time to post code right now, but will try to tomorrow.
Copy link to clipboard
Copied
It's my guess, that
textRange = doc.Find(textRange.beg, findParams);
Does not advance the start point for the next search and you always find the same item..
(I have not access to my own search scripts now to give a better advice).
Copy link to clipboard
Copied
Thanks Klaus for confirming my suspicion. I have a couple of your search scripts I'll look over and see if I can figure out how to advance the start point after each search. I suspect that would also speed up my searches.
Copy link to clipboard
Copied
If you want to stay with the Find method:
Russ Ward created the term "lets jimmy the text range" in his post. Although his post is for replacement, the method to go forward is the same for searching.
tr.beg.offset += sFound.length; // lets jimmy the text range in memory
Copy link to clipboard
Copied
Thansk Klaus...I think 'jimmying the text range' is what I'm looking for, but after adding the line of code my script runs slower and has same endless loops. I may not be doing it right and will play around with this later today. Many thanks for the link to Russ Ward's post...the comments are a good tutorial on find/replace and manipulating the text ranges.
Copy link to clipboard
Copied
You may already have the answer, but if not, also look for any possible looping structures in the document itself: circular Xrefs, Text Insets with refs to the importing doc, etc.
FM does not try to prohibit these, and generally avoids its own ∞loops by doing only one pass per Update click.
Copy link to clipboard
Copied
Bob, thanks for tip on searching for looping structures. I tried that using Insert > Index > Of References, but it came up blank. In one book, the only place I have a problem is the LOT document. I updated the book, to include the LOT, but still no luck. In that book, it only goes into an endless loop on four out of 322 search words, all four of which are found once or twice in the LOT. In another book, the endless loops occur in one of the chapter documents and involve about 25 words. I haven't checked that chapter for cross references yet...but will.
Copy link to clipboard
Copied
I used to see this when I first started scripting with FrameScript. So I never felt comfortable trusting the Find method. My way of doing it is to loop through the body page paragaphs, and for each paragraph, get the text and use a regular expression to search the text. If I actually need to manipulate the text, then I use doc.Find (), starting with a TextLoc of the paragraph and offset of the found text. I don't have time to post code right now, but will try to tomorrow.
Copy link to clipboard
Copied
Thanks Rick...I've thought about your method of searching by pgf since we spoke last year, and have often considered trying to implement it. However, I have two concerns. I currently search for over a thousand words & terms, running the entire search list one time for each document. Doing it pgf by pgf, I'd have to run the entire search list for each pgf. Wouldn't that increase processing time considerably. Also, will it search tables natively, or would a separate cell by cell search function need to be run. One possible advantage of my current search method is that it searches tables & pgfs without a separate function. I'm certain your method is more reliable and I certainly appreciate any code you have time to share.
Copy link to clipboard
Copied
I am uploading a series of videos to YouTube that explain how I do finds/changes with FrameMaker ExtendScript. The videos aren't edited or polished, but they will give you useful information. Search for FindChange with FrameMaker ExtendScript on YouTube. I will upload more later today.
Get ready! An upgraded Adobe Community experience is coming in January.
Learn more