• 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 stop a search at the end of the flow?

Community Expert ,
Aug 05, 2019 Aug 05, 2019

Copy link to clipboard

Copied

Dear all,

In a document are cross references to EndNotes which are paragraphs towards the end of the document. The cross references have a distinct format ("zenref-endnote-reference").

I'm able to insert new such references as long as the current location is prior to an already existent such XRef. For this I look for the next XRef starting at the current location.

→ But how can I determine that there is no other such XRef after the current location?

The Find process just wraps at the end of the flow and finds the first XRef...

If oCurrentLoc is the current location and oFoundLoc is the result of the "Find next XRef", how can I determine whether oCurrentloc > oFoundLoc? There is no such thing as a global distance in the document (or is it?).

Any ideas are welcome!

My current idea is this:

  1. startPgf is the paragraph with the current location, where the Find starts
  2. foundPgf is the paragraph where the Find found the next XRef.
  3. In a loop from FirstPgfInFlow (to be determined) to LastPgfInFlow (see Re: Strange behaviour at bottom of page) I can check (by the famous ID) which one appears first.
  4. If it is foundPgf, then there was no further XRef after the starting location.
TOPICS
Scripting

Views

381

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

Community Expert , Aug 08, 2019 Aug 08, 2019

The caution here: objects in linked lists are not necessarily in document order.

Votes

Translate

Translate
Community Expert ,
Aug 05, 2019 Aug 05, 2019

Copy link to clipboard

Copied

When you set your find parameters, you can use this:

propVal = new PropVal ();

propVal.propIdent.num = Constants.FS_FindWrap;

propVal.propVal.valType = Constants.FT_Integer;

propVal.propVal.ival = 0;

This should turn off the wrapping; the default is on.

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 ,
Aug 05, 2019 Aug 05, 2019

Copy link to clipboard

Copied

Rick, the nowrap property does not help to observe the 'end of flow' boundary.

No wrapping means that the find will stop if comes along the strart of the search - IMHO it is completely useless, because each Find operation moves the start location for the next search...

And yes, I need to consider the your second post. But then I need to find out where in the sequence of XRefs i'm currently. The point is: I want to insert a new XRef between exiisting ones or after the last one and hnec must compare the current location with the locations of the existing XRefs.

This needs further thoughts - maybe the whole process of 'finding my current situation' has to be reworked.

My current (working solution) is this (I will integrate function NoXRefFollows into function FindNextEnXref):

// NoXRefFollows.jsx

#target framemaker

main ();

function main () {

var oDoc = app.ActiveDoc, oTL, sXRefFmt;

  sXRefFmt = "zenref-endnote-reference"; // goFno.FmtEnRefName;

  oTL = oDoc.TextSelection.beg;

  $.writeln ("No XRef follows: " + NoXRefFollows (oDoc, oTL, sXRefFmt));

} //--- end main 

function NoXRefFollows (oDoc, oTL, sXRefFmt) {

// Arguments  oDoc      Current document

//            oTL       Curent location

//            sXrefFmt  Cross reference format of xref to endnote

// Returns    True if the current location is later than the found location, else false

// Comment    In a loop from FirstPgfInFlow to LastPgfInFlow the ¶-ID helps to compare the order

//            of the current ¶ and that of the found XREF

var ID, IDcurrent, IDfound, jPgf = 1, jThis, jFound, oPgf, oPgfEnd, oPgfStart, oPgfThis, oPgfFound, oXref;

  IDcurrent = oTL.obj.id;

  oXref = FindNextEnXref (oDoc, sXRefFmt);

  IDfound   = oXref.TextRange.beg.obj.id;

  oPgfStart = oDoc.MainFlowInDoc.FirstTextFrameInFlow.FirstPgf;

  oPgfEnd = Fno_GetLastPgfInMainFlow (oDoc);

  oPgf = oPgfStart;

  while (oPgf.ObjectValid() ) {

    if (IDcurrent == oPgf.id) {jThis = jPgf;}

    if (IDfound == oPgf.id) {jFound = jPgf;}

    oPgf = oPgf.NextPgfInFlow;

    jPgf += 1;

    if (jThis != undefined && jFound != undefined) {break}

  }

  if (jFound <= jThis) { return true;             // No XRef after the current location

  } else {return false;}

} //--- end NoXRefFollows 

function FindNextEnXref (oDoc, sXRefFmt) { //=== Find next xref to endnote ========================

// Arguments  oDoc:       Document receiving the XRef and containing the target marker

//            sXrefFmt:   Cross reference format of xref to endnote

// Returns    XRef object or null

// Called by  xxxx

// Comment    - what happens if we start beyong the last xref to an endnote?

//            - strongly depends on bookfile/single file

var k, oFindParams, oTL, oTRfound, oXRefTI;

  oTL = oDoc.TextSelection.beg;                   // current cursor location

  sXRefFmnt =  goFno.FmtEnRefName;

  oFindParams= GetFindParameters (8, sXRefFmnt);  // find XRef forwards

  oTRfound = oDoc.Find(oTL, oFindParams);

  if (oTRfound.beg.obj.ObjectValid()) {

    oXRefTI  = oDoc.GetTextForRange (oTRfound, Constants.FTI_XRefBegin); // one 1 item in array

    for (k = 0; k < oXRefTI.length; k++) {        // k always 0 nevertheless loop necessary!

      oXRef = oXRefTI.obj;

      return oXRef;

    } 

  }

  return null;                                    // no XRefs at all in Doc

} //--- end FindNextEnXref

function Fno_GetLastPgfInMainFlow (oDoc) { // === Get the last ¶ in the main flow =================

// Arguments  oDoc    Current document

// Returns    object LastPfg in current flow

// Reference  Rick Quatro in https://forums.adobe.com/message/11169995

var textFrame; 

     

  textFrame = oDoc.MainFlowInDoc.LastTextFrameInFlow; 

  while (textFrame.ObjectValid () === 1) { 

    if (textFrame.LastPgf.ObjectValid () === 1) { 

        return textFrame.LastPgf; 

    } 

    textFrame = textFrame.PrevTextFrameInFlow; 

  }

} //--- end Fno_GetLastPgfInMainFlow 

function GetFindParameters (iType, sSearch) { //=== set up parameters for various find actions

// Arguments iType:   what find to be performed

//                    3  Marker of type sSearch

//                    8  Cross reference sSearch forwared

//           sSearch: what to search for

// Returns   Parameters for the find method

// Called by xxx

// Reference FDK Function Reference, F_ApiFind(), https://forums.adobe.com/thread/961616

// Used in   FMcalc, FMvars, FMgraph

var findParams, propVal;

  findParams = new PropVals() ;

  switch (iType) {

    case 8: // ---------------------------------- find cross reference sSearch forwards

      propVal = new PropVal() ; 

      propVal.propIdent.num = Constants.FS_FindWrap ; 

      propVal.propVal.valType = Constants.FT_Integer; 

      propVal.propVal.ival = 0 ;                  // don't wrap

      findParams.push(propVal); 

      propVal = new PropVal() ; 

      propVal.propIdent.num = Constants.FS_FindXRefWithFormat; 

      propVal.propVal.valType = Constants.FT_String; 

      propVal.propVal.sval = sSearch; 

      findParams.push(propVal); 

      return findParams;

    default:

      alert ("GetFindParameters: Case " + iType + " is not defined");

      return null;

  }

} //---  end GetFindParameters

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 ,
Aug 05, 2019 Aug 05, 2019

Copy link to clipboard

Copied

Forgive me if I am missing the scope of the bigger script, but I don't like using the Find method for doing something like this. I would either loop through the cross-references with this:

xref = doc.FirstXRefInDoc;

while (xref.ObjectValid () === 1) {

    //...

    xref = xref.NextXRefInDoc;

}

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 Beginner ,
Aug 08, 2019 Aug 08, 2019

Copy link to clipboard

Copied

You can tell if the current Xref you have is the last one in the doc by using:

if (!currentXref.NextXRefInDoc.ObjectValid()) {

    // currentXref is the last one

} else {

    // it is not

}

where currentXref is a valid Xref object.

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 ,
Aug 08, 2019 Aug 08, 2019

Copy link to clipboard

Copied

The caution here: objects in linked lists are not necessarily in document order.

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 ,
Aug 09, 2019 Aug 09, 2019

Copy link to clipboard

Copied

LATEST

Rick, this is exactly the cause why I can not rely on the simple method and need to use the Find method.

Hence my final solution is this (already implemented and working):

  • From the current location search forwards for another XRef
  • If found, check whether a wrap around the end of the flow happened (see later)
  • If wrap happened, use Find backwards from the current location (In this case the new endnote paragraph must be inserted after the one related to the XRef).
  • If no wrap happened, then the new endnote paragraph must be inserted before the one related to the XRef).

Detecting the wrap:

IDcurrent = oTL.obj.id;                       // ¶ of current location
IDfound  = oXRef.TextRange.beg.obj.id;        // ¶ of found XRef

Looping through all paragraphs in the flow I can determine whether the IDcurrent is after IDfound. Then a wrap occurred.

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