Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ Thumbs.db
*~
.env
.env.*.local

uv.lock
.local/*
224 changes: 112 additions & 112 deletions content/about/publications.md

Large diffs are not rendered by default.

112 changes: 112 additions & 0 deletions data/publications.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
publication-dois:
- 10.1038/s41597-025-05503-w
- 10.48550/arXiv.2507.03674
- 10.48550/arXiv.2504.07824
- 10.2196/63343
- 10.1002/hipo.70028
- 10.1007/s12021-024-09665-7
- 10.1038/s41592-023-02145-x
- 10.1038/s41597-024-03629-x
- 10.1093/gigascience/giae009
- 10.1101/2024.04.29.24306516
- 10.1162/imag_a_00103
- 10.1176/appi.ajp.20230249
- 10.1186/s12984-024-01309-w
- 10.1371/journal.pdig.0000516
- 10.1371/journal.pone.0295069
- 10.21105/joss.05839
- 10.3389/fninf.2024.1376022
- 10.52294/001c.123059
- 10.1016/j.neuroimage.2022.119807
- 10.1038/s41562-023-01647-0
- 10.1038/s41597-023-01946-1
- 10.1038/s41598-022-25306-y
- 10.1101/2023.08.01.551505
- 10.1101/2023.08.16.552472
- 10.1159/000530358
- 10.21203/rs.3.rs-2649734/v1
- 10.3389/fnhum.2023.1237651
- 10.3389/fnimg.2022.1098604
- 10.3389/fnimg.2023.1099301
- 10.3389/fninf.2023.1174156
- 10.3389/fnins.2023.1233416
- 10.1148/radiol.230096
- 10.1007/s10548-022-00935-8
- 10.1007/s12021-021-09557-0
- 10.1016/j.neuroimage.2022.119612
- 10.1016/j.neuroimage.2022.119623
- 10.1016/j.neuron.2021.11.017
- 10.1038/s41398-022-02211-6
- 10.1038/s41592-022-01681-2
- 10.1038/s41597-022-01682-y
- 10.1038/s41598-022-19356-5
- 10.1093/gigascience/giac013
- 10.1148/radiol.210385
- 10.12688/f1000research.108008.2
- 10.1371/journal.pcbi.1009651
- 10.3389/fnhum.2022.749767
- 10.7554/eLife.79277
- 10.1002/hbm.25351
- 10.1007/s12021-020-09509-0
- 10.1007/s12021-021-09517-8
- 10.1007/s12021-021-09522-x
- 10.1007/s12021-021-09533-8
- 10.1016/j.mex.2021.101595
- 10.1016/j.neuroimage.2021.118683
- 10.1016/j.neuron.2021.04.001
- 10.1016/j.nicl.2021.102790
- 10.1038/s41597-021-01033-3
- 10.1038/s41598-021-87069-2
- 10.1038/s41598-021-94733-0
- 10.1093/gigascience/giaa155
- 10.1093/gigascience/giab055
- 10.12688/f1000research.25306.2
- 10.1515/nf-2020-0037
- 10.21105/joss.03262
- 10.2196/22369
- 10.7554/eLife.71774
- 10.7554/eLife.72129
- 10.1002/lio2.354
- 10.1016/j.neuroimage.2019.116330
- 10.1016/j.nicl.2020.102240
- 10.1016/j.nicl.2020.102242
- 10.1016/j.nicl.2020.102266
- 10.1038/s41586-020-2314-9
- 10.1038/s41596-020-0327-3
- 10.1038/s41597-020-0486-7
- 10.1101/2020.11.23.20235945
- 10.1146/annurev-neuro-100119-110036
- 10.12688/f1000research.24544.1
- 10.1016/j.neulet.2019.01.037
- 10.1016/j.neuroimage.2019.116091
- 10.1038/s41597-019-0031-8
- 10.12688/mniopenres.12772.2
- 10.1371/journal.pone.0210028
- 10.21105/joss.01294
- 10.3233/JPD-191775
- 10.3389/fninf.2019.00001
- 10.3389/fninf.2019.00003
- 10.7554/eLife.48932
- 10.1007/s12021-018-9379-8
- 10.1038/sdata.2018.29
- 10.1093/database/bay130
- 10.1093/gigascience/giy077
- 10.1109/TMI.2018.2831261
- 10.3389/fnins.2018.00727
- 10.7554/eLife.36652
- 10.1007/s12021-017-9331-3
- 10.1007/s12021-017-9335-z
- 10.1038/nn.4500
- 10.1038/nn.4550
- 10.1038/nrn.2016.167
- 10.1038/sdata.2017.59
- 10.1093/cercor/bhx030
- 10.12688/f1000research.10783.2
- 10.1371/journal.pcbi.1005209
- 10.1371/journal.pcbi.1005350
- 10.1016/j.neuron.2016.04.030
- 10.1038/sdata.2016.102
- 10.1038/sdata.2016.44
- 10.1073/pnas.1608282113
- 10.1093/gerona/glw236
- 10.3389/fninf.2016.00034
10 changes: 10 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[project]
name = "repronim-publications"
version = "0.1.0"
description = "Scripts for generating ReproNim publications from DOIs"
requires-python = ">=3.10"
dependencies = [
"citeproc-py[full]>=0.9.0",
"pyyaml>=6.0",
"duecredit>=0.9.0",
]
12 changes: 12 additions & 0 deletions scripts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Publication Generation

Regenerate publications from DOIs in `data/publications.yaml`:

Run from the root of this repo:

```bash
datalad run -m "Generate publications from DOIs" \
--input data/publications.yaml \
--output content/about/publications.md \
"uv run python scripts/generate_publications.py"
```
118 changes: 118 additions & 0 deletions scripts/generate_publications.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#!/usr/bin/env python3
"""
Generate publications.md from list of DOIs using duecredit/citeproc-py.

This script reads DOIs from data/publications.yaml and generates
formatted citations in APA style, writing to content/about/publications.md
"""

import sys
import yaml
from pathlib import Path
from duecredit.io import format_bibtex, import_doi, BibTeX


def fetch_citation(doi):
"""
Fetch and format a single citation from a DOI.

Args:
doi: DOI string (e.g., "10.1038/s41597-025-05503-w")

Returns:
Formatted citation string in APA style, or None if fetch failed
"""
try:
# Add https://doi.org/ prefix if not present
doi_url = doi if doi.startswith('http') else f'https://doi.org/{doi}'

# Fetch citation data and format as APA
bibtex_data = BibTeX(import_doi(doi_url))
citation = format_bibtex(bibtex_data, style='apa')

return citation
except Exception as e:
print(f"Warning: Failed to fetch DOI {doi}: {e}", file=sys.stderr)
return None


def generate_publications_markdown(dois, output_path):
"""
Generate the publications markdown file from a list of DOIs.

Args:
dois: List of DOI strings
output_path: Path to write the generated markdown file
"""
# Frontmatter for the markdown file
frontmatter = """---
Title: ReproNim Publications
linkTitle: "Publications"
type: docs
weight: 60
---
"""

citations = []
failed_dois = []

print(f"Fetching {len(dois)} publications...")

for i, doi in enumerate(dois, 1):
print(f" [{i}/{len(dois)}] Fetching {doi}...", end=' ')
citation = fetch_citation(doi)

if citation:
citations.append(citation)
print("✓")
else:
failed_dois.append(doi)
print("✗")

# Write the markdown file
with open(output_path, 'w') as f:
f.write(frontmatter)

for i, citation in enumerate(citations, 1):
f.write(f"{i}. {citation}\n\n")

print(f"\nGenerated {len(citations)} citations to {output_path}")

if failed_dois:
print(f"\nWarning: {len(failed_dois)} DOIs failed to fetch:")
for doi in failed_dois:
print(f" - {doi}")


def main():
# Paths
repo_root = Path(__file__).parent.parent
doi_yaml = repo_root / 'data' / 'publications.yaml'
output_md = repo_root / 'content' / 'about' / 'publications.md'

# Load DOIs from YAML
print(f"Loading DOIs from: {doi_yaml}")
with open(doi_yaml, 'r') as f:
data = yaml.safe_load(f)
dois = data.get('publication-dois', [])

if not dois:
print("Error: No DOIs found in publications.yaml", file=sys.stderr)
sys.exit(1)

# Optional: limit number of DOIs for testing (use first argument)
if len(sys.argv) > 1:
limit = int(sys.argv[1])
print(f"Testing mode: processing first {limit} DOIs only")
dois = dois[:limit]

# Generate publications
generate_publications_markdown(dois, output_md)

print("\nDone! To add new publications:")
print(f" 1. Add DOI to {doi_yaml}")
print(f" 2. Run: uv run python scripts/generate_publications.py")


if __name__ == '__main__':
main()
Loading