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

Is there a function to 'follow' an XRef?

Community Expert ,
Jul 30, 2019 Jul 30, 2019

Copy link to clipboard

Copied

Putting pieces together.

I have a cross reference object and want to follow it to the target object (oXRef.XRefFile, ???),

I imagine to do the following:

- open the target document

- loop until i find the XRef marker with the content oXRef.XRefSrcText)

... or is there something simpler?

BTW: FDK reference: "XRefFile" The filename of the file containing the crossreference source. If the cross-reference source is in the same document as the cross reference, the filename is an empty string ("").

This not true, it is always the absolute path to a doc.

// Comment    FDK reference: "XRefFile" The filename of the file containing the crossreference source.
//            If the cross-reference source is in the same document as the cross reference,
//            the filename is an empty string (""). This not true, it is always the path to a doc.

TOPICS
Scripting

Views

553

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

Using the Find method to get the relevant markers works fine. I did however not succeed in using the linked list. This fails after the first iteration (see Markers can be found, but are undefined

  oMarker = oTgtDoc.FirstMarkerInDoc;

  while (oMarker.ObjectValid()) {

    if (oMarker.MarkerTypeId.Name == "Cross-Ref") {

      if (oMarker.MarkerText == sMarkerText) {

        oTR = new TextRange (oMarker.TextLoc, oMarker.TextLoc);

        oTgtDoc.TextSelection = oTR;

        return oTR;

      }

    }

    oMar

...

Votes

Translate

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

Copy link to clipboard

Copied

Using the Find method to get the relevant markers works fine. I did however not succeed in using the linked list. This fails after the first iteration (see Markers can be found, but are undefined

  oMarker = oTgtDoc.FirstMarkerInDoc;

  while (oMarker.ObjectValid()) {

    if (oMarker.MarkerTypeId.Name == "Cross-Ref") {

      if (oMarker.MarkerText == sMarkerText) {

        oTR = new TextRange (oMarker.TextLoc, oMarker.TextLoc);

        oTgtDoc.TextSelection = oTR;

        return oTR;

      }

    }

    oMarker = oTgtDoc.NextMarkerInDoc;

  }

The following works as expected

// FollowXRef.jsx

#target framemaker

main ();

function main () {

var oDoc, oPgf, oPgfNew, oTRfound, oTextItem, oTL, oTR, oXRef, oXRefTI, sPath;

  oDoc = app.ActiveDoc;

  oTL = oDoc.TextSelection.beg;

  sXRefFmnt =  "zenref-endnote-reference";        //  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;

    } 

  }

// ------------------------------------------------------------------------------------------------

  oTR = FollowXRef (oDoc, oXRef); // oXRef.XRefFile can be relative "\endnote".

// ------------------------------------------------------------------------------------------------

  sPath = oXRef.XRefFile;                         // Some experiment to verify the TextRange

  if (sPath == "") {                              // XRef marker in same file

    oTgtDoc = oDoc;

  } else {

    oTgtDoc = SimpleOpen (oXRef.XRefFile) ;       // File with XRef (may be relative "\endotes"

  }

  app.ActiveDoc = oTgtDoc;                        // Ttarget doc with XRef marker

  oPgf = oTR.beg.obj.PrevPgfInFlow;

  oPgfNew = oTgtDoc.NewSeriesPgf(oPgf);           // new empty ¶ after previous ¶

} //--- end main 

function FollowXRef (oDoc, oXRef) { // === jump to the target of the cross reference ==============

// Arguments  oDoc    Current document

//            oXRef   Cross reference to follow, target may be another document!

// Returns    false in case of problems

// Called by  xx

var docStart, k, oFindParams, oMarker, oMarkTI, oTgtDoc, oTL, oTRfound, oTR, sDocPath, sMarkerText, sPath;

  app.ActiveDoc = oDoc;                           // required ?

  sDocPath = oDoc.Name;

  sPath = oXRef.XRefFile;

  if (sPath == "") {                              // XRef marker in same file

    oTgtDoc = oDoc;

  } else {

    oTgtDoc = SimpleOpen (oXRef.XRefFile) ;       // File with XRef (may be relative "\endotes"

  }

  sMarkerText = oXRef.XRefSrcText

  app.ActiveDoc = oTgtDoc;                        // Target doc with XRef marker

  docStart = oTgtDoc.MainFlowInDoc.FirstTextFrameInFlow.FirstPgf;

  oTL = new TextLoc (docStart, 0);

  oFindParams= GetFindParameters (3, "Cross-Ref");  // find XRef marker

  oTRfound = oTgtDoc.Find(oTL, oFindParams);

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

    oMarkTI  = oTgtDoc.GetTextForRange (oTRfound, Constants.FTI_MarkerAnchor); // one 1 item in array

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

      oMarker = oMarkTI.obj;

      if (oMarker.MarkerText == sMarkerText) {

        oTR = new TextRange (oMarker.TextLoc, oMarker.TextLoc);

        oTgtDoc.TextSelection = oTR;

//$.bp(true);

        return oTR;

      }

    }

    oTL = oMarker.TextLoc;                        // attention - potential loop !!!!!!!

    oTRfound = oTgtDoc.Find(oTL, oFindParams);

  }

} //--- end FollowXRef 

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 3: // ---------------------------------- find marker of type sSearch, don't wrap

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

      propVal.propVal.valType = Constants.FT_String; 

      propVal.propVal.sval = sSearch; 

      findParams.push(propVal); 

      return findParams;

    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

