Word: Possibility to link references and bibliography in a document?

13»
  • +1 wishing to have an in-text citation option for my zotero bibliography..
    astonishing (and a bit sad) to see this thread open since 2013..
    and still no reply from zotero :(
  • it's a pity.. but quite clear. thanks
  • Hello,
    I made a review of @cjac1 s word macro, because I also need the links and there were some issues with the script.
    You can use this as a basis, or adjust some parts to your needs. My citations are of the type [1], [2], [4]; or [1]-[3]; or [1], [2]-[5], and the macro (below) can handle all of these. Each Ref. has to be in brackets [].
    Every visible number of the citation block is converted to a hyperlink. I have tested it with my thesis (Word 2016, >70 references). It worked quite well, but i recommend to test it on a copy of your file. The changes are irreversible.
    I have mainly only standard references (articles, papers, thesis, books and book sections). I got a problem with a document type ref, but i fixed this (more or less). So in some special cases there are issues... maybe, I dont know.

    Hyperlinks doesnt work in footnotes.

    copy it: in Word Alt+F8; type any name --> create; copy+paste all of the code there,
    start it: in Word Alt+F8; choose ' ZoteroLinkCitation' --> run

    Have Fun! And sry for the long post.



    Public Sub 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
    End With
    Selection.Find.Execute

    ' add bookmark for the Zotero bibliography
    With ActiveDocument.Bookmarks
    .Add Range:=Selection.Range, Name:="Zotero_Bibliography"
    .DefaultSorting = wdSortByName
    .ShowHidden = True
    End With

    ' loop through each field in the document
    For Each aField In ActiveDocument.Fields
    ' check if the field is a Zotero in-text reference
    '##################################################
    If InStr(aField.Code, "ADDIN ZOTERO_ITEM") > 0 Then
    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
    Do While InStr(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
    End If
    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
    Do While (InStr(plain_Cit, "]") Or InStr(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


  • ' Part 2: seamless copy!


    '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
    Do While Refs_in_Cit + i <= Titles_in_Cit
    array_RefTitle(Refs_in_Cit + i - 1) = ""
    i = i + 1
    Loop
    End If

    '#############
    'Make the links
    For Refs = 0 To Refs_in_Cit - 1 Step 1
    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
    End With
    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
    End With

    ' 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
    End With
    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
    End With

    Next Refs 'References in Cit

    End If 'If Zotero-Field
    '#########################

    Next aField ' next field

    ' go back to original range selected
    ActiveWindow.View.ShowFieldCodes = False
    ActiveDocument.Range(nStart, nEnd).Select

    End Sub
    Function MakeValidBMName(strIn As String)
    Dim pFirstChr As String
    Dim i As Long
    Dim tempStr As String
    strIn = Trim(strIn)
    pFirstChr = Left(strIn, 1)
    If Not pFirstChr Like "[A-Za-z]" Then
    strIn = "A_" & strIn
    End If
    For i = 1 To Len(strIn)
    Select Case Asc(Mid$(strIn, i, 1))
    Case 49 To 57, 65 To 90, 97 To 122
    tempStr = tempStr & Mid$(strIn, i, 1)
    Case Else
    tempStr = tempStr & "_"
    End Select
    Next i
    tempStr = Replace(tempStr, " ", " ")
    MakeValidBMName = Left(tempStr, 40)
    End Function
  • I have been writing a macro for libreoffice odt files. I assumed that the listing of references was by numbered paragraph, and therefore just made a bookmark called _Ref_n where n is the paragraph number, and linked from the citation number to that. This would be much shorter.
    Also similar procedure for author names (by this is not so accurate with multiple references where the first author is the same - links just to the first reference in the sequence, or to authors with say "van der" or some other lowercase prenom).
  • Thanks for the great work and for sharing, the macro's newest version worked perfectly for me.
  • This thread is great and just what I'm looking for. I need to link citations in a PDF for a report I'm writing.

    When I run the script though, the whole document appears to be blank. The word count still shows up, so it's doing something bad to the document, but I'm afraid I'm not enough of a programmer to understand what.

    Have folks gotten this script to work?
  • Very interesting thread. I hope we can have an official release of such a feature.
  • Checking back in to see if Zotero has made any progress with this feature.
  • Nothing new
  • Thank you, @freim86 , for the work ! It's like magic !

    I would like to update the instructions for those who are not on Windows:
    I copied the 2 parts of the script in a text file.
    Then open Tools > Macros > Visual Basic Editor . In there, I created a new module under Normal > Modules, and in that window I pasted everything from the text file. Save, close. Switch back to Word. You may need to restart it.
    Then, to run it, you open Tools > Macros > "Macros...". You should see the name "ZoteroLinkCitation" in there. Select it, then click Run. Wait. Voilà !

    So yes, @Phill_Jones , it works for me. But I have a small 5-page document.
  • I'm currently using Zotero with Google Docs, and I have to "Unlink citations" before exporting to PDF. (otherwise it will point to Zotero's webpage)

    It seems that it would be possible to create an option "link citations to bibliography" before exporting to PDF.
Sign In or Register to comment.