View Single Post
 
Old 10-10-2017, 08:10 AM
slaycock slaycock is offline Windows 7 64bit Office 2013
Expert
 
Join Date: Sep 2013
Posts: 255
slaycock is on a distinguished road
Default

Well, that was an entertaining exercise. There are certainly some vagaries and ranges and moving ranges after inserting a hyperlink.

The following code is now much close to what you want. You have to ensure that the last text is not s reference, hence my 'some more text'

Code:
Option Explicit

' Note the use of module scope constants and variable
 
Const NAME                              As Long = 0
Const CHAPTER                           As Long = 1
Const VERSE_1                           As Long = 2
Const VERSE_2                           As Long = 3
Const NULL_REFERENCE                    As String = ",,,"

Const SPACE                             As String = " "
Const COMMA                             As String = ","
Const SEMI_COLON                        As String = ";"
Const HYPHEN                            As String = "-"
Const USCORE                            As String = "_"
Const LBRACKET                          As String = "("
Const RBRACKET                          As String = ")"
Const COLON                             As String = ":"
Const POINT                             As String = "."

Const FULL_HYPERLINK                    As Boolean = True
Const VERSE_ONLY_HYPERLINK              As Boolean = False

Const AUTHORITY_PLACEHOLDER             As String = "<authority>"
Const PATH_TO_REFERENCES                As String = "W:\Skydrive\Docs\<authority>.htm#chpt_"

Const LIST_OF_AUTHORITIES               As String = "John, Matthew,Mark , Revelation," _
                                                    & "Genesis, Exodus , Judges "
                                                    
Private authority_ref()                     As String

Sub main()
 
    Dim authorities()                       As String
    Dim authority                           As Variant
    
    authorities = Split(Replace(LIST_OF_AUTHORITIES, SPACE, vbNullString), COMMA)
    authority_ref = Split(NULL_REFERENCE, COMMA)
    For Each authority In authorities                   'authority is a variant but the sub argument is a string hence the cast
        authority_ref(NAME) = CStr(authority)
        insert_authority_hyperlinks
    Next
   
End Sub
   
Sub insert_authority_hyperlinks()
 
    ' The search text means the following
    ' Search terms have been split into a number of terms using ()
    '(<authority>)  find text starting with the reference authority
    '(*) select all characters until the character specified in the next () field
    '(:) include the colon in the selection
    '(*) select all characters until the character specified in the next field is found
    '([ ,-;]) select all characters until we find a space, comma, hyphen or semicolon
   
    Const PRIMARY_SEARCH_TEXT                       As String = "(<authority>)( @)([0-9])(*)(:)(*)([ ,\-;])"
    
    Dim rng                                 As Word.range
    Dim end_of_rng                          As Long
 
    Set rng = ActiveDocument.StoryRanges(wdMainTextStory)
    Do
        With rng.Find
            .Text = Replace(PRIMARY_SEARCH_TEXT, AUTHORITY_PLACEHOLDER, authority_ref(NAME))
            .MatchWildcards = True
            .Forward = True
            .Wrap = wdFindStop
            .Execute
            If .Found Then
               process_single_hyperlink rng, FULL_HYPERLINK
            End If
        End With
    Loop Until Not rng.Find.Found
   
End Sub

Function process_single_hyperlink(rng As Word.range, hyperlink_type As Boolean)

    Const AFTER_A_NUMBER                        As String = " ),.;"
    Const RUN_OF_NUMBERS                        As String = "([0-9]{1,})"

    Dim last_char                               As String
    
    last_char = rng.Characters.Last.Text
    Select Case last_char
    
        Case HYPHEN
            rng.MoveEndUntil cset:=AFTER_A_NUMBER
            authority_ref(NAME) = Split(rng.Text, SPACE)(0)
            authority_ref(CHAPTER) = Split(Split(rng.Text, SPACE)(1), COLON)(0)
            authority_ref(VERSE_1) = Split(Split(rng.Text, COLON)(1), HYPHEN)(0)
            'Just in case you need the end reference
            authority_ref(VERSE_2) = Split(Split(rng.Text, COLON)(1), HYPHEN)(1)
            authority_ref(VERSE_2) = Mid$(authority_ref(VERSE_2), 1, Len(authority_ref(VERSE_2)) - 1)
            insert_hyperlink rng, FULL_HYPERLINK
            If last_char = COMMA Then
                insert_hyperlink rng, VERSE_ONLY_HYPERLINK
            End If
            
        Case COMMA
            rng.MoveEnd unit:=wdCharacter, Count:=-1
            authority_ref(NAME) = Split(rng.Text, SPACE)(0)
            authority_ref(CHAPTER) = Split(Split(rng.Text, SPACE)(1), COLON)(0)
            authority_ref(VERSE_1) = Split(Split(rng.Text, COLON)(1), HYPHEN)(0)
            insert_hyperlink rng, FULL_HYPERLINK
           
            If rng.Characters.Last = "," Then
                rng.Select
                rng.End = ActiveDocument.StoryRanges(wdMainTextStory).End
                rng.Select
                 With rng.Find
                    .Text = RUN_OF_NUMBERS
                    .MatchWildcards = True
                    .Forward = True
                    .Wrap = wdFindStop
                    .Execute
                End With
                rng.MoveEnd unit:=wdCharacter, Count:=1
                process_single_hyperlink rng, VERSE_ONLY_HYPERLINK
            End If
            
        Case SPACE, SEMI_COLON, POINT, RBRACKET
            rng.MoveEnd unit:=wdCharacter, Count:=-1
            If hyperlink_type = FULL_HYPERLINK Then
                authority_ref(NAME) = Split(rng.Text, SPACE)(0)
                authority_ref(CHAPTER) = Split(Split(rng.Text, SPACE)(1), COLON)(0)
                authority_ref(VERSE_1) = Split(Split(rng.Text, COLON)(1), HYPHEN)(0)
            Else
                authority_ref(VERSE_1) = rng.Text
            End If
            insert_hyperlink rng, hyperlink_type
            
        Case Else
            MsgBox "Oops.  We found something that wasn't expected.  The problem text is selected", vbOKOnly
            rng.Select
            Stop
    End Select
    
End Function

Sub insert_hyperlink(reference As Word.range, hyperlink_type As Boolean)
    
    Dim range_len                       As Long
    
    range_len = reference.Characters.Count
    
    ActiveDocument.Hyperlinks.Add _
                Anchor:=reference, _
                Address:= _
                    Replace(PATH_TO_REFERENCES, AUTHORITY_PLACEHOLDER, authority_ref(NAME)) _
                    & authority_ref(CHAPTER) _
                    & "_" _
                    & authority_ref(VERSE_1), _
                TextToDisplay:=IIf(hyperlink_type, reference.Text, authority_ref(VERSE_1))
    reference.MoveStart unit:=wdCharacter, Count:=range_len
    
End Sub
The case statement code in process_single_hyperlink is a bit messy but I don't have time to tidy it further.

The code above has been tested on the text below.

Quote:

(John 1:16-20)
(Mark 3:18-33)
(Matthew 9:89-101)
(John 1:16-20)
(Mark 3:18-33)
(Matthew 9:89-101)
(John 1:16-20)
(Mark 3:18-33)
(Matthew 9:89-101)
(John 1:16-20)
(Mark 3:18-33)
(Matthew 9:89-101)
John was apparently among the first of John the Baptist’s disciples to be introduced to Jesus and one of the first four to be invited to be followers of Christ. (Mark 1:16-20; John 1:35-39) John, who may have been a cousin of Jesus, developed a close friendship with Jesus, becoming known as “the disciple whom Jesus loved.” (John 13:23; John 21:20, 24) John was present at the heartbreaking scene of execution, where Jesus entrusted the care of his mother to John. Also, it was John who outran Peter as they sped to the tomb to investigate the report that Jesus had risen.— John 19:26, 27; John 20:2-4.

the Word: Or “the Logos.” Greek, ho loʹgos. Here used as a title, it is also used at John 1:14 and Revelation 19:13. John identified the one to whom this title belongs, namely, Jesus. This title was applied to Jesus during his prehuman existence as a spirit creature, during his ministry on earth as a perfect man, and after his exaltation to heaven. Jesus was God’s Word of communication, or Spokesman, for conveying information and instructions to the Creator’s other spirit sons and to humans. So it is reasonable to think that prior to Jesus’ coming to earth.—Genesis 16:7-11; Genesis 22:11; Genesis 31:11; Exodus 3:2-5; Judges 2:1-4; Judges 6:11, 12; Judges 13:3. some more text
I've still no idea if the hyperlink fields that are inserted are actually correct hyperlinks.

Good luck.
Reply With Quote