Skip to main content
Participant
September 28, 2020
Answered

Converting HTML Anchors to FrameMaker XREFs

  • September 28, 2020
  • 1 reply
  • 500 views

Hi All,

   I've been asked to debug a FrameScript.   I'm having trouble finding anything on Google ...   I hope this is the correct forum to ask this question.

 

 

What is the proper way to convert an HTML Anchor to an XREF in FrameScript
As an example:
In the html document that is being converted, there is this line
<a href="./sysPicTimer.html#sysPicTimerDisable" class="routine">sysPicTimerDisable(&nbsp;)</a>

In the resulting document, we want sysPicTimerDisable() to be the text and the XREF will direct you to ./sysPicTimer.html#sysPicTimerDisable

 

i.e.    sysPicTimerDisable()

 

 

This is what we have - which apparently has been working for many years ....

 

Loop While(gvPgfVar)
   Write console gvPgfVar.Text;
   Set gvNextPgf = gvPgfVar.NextPgfInDoc;
   Find '<a href="./' InObject(gvPgfVar) ScrollTo ReturnStatus(gvStat) ReturnRange(gvRange);
   If gvStat=true
      Delete Text(gvRange);
      Set gvNewRange = gvRange;
      Find '" class="routine">' InObject(gvPgfVar) ScrollTo ReturnStatus(gvStat) ReturnRange(gvRange);
      If gvStat=true
         Set gvNewRange.end = gvRange.end; //gvNewRange contains HTML Xref
         set temp=Text(gvNewRange);
         Delete Text(gvNewRange); //delete HTML Xref
         Find '</a>' InObject(gvPgfVar) ScrollTo ReturnStatus(gvStat) ReturnRange(gvRange);
         If gvStat=true
            Set gvNewRange.end = gvRange.begin; //gvNewRange contains Xref text
            Set gvXrefText= gvNewRange.Text;
            Set gvNewRange.end = gvRange.end;
            Delete Text(gvNewRange); //delete HTML Xref
            New XRef Format('Heading Only') TextLoc(gvNewRange.begin) NewVar(gvXRef);
            Set gvXRef.XRefSrcText = gvXrefText;   \\ ERROR OCCURS hear . Read Only Variable
         Endif
      Endif
   EndIf
   Find '<a href="./' InObject(gvPgfVar) ScrollTo ReturnStatus(gvStat) ReturnRange(gvRange);
   If gvStat=false
      Set gvPgfVar = gvNextPgf; //Go to next paragraph. Otherwise, continue in this paragraph.
   Endif
EndLoop
// Update the cross-references.
Update DocObject(ActiveDoc) XRefs Everything;


I've been told that this has been working for years ... but has since stopped working with an error at this line
Set gvXRef.XRefSrcText = gvXrefText;

Indicating that gvXRef.XRefSrcText is read-only

Is there a better way to approach this?

 

    This topic has been closed for replies.
    Correct answer frameexpert

    Right, but I would still think of terms of testable and reusable functions. For this one, you need the same XRefFmt object for the entire document, so get that upfront. I am pressed for time so I will just show you pseudo-code:

    Function ProcessDoc oDoc

    Local oXRefFmt;

    // Get the required cross-reference format object before starting.

    Set oXRefFmt = GetXRefFmt {'Heading Only', '<$paratext>', oDoc};

    ....

    EndFunc

     

    Function GetXRefFmt sName sFmt oDoc

    Local oXRefFmt;

    Get Object Name(sName) Type(XRefFmt) DocObject(oDoc) NewVar(oXRefFmt);

    If oXRefFmt = 0

        New XRefFmt Name(sName) DocObject(oDoc) NewVar(oXRefFmt);

        Set oXRefFmt.Fmt = sFmt;

    End If

     

    Set Result = oXRefFmt;

    End Func

     

    Now you have a reuseable function that you can use anywhere and not worry about how it works. It is just a "black box" that you plug into any script that needs it. Best of all, it doesn't clutter up the main part of your script; it is just called where it is needed.

    1 reply

    frameexpert
    Community Expert
    Community Expert
    September 29, 2020

    I wouldn't have all of the tasks done in one big loop, but would call one or more functions to find the text, replace it with xref, etc. That would make it easier to test and troubleshoot with a single occurrence. Plus, you need some error checking; for example, does the "Heading Only" Cross-reference format exist in the document? If not, this could cause the error you are getting.

    Participant
    October 1, 2020

    Thanks @frameexpert !!!

     

    You were spot on the money.   Someone had changed the Cross-reference format name in the document from "Heading Only" to "Headings".  😞      

     

    For the Eror Checking of the XRef format ... Would you recommend something like this?

    ...

    Get Object Name('Heading Only') Type (XRefFmt) NewVar(oTestXRefFmt);

    If (oTestXRefFmt = 0)

       // Create the 'Heading Only' Cross Reference format

       New XRefFormat name('oTempXRefFmt')

       Set oTempXRefFmt.Fmt = 'I will do some testing to figure out what goes here';

       Set oTempXRefFmt.Name = 'Heading Only';

       // I have no idea how to apply it to a document ... so I might just write it out to the console, halt the script and get the user to manually enter it.

    End If

     

    frameexpert
    Community Expert
    frameexpertCommunity ExpertCorrect answer
    Community Expert
    October 2, 2020

    Right, but I would still think of terms of testable and reusable functions. For this one, you need the same XRefFmt object for the entire document, so get that upfront. I am pressed for time so I will just show you pseudo-code:

    Function ProcessDoc oDoc

    Local oXRefFmt;

    // Get the required cross-reference format object before starting.

    Set oXRefFmt = GetXRefFmt {'Heading Only', '<$paratext>', oDoc};

    ....

    EndFunc

     

    Function GetXRefFmt sName sFmt oDoc

    Local oXRefFmt;

    Get Object Name(sName) Type(XRefFmt) DocObject(oDoc) NewVar(oXRefFmt);

    If oXRefFmt = 0

        New XRefFmt Name(sName) DocObject(oDoc) NewVar(oXRefFmt);

        Set oXRefFmt.Fmt = sFmt;

    End If

     

    Set Result = oXRefFmt;

    End Func

     

    Now you have a reuseable function that you can use anywhere and not worry about how it works. It is just a "black box" that you plug into any script that needs it. Best of all, it doesn't clutter up the main part of your script; it is just called where it is needed.