Copy link to clipboard
Copied
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;
}
}
Copy link to clipboard
Copied
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...
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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;
}
Copy link to clipboard
Copied
Hello to all,
I know this is an old thread, but I'm just now getting around to trying this task myself and I am unsuccessful as you were. My script is very simple... just attempts to apply a single condition to several areas of text within a document. It does a few instances and then FM freezes, requiring the task manager to kill it (and it then crashes on the way out). I'm using Fm 10 on Windows 7. I've tried every which way of setting up the PropVal structure including simply retrieving it from a textloc that already has the desired condition... no joy.
If anyone found a solution, please let me know.
Thanks,
Russ
Copy link to clipboard
Copied
Hi Russ, This may be more of a FrameMaker 10 ExtendScript issue. I just mocked up a sample document of almost 2000 pages and ran a modified version of Anchal's code. It took awhile, but it worked in FrameMaker 11.
#target framemaker
var doc = app.ActiveDoc
var tr = doc.TextSelection
var newFmt = doc.GetNamedCondFmt("Comment");
var props = doc.GetTextPropVal(tr.beg,Constants.FP_InCond);
props.propVal.isval[0] = newFmt.id;
props.propVal.osval[0] = newFmt;
var pgf = doc.MainFlowInDoc.FirstTextFrameInFlow.FirstPgf;
while (pgf.ObjectValid()) {
tr = new TextRange ();
tr.beg.obj = tr.end.obj = pgf;
tr.beg.offset = 0;
tr.end.offset = Constants.FV_OBJ_END_OFFSET;
doc.SetTextPropVal(tr, props);
pgf = pgf.NextPgfInFlow;
}
Rick
Copy link to clipboard
Copied
@
Hi Anchal,
Here is the script that I am trying to run to traverse through the paragraph tags in the book files and check for a condition applied on them:
var openedBook = app.ActiveBook
//openBookFiles(openedBook)
//savePdf(openedBook,bookFile + ".pdf")\
var arr_ChapterIds=new Array();
var bookChapter=openedBook.FirstComponentInBook
var chapterId = bookChapter.id
var pgfText = null;
var msg = null;
var totalPgfs = 0;
/* Calculating the number of chapters in the book */
while(chapterId)
{
var chapterId = bookChapter.id
var chapterName = bookChapter.Name
chapterId=openFile(chapterName)
if(chapterId!=0 && chapterId!="")
{
arr_ChapterIds.push(chapterId)
}
bookChapter = bookChapter.NextComponentInBook;
chapterId = bookChapter.id;
}
// Err(arr_ChapterIds.length);
/*Processing the tasks for each chapter*/
for(i=0; i<arr_ChapterIds.length;i++)
{
var objcid=arr_ChapterIds;
cid=objcid.id;
cname=objcid.Name;
/* Traversing through the paragraphs*/
var pgf = objcid.MainFlowInDoc.FirstTextFrameInFlow.FirstPgf;
while(pgf.ObjectValid() == true)
{
totalPgfs = totalPgfs + 1;
var formatName = pgf.Name;
var textRange = new TextRange();
textRange.beg.obj = pgf;
textRange.beg.offset = 0;
textRange.end.obj = pgf;
textRange.end.offset = Constants.FV_OBJ_END_OFFSET;
var textItems = objcid.GetTextForRange(textRange, Constants.FTI_String);
if(textItems.length > 0)
{
pgfText = textItems[0].sdata;
if(pgfText.length > 50)
pgfText = pgfText.substring(0, 50);
}
else pgfText = "(No text!)";
if(pgf.Name=="Related_Topics" && textItems.length>0)
{ Err ("Related Topics tag is applied for:"+pgfText+"\n\n");}
pgf = pgf.NextPgfInFlow;
}
var getChangeBarVal=objcid.AutoChangeBars;
if (getChangeBarVal==1)
Err("Change Bars are on for:"+cname+"\n\n");
else
Err("Change Bars are off for:"+cname+"\n\n");
}
function openFile(chapterName)
{
openProp = GetOpenDefaultParams()
retParm = new PropVals()
fileOpen=Open(chapterName,openProp,retParm)
return fileOpen;
}
This script runs fine for the first time and displays the result on the FrameMaker console. However, here are the issues that I am facing:
There are many paragraph tags that the script traverses through and probably stores in a variable. Therefore, I think it may be a memory issue.
Can you please go through the script and help me in debugging the issue. Thanks.
Regards,
Bhavna
@