pages/_layouts/bib.liquid
Dominik Fuchß 1f349ffda2
Adapt mechanism for citiation count (#3177)
## Summary

This PR introduces an automated mechanism to update the citation count
for authors' publications.

- Inspired by @BernardoCama’s suggestion in #3150.
- Resolves #3150.

## Key Changes

- Adds an action to update publication citation counts.
    - Note: This action creates a commit on the main branch.
- To trigger further GitHub Actions workflows from this commit, a
Personal Access Token (PAT) must be used (the default GitHub Actions
token cannot trigger subsequent workflows).
- Adds and manages citation data in `_data/citations.yml`.
- Adds and adapts `bin/update_scholar_citations.py` to handle citation
updates.

## Usage Examples
### Timeout
<img width="758" height="415" alt="image"
src="https://github.com/user-attachments/assets/0a330d35-b386-4670-8668-62701f2dc68b"
/>

### Success

<img width="1684" height="857" alt="image"
src="https://github.com/user-attachments/assets/44aa0558-e02a-4f00-b8cb-9e0ce16dd53c"
/>
2025-11-16 22:17:17 -03:00

391 lines
16 KiB
Plaintext

---
---
<div class="row">
{% if site.enable_publication_thumbnails %}
<div class="col col-sm-2 abbr">
{%- if entry.abbr -%}
{%- if site.data.venues[entry.abbr] -%}
{% assign venue_style = null %}
{% if site.data.venues[entry.abbr].color != blank %}
{% assign venue_style = site.data.venues[entry.abbr].color | prepend: 'style="background-color:' | append: '"' %}
{%- endif -%}
<abbr
class="badge rounded w-100"
{% if venue_style %}
{{ venue_style }}
{% endif -%}
>
{% if site.data.venues[entry.abbr].url %}
<a href="{{ site.data.venues[entry.abbr].url }}">{{ entry.abbr }}</a>
{% else %}
<div>{{- entry.abbr -}}</div>
{% endif %}
</abbr>
{% else %}
<abbr class="badge rounded w-100">{{ entry.abbr }}</abbr>
{% endif %}
{% endif %}
{% if entry.preview %}
{% if entry.preview contains '://' %}
<img class="preview z-depth-1 rounded" src="{{ entry.preview }}">
{% else %}
{% assign entry_path = entry.preview | prepend: '/assets/img/publication_preview/' %}
{%
include figure.liquid
loading="eager"
path=entry_path
sizes = "200px"
class="preview z-depth-1 rounded"
zoomable=true
avoid_scaling=true
alt=entry.preview
%}
{% endif %}
{% endif %}
</div>
{% endif %}
<!-- Entry bib key -->
<div id="{{ entry.key }}" class="{% if site.enable_publication_thumbnails %}col-sm-8{% else %}col-sm-10{% endif %}">
<!-- Title -->
<div class="title">{{ entry.title }}</div>
<!-- Author -->
<div class="author">
{% assign author_array_size = entry.author_array | size %}
{% assign author_array_limit = author_array_size %}
{% if site.max_author_limit and author_array_size > site.max_author_limit %}
{% assign author_array_limit = site.max_author_limit %}
{% endif %}
{%- for author in entry.author_array limit: author_array_limit -%}
{% assign author_is_self = false %}
{%- assign author_last_name = author.last | regex_replace: '[*∗†‡§¶‖&^]', '' -%}
{%- assign author_last_html = author.last | regex_replace: '([*∗†‡§¶‖&^]+)', '<sup>\1</sup>' -%}
{% if site.scholar.last_name contains author_last_name %}
{% if site.scholar.first_name contains author.first %}
{% assign author_is_self = true %}
{% endif %}
{%- endif -%}
{% assign coauthor_url = null %}
{%- assign clean_last_name = author_last_name | downcase | remove_accents -%}
{% if site.data.coauthors[clean_last_name] %}
{%- for coauthor in site.data.coauthors[clean_last_name] -%}
{% if coauthor.firstname contains author.first %}
{%- assign coauthor_url = coauthor.url -%}
{% break %}
{%- endif -%}
{% endfor %}
{%- endif -%}
{%- if forloop.length > 1 -%}
{% if forloop.first == false -%}
{%- if forloop.length > 2 %}, {% elsif forloop.length == 2 %} {% endif %}
{%- endif %}
{%- if forloop.last and author_array_limit == author_array_size %}and {% endif -%}
{% endif %}
{%- if author_is_self -%}
<em>
{{- author.first }}
{{ author_last_html -}}
</em>
{%- else -%}
{%- if coauthor_url -%}
<a href="{{ coauthor_url }}">
{{- author.first }}
{{ author_last_html -}}
</a>
{%- else -%}
{{- author.first }}
{{ author_last_html -}}
{% endif %}
{%- endif -%}
{% endfor %}
{%- assign more_authors = author_array_size | minus: author_array_limit -%}
{%- assign more_authors_hide = more_authors | append: ' more author' -%}
{% if more_authors > 0 %}
{%- if more_authors > 1 -%}
{% assign more_authors_hide = more_authors_hide | append: 's' %}
{%- endif -%}
{% assign more_authors_show = '' %}
{%- for author in entry.author_array offset: author_array_limit -%}
{% assign more_authors_show = more_authors_show | append: author.first | append: ' ' | append: author.last %}
{% unless forloop.last %}
{% assign more_authors_show = more_authors_show | append: ', ' %}
{% endunless %}
{%- endfor -%}
{%- assign more_authors_show = more_authors_show | regex_replace: '([*∗†‡§¶‖&^]+)', '<sup>\1</sup>' -%}
, and
<span
class="more-authors"
title="click to view {{ more_authors_hide }}"
onclick="
var element = $(this);
element.attr('title', '');
var more_authors_text = element.text() == '{{ more_authors_hide }}' ? '{{ more_authors_show }}' : '{{ more_authors_hide }}';
var cursorPosition = 0;
var textAdder = setInterval(function(){
element.html(more_authors_text.substring(0, cursorPosition + 1));
if (++cursorPosition == more_authors_text.length){
clearInterval(textAdder);
}
}, '{{ site.more_authors_animation_delay }}');
"
>
{{- more_authors_hide -}}
</span>
{% endif %}
{% if entry.annotation %}
<i
class="fa-solid fa-circle-info ml-1"
data-toggle="popover"
data-placement="top"
data-html="true"
data-content="{{ entry.annotation | escape }}"
>
</i>
{% endif %}
</div>
<!-- Journal/Book title and date -->
{% assign proceedings = 'inproceedings,incollection' | split: ',' %}
{% assign thesis = 'thesis,mastersthesis,phdthesis' | split: ',' %}
{% if entry.type == 'article' %}
{% capture entrytype %}<em>{{ entry.journal }}</em>{% endcapture %}
{% elsif proceedings contains entry.type %}
{% capture entrytype %}<em>In {{ entry.booktitle }}</em>{% endcapture %}
{% elsif thesis contains entry.type %}
{% capture entrytype %}<em>{{ entry.school }}</em>{% endcapture %}
{% else %}
{% capture entrytype %}{% endcapture %}
{% endif %}
{% if entry.month %}
{% capture entrymonth %}{{ " " }}{{ entry.month | capitalize }}{% endcapture %}
{% endif %}
{% if entry.year %}
{% capture entryyear %}{{ " " }}{{ entry.year }}{% endcapture %}
{% endif %}
{% if entry.location %}
{% capture entrytype %}{{ entrytype }}{{ ", " }}{{ entry.location }}{% endcapture %}
{% endif -%}
{% if entry.additional_info %}
{% capture entrytype %}{{ entrytype }}{{ entry.additional_info | markdownify | remove: '<p>' | remove: '</p>' }}{% endcapture %}
{% endif %}
{% capture hook_exists %}{% file_exists _includes/hook/bib.liquid %}{% endcapture %}
{% if hook_exists == 'true' %}
{% include hook/bib.liquid %}
{% endif %}
{% assign entrytype_text = entrytype | strip_html | strip %}
{% capture periodical %}{{ entrytype }}{% if entrytype_text != "" and entryyear != "" %}, {% endif %}{{ entrymonth }}{{ entryyear }}{% endcapture %}
<div class="periodical">
{{ periodical | strip }}
</div>
<div class="periodical">
{{ entry.note | strip }}
</div>
<!-- Links/Buttons -->
<div class="links">
{% if entry.award %}
<a class="award btn btn-sm z-depth-0" role="button">
{%- if entry.award_name %}{{ entry.award_name }}{% else %}Awarded{% endif -%}
</a>
{% endif %}
{% if entry.abstract %}
<a class="abstract btn btn-sm z-depth-0" role="button">Abs</a>
{% endif %}
{% if entry.doi %}
<a href="https://doi.org/{{ entry.doi }}" class="btn btn-sm z-depth-0" role="button">DOI</a>
{% endif %}
{% if entry.arxiv %}
<a href="http://arxiv.org/abs/{{ entry.arxiv }}" class="btn btn-sm z-depth-0" role="button">arXiv</a>
{% endif %}
{% if entry.bibtex_show %}
<a class="bibtex btn btn-sm z-depth-0" role="button">Bib</a>
{% endif %}
{% if entry.html %}
{% if entry.html contains '://' %}
<a href="{{ entry.html }}" class="btn btn-sm z-depth-0" role="button">HTML</a>
{% else %}
<a href="{{ entry.html | prepend: '/assets/html/' | relative_url }}" class="btn btn-sm z-depth-0" role="button">HTML</a>
{% endif %}
{% endif %}
{% if entry.pdf %}
{% if entry.pdf contains '://' %}
<a href="{{ entry.pdf }}" class="btn btn-sm z-depth-0" role="button">PDF</a>
{% else %}
<a href="{{ entry.pdf | prepend: '/assets/pdf/' | relative_url }}" class="btn btn-sm z-depth-0" role="button">PDF</a>
{% endif %}
{% endif %}
{% if entry.supp %}
{% if entry.supp contains '://' %}
<a href="{{ entry.supp }}" class="btn btn-sm z-depth-0" role="button">Supp</a>
{% else %}
<a href="{{ entry.supp | prepend: '/assets/pdf/' | relative_url }}" class="btn btn-sm z-depth-0" role="button">Supp</a>
{% endif %}
{% endif %}
{% if entry.video and site.enable_video_embedding %}
<a class="abstract btn btn-sm z-depth-0" role="button">Video</a>
{% elsif entry.video %}
<a href="{{ entry.video }}" class="btn btn-sm z-depth-0" role="button">Video</a>
{% endif %}
{% if entry.blog %}
<a href="{{ entry.blog }}" class="btn btn-sm z-depth-0" role="button">Blog</a>
{% endif %}
{% if entry.code %}
<a href="{{ entry.code }}" class="btn btn-sm z-depth-0" role="button">Code</a>
{% endif %}
{% if entry.poster %}
{% if entry.poster contains '://' %}
<a href="{{ entry.poster }}" class="btn btn-sm z-depth-0" role="button">Poster</a>
{% else %}
<a href="{{ entry.poster | prepend: '/assets/pdf/' | relative_url }}" class="btn btn-sm z-depth-0" role="button">Poster</a>
{% endif %}
{% endif %}
{% if entry.slides %}
{% if entry.slides contains '://' %}
<a href="{{ entry.slides }}" class="btn btn-sm z-depth-0" role="button">Slides</a>
{% else %}
<a href="{{ entry.slides | prepend: '/assets/pdf/' | relative_url }}" class="btn btn-sm z-depth-0" role="button">Slides</a>
{% endif %}
{% endif %}
{% if entry.website %}
<a href="{{ entry.website }}" class="btn btn-sm z-depth-0" role="button">Website</a>
{% endif %}
</div>
{% if site.enable_publication_badges %}
{% assign entry_has_altmetric_badge = false %}
{% if entry.altmetric and entry.altmetric != 'false' %}
{% assign entry_has_altmetric_badge = true %}
{% endif %}
{% assign entry_has_dimensions_badge = false %}
{% if entry.dimensions and entry.dimensions != 'false' %}
{% assign entry_has_dimensions_badge = true %}
{% endif %}
{% assign entry_has_google_scholar_badge = false %}
{% if entry.google_scholar_id %}
{% assign entry_has_google_scholar_badge = true %}
{% endif %}
{% assign entry_has_inspirehep_badge = false %}
{% if entry.inspirehep_id %}
{% assign entry_has_inspirehep_badge = true %}
{% endif %}
{% if entry_has_altmetric_badge or entry_has_dimensions_badge or entry_has_google_scholar_badge or entry_has_inspirehep_badge %}
<div class="badges">
{% if site.enable_publication_badges.altmetric and entry_has_altmetric_badge %}
<span
class="altmetric-embed"
data-badge-type="2"
data-badge-popover="right"
{% if entry.altmetric != blank and entry.altmetric != 'true' %}
data-altmetric-id="{{ entry.altmetric }}"
{% elsif entry.arxiv %}
data-arxiv-id="{{ entry.arxiv }}"
{% elsif entry.eprint %}
data-arxiv-id="{{ entry.eprint }}"
{% elsif entry.doi %}
data-doi="{{ entry.doi }}"
{% elsif entry.pmid %}
data-pmid="{{ entry.pmid }}"
{% elsif entry.isbn %}
data-isbn="{{ entry.isbn }}"
{% endif %}
></span>
{% endif %}
{% if site.enable_publication_badges.dimensions and entry_has_dimensions_badge %}
<span
class="__dimensions_badge_embed__"
{% if entry.dimensions != blank and entry.dimensions != 'true' %}
data-id="{{ entry.dimensions }}"
{% elsif entry.doi %}
data-doi="{{ entry.doi }}"
{% else %}
data-pmid="{{ entry.pmid }}"
{% endif %}
data-style="small_rectangle"
data-legend="hover-right"
style="margin-bottom: 3px;"
></span>
{% endif %}
{% if site.enable_publication_badges.google_scholar and entry_has_google_scholar_badge %}
<a
href="https://scholar.google.com/citations?view_op=view_citation&hl=en&user={{ site.data.socials.scholar_userid }}&citation_for_view={{ site.data.socials.scholar_userid }}:{{ entry.google_scholar_id }}"
aria-label="Google Scholar link"
role="button"
>
{% assign citation_count = 0 %}
{% assign scholar_id_key = site.scholar_userid | append: ':' | append: entry.google_scholar_id %}
{% assign publication_key = entry.google_scholar_id %}
{% if site.data.citations.papers[scholar_id_key] %}
{% assign citation_count = site.data.citations.papers[scholar_id_key].citations %}
{% elsif site.data.citations.papers[publication_key] %}
{% assign citation_count = site.data.citations.papers[publication_key].citations %}
{% else %}
{% for paper in site.data.citations.papers %}
{% assign paper_key = paper[0] %}
{% if paper_key contains entry.google_scholar_id %}
{% assign citation_count = paper[1].citations %}
{% break %}
{% endif %}
{% endfor %}
{% endif %}
<img
src="https://img.shields.io/badge/scholar-{{ citation_count }}-4285F4?logo=googlescholar&labelColor=beige"
alt="{{ citation_count }} Google Scholar citations"
>
</a>
{% endif %}
{% if site.enable_publication_badges.inspirehep and entry_has_inspirehep_badge %}
<a
href="https://inspirehep.net/literature/{{ entry.inspirehep_id }}"
aria-label="Inspirehep link"
role="button"
>
<img
src="https://img.shields.io/badge/inspire-{% inspirehep_citations entry.inspirehep_id %}-001628?logo=inspire&logoColor=001628&labelColor=beige"
alt="{% inspirehep_citations entry.inspirehep_id %} InspireHEP citations"
>
</a>
{% endif %}
</div>
{% endif %}
{% endif %}
{% if entry.award %}
<!-- Hidden Award block -->
<div class="award hidden d-print-inline">
<p>{{ entry.award | markdownify }}</p>
</div>
{% endif %}
{% if entry.abstract %}
<!-- Hidden abstract block -->
<div class="abstract hidden">
<p>{{ entry.abstract }}</p>
</div>
{% endif %}
{% if entry.bibtex_show %}
<!-- Hidden bibtex block -->
<div class="bibtex hidden">
{% highlight bibtex %}
{{- entry.bibtex | hideCustomBibtex -}}
{% endhighlight %}
</div>
{% endif %}
{% if entry.video and site.enable_video_embedding %}
<!-- Hidden video block -->
<div class="abstract hidden">
<div style="text-align: center;">{% include video.liquid path=entry.video class="img-fluid rounded z-depth-1" controls=true %}</div>
</div>
{% endif %}
</div>
</div>