Copy link to clipboard
Copied
Dear experts,
To be able to navigate to any variable in the document (used on any page type) I first collect all information about the variables. The arry elements are built by the prototype function (is this the correct term?)
function oVariable (sName, sContents, oVar, bUsed, bSystem, oTr, sPageType, iPageNr, sPageName) {
this.Name = sName; // Name of variable
this.Contents = sContents; // Contents of variable
this.VarObj = oVar; // Var object in document
this.VarUsed = bUsed; // User var is used in document
this.IsSystem = bSystem; // true for system variable
this.TextRange= oTr; // textrange of this occurance in the doc
this.PageType = sPageType; // BodyPage or ... where var was found
this.PageNr = iPageNr; // for BodyPage
this.PageName = sPageName; // for the other types
} //--- end oVariable
In a loop through the variables I fill the global array of objects, which works fine.
For the following don't worry about the goFMc prefix: it is the name of the global object holding all stuff.
function GetVarsInDoc (oDoc) { //=== Fill the doc variables array with all found vars in Doc ======
var bIsSystem, bIsUsed, oPage, oTR, oVar, index, iPageType, sPageType, sVarName, sVarContents;
goFMc.aDocVars.length = 0; // clear array for new build up
oVar = oDoc.FirstVarInDoc; // the variable in the text
while (oVar.ObjectValid()) {
sVarName = oVar.VarFmt.Name; // name of the variable
sValue = oVar.VarFmt.Fmt; // contents of variable
oTR = oVar.TextRange; // the text range of the variable
bIsSystem= (oVar.VarFmt.SystemVar !== Constants.FV_VAR_USER_VARIABLE);
bIsUsed = UsrVarIsUsed (oDoc, sVarName);
goFMc.aDocVars.push (new oVariable (sVarName, sValue, oVar, bIsUsed, bIsSystem, oTr, null, null)); // array element
oDoc.ScrollToText(oTR); // Go there to get page type
oPage = oDoc.CurrentPage;
sPageType = oPage.constructor.name; // BodyPage, MasterPage, RefPage [Rick Quatro]
index = goFMc.aDocVars.length - 1; // use current array entry
goFMc.aDocVars[index].PageType = sPageType;
if (sPageType == "BodyPage") {
goFMc.aDocVars[index].PageNr = oPage.PageNum;
} else if (sPageType == "MasterPage") {
goFMc.aDocVars[index].PageName = oPage.Name;
} else if (sPageType == "RefPage") {
goFMc.aDocVars[index].PageName = oPage.Name;
}
oVar = oVar.NextVarInDoc;
}
goFMc.nDocVars = goFMc.aDocVars.length;
} //--- end GetVarsInDoc
To get to the first variable in the document I have the following function in the dialogue:
function ButtonFirst () { //=== Go to first variable in document ==================================
var bSystemVar, iVar, jVar, oVar, sName;
iVar =0; // index in doc variable array
goFMc.indexDocVars = iVar; // keep for other nav buttons
oVar = goFMc.aDocVars[iVar].VarObj; // first item in doc variable array
sName = goFMc.aDocVars[iVar].Name;
bSystemVar = goFMc.aDocVars[iVar].IsSystem;
DisplayVariable (goFMc.oCurrentDoc, iVar); // can be on any page type
// ...} //--- end ButtonFirst
Relevant data (the ingredients) from goFMc.aDocVars[0] for DisplayVariable is
Name = Running H/F 1
Contents = <$paratext[0chapter-title]>
VarObj = // Var object in document
VarUsed = false // User var is used in document
IsSystem = true
TextRange= // textrange of this occurance in the doc
PageType = MasterPage
PageName = Left
The user normally start on the body pages, while many variables can be on the master pages and even on the reference pages. Hence the display should switch between the various page types. However, in my test case the variable is on the first master page - but the display is still the current body page.
My question now is: why does DisplayVariable not jump to the appropriate page type and show the selected variable?
After executing ButtonFirst I can manually switch to the master pages where I see the variable selected on the very first one.
function DisplayVariable (oDoc, iVar) { //=== display the indexed variable ========================
var oTR;
oTR = goFMc.aDocVars[iVar].TextRange;
oDoc.TextSelection = oTR;
oDoc.ScrollToText(oTR);
} //--- end DisplayVariable
When switching manually to the last master page before I use the button then the display is correct.
But how can I make the function automatically go to the relvant page type?
I have the necessary ingredients, but no recipe...
Any ideas are welcome
Klaus
Hi Klaus, You can set the current page to the page containing the variable by using line 15. I think this is what you are trying to do. -Rick
...#target framemaker
var doc = app.ActiveDoc;
showVariables (doc);
function showVariables (doc) {
var variable, page, result;
variable = doc.FirstVarInDoc;
while (variable.ObjectValid () === 1) {
page = getPage (variable, doc);
if (page.ObjectValid () === 1) {
// Go to the page containing the variable.
doc.Cur
Copy link to clipboard
Copied
Hi Klaus, You can set the current page to the page containing the variable by using line 15. I think this is what you are trying to do. -Rick
#target framemaker
var doc = app.ActiveDoc;
showVariables (doc);
function showVariables (doc) {
var variable, page, result;
variable = doc.FirstVarInDoc;
while (variable.ObjectValid () === 1) {
page = getPage (variable, doc);
if (page.ObjectValid () === 1) {
// Go to the page containing the variable.
doc.CurrentPage = page;
}
variable = variable.NextVarInDoc;
}
}
function getPage (obj,doc) {
var frame = 0, cell = 0;
var objType = "", prop = 0;
while (obj) {
frame = obj;
objType = obj.constructor.name;
switch (objType) {
case "SubCol" :
obj = obj.ParentTextFrame;
break;
case "Tbl" :
obj = obj.FirstRowInTbl.FirstCellInRow;
break;
case "Row" :
obj = obj.FirstCellInRow;
break;
case "Cell" :
case "Pgf" :
case "AFrame" :
obj = obj.InTextFrame;
break;
case "TextLine" :
case "TextFrame" :
case "UnanchoredFrame" :
case "Arc" :
case "Ellipse" :
case "Group" :
case "Inset" :
case "Line" :
case "Math" :
case "Polygon" :
case "Polyline" :
case "Rectangle" :
case "RoundRect" :
if (obj.FrameParent.ObjectValid()) {
obj = obj.FrameParent;
} else {
obj = 0;
}
break;
case "XRef" :
case "Var" :
prop = doc.GetTextPropVal (obj.TextRange.beg, Constants.FP_InTextObj);
var obj = prop.propVal.obj;
break;
default:
// Prevent endless loop if unknown object type is found.
obj = 0;
break;
}
}
if (frame) {
return frame.PageFramePage;
} else {
return 0;
}
}
Copy link to clipboard
Copied
Thank You, Rick - I feared that I will need such an elaborate process you provide with function GetPage.
Now my function DisplayVariable became very simple:
function DisplayVariable (oDoc, iVar) { //=== display the indexed variable ========================
// Select variable to visualize the location of it
// Arguments oDoc: current document
// iVar: index in array of variable objects
// Called by
// Reference GetPage by Rick Quatro, https://forums.adobe.com/thread/2424187
var oPage, oTR;
if (settings.bIsDebug) {ZTrace ();}
oPage = GetPage (goFMc.aDocVars[iVar].VarObj, oDoc);
if (oPage.ObjectValid () === 1) {
oDoc.CurrentPage = oPage; // Go to the page containing the variable.
}
oTR = goFMc.aDocVars[iVar].TextRange;
oDoc.TextSelection = oTR; // Variable is selected
oDoc.ScrollToText(oTR); // Selection is viewed
} //--- end DisplayVariable
... and it works like a charm. Later I will insert here and there "display on/off" to avoid flicker of the window.