The front-end application requires that each hypertext link have an integer associated with that identifies a record in the Hypertext table. In addition, the front-end application requires a specific formatting code sequence to identify a segment of text as hypertext (which it will then turn green and underlined). Rather than having the author try to specify hyperlinks the way front end expects them, we developed an alternative format that the compiler can translate into the appropriate format. The author specifies a hypertext link as follows:
^.^Text to be made hot@Id of screen&
This text consists of the phrase the author wants to be hot, the id of the screen to be displayed when the hot text is clicked, and three delimiters: ^.^ marks the beginning of the hot text; @ marks the end of the hot text and the beginning of the screen id; & marks the end of the screen id.
When the compiler finds this type of text string it translates it into the appropriate front-end formatting and creates a record in the Hypertext table. For example, the text above might look like this when the compiler has transformed it
\ATXht123 \uldb \ATXul1282 Text to be made hot\ATXht0 \ulnone \ATXul0
The hot text is bracketed by various formatting and hypertext identifiers. The screen id has been transformed into an integer code (in this case 123).
The transformation is accomplished in the following routine. It searches for the delimiters in the string it is passed (sText), transforms the string, and creates a record in the Hypertext table (if the appropriate one does not already exist.
Function bProcessHotText (sText As String) As Integer 'kill variations on the starting tag sText = sReplaceString(sText, "^" & Chr$(13) & Chr$(10) & ".^", "^.^") sText = sReplaceString(sText, "^." & Chr$(13) & Chr$(10) & "^", "^.^") ' find hypertext hot text and screen id nOffset1 = InStr(sText, "^.^") nMax = Len(sText) Do While nOffset1 nOffset2 = nOffset1 Do While Mid$(sText, nOffset2, 1) <> "@" If nOffset2 > nMax Then <error trap: missing @> Exit Function End If nOffset2 = nOffset2 + 1 Loop nOffset3 = nOffset2 Do While Mid$(sText, nOffset3, 1) <> "&" If nOffset3 > nMax Then <error trap: missing &> Exit Function End If nOffset3 = nOffset3 + 1 Loop 'figure id sId = Mid$(sText, nOffset2 + 1, nOffset3 - nOffset2 - 1) 'Kill any CRs or line feeds stuck in there sId = sReplaceString(sId, Chr$(13), "") sId = sReplaceString(sId, Chr$(10), "") sId = UCase$(sId) 'get or create integer key sKey = Format$(nLogHtLink(sId)) 'Reformat text with hotlink formatting sMidStr = Mid$(sText, nOffset1 + 3, nOffset2 - nOffset1 - 3) sMidStr = sReplaceString(sMidStr, "}{", "") sText = Left$(sText, nOffset1 - 1) sText = sText & "\ATXht" & sKey & " \uldb \ATXul1282 " sText = sText & sMidStr & "\ATXht0 \ulnone \ATXul0 " sText = sText & Mid$(sText, nOffset3 + 1) 'get next hyperlink nOffset1 = InStr(sText, "^.^") nMax = Len(sText) Loop bProcessHotText = True End Function
The routine above uses string manipulations to extract the hot text and screen id that the author entered. Much of the code is there to avoid problems in the RTF stream. For example, suppose the author types ^.^ in the source document. In a valid RTF representation of these characters there could be a carriage return/line feed between any two of these characters. Thus, the routine cannot simply search for these three contiguous characters. It must first reduce the various representations of this delimiter to a single version before searching the input string for it.
Character formatting in the RTF text may introduce any of a large variety of character combinations between any two characters in a given text segment. To avoid the potential problems of character formatting, we make sure that there is no character formatting applied to our hypertext delimiters.
To transform the screen id that the author types into the integer key that the front-end expects, the compiler uses the following routine.
Function nLogHtLink (sId As String) As Integer If Len(sId) > 15 Then errorflag "Invalid Hypertext id: " & sId Else mtbHyper.Index = "id" mtbHyper.Seek "=", sId If mtbHyper.NoMatch Then mtbHyper.AddNew mtbHyper("id") = sId mtbHyper.Update mtbHyper.Seek "=", sId End If mtbHyper.Seek "=", sId nLogHtLink = mtbHyper("key") End If
The routine searches the Hypertext table for the screen id it is passed. If the screen id is there, the routine returns the integer key associated with this screen id. If the screen id is not already in the Hypertext table, the routine creates a new record with the screen id it is passed. Because the integer key is an Access counter field, it is automatically set to the next available integer. To figure out what this next integer is, the routine seeks to the newly created record after creating it and returns its integer key.