Skip navigation
Currently Being Moderated

Searching within a book using ExtendScript

Aug 14, 2013 4:18 PM

Tags: #extendscript #framemaker_11

I'm having trouble using ExtendScript to search through all the chapters in my book for a text string. The code I've posted does find the first instance of the search string in the document, but my attempt to reposition the starting point of the search beyond the text that was just found is unsuccessful (tloc = new TextLoc(foundText.end.obj, foundText.end.offset + 1);) Instead the repeated calls to "Find" in the loop keep highlighting the first instance instead of incrementally moving throughout the document.

 

var book = app.ActiveBook;


var comp=book.FirstComponentInBook;


while(comp.ObjectValid())
{

        //alert (comp.Name);


        doc = open(comp.Name);

        if (doc.ObjectValid() )
        {
            findAndChange(doc);
        }

        comp = comp.NextBookComponentInDFSOrder;
 }


function findAndChange(doc) {


    var docStart = doc.MainFlowInDoc.FirstTextFrameInFlow.FirstPgf ;
    var tloc = new TextLoc(docStart, 0);


    var searchString = "StringToFind";


    // setup find parameters
    findParams = AllocatePropVals(1);
    findParams[0].propIdent.num = Constants.FS_FindText; 
    findParams[0].propVal.valType = Constants.FT_String;
    findParams[0].propVal.sval = searchString;


    foundText = doc.Find(tloc, findParams);


    while (foundText.beg.obj.ObjectValid()) {

            //alert(foundText.end.offset);

            //do stuff to found text




            //end do stuff to found text

            tloc = new TextLoc(foundText.end.obj, foundText.end.offset + 1);

            foundText = doc.Find(tloc, findParams);    // this call keeps finding the first match in the document!
    }  

}


function open(filename)
{
    openProp = GetOpenDefaultParams();


    i=GetPropIndex(openProp,Constants.FS_FileIsOldVersion);
    openProp[i].propVal.ival=Constants.FV_DoOK;


    i=GetPropIndex(openProp,Constants.FS_FontNotFoundInCatalog);
    openProp[i].propVal.ival=Constants.FV_DoOK;


    i=GetPropIndex(openProp,Constants.FS_FontNotFoundInDoc);
    openProp[i].propVal.ival=Constants.FV_DoOK;


    i=GetPropIndex(openProp,Constants.FS_FileIsInUse);
    openProp[i].propVal.ival=Constants.FV_DoCancel;


    i=GetPropIndex(openProp,Constants.FS_AlertUserAboutFailure);
    openProp[i].propVal.ival=Constants.FV_DoCancel;


    retParm = new PropVals();
    docOpen=Open(filename,openProp,retParm);


    return docOpen;
}



 

[Discussion moved to FM Scripting Forum by Host]

 
Replies
  • Currently Being Moderated
    Aug 14, 2013 5:17 AM   in reply to hunter.stern@autodesk.com

    You know that there’s a dedicated Scripting forum - http://forums.adobe.com/community/framemaker/extendscript?view=overvie w where you might get a faster response?

     
    |
    Mark as:
  • Currently Being Moderated
    Aug 14, 2013 5:23 AM   in reply to hunter.stern@autodesk.com

    Hi Hunter (?)

     

    I tried out your code on FM11 and it worked great! So you have no problems!

     

    In all seriousness, I did try it and it worked fine and I was not surprised, because it looks fine. I placed three instances of the string into a document and it found them as expected. I added this to your code after " //do stuff to found text" to visually verify:

     

     

       doc.TextSelection = foundText;

       doc.ScrollToText (foundText);

       if(!confirm("Keep going?")) return;

     

    So the obvious question is... are you absolutely sure? Are you doing something to the text after you find it, something that might whack out the paragraph structures/offsets/etc. that confuses the search?

     

    A couple of other notes:

     

    I don't think you need both of these lines, although they work:

     

      tloc = new TextLoc(foundText.end.obj, foundText.end.offset + 1);

      foundText = doc.Find(tloc, findParams);

     

    I think this line will suffice instead:

     

      foundText = doc.Find(foundText.end, findParams);

     

    Also, I augmented the find parameters so that it stops after the last match:

     

        findParams = AllocatePropVals(2);

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

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

        findParams[0].propVal.sval = searchString;

     

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

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

        findParams[1].propVal.ival = false;

     

    With that, you have to add another conditional to the while():

     

      while (foundText.beg.obj.ObjectValid() && FA_errno == Constants.FE_Success) {

     

    Let me know what you think about all this. I'm sure there is a solution here and it probably isn't too complex.

     

    Russ

     

    Message was edited by: Russ Ward (Accidentally submitted too soon!)

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points