Skip to main content
Participant
October 27, 2011
Question

Applying a condition to a paragraph

  • October 27, 2011
  • 2 replies
  • 3057 views

Greetings,

I want to iterate through all paragraphs in a document and for each paragraph with the "comment" style, I want to apply an existing condition called "Comment" (as per p. 126 of the FDK Programmer's Guide)

The script below iterates, selects the correct text, but it doesn't apply the condition.  I suspect I am not adding the correct information to the condid variable. I've tried adding the object or just the Id integer value of the condition without success.

If I apply the condition manually to a paragraph and then run a script to look at the property values, Framemaker seems to apply the condition object to "osval" which is different than what the FDK states (isval).  And, of course, "osval" seems to be undocumented. So, I'm stumped on what Frame is expecting.

I'd appreciate any pointers.

Thanks.


#target framemaker

if (app.ActiveDoc.ObjectValid()) {
    processDoc(app.ActiveDoc);
}
else{
    Alert("No doc open");
}

function processDoc(doc) {
 
    var txtFrame= doc.MainFlowInDoc.FirstTextFrameInFlow;
    var pgf = txtFrame.FirstPgf;
   
    var CondObj=doc.GetNamedObject(Constants.FO_CondFmt,"Comment");
     
   
    while (pgf.ObjectValid()){

        var stylename="Comment";
        var paraname=pgf.Name;
        if (paraname == stylename){

          //get text selection for paragraph
            var tr = new TextRange();               
            tr.beg.obj = tr.end.obj = pgf;
            tr.beg.offset = 0;
          //Retrieve the text from the paragraph
            var txtstring = "";
            var textItems = pgf.GetText(Constants.FTI_String | Constants.FTI_LineEnd);
            for (var i = 0; i < textItems.len; i += 1) {
                txtstring += (textItems.sdata);
            }
          //Get length + line end          
            tr.end.offset = txtstring.length+1;
          // set text selection
            doc.TextSelection = tr;

          // Set up the Condition object          
            var condid = new Ints();
            condid.push(CondObj);
           
          // Create the properties and apply to the selection
            var newprops = AllocatePropVals(1);
            newprops[0].propIdent.num = Constants.FP_InCond;
            newprops[0].propVal.valType = Constants.FT_Ints;
            newprops[0].propVal.isval = condid;          

            FA_errno = Constants.FE_Success;
            doc.SetTextPropVal(tr, newprops);
           
            if (FA_errno != Constants.FE_Success){
                $.writeln ("Error : " + FA_errno);
            }
        }
        pgf=pgf.NextPgfInFlow;
    }

}

This topic has been closed for replies.

2 replies

April 16, 2013

Hi -

Can anyone apply a condition to a textrange? Like everyone else (evidently), doing so causes FM  to crash every time. Seems as if this would be an scripting task that is rather common, and it's hard to believe that Adobe hasn't fixed it (or educated the community on what we're doing wrong).

Using FM 10 and ESTK in Windows 7. I can sometimes see the condition being applied to the textrange just before FM dies, but no fiddling with the PropVal object yields any other result and the documentation is very much lacking.

Thanks.

Inspiring
February 20, 2014

Hello All,

This is the script that I use for applying condition tag to a paragraph, and it is not leading to crash in my case. Can anyone of you pls share your complete script so that we can take a look into the issue and try to fix it. I have tried the code snippet shared by Oliver and that too is working fine in my case.

doc=app.ActiveDoc

tr= doc.TextSelection

newFmt =doc.GetNamedCondFmt("Comment")

var props = doc.GetTextPropVal(tr.beg,Constants.FP_InCond)

props.propVal.isval[0] = newFmt.id

props.propVal.osval[0] = newFmt

doc.SetTextPropVal(tr, props)

Thanks,

Anchal Arora

Adobe Framemaker Engineering

February 20, 2014

Here is what I'm using that crashes FM...intended to loop through a doc and change existing condition (PrevTag) to a condition that has been detected in the document (NewTag):

function ChangeAllTextCondition(CurrDoc, PrevTag, NewTag) {
    var currPgf = CurrDoc.FirstFlowInDoc.FirstTextFrameInFlow.FirstPgf;       
    var oldFmt = CurrDoc.GetNamedCondFmt(PrevTag.Name);
    var newFmt = CurrDoc.GetNamedCondFmt(NewTag.Name);       
   
    var cTextLoc = new TextLoc(currPgf,0);   
    var cPropVal = allocatePropertiesCR(PrevTag.Name);
   
    var cTextRange = CurrDoc.Find(cTextLoc, cPropVal);   
    while (FA_errno == 0 && !CF_isInReferenceOrHiddenPageOrMasterPageCR(cTextRange.beg)) {  
        var cTextItems = CurrDoc.GetTextForRange (cTextRange, Constants.FTI_String);
        var counter = 0;
        while (counter < cTextItems.length) {
            var changed = 0;
            var temptr = new TextRange;
            temptr.beg.obj = cTextRange.beg.obj;
            temptr.end.obj = cTextRange.end.obj;
            temptr.beg.offset = cTextItems[counter].offset;
            if (counter != cTextItems.length-1) {
                temptr.end.offset = (cTextItems[counter+1].offset);
                }
            else if (counter == cTextItems.length-1) {
                temptr.end.offset = cTextRange.end.offset;
                }
                           
            var tempLoc =new TextLoc(cTextRange.beg.obj, cTextItems[counter].offset);
            var props = CurrDoc.GetTextPropVal(tempLoc, Constants.FP_InCond);
                        
            if (props.propVal.isval.length > 0) {
                var count = 0;    
                var propLength= props.propVal.isval.length;
                while (count < propLength) {
                    if (props.propVal.osval[count].id == oldFmt.id) {
                        props.propVal.isval[count] = newFmt.id;
                        props.propVal.osval[count] = newFmt;
                        changed = 1;
                        break;
                        }
                    }

                if (changed) {   
                    var result = CurrDoc.SetTextPropVal(temptr, props);   
                    }
                }
            cTextLoc = cTextRange.end;
            cTextRange = cCurrDoc.Find(TextLoc, tempPropVal);
            }
        }
  return
}


/*This functions returns whether a location is in which page*/
function CF_isInReferenceOrHiddenPageOrMasterPageCR(textLoc) {
    var pageType = CF_getTextLocPageTypeCR(textLoc);   
return ( pageType == Constants.FO_RefPage) ||
   (pageType == Constants.FO_HiddenPage) ||
            (pageType == Constants.FO_MasterPage);
}


function allocatePropertiesCR(iniTag) {
        var tempPropVal = new PropVal;
        tempPropVal = AllocatePropVals(1);
        tempPropVal[0].propIdent.num = Constants.FS_FindCondTextInCondTags;
        tempPropVal[0].propVal.valType = Constants.FT_Strings;
        tempPropVal[0].propVal.ssval[0]= iniTag;
        return tempPropVal;
}


function CF_getTextLocPageTypeCR(textLoc) {
var inPageType = Constants.FO_Bad;
if(textLoc.obj.ObjectValid()) {
  var parentFrame = textLoc.obj.InTextFrame;
  var parentType = parentFrame.type;
 
  while(parentType != Constants.FO_BodyPage
   && parentType != Constants.FO_MasterPage
   && parentType != Constants.FO_HiddenPage
   && parentType != Constants.FO_RefPage) {
   var oldParentFrame = parentFrame;
   parentFrame = parentFrame.FrameParent;
  
   if(!parentFrame.ObjectValid()) {
    parentFrame = oldParentFrame.PageFramePage;   
    if(!parentFrame.ObjectValid())
     break;
                }  
   parentType = parentFrame.type;
            }
  inPageType = parentType;
        }
return inPageType;
}

November 1, 2011

I've been playing around with this puzzle off and on, and can report some moderate progress.

The osval type refers to objects, but interacting with it seems buggy.

Rather than allocating a new property, I tried the approach of retrieving and modifying an existing structure:

...

               // set text selection

               doc.TextSelection = tr;

               // Retrieve the existing Condition property

               condProp = doc.GetTextPropVal(tr.beg,Constants.FP_InCond)    

               // Add the new condition to the property

               condProp.propVal.osval.push(CondObj);

               // Strange behavior happens here

               $.bp();

               FA_errno = Constants.FE_Success;

               doc.SetTextPropVal(tr, condProp);

...

The "strange behavior" was FrameMaker becoming completely non-responsive and requiring a forced quit if I omitted the break point. With the break point there, however, the script was successful in changing the conditional state of the target paragraph. Of course, a script that needs to stop repeatedly to work isn't much use, but a least it's a step in the right direction...

Participant
November 2, 2011

I appreciate you taking a look at the problem, and I'm pleased I wasn't missing something obvious in my code.

Your suggested code will sometimes work fine on my system, both with the breakpoint code and without it; however, in both cases, it eventually crashes framemaker if the script is run often enough.

I suspect this is something Adobe needs to fix in a patch.

Thanks.

Participant
November 1, 2012

Does anyone know if this has been patched? I am having the same issue. Script works fine at first. But after repeated runs, the script crashes FrameMaker. The SetTextPropVal method is causing the crash.

Thanks.