Skip to content

Commit a0bcaaf

Browse files
authored
Added support for google scholar citations (#2193)
Closes #1809, but there are caveats: 1 - it only works at build time, which means it won't update the numbers unless you build your site again 2 - Google might block the request if it receives lots of it, failing the whole process. This is how it looks like when it can fetch the information: ![Screenshot from 2024-02-13 00-37-52](https://github.com/alshedivat/al-folio/assets/31376482/646d1f3c-1294-491b-bc13-9013e38918b4) And this when it fails: ![image](https://github.com/alshedivat/al-folio/assets/31376482/516eefff-d394-44ad-8702-8982233f8c4f) Signed-off-by: George Araujo <[email protected]>
1 parent 007b504 commit a0bcaaf

File tree

4 files changed

+88
-2
lines changed

4 files changed

+88
-2
lines changed

_bibliography/papers.bib

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ @article{PhysRev.47.777
4444
pdf={example_pdf.pdf},
4545
altmetric={248277},
4646
dimensions={true},
47+
google_scholar_id={qyhmnyLat1gC},
4748
selected={true}
4849
}
4950

_config.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ x_username: # your X handle
7373
mastodon_username: # your mastodon instance+username in the format instance.tld/@username
7474
linkedin_username: # your LinkedIn user name
7575
telegram_username: # your Telegram user name
76-
scholar_userid: # your Google Scholar ID
76+
scholar_userid: qc6CJjYAAAAJ # your Google Scholar ID
7777
semanticscholar_id: # your Semantic Scholar ID
7878
whatsapp_number: # your WhatsApp number (full phone number in international format. Omit any zeroes, brackets, or dashes when adding the phone number in international format.)
7979
orcid_id: # your ORCID ID
@@ -311,6 +311,7 @@ scholar:
311311
enable_publication_badges:
312312
altmetric: true # Altmetric badge (https://www.altmetric.com/products/altmetric-badges/)
313313
dimensions: true # Dimensions badge (https://badge.dimensions.ai/)
314+
google_scholar: true # Google Scholar badge (https://scholar.google.com/intl/en/scholar/citations.html)
314315

315316
# Filter out certain bibtex entry keywords used internally from the bib output
316317
filtered_bibtex_keywords:

_layouts/bib.liquid

+7-1
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,8 @@
211211
{% if site.enable_publication_badges %}
212212
{% assign entry_has_altmetric_badge = entry.altmetric or entry.doi or entry.eprint or entry.pmid or entry.isbn %}
213213
{% assign entry_has_dimensions_badge = entry.dimensions or entry.doi or entry.pmid %}
214-
{% if entry_has_altmetric_badge or entry_has_dimensions_badge %}
214+
{% assign entry_has_google_scholar_badge = entry.google_scholar_id %}
215+
{% if entry_has_altmetric_badge or entry_has_dimensions_badge or entry_has_google_scholar_badge %}
215216
<div class="badges">
216217
{% if site.enable_publication_badges.altmetric and entry_has_altmetric_badge %}
217218
<span
@@ -249,6 +250,11 @@
249250
style="margin-bottom: 3px;"
250251
></span>
251252
{% endif %}
253+
{% if site.enable_publication_badges.google_scholar and entry_has_google_scholar_badge %}
254+
<a href="https://scholar.google.com/citations?view_op=view_citation&hl=en&user={{ site.scholar_userid }}&citation_for_view={{ site.scholar_userid }}:{{ entry.google_scholar_id }}">
255+
<img src="https://img.shields.io/badge/scholar-{% google_scholar_citations site.scholar_userid entry.google_scholar_id %}-4285F4?logo=googlescholar&labelColor=beige">
256+
</a>
257+
{% endif %}
252258
</div>
253259
{% endif %}
254260
{% endif %}

_plugins/google-scholar-citations.rb

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
require "active_support/all"
2+
require 'nokogiri'
3+
require 'open-uri'
4+
5+
module Helpers
6+
extend ActiveSupport::NumberHelper
7+
end
8+
9+
module Jekyll
10+
class GoogleScholarCitationsTag < Liquid::Tag
11+
Citations = { }
12+
13+
def initialize(tag_name, params, tokens)
14+
super
15+
splitted = params.split(" ").map(&:strip)
16+
@scholar_id = splitted[0]
17+
@article_id = splitted[1]
18+
end
19+
20+
def render(context)
21+
article_id = context[@article_id.strip]
22+
scholar_id = context[@scholar_id.strip]
23+
article_url = "https://scholar.google.com/citations?view_op=view_citation&hl=en&user=#{scholar_id}&citation_for_view=#{scholar_id}:#{article_id}"
24+
25+
begin
26+
# If the citation count has already been fetched, return it
27+
if GoogleScholarCitationsTag::Citations[article_id]
28+
return GoogleScholarCitationsTag::Citations[article_id]
29+
end
30+
31+
# Sleep for a random amount of time to avoid being blocked
32+
sleep(rand(1.5..3.5))
33+
34+
# Fetch the article page
35+
doc = Nokogiri::HTML(URI.open(article_url, "User-Agent" => "Ruby/#{RUBY_VERSION}"))
36+
37+
# Attempt to extract the "Cited by n" string from the meta tags
38+
citation_count = 0
39+
40+
# Look for meta tags with "name" attribute set to "description"
41+
description_meta = doc.css('meta[name="description"]')
42+
og_description_meta = doc.css('meta[property="og:description"]')
43+
44+
if !description_meta.empty?
45+
cited_by_text = description_meta[0]['content']
46+
matches = cited_by_text.match(/Cited by (\d+[,\d]*)/)
47+
48+
if matches
49+
citation_count = matches[1].to_i
50+
end
51+
52+
elsif !og_description_meta.empty?
53+
cited_by_text = og_description_meta[0]['content']
54+
matches = cited_by_text.match(/Cited by (\d+[,\d]*)/)
55+
56+
if matches
57+
citation_count = matches[1].to_i
58+
end
59+
end
60+
61+
citation_count = Helpers.number_to_human(citation_count, :format => '%n%u', :precision => 2, :units => { :thousand => 'K', :million => 'M', :billion => 'B' })
62+
63+
rescue Exception => e
64+
# Handle any errors that may occur during fetching
65+
citation_count = "N/A"
66+
67+
# Print the error message including the exception class and message
68+
puts "Error fetching citation count for #{article_id}: #{e.class} - #{e.message}"
69+
end
70+
71+
72+
GoogleScholarCitationsTag::Citations[article_id] = citation_count
73+
return "#{citation_count}"
74+
end
75+
end
76+
end
77+
78+
Liquid::Template.register_tag('google_scholar_citations', Jekyll::GoogleScholarCitationsTag)

0 commit comments

Comments
 (0)