Dear friends,
While it is quite simple to find the next marker with oDoc.NextMarkerInDoc the sequence of the found markers is not that what the user sees in the document: you get the markers in the sequence they were inserted into the document (which may be quite random). To get the same sequence as using the Find dialogue, I need ...
But again my knowledge is to low - see lines 91 or 92:
#target framemaker
/* Navigate markers and get them
Document in charge is E:\_DDDprojects\FM-calc\FM-testfiles\NavigateMarkers.fm
Which contains both #calc and Author markers
It turns out that the sequence of marker.NextMarkerInDoc is that of creating the markers.
For the first and last marker the simple method is OK (since absolute postions).
For next and previous the find method must be used.
*/
var oDoc = app.ActiveDoc, oCurrentMarker;
if (!oDoc.ObjectValid ()) {
alert ("There is no active document.");
} else {
oCurrentMarker = GetMarker (oDoc, "#calc", "first"); // OK Alert ("marker found = " + oCurrentMarker.MarkerText);
oCurrentMarker = GetMarker (oDoc, "#calc", "next", oCurrentMarker); // undefined Alert ("marker found = " + oCurrentMarker.MarkerText);
}
function GetMarker (oDoc, sMarkerName, sAdverb, oCurrentMarker) { // =============================
// sAdverb may be first, last, previous, next
// returns undefined if sMarkerName not defined in oDoc
// argument oCurrentMarker unused for "first"
// unfortunately there are no such methods as LastMarkerInDoc or PreviousMarkerInDoc var marker, nextMarker, exit, currenMarker; markerType = oDoc.GetNamedMarkerType (sMarkerName); // Get the specified marker type. if (!markerType.ObjectValid ()) { return undefined;} switch (sAdverb) { case "first": oCurrentMarker = GetFirstMarker (oDoc, sMarkerName); break; case "previous": oCurrentMarker = FindNextPrevMarker (oDoc, sMarkerName, "previous", oCurrentMarker); break; case "next": oCurrentMarker = FindNextPrevMarker (oDoc, sMarkerName, "next", oCurrentMarker); break; case "last": oCurrentMarker = GetLastMarker (oDoc, sMarkerName); break; default: Alert ("Error in routine NavigateMarker\nUndefined sAdverb = " + sAdverb); break; } return oCurrentMarker;
}
function GetFirstMarker (oDoc, sMarkerName) { // get first marker of type sMarkerName =============
// function returns the current marker, null if it does not exist
// parameter oCurrentMarker is not used
var marker = null, nextMarker, oCurrentMarker; marker = oDoc.FirstMarkerInDoc; while (marker.ObjectValid ()) { nextMarker = marker.NextMarkerInDoc; if (marker.MarkerTypeId.Name === sMarkerName) { return marker; } marker = nextMarker; }
}
function GetLastMarker (oDoc, sMarkerName) { // get last marker of type sMarkerName ===============
// function returns the last marker of type sMarkerName, null if it does not exist
// parameter oCurrentMarker is not used
var marker, nextMarker, lastMarker; marker = oDoc.FirstMarkerInDoc; marker = marker.NextMarkerInDoc; while (marker.ObjectValid ()) { if (marker.MarkerTypeId.Name === sMarkerName) { lastMarker = marker; } marker = marker.NextMarkerInDoc; } return lastMarker;
}
function FindNextPrevMarker (oDoc, sMarkerName, sAdverb, oCurrentMarker) { // get next/previous ===
// function returns the current marker, null if it does not exist
// Base: Russ Ward in https://forums.adobe.com/message/3888653#3888653
var marker; var tr = new TextRange(); var findParams = new PropVals(); tr.beg.obj = tr.end.obj = oCurrentMarker; // Starting tr is the current marker tr.beg.offset = tr.end.offset = 0; // // Wrapping not wanted. findParams = GetFindParamsMarker (sMarkerName, sAdverb); // Find parameters for marker InitFA_errno (); // reset - it is write protected
//marker = oDoc.Find(tr.beg, findParams); // => undefined marker = oDoc.Find(oCurrentMarker, findParams); // => undefined if (FA_errno !== Constants.FE_Success) { return undefined; // no next/previvious marker present } return marker; // we have found a next/prev marker
}
function GetFindParamsMarker (sMarkerName, direction) { //=========================================
// Get/set the find parameters: find marker of type sMarkerName, consider direction, no wrapping around
// Returns find parameters in the function
var findParams; if (direction = "next") { findParams = AllocatePropVals (1); findParams[0].propIdent.num = Constants.FS_FindMarkerOfType; findParams[0].propVal.valType = Constants.FT_String; findParams[0].propVal.sval = sMarkerName; } else { // previous findParams = AllocatePropVals (2); findParams[0].propIdent.num = Constants.FS_FindMarkerOfType; findParams[0].propVal.valType = Constants.FT_String; findParams[0].propVal.sval = sMarkerName; findParams[1].propIdent.num = Constants.FS_FindCustomizationFlags; findParams[1].propVal.valType = Constants.FT_Integer; findParams[1].propVal.ival = Constants.FF_FIND_BACKWARDS; } return findParams;
} // --- end GetFindParams
function InitFA_errno() { //========================================================================
// Reset FA_errno as it is write protected. See https://forums.adobe.com/thread/962910
app.GetNamedMenu("!MakerMainMenu"); //If this fails, you've got bigger problems return;
}
How to specify the (most likely needed) text range?
Thank You
Klaus Daube