• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

How to find a variable just after a marker?

Community Expert ,
Oct 27, 2016 Oct 27, 2016

Copy link to clipboard

Copied

Dear experts,

My project steps further - but as soon as I have to deal with FM-objects I still struggle. The script should do this:

  • In the document (http://www.daube.ch/zz_tests/Markers-and-variables.fm) there are markers of type #calc (which are all found and stored into an array.
  • Some of them are immediately followed by a variable (called temporary variable, because the names are built by date/time).
  • Before I insert the new variable, the old one should be found and removed.
  • The problem is that I do not find the old variable and hence can not remove it, before the new one is inserted. The inserting is OK, but it occurs independently of existing variables.
  • Line 49 always evaluates to false, even if there is a variable present.

How can I find (at first hand) any variable (Later I will need to check whether it is really a temprary variable) ?

#target framemaker
// Required doc: Markers-and-variables.fm:
  aVariables = ["#DOCname", "#TEST", "2016-09-27T10:28:46.060Z"];
  goCurrentDoc =  app.ActiveDoc;
  giNCalcMarkers = CollectMarkers  (gaoCalcMarkers, "#calc");

for (j = 0; j < giNCalcMarkers; j++) {
  goCurrentMarker = gaoCalcMarkers;            // find a marker
  oFound = FindVariable (goCurrentDoc, goCurrentMarker);
  if (oFound[0]) {                                // true, variable found
    oFound[1].Delete();                           // remove temp. variable from document
  }
  oTextLoc = goCurrentMarker.TextLoc;
  oTextLoc.offset = oTextLoc.offset + 1;          // insert temp variable behind marker
  InsertVariable (goCurrentDoc, oTextLoc, "#TEST", "\+1.275×10<super>\+9" );
}
// ================= Routines to be tested ========================================================
function CollectMarkers (aMarkers, sMarkerName) { //=== Collect marker-objects, store in array ====
// In        aMarkers:    global array of markers to be filled
//           sMarkerName: type of marker to be collected
// Out       Return number of markers collected
var  oMarker, MarkerTI, nMarkers;
  tsSave = goCurrentDoc.TextSelection;            // save current cursor location
  oMarker = goCurrentDoc.FirstMarkerInDoc;
  while (oMarker.ObjectValid()) {
    MarkerTI = oMarker.MarkerTypeId;
    if (MarkerTI.Name == sMarkerName) {
      aMarkers.push(oMarker);                     // store the marker objects
    }
    oMarker = oMarker.NextMarkerInDoc;
  }
  goCurrentDoc.TextSelection = tsSave;            // Restore cursor location
  nMarkers = aMarkers.length;
  return nMarkers;                                // number of markers in array
} //--- end CollectMarkers 

function FindVariable (oDoc, oMarker) { //=== Find variable behind marker ========================
// In        oMarker: current marker
// Out       Function returns [true, found variable] or [false, loc behind the marker]
var tLoc1 = oMarker.TextLoc,
    tLoc2 = oMarker.TextLoc,                      // should be just behind the marker
    j, myTextRange, findParams, fRange, oTextItem, aVarsRange, nVars, thisVar; 
  tLoc1.offset = tLoc1.offset + 1;
  tLoc2.offset = tLoc2.offset + 2;
  myTextRange  = new TextRange(tLoc1,tLoc2);
  oDoc.TextSelection = myTextRange;               // Does this hold a variable ?
  findParams= GetFindParamsVariable ("");         // search for any variable
  fRange = goCurrentDoc.Find  (tLoc1, findParams);// is a textrange
  if (fRange.beg.obj.ObjectValid()) {
    aVarsRange = goCurrentDoc.GetTextForRange (fRange, Constants.FTI_VarBegin);
    nVars = aVarsRange.length;
    for (j = 0; j < nVars; j++) {                   // loop should not be necessary
      oTextItem = aVarsRange;                    // superfluous ?
      thisVar = oTextItem.obj;                      // should contain only one variable
      return [true, thisVar];
    }
  } else {
    return [false, tLoc1];
  }
} //--- end FindVariable 

function GetFindParamsVariable (sVarName) { //=== Set up parameters to Find variable ==============
// In        sVarName: variable type to be found
// Out       Returns parameters for the find function: no wrapping around ?
var findParams;
  findParams = AllocatePropVals (2); 
  findParams[0].propIdent.num = Constants.FS_FindWrap ; 
  findParams[0].propVal.valType = Constants.FT_Integer; 
  findParams[0].propVal.ival = 0 ; // don't start at the beginning => seems to be 'nowrap'
  findParams[1].propIdent.num = Constants.FS_FindNamedVariable; 
  findParams[1].propVal.valType = Constants.FT_String; 
  findParams[1].propVal.sval = sVarName; 
  return findParams; 
} //--- end GetFindParams

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;
}