When working with cross-references, I will sometimes create an xml "map" on the first pass. It will contain all of the details about each Cross-Ref marker and its containing document, etc. Then, as I process the cross-references, I can use the map to resolve them, etc. Here is a partial map:

<?xml version="1.0" standalone="no"?>

<map file="C:\DATA\Scripts\20160811_ReportXRefs\User_Manual\Text\xref-map.xml">

    <chapter name="nextgene_usersmanual_frontcover.fm" number="1" file="C:/DATA/Scripts/20160811_ReportXRefs/User_Manual/Text/NextGene_UsersManual_FrontCover.fm"/>

    <chapter name="nextgene_usersmanual_frontmatter.fm" number="1" file="C:/DATA/Scripts/20160811_ReportXRefs/User_Manual/Text/NextGene_UsersManual_FrontMatter.fm"/>

    <chapter name="nextgene_usersmanualtoc.fm" number="1" file="C:/DATA/Scripts/20160811_ReportXRefs/User_Manual/Text/NextGene_UsersManualTOC.fm"/>

    <chapter name="nextgene_usersmanual_preface.fm" number="1" file="C:/DATA/Scripts/20160811_ReportXRefs/User_Manual/Text/NextGene_UsersManual_Preface.fm"/>

    <chapter name="gettingstarted.fm" number="1" file="C:/DATA/Scripts/20160811_ReportXRefs/User_Manual/Text/GettingStarted.fm">

        <marker id="1437496" text="77254: ChapterTitle: Getting Started with NextGENe" page="23"/>

        <marker id="1458094" text="81205: HeadLev1: NextGENe System Requirements" page="25"/>

        <marker id="1449664" text="12102: HeadLev1: Installing NextGene" page="26"/>

        <marker id="1474073" text="59235: HeadLev1: Starting NextGENe" page="28"/>

        <marker id="1474711" text="74643: HeadLev1: Managing User Accounts" page="29"/>

        <marker id="1474712" text="35708: HeadLev1: Starting EMS" page="29"/>

        <marker id="1474713" text="25292: StepNumber: 3 Click OK or press Enter" page="29"/>

        <marker id="1474714" text="52525: HeadLev1: The EMS Lite Main Window" page="29"/>

        <marker id="1474759" text="86191: HeadLev2: Title bar" page="30"/>

        <marker id="1474800" text="66015: HeadLev2: Main menu" page="30"/>

        <marker id="1474818" text="68495: HeadLev2: Toolbar" page="30"/>

        <marker id="1483250" text="86204: HeadLev1: Viewing NextGENe License Information" page="32"/>

        <marker id="1482479" text="74810: HeadLev1: Configuring User Management" page="33"/>

        <marker id="1478663" text="72906: HeadLev2: To configure user management" page="33"/>

        <marker id="1483657" text="48910: StepNumberContinued: 2 Close the NextGENe Project Wizard and then on the Next" page="33"/>

ExtendScript's XML object is pretty powerful and easy to use, so it is easy to create a map like this. I usually create them in memory and use them as the script runs, but it is easy to save the XML file to disk for troubleshooting purposes.

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

LATEST

Thanks Rick, for this great hint!

... and after Ian Proudfoot spottet my small, but powerful error in Markers can be found, but are undefined" here is the alternative solution to the function FollowXRef:

function FollowXRef (oDoc, oXRef) { // === jump to the target of the cross reference ==============

// Arguments  oDoc    Current document

//            oXRef   Cross reference to follow, target may be another document!

// Returns    Textrange of the marker or null

// Called by  xx

var oMarker, oTgtDoc, oTR, sMarkerText, sPath;

  app.ActiveDoc = oDoc;                           // required ?

  sPath = oXRef.XRefFile;

  if (sPath == "") {                              // XRef marker in same file

    oTgtDoc = oDoc;

  } else {

    oTgtDoc = SimpleOpen (oXRef.XRefFile) ;       // File with XRef (may be relative "\endotes"

  }

  sMarkerText = oXRef.XRefSrcText

  app.ActiveDoc = oTgtDoc;                        // Target doc with XRef marker

  oMarker = oTgtDoc.FirstMarkerInDoc;

  while (oMarker.ObjectValid()) {

    if (oMarker.MarkerTypeId.Name == "Cross-Ref") {

      if (oMarker.MarkerText == sMarkerText) {

        oTR = new TextRange (oMarker.TextLoc, oMarker.TextLoc);

        oTgtDoc.TextSelection = oTR;

        return oTR;

      }

    }

    oMarker = oMarker.NextMarkerInDoc;

  }

  return null;

} //--- end FollowXRef 

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