Advertisement
Guest User

VB Hyperlinks for Mendeley Citations

a guest
Sep 26th, 2023
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.78 KB | None | 0 0
  1. Attribute VB_Name = "igi"
  2.  
  3. '*****************************************************************************************
  4. '*****************************************************************************************
  5. ' Change Mendeley citations to be hyperlinks, with bibliography links to the actual documents.
  6. '** Based on work by : JosÈ Luis Gonz·lez GarcÌa
  7. '** Only for IEEE CSL citation style.
  8. ' ** Only supports IEEE style citations, and only single cites, not [1,2].
  9. ' ** (C) 2023 Charles Weir. Changes subject to MIT Licence (i.e. free use)
  10. '*****************************************************************************************
  11. '*****************************************************************************************
  12.  
  13. Sub hyp_CreateLinksForCitationsIEEE()
  14. Dim documentSection As Section
  15. Dim sectionField As Field
  16. Dim citationNumberRange As Range
  17. Dim biblioField As Field
  18. Dim citationUrl As String
  19.  
  20. 'removes all hyperlinks and related bookmarks
  21. Call hyp_removeHyperlinksForCitations
  22.  
  23. 'disables the screen updating while creating the hyperlinks to increase speed
  24. 'Application.ScreenUpdating = False
  25.  
  26. 'Put bookmarks into the bibliography:
  27. For referenceNumber = 1 To 999999
  28. Set citationNumberRange = bibliographyPara(referenceNumber)
  29. If citationNumberRange Is Nothing Then Exit For
  30. citationNumberRange.Collapse
  31.  
  32. 'creates the bookmark
  33. citationNumberRange.Bookmarks.Add _
  34. Name:="ReferenceLink_" & CStr(referenceNumber), _
  35. Range:=citationNumberRange
  36. Next referenceNumber
  37.  
  38. '* Putting the links in the remainder of the document:
  39.  
  40. 'Todo: Cope with citations like [1,3]
  41. For Each documentSection In ActiveDocument.Sections
  42. For Each sectionField In documentSection.Range.Fields
  43. 'if it is a citation
  44. If sectionField.Type = wdFieldAddin And Left(sectionField.Code, 18) = "ADDIN CSL_CITATION" Then
  45. MakeCitationHyperlink sectionField
  46. citationUrl = UrlForCitation(sectionField)
  47. MakeBiblioHyperlink CitationIdentifierRange(sectionField).Text, citationUrl
  48. End If
  49. Next 'sectionField
  50. Next 'documentSection
  51.  
  52. 'reenables the screen updating
  53. 'Application.ScreenUpdating = True
  54.  
  55. End Sub
  56.  
  57.  
  58. Sub hyp_removeHyperlinksForCitations()
  59. '* Remove hyperlinks and bookmarks *
  60.  
  61. Dim documentSection As Section
  62. Dim sectionField As Field
  63. Dim fieldHyperlinks As Hyperlinks
  64. Dim fieldBookmarks As Bookmarks
  65. Dim fieldRange As Range
  66.  
  67. For Each documentSection In ActiveDocument.Sections
  68. For Each sectionField In documentSection.Range.Fields
  69. 'Delete hyperlinks in each citation:
  70. If (sectionField.Type = wdFieldAddin) And (Left(sectionField.Code, 18) = "ADDIN CSL_CITATION") Then
  71. Set fieldRange = sectionField.Result.Duplicate
  72. fieldRange.MoveStart Unit:=wdCharacter, Count:=1
  73. fieldRange.MoveEnd Unit:=wdCharacter, Count:=-1
  74. Set fieldHyperlinks = fieldRange.Hyperlinks
  75. For i = fieldHyperlinks.Count To 1 Step -1
  76. fieldHyperlinks(1).Delete
  77. Next
  78. ' Delete bookmarks and hyperlinks in the bibliography:
  79. ElseIf (sectionField.Type = wdFieldAddin) And InStr(bibliographyField.Code.Text, "CSL_BIBLIOGRAPHY") Then
  80. Set fieldBookmarks = sectionField.Result.Bookmarks
  81. For i = fieldBookmarks.Count To 1 Step -1
  82. fieldBookmarks(1).Delete
  83. Next
  84. Set fieldHyperlinks = sectionField.Result.Hyperlinks
  85. For i = fieldHyperlinks.Count To 1 Step -1
  86. fieldHyperlinks(1).Delete
  87. Next
  88. End If
  89. Next
  90. Next
  91.  
  92. End Sub
  93. Sub MakeBiblioHyperlink(citationIdentifier As String, citationUrl As String)
  94. ' Creates a hyperlink to the corresponding publication in the bibliography entry corresponding to citationIdentifer
  95. Dim biblioPara As Range
  96.  
  97. Set biblioPara = bibliographyPara(citationIdentifier)
  98. If biblioPara Is Nothing Then Exit Sub
  99. ' Already done?
  100. If biblioPara.Hyperlinks.Count > 0 Then Exit Sub
  101.  
  102. ' Setting hyperlinks can't cope with the ID at the start of the para
  103. biblioPara.MoveStart wdWord, 3
  104. ' Deleting hyperlinks can't cope with the end of the bibliography field
  105. biblioPara.MoveEnd wdCharacter, -1
  106. bibliographyField().Result.Hyperlinks.Add Anchor:=biblioPara, _
  107. Address:=citationUrl, ScreenTip:=citationUrl
  108.  
  109. End Sub
  110.  
  111.  
  112. Sub MakeCitationHyperlink(sectionField As Field)
  113. ' Makes the given Mendeley citation into a hyperlink to the appropriate para in the bibliography
  114. Dim citationNumberRange As Range
  115.  
  116. Set citationNumberRange = CitationIdentifierRange(sectionField)
  117. sectionField.Result.Hyperlinks.Add Anchor:=citationNumberRange, _
  118. Address:="", SubAddress:="ReferenceLink_" & citationNumberRange.Text, _
  119. ScreenTip:=""
  120. End Sub
  121.  
  122. Function CitationIdentifierRange(sectionField As Field) As Range
  123. ' Answers the location of the i.d. (e.g. 23) of a given citation:
  124.  
  125. Set CitationIdentifierRange = sectionField.Result.Duplicate
  126. ' Including the square brackets makes Word fail when removing the hyperlinks. Don't know why.
  127. CitationIdentifierRange.MoveStart Unit:=wdCharacter, Count:=1
  128. CitationIdentifierRange.MoveEnd Unit:=wdCharacter, Count:=-1
  129. End Function
  130.  
  131. Function bibliographyField() As Field
  132. ' Answers the bibliography field in the document
  133. ' N.b. might cache?
  134.  
  135. Dim rngStory As Range
  136.  
  137. For Each rngStory In ActiveDocument.StoryRanges
  138. Do
  139. For Each bibliographyField In rngStory.Fields
  140. If bibliographyField.Type = wdFieldAddin And InStr(bibliographyField.Code.Text, "CSL_BIBLIOGRAPHY") Then Exit Function
  141. Next
  142. Set rngStory = rngStory.NextStoryRange
  143. Loop Until rngStory Is Nothing
  144. Next
  145. MsgBox "Ouch! Bibliography not found."
  146. End
  147. Found:
  148.  
  149. End Function
  150.  
  151. Function bibliographyPara(referenceNumber) As Range
  152. ' Answers the paragraph in the Bibliography containing the given reference
  153.  
  154. Set bibliographyPara = bibliographyField().Result.Duplicate
  155.  
  156. With bibliographyPara.Find
  157. .Forward = True
  158. .Wrap = wdFindStop
  159. ' N.b. Ideally would have start of para as well
  160. .Text = "[" & CStr(referenceNumber) & "]"
  161. .Execute
  162. If Not .Found Then
  163. Set bibliographyPara = Nothing
  164. Exit Function
  165. End If
  166. End With
  167. bibliographyPara.Expand (wdParagraph)
  168.  
  169. ' 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.
  170.  
  171. bibliographyPara.MoveStart wdCharacter, 1
  172.  
  173. End Function
  174.  
  175. Function UrlForCitation(citationField As Field) As String
  176. ' Answers a suitable URL based on the metadata in the citation.
  177.  
  178. ' The metadata looks like this:
  179. ' ADDIN CSL_CITATION {"citationItems":[{"id":"ITEM-1","itemData":{"DOI":"10.1109/SEGE.2016.7589556","abstract":"The ma
  180.  
  181. ' "type":"article-journalî {"DOI":"10.1016/J.COSE.2021.102258"
  182. ' "type":îwebpage" {"URL":"https://www.itgovernance.co.uk/cyber-security-risk-managementî
  183. ' "type":îbook" "itemData":{"ISBN":î1119085292"
  184. ' "type":îreportî , "title":"2021 SANS Cyber Threat Intelligence (CTI) Surveyî
  185. ' "type":"paper-conferenceî ,"itemData":{"DOI":"10.1109/SEGE.2016.7589556î
  186. ' "type":îchapter" "DOI":"10.3233/978-1-61499-649-1-87","ISBN":"9781614996491"
  187. ' Else "title":"A Survey: Internet of Things (IOT) Technologies, Applications and Challengesî
  188.  
  189. ' If we have a URL, use it:
  190. If GetCitationParameter(citationField, "URL") <> "" Then
  191. UrlForCitation = GetCitationParameter(citationField, "URL")
  192. Exit Function
  193. End If
  194.  
  195. Select Case GetCitationParameter(citationField, "type")
  196. Case "article-journal", "paper-conference", "chapter", "book" ' Things listed by Google Scholar
  197. If GetCitationParameter(citationField, "DOI") <> "" Then
  198. UrlForCitation = "https://doi.org/" & GetCitationParameter(citationField, "DOI")
  199. ElseIf GetCitationParameter(citationField, "ISBN") <> "" Then
  200. UrlForCitation = "https://www.google.com/search?tbm=bks&q=isbn:" & GetCitationParameter(citationField, "ISBN")
  201. Else
  202. UrlForCitation = "https://scholar.google.com/scholar?q=""" & GetCitationParameter(citationField, "title") & """ " & GetCitationParameter(citationField, "family")
  203. End If
  204.  
  205. Case Else: ' Including report, as Mendeley doesn't include URLs for reports.
  206. UrlForCitation = "https://google.com/search?q=""" & GetCitationParameter(citationField, "title") & """ " & GetCitationParameter(citationField, "family")
  207. End Select
  208.  
  209. End Function
  210.  
  211. Function GetCitationParameter(citationField As Field, parameter As String) As String
  212. ' Answers the given parameter (e.g. DOI) from the metadata, returning the empty string if not found.
  213.  
  214. Dim metadataRange As Range
  215. Dim preamble As String
  216.  
  217. Set metadataRange = citationField.Code.Duplicate
  218. preamble = """" & parameter & """:""" ' I.e. "DOI":"
  219.  
  220. With metadataRange.Find
  221. .Forward = True
  222. .MatchWildcards = True
  223. .Wrap = wdFindStop
  224. .Text = preamble & "[!""]@""" ' I.e. [!"]@"
  225. .Execute
  226. If Not .Found Then
  227. GetCitationParameter = ""
  228. Exit Function
  229. End If
  230. End With
  231.  
  232. metadataRange.MoveStart wdCharacter, Len(preamble) ' Skip "DOI":"
  233. metadataRange.MoveEnd wdCharacter, -1 ' Skip "
  234. GetCitationParameter = metadataRange.Text
  235. End Function
  236.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement