Copy link to clipboard
Copied
Dear friends and experts, I'm again at the end of my knowledge:
- A variable just behind a marker is found and the variable can be deleted in the text
- This variable should also be removed from the catalogue. I'ts name is not known, because the name is generated at the time of insertion (the current name is 2016-11-10T09:46:52.136Z).
- Experiments with the text selection after finding the variable (line 31) did not reveal anything useful to get the name of the variable.
- Do You have an idea?
#target framemaker
// Required doc: #calc Marker with text containing "C7 at the beginning
// behind this marker the variable of unknown name is found
sMarkerText = '"C7';oDoc = app.ActiveDoc;
oMarker = oDoc.FirstMarkerInDoc;
while (oMarker.ObjectValid()) {
if (oMarker.MarkerTypeId.Name == "#calc") {
if (oMarker.MarkerText == sMarkerText) {
bFound = FindAndDeleteVariable (goCurrentDoc, goCurrentMarker); // remove already existing variable
// How to get the name of the variable to be able to remove it from the catalogue also?
oTextLoc = goCurrentMarker.TextLoc;
oTextLoc.offset = oTextLoc.offset + 1; // insert temp variable behind marker
InsertVariable (goCurrentDoc, oTextLoc, "#TEST", "\+1.275×10<super>\+9" );
}
}
}function FindAndDeleteVariable (oDoc, oMarker) { //=== Find variable behind marker and remove it ==
// In oMarker: current marker
// Out Function returns true for found+removed variable
var tLoc1 = oMarker.TextLoc,
tLoc2 = oMarker.TextLoc, // should be just behind the marker
iUnique1= oMarker.TextLoc.obj.Unique, // ¶ of the marker
myTextRange, findParams, fRange;
tLoc2.offset = tLoc2.offset + 1; // a - c are required!
myTextRange = new TextRange(tLoc1,tLoc2); // b
oDoc.TextSelection = myTextRange; // c
findParams= GetFindParamsVariable (); // search for any variable
fRange = oDoc.Find (tLoc1, findParams); // finds variable
if (fRange.beg.obj.ObjectValid()) { // variable found ?
if (fRange.beg.obj.Unique == iUnique1) { // same ¶ as the marker ?
if (fRange.beg.offset == tLoc1.offset+1) { // TR =? variable behind marker
oDoc.DeleteText(fRange); // Delete the selected Variable
return true;
}
}
}
return false; // there was'nt a variable
} //--- end FindAndDeleteVariablefunction GetFindParamsVariable () { //=== Set up parameters to Find a variable ====================
// Out Returns parameters for the find function: no wrapping around ?
// Reference Klaus Göbel, https://forums.adobe.com/thread/2227993
// FDK Function Reference, F_ApiFind()
var findParams = new PropVals() ;
propVal = new PropVal() ;
propVal.propIdent.num = Constants.FS_FindObject;
propVal.propVal.valType = Constants.FT_Integer;
propVal.propVal.ival = Constants.FV_FindAnyVariable ;
findParams.push(propVal);
return findParams;
} //--- end GetFindParamsVariable
function InsertVariable (oDoc, oTextLoc, sVarName, sContent) { //=== Insert variable at location ==
// In oTextLoc: where to insert the variable
// sVarName: name of the variable
// sContent: content of the variable
var oVar;
oVar = oDoc.NewAnchoredFormattedVar (sVarName, oTextLoc);
oVar.Fmt = sContent;
}
BTW the marker contains this text: "C7 ¶ after T2 TB" = @Pi / 180.0; which is successfully evaluated and placed in the temporary variable - there is progress in my project¨.
Thank You very much for Your help!
Klaus
1 Correct answer
Hi Klaus,
I am not clear on what you are trying to do, but here is the general algorithm for deleting unused formats:
1) Make an array to hold the used variable names.
2) Loop through all of the variables in the document, and if the name is not currently in the list, add it to the list. When the loop is done, you will have an array of all of the names of the variables in use.
3) Loop through all of the variable formats in the document. For each one, see if its name is in the used variables array; if
...Copy link to clipboard
Copied
Well, I already thought of this method:
- All of these variables have a name with a distinct pattern (Regex /\d+\-\d+\-\d+T\d+:\d+:\d+\.\d+Z/ ).
- Run through all variables in cataloge and look for those with this pattern
- If found: is is really used? => have not found the appropriate property
- If not used, delete from catalogue
You see, just another problem here.
Copy link to clipboard
Copied
Hi Klaus,
I am not clear on what you are trying to do, but here is the general algorithm for deleting unused formats:
1) Make an array to hold the used variable names.
2) Loop through all of the variables in the document, and if the name is not currently in the list, add it to the list. When the loop is done, you will have an array of all of the names of the variables in use.
3) Loop through all of the variable formats in the document. For each one, see if its name is in the used variables array; if not, delete the format. You should test each variable to make sure it is a user variable because system variables can't be deleted.
There is no property on a variable format itself to say that it is in use.
-Rick
Copy link to clipboard
Copied
Tank You, Rick, this gave me the kick!
The following works as expected:
function DeleteUnusedVariables (oDoc) { //=== Delete temporary variables in catalogue =============
// In oDoc: Current document
// Out Function returns false only in case of problems; else true
// Comment Only #calc temporary variables are deleted, if they are not used in the document
// What kind of problem could be encountered? => return false
// Reference Ric Quatro, https://forums.adobe.com/thread/2234619
var aUsedVariables = [],
oVar, oCatVarFmt, oNxtVarFmt,
re_TmpVarName = /\d+\-\d+\-\d+T\d+:\d+:\d+\.\d+Z/, // e.g. 2016-11-10T09:46:52.136Z
sVarName, sName, j;oVar = oDoc.FirstVarInDoc;
while (oVar.ObjectValid()) {
sVarName = oVar.VarFmt.Name;
if (re_TmpVarName.test(sVarName)) { // is it a temporary variable ?
if (IsInArray (aUsedVariables, sVarName)) { // already in the list
continue;
}
aUsedVariables.push(sVarName);
}
oVar = oVar.NextVarInDoc;
}oCatVarFmt = oDoc.FirstVarFmtInDoc;
while (oCatVarFmt.ObjectValid()) {
if (oCatVarFmt.SystemVar > 0) { // skip system variables
oCatVarFmt = oCatVarFmt.NextVarFmtInDoc;
continue;
}
sName = oCatVarFmt.Name;
if (re_TmpVarName.test(sName)) { // is it a temporary variable ?
if (IsInArray (aUsedVariables, sName) != null) {
oCatVarFmt = oCatVarFmt.NextVarFmtInDoc;
continue; // it is used in the document
} else {
oNxtVarFmt = oCatVarFmt.NextVarFmtInDoc;
oCatVarFmt.Delete(); // remove from catalogue
oCatVarFmt = oNxtVarFmt;
continue;
}
} else {
oCatVarFmt = oCatVarFmt.NextVarFmtInDoc;
}
}
return true;
} //--- end DeleteUnusedVariablesfunction IsInArray (array, item) { //=== Get index of item in array ===============================
// In array: where to find the item
// item: to be found in the array
// Out Returns index of found element or null.
// Comment array.indexOf() is not supported in ExtendScript, only string.indexOf () is defined.
var j, arLen = array.length;for (j = 0; j < arLen; j++) {
if (array== item ) { return j;}
}
return null; // not found in array
} //--- end IsInArray
Copy link to clipboard
Copied
Hi Klaus, Thank you for marking my answer as correct. I have to commend you on how much your scripting skill has increased, especially your use of functions. I do have one suggestion: I would consider separating the DeleteUnusedVariables function into two. One might be "getVariablesInUse". The advantage is that you could reuse this in another script where you just may want to report the variable formats in use, without actually deleting them. Also, in development, you would want to test your "get" code without actually deleting any of the variable formats. The third reason is that it keeps your functions shorter, which makes them easier to follow and understand when you visit them later. But this probably just quibbling; overall, I think you did an excellent job. -Rick
Copy link to clipboard
Copied
Hi Klaus,
there's a script on my website you could use. Feel free to load it there: Kostenlose Skripte
It's only in German at the moment, but that should'nt be a problem for you.

