Skip navigation
Currently Being Moderated

How do I use the find method to find multiple items in a single paragraph?

Feb 17, 2012 3:21 PM

I am desigining a script to find any instances where ctrl+b and ctrl+i are applied to body text and then replace those character format overrides with Italic or Bold chartag.  Here's what the script is supposed to do:

 

  1. put the find method in a while loop that searches for character format overrides.
  2. If a character format override is found, pass the text range returned by the find method and the CharPropsChange flag to the GetTextForRange method.
  3. Use a boolean compare between the idata of the text item to the character angle and character weight constants.
  4. Whichever boolean evaluates to true, then use the SetTextProp method to set properties of the text range to the properties of the italic or bold character tag.

 

This script does work on the first character format override found however it ignores any other overrides in the same paragraph. The cause of this is that the while loop updates the text loc that the find method uses to the next paragraph in flow. I suspect that i need to add an inner loop that goes through all the text in a single paragraph, where at teach iteration the text loc used by the find method is based on the same paragraph but the offset is modified. I am just not sure how to do that.

 

 

function removeOverrides (pDoc)

{

    var vDocStart = pDoc.MainFlowInDoc.FirstTextFrameInFlow.FirstPgf;

    var vBoldFmt=getCharFmt (pDoc, 'Bold')

    var vItalicFmt=getCharFmt (pDoc, 'Italic')

    initFA_errno ();

    while (FA_errno==Constants.FE_Success)

    {

        var vTextLoc = new TextLoc(vDocStart,0);

        var vFindParams=findOverrideParams (pDoc);

        var vTextRange=pDoc.Find(vTextLoc,vFindParams);

        if (vTextRange.beg.obj.ObjectValid())

        {

            var vTextItems=pDoc.GetTextForRange (vTextRange, Constants.FTI_CharPropsChange)

            if (vTextItems.length==!0 )

            {

                if (vTextItems[0].idata==Constants.FTF_WEIGHT)

                {

                   pDoc.SetTextProps (vTextRange, vBoldFmt.GetProps())

                    }

                if (vTextItems[0].idata==Constants.FTF_ANGLE)

                {

                   pDoc.SetTextProps (vTextRange, vItalicFmt.GetProps())

                    }

                } else (Log (vLogFileName, '\nERROR: No items were found in the text format array but format override was found: '+pDoc.Name))

            }

        vDocStart=vDocStart.NextPgfInFlow;

        } 

}

 

 

 

function findOverrideParams (pDoc)

{

    var vFindParams = AllocatePropVals(1);

    vFindParams[0].propIdent.num = Constants.FS_FindObject;

    vFindParams[0].propVal.valType = Constants.FT_Integer;

    vFindParams[0].propVal.ival = Constants.FV_FindCharacterFormatOverride;

   return vFindParams;

   }

 
Replies
  • Currently Being Moderated
    Feb 17, 2012 4:04 PM   in reply to jaloren28

    have you tried moving backward through the document.

    I don't know if this works for that case but in similar cases, where I delete things in a document, that worked for me

    Markus

     
    |
    Mark as:
  • Currently Being Moderated
    Feb 17, 2012 5:13 PM   in reply to jaloren28

    Another approach (which is what I've usually done) is after the first search to set vTextLoc = vTextRange.end

     

    Either way, you might consider moving your initializing of vTextLoc and vFindParams outside of the while loop. The parameters don't change, why redefine them for each search?

     
    |
    Mark as:
  • Currently Being Moderated
    Feb 21, 2012 10:18 AM   in reply to jaloren28

    In general, using the Find method to locate FrameMaker objects is not the best way to go. I have written thousands of FrameScript scripts since 1998, and have probably used Find less than a dozen times. To find tables, you can simply loop through the tables in the document. Or, you can use GetTextItems to get the tables from the main flow in document order. To locate character formatting, you can use GetTextItems on a paragraph to get the character property changes. This takes a bit more code than Find, but it is definitely more reliable and you don't have to manage text ranges and wrapping issues.

     

    Rick

     
    |
    Mark as:
  • Currently Being Moderated
    Feb 21, 2012 10:52 AM   in reply to jaloren28

    Hi Joe,

     

    Here is some code that will find each table in the document's (doc) main text flow. For each table, it will call a processTable function (which you would define). In my post, I referred to GetTextItems, but the method is actually called GetText. Most text objects like paragraphs, flows, text frames, etc., have a GetText method.

     

    var flow = doc.MainFlowInDoc;
    var textItems = flow.GetText(Constants.FTI_TblAnchor);
    for (var i = 0; i < textItems.len; i += 1) {
      tbl = doc.GetUniqueObject(Constants.FO_Tbl, textItems[i].obj.Unique);
      processTable(tbl, doc);
    }

     

    Rick

     
    |
    Mark as:
  • Currently Being Moderated
    Oct 29, 2012 11:55 AM   in reply to jaloren28

    There is something I've noticed about Constants.FV_OBJ_END_OFFSET. Instead of a reasonable number, for example, 57, it seems to be a long number like 1342177280.

     

    Is this expected? If not, could it be causing FM to crash after setting a text range?

     

    Thanks,

     

    Jason

     
    |
    Mark as:
  • Currently Being Moderated
    Oct 29, 2012 12:17 PM   in reply to Jason L-S

    Constants.FV_OBJ_END_OFFSET is the last position of a textrange (text location).

    This is expected. I used it several times in ES and FDK progamming, with no issues

    Markus

     
    |
    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