PublicSub ZoteroLinkCitation() ' get selected area (if applicable) Dim nStart&, nEnd& nStart = Selection.Start nEnd = Selection.End ' toggle screen updating Application.ScreenUpdating = False ' define variables Dim title As String Dim titleAnchor As String Dim style As String Dim fieldCode As String Dim numOrYear As String Dim pos&, n1&, n2&, n3&
ActiveWindow.View.ShowFieldCodes = True Selection.Find.ClearFormatting ' find the Zotero bibliography With Selection.Find .Text = "^d ADDIN ZOTERO_BIBL" .Replacement.Text = "" .Forward = True .Wrap = wdFindContinue .Format = False .MatchCase = False .MatchWholeWord = False .MatchWildcards = False .MatchSoundsLike = False .MatchAllWordForms = False EndWith Selection.Find.Execute ' add bookmark for the Zotero bibliography With ActiveDocument.Bookmarks .Add Range:=Selection.Range, Name:="Zotero_Bibliography" .DefaultSorting = wdSortByName .ShowHidden = True EndWith ' loop through each field in the document ForEach aField In ActiveDocument.Fields ' check if the field is a Zotero in-text reference '################################################## IfInStr(aField.Code, "ADDIN ZOTERO_ITEM") > 0Then fieldCode = aField.Code '############# ' Prepare ' Plain citation== Format of Textfield shown ' must be in Brackets Dim plain_Cit As String plCitStrBeg = """plainCitation"":""[" plCitStrEnd = "]""" n1 = InStr(fieldCode, plCitStrBeg) n1 = n1 + Len(plCitStrBeg) n2 = InStr(Mid(fieldCode, n1, Len(fieldCode) - n1), plCitStrEnd) - 1 + n1 plain_Cit = Mid$(fieldCode, n1 - 1, n2 - n1 + 2) 'Reference 'as shown' in word as a string 'Title array in fieldCode (all referenced Titles within this field) Dim array_RefTitle(32) As String i = 0 DoWhileInStr(fieldCode, """title"":""") > 0 n1 = InStr(fieldCode, """title"":""") + Len("""title"":""") n2 = InStr(Mid(fieldCode, n1, Len(fieldCode) - n1), """,""") - 1 + n1 If n2 < n1 Then'Exception the type 'Article' n2 = InStr(Mid(fieldCode, n1, Len(fieldCode) - n1), "}") - 1 + n1 - 1 EndIf array_RefTitle(i) = Mid(fieldCode, n1, n2 - n1) fieldCode = Mid(fieldCode, n2 + 1, Len(fieldCode) - n2 - 1) i = i + 1 Loop Titles_in_Cit = i 'Number array with References shown in PlainCit 'Numer is equal or less than Titels, depending on the type '[3], [8]-[10]; [2]-[4]; [2], [4], [5] ' All citations have to be in Brackets each! [3], [8] not [3, 8] ' This doesnt work otherwise! ' --> treatment of other delimiters could be implemented here Dim RefNumber(32) As String i = 0 DoWhile (InStr(plain_Cit, "]") OrInStr(plain_Cit, "[")) > 0 n1 = InStr(plain_Cit, "[") n2 = InStr(plain_Cit, "]") RefNumber(i) = Mid(plain_Cit, n1 + 1, n2 - (n1 + 1)) plain_Cit = Mid(plain_Cit, n2 + 1, Len(plain_Cit) - (n2 + 1) + 1) i = i + 1 Loop Refs_in_Cit = i
'treat only the shown references (skip the rest) '[3], [8]-[10] --> skip [9] 'Order of titles given from fieldcode, not checked! If Titles_in_Cit > Refs_in_Cit Then array_RefTitle(Refs_in_Cit - 1) = array_RefTitle(Titles_in_Cit - 1) i = 1 DoWhile Refs_in_Cit + i <= Titles_in_Cit array_RefTitle(Refs_in_Cit + i - 1) = "" i = i + 1 Loop EndIf '############# 'Make the links For Refs = 0To Refs_in_Cit - 1Step1 title = array_RefTitle(Refs) array_RefTitle(Refs) = "" ' make title a valid bookmark name titleAnchor = title titleAnchor = MakeValidBMName(titleAnchor) ActiveWindow.View.ShowFieldCodes = False Selection.GoTo What:=wdGoToBookmark, Name:="Zotero_Bibliography" '' locate the corresponding reference in the bibliography '' by searching for its title Selection.Find.ClearFormatting With Selection.Find .Text = Left(title, 255) .Replacement.Text = "" .Forward = True .Wrap = wdFindContinue .Format = False .MatchCase = False .MatchWholeWord = False .MatchWildcards = False .MatchSoundsLike = False .MatchAllWordForms = False EndWith Selection.Find.Execute ' select the whole caption (for mouseover tooltip) Selection.MoveStartUntil ("["), Count:=wdBackward Selection.MoveEndUntil (vbBack) lnkcap = "[" & Selection.Text lnkcap = Left(lnkcap, 70) ' add bookmark for the reference within the bibliography Selection.Shrink With ActiveDocument.Bookmarks .Add Range:=Selection.Range, Name:=titleAnchor .DefaultSorting = wdSortByName .ShowHidden = True EndWith ' jump back to the field aField.Select ' find and select the numeric part of the field which will become the hyperlink Selection.Find.ClearFormatting With Selection.Find .Text = RefNumber(Refs) .Replacement.Text = "" .Forward = True .Wrap = wdFindContinue .Format = False .MatchCase = False .MatchWholeWord = False .MatchWildcards = False .MatchSoundsLike = False .MatchAllWordForms = False EndWith Selection.Find.Execute numOrYear = Selection.Range.Text & "" ' store current style style = Selection.style ' Generate the Hyperlink -->Forward! ActiveDocument.Hyperlinks.Add Anchor:=Selection.Range, Address:="", SubAddress:=titleAnchor, ScreenTip:=lnkcap, TextToDisplay:="" & numOrYear ' reset the style Selection.style = style
' comment if you want standard link style aField.Select With Selection.Font .Underline = wdUnderlineNone .ColorIndex = wdBlack EndWith Next Refs 'References in Cit
EndIf'If Zotero-Field '#########################
Next aField ' next field
' go back to original range selected ActiveWindow.View.ShowFieldCodes = False ActiveDocument.Range(nStart, nEnd).Select EndSub Function MakeValidBMName(strIn As String) Dim pFirstChr As String Dim i As Long Dim tempStr As String strIn = Trim(strIn) pFirstChr = Left(strIn, 1) IfNot pFirstChr Like "[A-Za-z]"Then strIn = "A_" & strIn EndIf For i = 1ToLen(strIn) SelectCaseAsc(Mid$(strIn, i, 1)) Case49To57, 65To90, 97To122 tempStr = tempStr & Mid$(strIn, i, 1) CaseElse tempStr = tempStr & "_" EndSelect Next i tempStr = Replace(tempStr, " ", " ") MakeValidBMName = Left(tempStr, 40) EndFunction