Skip to content

Instantly share code, notes, and snippets.

@Eddy-Barraud
Last active February 7, 2026 15:48
Show Gist options
  • Select an option

  • Save Eddy-Barraud/5be16d32fee065a66fcaa92ce3f02cb9 to your computer and use it in GitHub Desktop.

Select an option

Save Eddy-Barraud/5be16d32fee065a66fcaa92ce3f02cb9 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "d0b4ff2f",
"metadata": {},
"outputs": [],
"source": [
"import requests\n",
"from IPython.display import Markdown, display\n",
"\n",
"def get_citation_from_doi(doi, format_type='markdown'):\n",
" \"\"\"\n",
" Fetch DOI metadata and return citation in format:\n",
" \"AuthorLastName. et al. Journal Year, Volume (Issue), Pages\"\n",
" with year in bold, \"et al.\" and journal name in italic\n",
" \n",
" Args:\n",
" doi: DOI string (e.g., \"10.1063/5.0180431\")\n",
" format_type: 'markdown' (default) or 'html' or 'plain'\n",
" \n",
" Returns:\n",
" Formatted citation string\n",
" \"\"\"\n",
" # Clean the DOI (remove any https://doi.org/ prefix if present)\n",
" if doi.startswith('http'):\n",
" doi = doi.split('doi.org/')[-1]\n",
" \n",
" # Fetch metadata from CrossRef API\n",
" url = f\"https://api.crossref.org/works/{doi}\"\n",
" \n",
" try:\n",
" response = requests.get(url)\n",
" response.raise_for_status()\n",
" data = response.json()['message']\n",
" \n",
" # Extract author information\n",
" authors = data.get('author', [])\n",
" if authors:\n",
" first_author = authors[0].get('family', 'Unknown')\n",
" if len(authors) > 1:\n",
" if format_type == 'markdown':\n",
" author_str = f\"{first_author}. *et al.*\"\n",
" elif format_type == 'html':\n",
" author_str = f\"{first_author}. <i>et al.</i>\"\n",
" else:\n",
" author_str = f\"{first_author}. et al.\"\n",
" else:\n",
" author_str = f\"{first_author}.\"\n",
" else:\n",
" author_str = \"Unknown.\"\n",
" \n",
" # Extract journal name (abbreviated if available, otherwise full)\n",
" journal = data.get('short-container-title', data.get('container-title', ['Unknown Journal']))[0]\n",
" \n",
" # Format journal name in italic\n",
" if format_type == 'markdown':\n",
" journal = f\"*{journal}*\"\n",
" elif format_type == 'html':\n",
" journal = f\"<i>{journal}</i>\"\n",
" \n",
" # Extract year\n",
" pub_date = data.get('published-print', data.get('published-online', {}))\n",
" year = pub_date.get('date-parts', [[None]])[0][0] if pub_date else 'N/A'\n",
" \n",
" # Format year in bold\n",
" if format_type == 'markdown':\n",
" year = f\"**{year}**\"\n",
" elif format_type == 'html':\n",
" year = f\"<b>{year}</b>\"\n",
" \n",
" # Extract volume\n",
" volume = data.get('volume', '')\n",
" \n",
" # Extract issue\n",
" issue = data.get('issue', '')\n",
" \n",
" # Extract pages\n",
" page = data.get('page', '')\n",
" \n",
" # Format citation\n",
" citation = f\"{author_str} {journal} {year}\"\n",
" \n",
" if volume:\n",
" citation += f\", {volume}\"\n",
" \n",
" if issue:\n",
" citation += f\" ({issue})\"\n",
" \n",
" if page:\n",
" citation += f\", {page}\"\n",
" \n",
" return citation\n",
" \n",
" except requests.exceptions.RequestException as e:\n",
" return f\"Error fetching DOI: {e}\"\n",
" except (KeyError, IndexError) as e:\n",
" return f\"Error parsing metadata: {e}\"\n",
"\n",
"def display_citation(doi):\n",
" \"\"\"Display citation with proper markdown formatting in Jupyter\"\"\"\n",
" citation = get_citation_from_doi(doi, format_type='markdown')\n",
" display(Markdown(citation))\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "b4154c2e",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Formatted citation:\n"
]
},
{
"data": {
"text/markdown": [
"Musaelian. *et al.* *Nat Commun* **2023**, 14 (1)"
],
"text/plain": [
"<IPython.core.display.Markdown object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"As markdown text:\n",
"Musaelian. *et al.* *Nat Commun* **2023**, 14 (1)\n",
"\n",
"As HTML:\n",
"Musaelian. <i>et al.</i> <i>Nat Commun</i> <b>2023</b>, 14 (1)\n",
"\n",
"As plain text:\n",
"Musaelian. et al. Nat Commun 2023, 14 (1)\n"
]
}
],
"source": [
"# Example usage\n",
"example_doi = \"10.1038/s41467-023-36329-y\"\n",
"\n",
"# Display with markdown formatting (renders in notebook)\n",
"print(\"Formatted citation:\")\n",
"display_citation(example_doi)\n",
"\n",
"# Or get as plain text\n",
"print(\"\\nAs markdown text:\")\n",
"print(get_citation_from_doi(example_doi, format_type='markdown'))\n",
"\n",
"# Or get as HTML\n",
"print(\"\\nAs HTML:\")\n",
"print(get_citation_from_doi(example_doi, format_type='html'))\n",
"\n",
"# Or get as plain text\n",
"print(\"\\nAs plain text:\")\n",
"print(get_citation_from_doi(example_doi, format_type='plain'))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment