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.
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
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;
}
// 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
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.
Copy link to clipboard
Copied
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