A tiny Vim Snippet
Table of Contents
A tiny code snippet for Vim using UltiSnips plugin that can convert links to papers into APA citation in markdown.
The first snippet auto-completes alin and form a block of code with the link inside. The second snippet evaluates the link and returns the APA citation in markdown.
Usage
- Copy the code below into your
UltiSnipsfolder, which on my Mac is~/.vim/UltiSnips/. - Open a markdown file, type
alinand presstab. This will create a block of code with the link inside; presstabagain to complete the link.

Caveat Emptor
I was only able to find an API for arxiv but not for other websites like openreview. This can break if the website changes its structure.
Code
snippet alin "create markdown links from paper links" w
alin $1 alin$0
endsnippet
priority 1000
snippet 'alin(.*)alin' "evaluate link and return APA cite in markdown" wr
`!p
import requests
from bs4 import BeautifulSoup
import json
import warnings
warnings.filterwarnings("ignore")
def get_arxiv_metadata(arxiv_id):
url = f'http://export.arxiv.org/api/query?id_list={arxiv_id}'
response = requests.get(url)
feed = BeautifulSoup(response.content)
entry = feed.find('entry')
print(entry)
print(entry.find_all('author'))
authors = [author.find('name').text for author in entry.find_all('author')]
published_date = entry.find('published').text
year = published_date.split('-')[0]
return authors, year
def get_openreview_metadata(url):
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')
script_tag = soup.find('script', {'id': '__NEXT_DATA__'})
if not script_tag:
raise Exception('Data script tag not found')
data_str = script_tag.string
data_json = json.loads(data_str)
authors = data_json['props']['pageProps']['forumNote']['content']['authors']
if isinstance(authors, dict):
authors = authors['value']
try:
year = data_json['props']['pageProps']['forumNote']['invitation']
except KeyError:
year = data_json['props']['pageProps']['forumNote']['invitations'][0]
# year of the form neurips.cc/2021/...
year = year.split('/')[1]
return authors, year
def format_authors(authors):
if len(authors) == 1:
# use last names only
return authors[0].split(' ')[-1]
elif len(authors) == 2:
return f"{authors[0].split(' ')[-1]} and {authors[1].split(' ')[-1]}"
else:
print(authors)
return f"{authors[0].split(' ')[-1]} et al."
def generate_citation(arxiv_link, type = 'arxiv'):
if type == 'arxiv':
arxiv_link = arxiv_link.replace('/pdf/', '/abs/').replace('.pdf', '')
arxiv_id = arxiv_link.split('/')[-1]
authors, year = get_arxiv_metadata(arxiv_id)
formatted_authors = format_authors(authors)
citation = f"[{formatted_authors}, {year}]({arxiv_link})"
elif type == 'openreview':
# openreview_id = arxiv_link.split('/')[-1].split('?')[-1].split('=')[-1]
# replace pdf with forum
arxiv_link = arxiv_link.replace('/pdf?', '/forum?')
authors, year = get_openreview_metadata(arxiv_link)
formatted_authors = format_authors(authors)
citation = f"[{formatted_authors}, {year}]({arxiv_link})"
return citation
arxiv_link = f"{match.group(1)}"
arxiv_link = arxiv_link.strip()
type = None
if 'arxiv' in arxiv_link:
type = 'arxiv'
elif 'openreview' in arxiv_link:
print('openreview')
type = 'openreview'
snip.rv = generate_citation(arxiv_link, type)
`
endsnippet