Citation resolution and manuscript-as-software CI for Quarto.
Project description
quartobot
Citation resolution and manuscript-as-software CI for Quarto.
Paste a DOI in your prose. Render the manuscript. The bibliography is already correct.
uv tool install quartobot
Documentation: seandavi.github.io/quartobot · Source: seandavi/quartobot · PyPI: quartobot
What it does
Authors write persistent-identifier cite keys directly in prose:
We follow @doi:10.1371/journal.pcbi.1007128, with the dataset described
in @pmid:31479462 and methods inspired by @arxiv:2104.10729.
A Quarto project.pre-render: hook resolves each key to canonical
metadata before pandoc-citeproc runs, writes the result to a
references.resolved.bib (BibLaTeX) you can commit, and the
manuscript renders the same way on every machine. No quartobot
install needed at render time, no live Crossref / PubMed / arXiv hit
per render. CI gets the same behavior the author saw locally, and a
network blip mid-render is no longer a build failure.
Supported prefixes: @doi:, @pmid:, @arxiv:, @isbn:, @url:,
@wikidata:, @pmc:, plus hand-curated keys from a project .bib.
Resolution goes through manubot's
citekey_to_csl_item — eight years of accumulated source-API quirks
behind a single function call. quartobot itself doesn't reimplement
resolution; it provides the Quarto integration, the CI scaffolding,
and an agent-facing MCP surface.
Quick start
uv tool install quartobot
quarto create project manuscript my-paper
cd my-paper && quartobot init
# Optional: scaffold render + PR-preview CI.
quartobot use github-ci
That's the canonical path. Three other on-ramps live in Choose a path in for "I have an existing Quarto project" and the resolver-only minimum.
The CLI
| Command | What it does |
|---|---|
resolve |
The pre-render hook. Invoked by Quarto from _quarto.yml's project.pre-render: line. Reads cite keys, writes BibLaTeX (references.resolved.bib) plus a CSL JSON cache. |
scan / validate |
CI-lint surfaces. Cite-key inventory and static _quarto.yml checks. |
init |
Scaffolds the citation pipeline into an existing Quarto project. Three files only. |
use github-ci |
Layers the render + PR-preview CI on top. Lean default; --with-versioned-snapshots for the manubot per-commit-permalink pattern. |
reconcile |
Resolves references.bib ↔ resolved-bibliography citation-key collisions with explicit modes. Backup-then-mutate. |
versions |
Generates the /versions/ page on gh-pages — tagged releases + open PR previews. |
mcp |
Stdio MCP server. Agents in Claude Desktop, Codex, Gemini Code Assist call the same resolver as part of drafting. |
Full reference: CLI and Workflows and actions.
Why this exists
manubot/manubot#332 ("Quarto integration") was opened by Anthony Gitter in April 2022 after a conversation with Sean Davis. Four years on, no PR, no assignee — but Quarto Manuscripts shipped as a first-party project type, and the integration turned out to be small once the resolver question was settled. This repo is the work to close that issue.
The longer story: Differences from manubot, Design, Citation pipeline.
Working example
seandavi/2026-venice-spatial-hackathon-manuscript runs the CI / permalink / banner half of the pattern on a live 25-author preprint from the Bioconductor Spatial Hackathon. That's the production reference the template lifted from.
See also
- Docs site: seandavi.github.io/quartobot — install, CLI reference, tutorials, migration guides, MCP setup
- Coming from another tool: Quarto · manubot · Zotero · LaTeX
- Release process:
RELEASE_CHECKLIST.md— grounded in actual failure modes - Contributing:
CONTRIBUTING.mdandCODE_OF_CONDUCT.md - Changelog:
CHANGELOG.md
Demo recording
The GIF above walks quartobot scan → quartobot resolve (live registrar lookups) → quarto render --to html → the formatted citation in the rendered manuscript. Recorded with asciinema (cast) + agg (cast → GIF). To re-record after changing the demo flow:
brew install asciinema agg
bash scripts/demo-setup.sh
asciinema rec docs/demo.cast --command 'bash scripts/demo.sh' --overwrite
agg docs/demo.cast docs/demo.gif --font-size 18 --theme dracula --speed 1.2 --cols 80 --rows 28
cp docs/demo.gif site/public/demo.gif # also serves the landing-page embed
The scripts/demo.tape file is a vhs alternative for a higher-fidelity render once a Chrome/Chromium environment is available.
License
MIT.
Maintained by Sean Davis.
quartobot is an independent community project. It builds on Quarto but is not affiliated with or endorsed by Posit, PBC.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file quartobot-0.6.0.tar.gz.
File metadata
- Download URL: quartobot-0.6.0.tar.gz
- Upload date:
- Size: 88.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c577783c8a12a225d0ccd2367cb1299264dc238bd7c56ba6d81dddb52b06a8b9
|
|
| MD5 |
bf0df76af703a4eb14551b389dde4f20
|
|
| BLAKE2b-256 |
18325d6069b1c46413a5cd7c7b0e1e61ca85533162caab1a38cefc5021bf408c
|
Provenance
The following attestation bundles were made for quartobot-0.6.0.tar.gz:
Publisher:
publish-pypi.yml on seandavi/quartobot
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
quartobot-0.6.0.tar.gz -
Subject digest:
c577783c8a12a225d0ccd2367cb1299264dc238bd7c56ba6d81dddb52b06a8b9 - Sigstore transparency entry: 1658673485
- Sigstore integration time:
-
Permalink:
seandavi/quartobot@dac5c233010b3905fb2e51ffc71cb5cc99aeda44 -
Branch / Tag:
refs/tags/v0.6.0 - Owner: https://github.com/seandavi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@dac5c233010b3905fb2e51ffc71cb5cc99aeda44 -
Trigger Event:
push
-
Statement type:
File details
Details for the file quartobot-0.6.0-py3-none-any.whl.
File metadata
- Download URL: quartobot-0.6.0-py3-none-any.whl
- Upload date:
- Size: 59.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e99174d257e0bfa9eb08231a105a6dd44c8c7975ec54ebeeb64a524cb884e7e1
|
|
| MD5 |
bc7c5301802d6fb4a01e9e1e894fd64e
|
|
| BLAKE2b-256 |
28a4005abe24cf3a4bcd02943e9693a15684d658a84faa85c9d8b965b2a5aac2
|
Provenance
The following attestation bundles were made for quartobot-0.6.0-py3-none-any.whl:
Publisher:
publish-pypi.yml on seandavi/quartobot
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
quartobot-0.6.0-py3-none-any.whl -
Subject digest:
e99174d257e0bfa9eb08231a105a6dd44c8c7975ec54ebeeb64a524cb884e7e1 - Sigstore transparency entry: 1658673771
- Sigstore integration time:
-
Permalink:
seandavi/quartobot@dac5c233010b3905fb2e51ffc71cb5cc99aeda44 -
Branch / Tag:
refs/tags/v0.6.0 - Owner: https://github.com/seandavi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@dac5c233010b3905fb2e51ffc71cb5cc99aeda44 -
Trigger Event:
push
-
Statement type: