Skip to content

Tutorial: your first manuscript in 15 minutes

This tutorial walks one path. By the end you will have a Quarto manuscript with citations resolved automatically from DOIs and PubMed IDs, rendering itself on every push, deployed to GitHub Pages with a /v/<commit-sha>/ immutable permalink for each commit.

Budget: 15 minutes if you have Quarto, uv, and gh already on your machine. First render takes longer because Quarto installs TinyTeX the first time it sees a PDF format. After that, every render is fast.

You will not learn why the design choices are this way — that’s the Design and Citation pipeline pages’ job. This tutorial is doing, not understanding.

To set the example: the tooling that makes a Quarto manuscript self-rendering, citation-resolving, and version-banner-aware draws on the broader Quarto + pandoc-citeproc ecosystem; for the data side of a typical manuscript, the tidyverse (Wickham et al. 2019) is the most-cited starting point in R, single-cell methods like Seurat (Stuart et al. 2018) anchor a lot of methods-paper bibliographies, and transformer architectures (Vaswani et al. 2023) for LLM-driven analysis tooling, and reference datasets (2013) anchor the biological claims a paper makes. Those four citations live in this paragraph, were resolved by quartobot resolve against their registrars (Crossref, bioRxiv via Crossref, PubMed), and pandoc-citeproc formatted the inline citations and bibliography section below.

You need:

  • Quarto ≥ 1.4quarto --version. Install Quarto if needed.
  • uvuv --version. Install uv if needed; it handles the Python install for you transparently.
  • gh (the GitHub CLI) — gh --version. Install gh if needed.
  • A GitHub account authenticated with gh auth login.

That’s it. No separate Python install, no quarto add step, no Quarto extension to install — uv tool install quartobot brings everything along, including the resolver library.

Terminal window
uv tool install quartobot

This puts quartobot on your user PATH so Quarto’s pre-render subprocess can find it without venv activation. Confirm:

Terminal window
quartobot --version
quartobot, version 0.3.0

You should see quartobot, version 0.2.0 or later.

Use Quarto’s own scaffolder for the project shape:

Terminal window
quarto create project manuscript my-paper
cd my-paper

Quarto writes a manuscript-shaped directory: an index.qmd, a _quarto.yml, and the layout pandoc expects for a single-document manuscript.

Layer the citation pipeline on top:

Terminal window
quartobot init

