Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Attribute VB_Name = "igi"
- '*****************************************************************************************
- '*****************************************************************************************
- ' Change Mendeley citations to be hyperlinks, with bibliography links to the actual documents.
- '** Based on work by : JosÈ Luis Gonz·lez GarcÌa
- '** Only for IEEE CSL citation style.
- ' ** Only supports IEEE style citations, and only single cites, not [1,2].
- ' ** (C) 2023 Charles Weir. Changes subject to MIT Licence (i.e. free use)
- '*****************************************************************************************
- '*****************************************************************************************
- Sub hyp_CreateLinksForCitationsIEEE()
- Dim documentSection As Section
- Dim sectionField As Field
- Dim citationNumberRange As Range
- Dim biblioField As Field
- Dim citationUrl As String
- 'removes all hyperlinks and related bookmarks
- Call hyp_removeHyperlinksForCitations
- 'disables the screen updating while creating the hyperlinks to increase speed
- 'Application.ScreenUpdating = False
- 'Put bookmarks into the bibliography:
- For referenceNumber = 1 To 999999
- Set citationNumberRange = bibliographyPara(referenceNumber)
- If citationNumberRange Is Nothing Then Exit For
- citationNumberRange.Collapse
- 'creates the bookmark
- citationNumberRange.Bookmarks.Add _
- Name:="ReferenceLink_" & CStr(referenceNumber), _
- Range:=citationNumberRange
- Next referenceNumber
- '* Putting the links in the remainder of the document:
- 'Todo: Cope with citations like [1,3]
- For Each documentSection In ActiveDocument.Sections
- For Each sectionField In documentSection.Range.Fields
- 'if it is a citation
- If sectionField.Type = wdFieldAddin And Left(sectionField.Code, 18) = "ADDIN CSL_CITATION" Then
- MakeCitationHyperlink sectionField
- citationUrl = UrlForCitation(sectionField)
- MakeBiblioHyperlink CitationIdentifierRange(sectionField).Text, citationUrl
- End If
- Next 'sectionField
- Next 'documentSection
- 'reenables the screen updating
- 'Application.ScreenUpdating = True
- End Sub
- Sub hyp_removeHyperlinksForCitations()
- '* Remove hyperlinks and bookmarks *
- Dim documentSection As Section
- Dim sectionField As Field
- Dim fieldHyperlinks As Hyperlinks
- Dim fieldBookmarks As Bookmarks
- Dim fieldRange As Range
- For Each documentSection In ActiveDocument.Sections
- For Each sectionField In documentSection.Range.Fields
- 'Delete hyperlinks in each citation:
- If (sectionField.Type = wdFieldAddin) And (Left(sectionField.Code, 18) = "ADDIN CSL_CITATION") Then
- Set fieldRange = sectionField.Result.Duplicate
- fieldRange.MoveStart Unit:=wdCharacter, Count:=1
- fieldRange.MoveEnd Unit:=wdCharacter, Count:=-1
- Set fieldHyperlinks = fieldRange.Hyperlinks
- For i = fieldHyperlinks.Count To 1 Step -1
- fieldHyperlinks(1).Delete
- Next
- ' Delete bookmarks and hyperlinks in the bibliography:
- ElseIf (sectionField.Type = wdFieldAddin) And InStr(bibliographyField.Code.Text, "CSL_BIBLIOGRAPHY") Then
- Set fieldBookmarks = sectionField.Result.Bookmarks
- For i = fieldBookmarks.Count To 1 Step -1
- fieldBookmarks(1).Delete
- Next
- Set fieldHyperlinks = sectionField.Result.Hyperlinks
- For i = fieldHyperlinks.Count To 1 Step -1
- fieldHyperlinks(1).Delete
- Next
- End If
- Next
- Next
- End Sub
- Sub MakeBiblioHyperlink(citationIdentifier As String, citationUrl As String)
- ' Creates a hyperlink to the corresponding publication in the bibliography entry corresponding to citationIdentifer
- Dim biblioPara As Range
- Set biblioPara = bibliographyPara(citationIdentifier)
- If biblioPara Is Nothing Then Exit Sub
- ' Already done?
- If biblioPara.Hyperlinks.Count > 0 Then Exit Sub
- ' Setting hyperlinks can't cope with the ID at the start of the para
- biblioPara.MoveStart wdWord, 3
- ' Deleting hyperlinks can't cope with the end of the bibliography field
- biblioPara.MoveEnd wdCharacter, -1
- bibliographyField().Result.Hyperlinks.Add Anchor:=biblioPara, _
- Address:=citationUrl, ScreenTip:=citationUrl
- End Sub
- Sub MakeCitationHyperlink(sectionField As Field)
- ' Makes the given Mendeley citation into a hyperlink to the appropriate para in the bibliography
- Dim citationNumberRange As Range
- Set citationNumberRange = CitationIdentifierRange(sectionField)
- sectionField.Result.Hyperlinks.Add Anchor:=citationNumberRange, _
- Address:="", SubAddress:="ReferenceLink_" & citationNumberRange.Text, _
- ScreenTip:=""
- End Sub
- Function CitationIdentifierRange(sectionField As Field) As Range
- ' Answers the location of the i.d. (e.g. 23) of a given citation:
- Set CitationIdentifierRange = sectionField.Result.Duplicate
- ' Including the square brackets makes Word fail when removing the hyperlinks. Don't know why.
- CitationIdentifierRange.MoveStart Unit:=wdCharacter, Count:=1
- CitationIdentifierRange.MoveEnd Unit:=wdCharacter, Count:=-1
- End Function
- Function bibliographyField() As Field
- ' Answers the bibliography field in the document
- ' N.b. might cache?
- Dim rngStory As Range
- For Each rngStory In ActiveDocument.StoryRanges
- Do
- For Each bibliographyField In rngStory.Fields
- If bibliographyField.Type = wdFieldAddin And InStr(bibliographyField.Code.Text, "CSL_BIBLIOGRAPHY") Then Exit Function
- Next
- Set rngStory = rngStory.NextStoryRange
- Loop Until rngStory Is Nothing
- Next
- MsgBox "Ouch! Bibliography not found."
- End
- Found:
- End Function
- Function bibliographyPara(referenceNumber) As Range
- ' Answers the paragraph in the Bibliography containing the given reference
- Set bibliographyPara = bibliographyField().Result.Duplicate
- With bibliographyPara.Find
- .Forward = True
- .Wrap = wdFindStop
- ' N.b. Ideally would have start of para as well
- .Text = "[" & CStr(referenceNumber) & "]"
- .Execute
- If Not .Found Then
- Set bibliographyPara = Nothing
- Exit Function
- End If
- End With
- bibliographyPara.Expand (wdParagraph)
- ' Exclude the leading [, since this causes problems - the start of the bibliography owns all the hyperlinks, so entry 1 doesn't get set up correctly.
- bibliographyPara.MoveStart wdCharacter, 1
- End Function
- Function UrlForCitation(citationField As Field) As String
- ' Answers a suitable URL based on the metadata in the citation.
- ' The metadata looks like this:
- ' ADDIN CSL_CITATION {"citationItems":[{"id":"ITEM-1","itemData":{"DOI":"10.1109/SEGE.2016.7589556","abstract":"The ma
- ' "type":"article-journalî {"DOI":"10.1016/J.COSE.2021.102258"
- ' "type":îwebpage" {"URL":"https://www.itgovernance.co.uk/cyber-security-risk-managementî
- ' "type":îbook" "itemData":{"ISBN":î1119085292"
- ' "type":îreportî , "title":"2021 SANS Cyber Threat Intelligence (CTI) Surveyî
- ' "type":"paper-conferenceî ,"itemData":{"DOI":"10.1109/SEGE.2016.7589556î
- ' "type":îchapter" "DOI":"10.3233/978-1-61499-649-1-87","ISBN":"9781614996491"
- ' Else "title":"A Survey: Internet of Things (IOT) Technologies, Applications and Challengesî
- ' If we have a URL, use it:
- If GetCitationParameter(citationField, "URL") <> "" Then
- UrlForCitation = GetCitationParameter(citationField, "URL")
- Exit Function
- End If
- Select Case GetCitationParameter(citationField, "type")
- Case "article-journal", "paper-conference", "chapter", "book" ' Things listed by Google Scholar
- If GetCitationParameter(citationField, "DOI") <> "" Then
- UrlForCitation = "https://doi.org/" & GetCitationParameter(citationField, "DOI")
- ElseIf GetCitationParameter(citationField, "ISBN") <> "" Then
- UrlForCitation = "https://www.google.com/search?tbm=bks&q=isbn:" & GetCitationParameter(citationField, "ISBN")
- Else
- UrlForCitation = "https://scholar.google.com/scholar?q=""" & GetCitationParameter(citationField, "title") & """ " & GetCitationParameter(citationField, "family")
- End If
- Case Else: ' Including report, as Mendeley doesn't include URLs for reports.
- UrlForCitation = "https://google.com/search?q=""" & GetCitationParameter(citationField, "title") & """ " & GetCitationParameter(citationField, "family")
- End Select
- End Function
- Function GetCitationParameter(citationField As Field, parameter As String) As String
- ' Answers the given parameter (e.g. DOI) from the metadata, returning the empty string if not found.
- Dim metadataRange As Range
- Dim preamble As String
- Set metadataRange = citationField.Code.Duplicate
- preamble = """" & parameter & """:""" ' I.e. "DOI":"
- With metadataRange.Find
- .Forward = True
- .MatchWildcards = True
- .Wrap = wdFindStop
- .Text = preamble & "[!""]@""" ' I.e. [!"]@"
- .Execute
- If Not .Found Then
- GetCitationParameter = ""
- Exit Function
- End If
- End With
- metadataRange.MoveStart wdCharacter, Len(preamble) ' Skip "DOI":"
- metadataRange.MoveEnd wdCharacter, -1 ' Skip "
- GetCitationParameter = metadataRange.Text
- End Function
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement