Copy link to clipboard
Copied
Dear all,
Script part InsertXRef2 works correctly when starting in a document (case a). It does not insert the cross reference if the document is a book component (case b).
In case a the footnote references and the endnotes are in the same document (at end).
In case b the footnote references are in one book component and the endnotes are collected in a new book component.
When calling InsertXRef2 the arguments are:
a: oDoc = app.ActiveDoc;
b: oDoc = SimpleOpen (goFno.aoBkDocsCollected[jDoc].Name);
a,b: oTR = new TextRange (oTL1, oTL2); // the footnote reference
a,b: sXRefFmt = "zenref-endnote-reference" containing "<hypertext><super>\ <$paranumonly>\ "
a: oTgtDoc = oDoc;
b: oTgtDoc = SimpleNewDoc (oTplDoc.Name, 0);
a,b: oTgtTL = goFno.aoEndNoteTL
; // Begin of endnote in oTgtDoc
I get this output for the first footnote reference to be replaced by a cross reference to the corresponding endnote:
oTR...offset: 214, 215
oXRef.TextRange...offset: 214, 215
The latter is strange since the XRef should have a length of 3 ($paranumonly is figure 1).
Terminating the script shows no inserted XRef and inspecting the current 'selection' yields:
app.ActiveDoc...offset: 216, 216
Which is even more strange, because this is 2 characters behind the deleted footnote ref (which was a superscripted figure 1).
→ I don't have the faintest idea what's going on here.
→ I also have no idea how to strip the situation down to a singe test script.
→ Hence I have ZIPped the full script and the book files at https://daube.ch/zz_tests/ConvertFootnotes.zip
Test 1: have one of the book files active before you start the script and run it through.
The cross reference will be there
Test 2: Have the book active before yu start the script.
The cross references are not inserted, albeit all footnote refs with the footnotes are deleted.
function InsertXRef2 (oDoc, oTR, sXRefFmt, oTgtDoc, oTgtTL) { //=== Replace TR by XRef ================
// Arguments oDoc: Document receiving the XRef
// oTR: Text Range which shall be replaced by the cross reference
// sXrefFmt: Cross reference format name from the catalogue
// oTgtDoc: Document in which the endnotes are (same as oDoc if just document processing)
// This document gets the cross ref marker
// oTgtTL: Where the XRef marker shall be inserted (beg of endnote ¶)
// 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 ("").
// Reference https://forums.adobe.com/thread/2088696
var oHTR, oMarker, oXRef, sXRefID, oEnPgf, oTL;
// --- Prepare the required information ------------
sXRefID = oTgtTL.obj.id + ":" + oTgtTL.obj.Unique; // take properties from the oTgtObj
// --- Create the Cross reference Marker -----------
app.ActiveDoc = oTgtDoc;
oMarker = oTgtDoc.NewAnchoredMarker(oTgtTL); // Marker to be inserted in target object
oMarker.MarkerTypeId = oTgtDoc.GetNamedMarkerType ("Cross-Ref"); //Make it a Cross-Ref marker
oMarker.MarkerText = sXRefID; // Marker text needs to be unique
// --- Create the Cross reference ------------------
app.ActiveDoc = oDoc;
oDoc.TextSelection = oTR;
oDoc.DeleteText (oTR); // delete the footnote
oTL = oTL = oTR.beg; // identicak to new TextLoc (oTR.beg.obj, oTR.beg.offset);
oXRef = oDoc.NewAnchoredFormattedXRef(sXRefFmt, oTL); // Insert a new xref object
$.writeln("oTR...offset: " + oTR.beg.offset + ", " + oTR.end.offset +
"\noXRef.TextRange...offset: " + oXRef.TextRange.beg.offset + ", " + oXRef.TextRange.end.offset);
$.bp(true);
oXRef.XRefSrcIsElem = false; // Required to make it an unstructured xref
oXRef.XRefFile = oTgtDoc.Name; // OK ???
oXRef.XRefSrcText = oMarker.MarkerText;
oDoc.UpdateXRef(oDoc, oXRef); //Update the new xref.
} //--- end InsertXRef2
Inspecting the various versions of XRefs in this game:
Property | Case a) | Case b) | Manually inserted |
---|---|---|---|
XRef-text in « and » | « 1 » | «» | « 1 » |
XRefFile | E:\_DDDprojects\FM-Notes\TestScripts\bookfile_1.fm | E:\_DDDprojects\FM-Notes\TestScripts\endnotes.fm | E:\_DDDprojects\FM-Notes\TestScripts\endnotes.fm |
XRefSrcText | 520282402:1000906 | 520302871:1001835 | 520302871:1001835 |
XRefFmtName | zenref-endnote-reference | zenref-endnote-reference | zenref-endnote-reference |
XRefFmt | <hypertext><super>\ <$paranumonly>\ | <hypertext><super>\ <$paranumon |
Copy link to clipboard
Copied
Still experimenting I find strange things:
Looking at the ordinary document which gets the endnotes at its end, the cross references inserted by the script is one:
Running the script from the book and leaving it at line 33 gives me a selection which is a cross reference (found with Find dialgoue):
If I do not use Find after the script is left, but use the selection/location to manually insert a cross reference, this is inserted immediately after the nearly invisible one - still both can be found with the Find dialogue.
This provokes the idea that I need to set up the full properties of the cross reference, before I insert it (as I have learned for graphic objects). But this is not possible here: nothing will be inserted:
oXRef = {};
oXRef.XRefSrcIsElem = false;
oXRef.XRefFile = oTgtDoc.Name;
oXRef.XRefSrcText = oMarker.MarkerText;
oXRef = oDoc.NewAnchoredFormattedXRef(sXRefFmt, oTL); // Insert a new xref object
oDoc.UpdateXRef(oDoc, oXRef); //Update the new xref.
So I'm still clueless for the book components...
Copy link to clipboard
Copied
I thought I'd picked up some tracks now - but no...
When storing the document in the array (for consistant access to them) the two items are different
a) goFno.aoBkDocsCollected[0].Doc.type = 4
b) goFno.aoBkDocsCollected[0].Doc.type = 3
But in the processing loop I use
oDoc = SimpleOpen (goFno.aoBkDocsCollected
and this guarantees that in InsertXRef2 oDoc.type is 4 in all cases.
→ This hunt does not lead to the wild boar…
Even this does not change anything - we still get the two Xrefs as pointed out yesterday (if at the stop of the script I insert an XRef manually at the current location):
// --- Create the Cross reference ------------------
app.ActiveDoc = oDoc;
//oDoc.TextSelection = oTR;
oDoc.DeleteText (oTR); // delete the footnote
oTRnew = oDoc.TextSelection;
oTL = oTRnew.beg;
oXRef = oDoc.NewAnchoredFormattedXRef(sXRefFmt, oTL); // Insert a new xref object
oXRef.XRefSrcIsElem = false; // Required to make it an unstructured xref
oXRef.XRefFile = oTgtDoc.Name; // OK ???
oXRef.XRefSrcText = oMarker.MarkerText;
oDoc.UpdateXRef(oDoc, oXRef); //Update the new xref.
$.bp(true);
Copy link to clipboard
Copied
Inspecting the various versions of XRefs in this game:
Property | Case a) | Case b) | Manually inserted |
---|---|---|---|
XRef-text in « and » | « 1 » | «» | « 1 » |
XRefFile | E:\_DDDprojects\FM-Notes\TestScripts\bookfile_1.fm | E:\_DDDprojects\FM-Notes\TestScripts\endnotes.fm | E:\_DDDprojects\FM-Notes\TestScripts\endnotes.fm |
XRefSrcText | 520282402:1000906 | 520302871:1001835 | 520302871:1001835 |
XRefFmtName | zenref-endnote-reference | zenref-endnote-reference | zenref-endnote-reference |
XRefFmt | <hypertext><super>\ <$paranumonly>\ | <hypertext><super>\ <$paranumonly>\ | <hypertext><super>\ <$paranumonly>\ |
I can not understand, why in case b) no XRef-text appears…
I'm definitely missing a property to set the visible text of the cross-reference. I could create it from all the information I have from the created XRef marker - but have no 'handle' to integrate it into the cross reference (line 4 hereafter).:
oDoc.TextSelection = oTR;
oDoc.DeleteText (oTR); // delete the footnote
oTL = oTR.beg;
oDoc.AddText (oTL, "sXRefText"); // does not become part of the XRef!
oXRef = oDoc.NewAnchoredFormattedXRef(sXRefFmt, oTL); // Insert a new xref object
oXRef.XRefSrcIsElem = false; // Required to make it an unstructured xref
oXRef.XRefFile = oTgtDoc.Name;
oXRef.XRefSrcText = oMarker.MarkerText;
oDoc.UpdateXRef(oTgtDoc, oXRef); //Update the new xref.
Documentation concerning the UpdateXRef is not clear at all:
FDK reference: F_ApiUpdateXRef() Updates a specified cross-reference in the document.
IntT F_ApiUpdateXRef(F_ObjHandleT docId, F_ObjHandleT srcDocId, F_ObjHandleT xrefId);
docId The ID of the document that contains the cross-reference.
srcDocId The ID of the source document that the cross-reference references.
xrefId The ID of the cross-reference to be updated.
Scripting Guide: UpdateXRef(srcDoc, xref) Updates the cross-references in a document. It performs the same operation as clicking Update in the Cross-Reference window.
srcDoc Doc No The document in which to update cross-references. This turns out to be wrong. This must be the document with the Xref Marker!
xref XRef No Flags to indicate which cross-references to update.
??? object type of flags be XRef ?
You can OR the values listed in the following tables into the updateXRefFlags argument.
The most useful flag for me would be
Constants.FF_XRUI_OPEN_DOCS (0x02) Updates only cross-references whose sources are in open documents.
New trial of script:
oDoc.UpdateXRef(oDoc, Constants.FF_XRUI_OPEN_DOCS);
This reports an FA_errno of -3 (FE_BadObjId)
→ So the question is whether I need to have 3 parameters as defined in FDK or another Document ID for the fist argument according to Scripting Guide
This is also mentioned at updateXRef(srcDoc, xref) framemaker documentation issue But whatever I try, I get this Error:
oDoc.UpdateXRef(oTgtDoc, oXRef); // FA_errno of -3 (FE_BadObjId)
oDoc.UpdateXRef(oDoc, oXRef); // FA_errno of -3 (FE_BadObjId)
For the single document (case a) both yield no error (FA_errno is 0).
Wait a minute, I did now three tests with the line 01 above - and HOORAY: success
function InsertXRef2 (oDoc, oTR, sXRefFmt, oTgtDoc, oTgtTL) { //=== Replace TR by XRef ================
// Arguments oDoc: Document receiving the XRef
// oTR: Text Range which shall be replaced by the cross reference
// sXrefFmt: Cross reference format name from the catalogue
// oTgtDoc: Document in which the endnotes are (same as oDoc if just document processing)
// This document gets the cross ref marker
// oTgtTL: Where the XRef marker shall be inserted (beg of endnote ¶)
// 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.
// Reference Russ Ward in https://forums.adobe.com/thread/2088696
var oHTR, oMarker, oXRef, sXRefID, oEnPgf, oTL;
// --- Create the Cross reference Marker -----------
app.ActiveDoc = oTgtDoc;
oMarker = oTgtDoc.NewAnchoredMarker(oTgtTL); // Marker to be inserted in target object
oMarker.MarkerTypeId = oTgtDoc.GetNamedMarkerType ("Cross-Ref"); //Make it a Cross-Ref marker
sXRefID = oTgtTL.obj.id + ":" + oTgtTL.obj.Unique; // Marker text needs to be unique
oMarker.MarkerText = sXRefID;
// --- Create the Cross reference ------------------
app.ActiveDoc = oDoc;
oDoc.TextSelection = oTR;
oDoc.DeleteText (oTR); // delete the footnote
oTL = oTR.beg;
oXRef = oDoc.NewAnchoredFormattedXRef(sXRefFmt, oTL); // Insert a new xref object
oXRef.XRefSrcIsElem = false; // Required to make it an unstructured xref
oXRef.XRefFile = oTgtDoc.Name; // OK ???
oXRef.XRefSrcText = oMarker.MarkerText;
oDoc.UpdateXRef(oTgtDoc, oXRef); //Update the new xref.
} //--- end InsertXRef2
Copy link to clipboard
Copied
I think the thing that is wrong is XRefSrcText.
It can be set up by doing the following:
var paragraphId = targetPgf.Unique;
var pgfTag; // The paragraph tag.
newXref.XRefSrcText = '' + paragraphId + ':' + pgfTag + ':';
Copy link to clipboard
Copied
Dan, thanks for this idea. IMHO this is what the GUI method Insert XRef does.
The description in FDK tells:
If FP_XRefSrcIsElem is False, the text of the cross-reference source marker; if FP_XRefSrcIsElem is True, ....
Be aware that the sentence here for the case "FP_XRefSrcIsElem is False" is not complete - it does not tell anything what the the string should contain.
FM scripting guide tells more (same as your comment):
If XRefSrcIsElem is False, the XRefSrcText property is a string specifying UID:pgf_tag:text, where UIDrepresents the unique ID for the paragraph, pgf_tag is the name of the paragraph format, and text is the text content of the paragraph.
I have however no problem with 'my identification' for XRefs pointing to a marker in the same file. My problem occurs only in XRefs which point to another file.
And: I havn't found single phrase "must be" related to the contents of the marker text for Cross-Ref markers.
Nevertheless I will check your advice.
Dan, sorry to tell: defining the stuff as shown below does not help against the failing UpdateXRef in case of a book file (target of XRef is a different file).
function Fno_InsertXRef (oDoc, oTL, sXRefFmt, oTgtDoc, oTgtTL) { //=== Insert XRef at Tloc ========
// Arguments oDoc Document receiving the XRef
// oTL TextLoc at which to insert the XRef
// sXrefFmt Cross reference format name from the catalogue
// oTgtDoc Document in which the XRef marker will reside
// oTgtTL Where the XRef marker shall be inserted
// Returns oXRef Created XRef object
// Reference https://forums.adobe.com/thread/2641818
var oHTR, oMarker, oXRef, pgfID, pgfTag, sXRefID, oTgtPgf;
// --- Create the Cross reference Marker -----------
app.ActiveDoc = oTgtDoc;
oTgtPgf = oTgtTL.obj;
pgfID = oTgtPgf.Unique;
pgfTag = oTgtPgf.tag
sXRefID = "" + pgfID + ": " + pgfTag + ":";
//sXRefID = oTgtTL.obj.id + ":" + oTgtTL.obj.Unique; // Marker text needs to be unique
oMarker = oTgtDoc.NewAnchoredMarker(oTgtTL); // Marker to be inserted in target object
oMarker.MarkerTypeId = oTgtDoc.GetNamedMarkerType ("Cross-Ref"); //Make it a Cross-Ref marker
oMarker.MarkerText = sXRefID; // Unique enough ?
// --- Create the Cross reference ------------------
app.ActiveDoc = oDoc;
oXRef = oDoc.NewAnchoredFormattedXRef(sXRefFmt, oTL); // Insert a new xref object
oXRef.XRefSrcIsElem = false; // Required to make it an unstructured xref
oXRef.XRefFile = oTgtDoc.Name; // Required for oDoc != oTgtDoc
oXRef.XRefSrcText = sXRefID;
oDoc.UpdateXRef(oTgtDoc, oXRef); // Establish the new xref.
return oXRef; // may be required by calling function
} //--- end Fno_InsertXRef