办公问答网

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 137|回复: 2

Zotero文献超链接(word)

[复制链接]

2

主题

7

帖子

12

积分

新手上路

Rank: 1

积分
12
发表于 2023-4-10 08:08:20 | 显示全部楼层 |阅读模式
打开word>视图>宏>创建


进入宏界面


将代码覆盖空白文件
参考网站:

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
            '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宏界面的文件>保存>退出(保险起见退出宏之后再重新进word)
进入word后用zotero插入文献,导出参考文献,然后点击宏>找到ZoteroLinkCitation>运行
最好先在空白文档中试一试,然后再论文中使用。参考文献最好在最后写完之后统一运行宏(不要取消zotero的连接(Unlink Citations))
我自己测试了一两次,多个文献或者单个文献超连接不会冲突,有一些问题我还未遇见,大家尝试后可以自行调试。
回复

使用道具 举报

1

主题

5

帖子

4

积分

新手上路

Rank: 1

积分
4
发表于 2023-4-10 08:08:28 | 显示全部楼层
不错,我遇到了一个问题,在遇到多个文献引用(例如[15-17,20])时会报错。此时只需要再次执行宏程序就可以了
回复

使用道具 举报

2

主题

6

帖子

9

积分

新手上路

Rank: 1

积分
9
发表于 2023-4-10 08:08:41 | 显示全部楼层
这个代码目前只对于上标文献格式有用,如果是括号的文献引用估计要重新编程。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|办公问答网

GMT+8, 2025-7-6 17:48 , Processed in 0.103888 second(s), 23 queries .

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc. Templated By 【未来科技 www.veikei.com】设计

快速回复 返回顶部 返回列表