Skip to main content
rombanks
Inspiring
May 30, 2015
Answered

Find chars/strings with a certain condition applied

  • May 30, 2015
  • 1 reply
  • 2382 views

Hello fellows,

I am writing an extendscript that is supposed to loop through all pgfs and find all characters/strings with a certain condition applied (let's say, Comment).

The problem is that in the scripting guide, I could not find a function that retrieves the condition property of a character. I tried using the JS "charAt(i)" function, but it does not seem to work in ES. Any idea how to implement such a function?

Below is the 1st draft of the script.

var doc = app.ActiveDoc;

if doc.ObjectValid() {

    checkCondFMt(doc);

}

else{

  Alert("No section open");

}

function checkCondFMt(doc) {

    var pgf = doc.MainFlowInDoc.FirstTextFrameInFlow.FirstPgf;

    var CondObj=doc.GetNamedObject("Comment");

     while (pgf.ObjectValid()){

                     

               var textItems =pgf.GetText(Constants.FTI_String | Constants.FTI_LineEnd);

                var tr = new TextRange();            

                tr.beg.obj = tr.end.obj = textItems;

                tr.beg.offset = 0;

                 for (var i = 0; i < tr.len; i++ ) {

                  var c = tr.charAt(i);             

                  var PgfProps =doc.GetTextVal(c, Constants.FO_CondFmt);

                  alert (PgfProps.Name);

           }

                

        pgf=pgf.NextPgfInFlow;

    }

}

Thank you for your input in advance!

This topic has been closed for replies.
Correct answer frameexpert

Hi Rick,

I think I found what drives FM crazy when running the script.

FM gets stuck when the string(s) with the condition we are searching for have additional conditions applied.

If only the condition specified in the script is applied to the string (in this case, Comment), then the script works OK.

I guess, this issue has something to do with Constants.FTI_CharPropsChange, but I am not sure.


Thanks again,

Roman


OK, I see the problem now. JavaScript does not have "block-scope" for its variables. It has function scope, so your "i" variable is being used in more than one loop. You should use a different variable for the inner loop:

for (var j = 0; j < oCond.length; j += 1) {

    if (oCond.Name == CondObj.Name) {

        applyCharFmt(textRange, doc);

    }                    

}

In the code sample above, I am using "j" for a counter for the inner loop.

In general, you can avoid problems like this by declaring all of your variables at the top of the function:

function functionName (param1, param2) {

    var i, j, textlist; // etc.

    // function code...

}

That makes it easier to "keep track" of the variables and make sure you are not using any more than once.

-Rick

1 reply

frameexpert
Community Expert
Community Expert
June 1, 2015

Roman, I have a 4-part post on my blog about removing conditions from text and table rows. Here is a link to the first one:

Removing Conditions From Text and Table Rows | FrameAutomation.com

-Rick

www.frameexpert.com
rombanks
rombanksAuthor
Inspiring
June 1, 2015

Hi Rick,

Thank you for your response and for a very useful and informative post!

In my specific case, I need to loop through all Pgfs and find all strings/characters to which the Comment condition is applied. My next step will be applying a char tag to those conditionalized strings/chars.

What I am trying to figure out is how to isolate the condtionalized strings and single characters in a Pgf. I found a JS function called "substr" or "substring" for isolating a range of chars and looping through them. Is this the one you would use?

Thanks again,

Roman

frameexpert
Community Expert
Community Expert
June 1, 2015

This is the part of the series I never got to :-). The following function will loop through all of the text in the selected paragraph and find each text range that has one or more conditions applied. You should be able to combine this with some of the code in my blog to test for a specific condition. Once you have the appropriate textRange, you should be able to apply a character format. Please let me know if you have any questions or comments.

#target framemaker

var doc = app.ActiveDoc;
var pgf = doc.TextSelection.beg.obj;

processConditions (pgf, doc);

function processConditions (pgf, doc) {

    var end = Constants.FV_OBJ_END_OFFSET, begin = 0, textRange = 0, prop;
   
    var textList = pgf.GetText(Constants.FTI_CharPropsChange);
    for (var i = textList.length - 1; i >= 0; i -= 1) {
       if (Constants.FTF_CONDITIONTAG & textList.idata) {
           begin = textList.offset;
            if (begin !== end) {
                textRange = new TextRange (new TextLoc (pgf, begin), new TextLoc (pgf, end));
                prop = doc.GetTextPropVal (textRange.beg, Constants.FP_InCond);
                if ((prop.propIdent.num) && (prop.propVal.osval.length !== 0)) {
                    alert (getText (textRange, doc));
                }
            }
            end = begin;
        }
    }
    if ((end < Constants.FV_OBJ_END_OFFSET) && (end > 0)) {
        textRange = new TextRange (new TextLoc (pgf, 0), new TextLoc (pgf, end));
        prop = doc.GetTextPropVal (textRange.beg, Constants.FP_InCond);
        if ((prop.propIdent.num) && (prop.propVal.osval.length !== 0)) {
            alert (getText (textRange, doc));
        }
    }   
}

function getText (textObj, doc) {
    // Gets the text from the text object.

    var text = "";
    // Get a list of the strings in the text object or text range.
    if (textObj.constructor.name !== "TextRange") {
        var textItems = textObj.GetText (Constants.FTI_String);
    } else {
         var textItems = doc.GetTextForRange (textObj, Constants.FTI_String);
    }
    // Concatenate the strings.
    for (var i = 0; i < textItems.len; i += 1) {
        text += (textItems.sdata);
    }
    return text; // Return the text
}

www.frameexpert.com