init adds two new files and modifies .gitignore: a seed references.bib you can hand-curate any non-registrar references into, plus .gitignore lines for _book/, _freeze/, .quarto/, *_files/, **/*.quarto_ipynb, and references.json. Because quarto create project already wrote a _quarto.yml, init won’t touch it; instead it prints a YAML snippet to paste in yourself. Copy the snippet and merge it into your _quarto.yml under the existing project: block — it adds the pre-render: line plus a bibliography: list with both references.bib and references.json.

That’s the minimum. If all you want is citations resolved from @doi: and friends, stop here.

Open index.qmd and replace the body with a paragraph that uses the cite keys quartobot supports. Authors who write the prose below get the rendered references below it for free — no hand-curating a .bib per source.

The tooling stack for a modern computational manuscript spans
several sources. The tidyverse [@doi:10.21105/joss.01686] gives R
users a coherent grammar for data manipulation. Single-cell
integration approaches like Seurat [@doi:10.1101/460147], still on
bioRxiv as a preprint, sit alongside transformer architectures
[@arxiv:1706.03762] for the LLM-driven tooling now common in
analysis pipelines. Reference datasets like the Genotype-Tissue
Expression Consortium's pilot analysis [@pmid:23715323] anchor the
biological claims.

Four cite keys, four registrars (Crossref, bioRxiv via Crossref, arXiv, PubMed). Save the file.

Before rendering, ask quartobot what citations it sees. The same prose you just wrote, scanned by quartobot scan:

Terminal window
quartobot scan fixtures/sample-paper/
arxiv:
1706.03762
doi:
10.1101/460147
10.21105/joss.01686
pmid:
23715323
4 unique key(s), 4 total occurrence(s) across 1 file(s).

That’s the inventory the pre-render hook will resolve when quarto render runs. Each prefix groups its keys; the summary line reports the total.

Terminal window
quarto render

First render installs TinyTeX (Quarto handles this; takes 1–2 minutes). On the second render and after, it’s seconds.

The pre-render hook fires before pandoc runs. It:

  1. Scans index.qmd for cite keys.
  2. Calls each registrar (Crossref for the DOI, PubMed for the PMID, arXiv for the arXiv preprint) to resolve canonical metadata.
  3. Writes the resulting CSL JSON to references.json.
  4. Hands control back to pandoc, which reads references.json and formats the citations.

Open _output/index.html (or index.pdf). The citations show as formatted references with author names, journal, year. No empty [?] placeholders.

Re-run quarto render. Now it’s near-instant — the pre-render hook sees references.json already exists with all keys cached, skips the network round-trip, and pandoc renders straight through.

If you want every push to your GitHub repo to render the manuscript, deploy it to GitHub Pages, embed a “this version: <sha>” banner in the rendered HTML, and post a sticky preview comment on each PR — add the second layer:

Terminal window
quartobot use github-ci

This scaffolds .github/workflows/render.yml (the trigger), the PR-preview cleanup workflow, the version-banner Quarto include, and prints a YAML snippet to merge into your _quarto.yml so the banner appears in the rendered HTML.

Skip this step entirely if you already have CI you’re happy with, or if you plan to publish via quarto publish. The citation pipeline from step 3 works the same either way.

For the full set of inputs you can override on the scaffolded workflow (formats, manuscript-name, quarto-version, project-title, etc.), see Workflows and actions in the Reference section. Same page covers the composite actions if you’d rather compose your own workflow instead.

Add the snippet that quartobot use github-ci printed to your _quarto.yml. It will look roughly like:

format:
html:
include-before-body:
- _version-banner.html
Terminal window
gh repo create my-paper --source=. --public --push

gh creates the repo, pushes your commit, and gives you the URL.

The render workflow fires on push. Watch it land:

Terminal window
gh run watch

When the workflow finishes, GitHub Pages serves your manuscript at https://<your-handle>.github.io/my-paper/. Every commit also deploys to a versioned subdirectory: https://<your-handle>.github.io/my-paper/v/<sha>/index.html. The version banner in the rendered HTML links you between them.

Make a change. Push to a branch. Open a PR.

Terminal window
git checkout -b add-context
# edit index.qmd, add another sentence with another citation
git add index.qmd
git commit -m "Add context paragraph"
git push -u origin add-context
gh pr create --fill

Within a couple of minutes a sticky comment lands on the PR with a link to a preview render. Reviewers see exactly what your branch renders to without checking it out locally.

When you merge the PR, quartobot use github-ci’s cleanup workflow removes the preview directory from gh-pages; the merge commit gets its own /v/<sha>/ permalink alongside the latest.

  • A manuscript that builds itself on every push.
  • Citations resolved from registrars at render time, cached so CI never sees a network blip mid-render.
  • An immutable /v/<sha>/ URL for every commit anyone can cite.
  • PR previews via sticky comment.
  • A version banner in the rendered HTML pointing at “this version” and “the latest version” of the paper.
  • CLI reference — every command, every flag.
  • MCP server — point Claude Desktop, Codex, or Gemini Code Assist at quartobot mcp so an agent can call the resolve_citation tool while you draft.
  • Migrating from manubot — if you have a manubot manuscript and want to translate the layout.
  • Design — the architecture decisions and prior art.

2013. “The Genotype-Tissue Expression (GTEx) Project.” Nature Genetics 45 (6): 580–85. https://doi.org/10.1038/ng.2653.

Stuart, Tim, Andrew Butler, Paul Hoffman, et al. 2018. “Comprehensive Integration of Single Cell Data.” openRxiv, November 2. https://doi.org/10.1101/460147.

Vaswani, Ashish, Noam Shazeer, Niki Parmar, et al. 2023. “Attention Is All You Need.” In arXiv, 1706.03762. arXiv. https://arxiv.org/abs/1706.03762.

Wickham, Hadley, Mara Averick, Jennifer Bryan, et al. 2019. “Welcome to the Tidyverse.” Journal of Open Source Software 4 (43): 1686. https://doi.org/10.21105/joss.01686.