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.
|