TOPICS
Scripting

Views

731

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Enthusiast , Oct 28, 2016 Oct 28, 2016
  1.     propVal = new PropVal() ; 
  2.     propVal.propIdent.num = Constants.FS_FindObject; 
  3.     propVal.propVal.valType = Constants.FT_Integer; 
  4.     propVal.propVal.ival = Constants.FV_FindAnyMarker ; 
  5.     FindParams.push(propVal); 

We discussed it some months ago.

Re: Find next marker

BTW: gaoCalcMarkers is undefined.

Votes

Translate

Translate
Enthusiast ,
Oct 27, 2016 Oct 27, 2016

Copy link to clipboard

Copied

Hi Klaus,

you can't use "find" with Constants.FS_FindNamedVariable and name = "" for any variable.

You have to use Constants.FS_FindObject and Constants.FV_FindAnyVariable.

cu in Stuttgart (tekom) ?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 28, 2016 Oct 28, 2016

Copy link to clipboard

Copied

Thanks, Klaus, for the tip.

It is, however, not easy to find all necessary ingredients of the PropVals setup:

Is It (a):

  findParams[1].propIdent.num = Constants.FS_FindObject; 
  findParams[1].propVal.valType = Constants.FV_FindAnyVariable; 
  findParams[1].propVal.ival = 0;     // ???

or (b):

  findParams[1].propIdent.num = Constants.FS_FindObject; 
  findParams[1].propVal.valType = Constants.FV_FindAnyVariable; 
  findParams[1].propVal.sval = "";    // ???

With a) the variable far away is found (after the next marker)

With b) nothing is found (as I had it before your answr).

Whether the third item (ival/sval) is needed and what the necessary values are: I have not found any information about that in the FDK - not speak of ES-docu.

Information such as "Parmeter name = findParams, Data Type = PropVals, Option = No, Desctiption = A property list that specifies what to search for" is the end of the story. No indication at all, what to specify for PropVals!

I have also tinkered around a lot with the tLoc1.offset value to start the find operation: even if stepping back 5 from the marker location the variable behind the next (not the current) marker is found.

Stuttgart (tekom) ? - I will not attend: to many items on stack.

Klaus

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Oct 28, 2016 Oct 28, 2016

Copy link to clipboard

Copied

  1.     propVal = new PropVal() ; 
  2.     propVal.propIdent.num = Constants.FS_FindObject; 
  3.     propVal.propVal.valType = Constants.FT_Integer; 
  4.     propVal.propVal.ival = Constants.FV_FindAnyMarker ; 
  5.     FindParams.push(propVal); 

We discussed it some months ago.

Re: Find next marker

BTW: gaoCalcMarkers is undefined.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 28, 2016 Oct 28, 2016

Copy link to clipboard

Copied

Thanks, now it works!

gaoCalcMarkers - undefined only in this snippet

I had used Find next marker as the base - but still was not clever enough.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 29, 2016 Oct 29, 2016

Copy link to clipboard

Copied

LATEST

To sum up, here the complete working example - needs a proper document.

#target framemaker
// Required doc: Markers-and-variables.fm:
  oDoc =  app.ActiveDoc;
  oMarker = oDoc.FirstMarkerInDoc;
  while (oMarker.ObjectValid()) {                 // get markers in order of creation
    MarkerTI = oMarker.MarkerTypeId;
    if (MarkerTI.Name == "#calc") {
      bFound = FindVariable (oDoc, oMarker);      // remove already existing variable
      if (bFound) {
        oTextLoc = oMarker.TextLoc;
        oTextLoc.offset = oTextLoc.offset + 1;    // insert temp variable behind marker
        InsertVariable (oDoc, oTextLoc, "#TEST", "\+1.275×10<super>\+9" );
      }
    }
    oMarker = oMarker.NextMarkerInDoc;
  }

function FindVariable (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;
  myTextRange  = new TextRange(tLoc1,tLoc2);
  oDoc.TextSelection = myTextRange;
  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 variableb
} //--- end FindVariable 

function GetFindParamsVariable () { //=== Set up parameters to Find a variable ====================
// Out       Returns parameters for the find method
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;
}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines