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:
The caution here: objects in linked lists are not necessarily in document order.
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.
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
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;
}
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.
Copy link to clipboard
Copied
The caution here: objects in linked lists are not necessarily in document order.
Copy link to clipboard
Copied
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):
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.