Skip to content

Publish a collection of talks

quarkfoil publish puts a presentation into a collection: a folder holding many talks that share one copy of the player and one pool of assets, with a listing page in front of them. It is the third way Quarkfoil writes a presentation out, beside a self-contained static export and an editable project copy, and it changes neither of them.

quarkfoil publish lecture.md --site ~/talks
quarkfoil publish lecture.md --site homepage:talks/

The destination may be a local directory or an rsync destination; everything else is identical.

What a collection looks like

talks/
├── index.html                    the listing, plain HTML
├── collection.json               its heading and standfirst
├── 2026-inc-school/
│   ├── index.html                the deck page
│   ├── presentation.md           published unchanged
│   └── meta.json                 what the listing is built from
└── assets/
    ├── quarkfoil/0.5.0/          player, Reveal.js, KaTeX, fonts, notices
    └── f/9c/9c3f1a2b…-transmon.png

Every asset is stored under a name derived from its content. Two decks that use the same figure store it once, however many collections of slides reuse it, and two different figures that happen to share a file name are simply two entries. Nothing has to be renamed, and no collision has to be resolved.

The deck's own Markdown is published exactly as written, still saying figures/transmon.png. The page carries a small map from those paths to the pool, which the player consults when it renders. Nothing rewrites the presentation, so what a reader downloads is what you wrote.

The runtime folder is named after the Quarkfoil version that built it. Publishing with a newer Quarkfoil adds a folder rather than replacing one, so talks published earlier keep rendering exactly as they did.

What controls the listing

The listing is built from front matter, so a talk describes itself:

---
title: Superconducting quantum circuits
description: A brief and biased introduction to circuit QED, from the Meissner
  effect to quantum simulation with transmons.
event: INC School, Innsbruck
date: 2026-09-07
---

title and description are the ordinary format fields; description falls back to subtitle. event and date are read only by the listing. date is required for a published talk, and an unreadable or missing one stops the publish rather than guessing a year for a public page.

Add unlisted: true to publish a talk that the listing leaves out. The page is reachable by its URL; it simply does not appear.

The page groups talks by year, newest year first and newest talk first inside it. It is generated at publish time and shipped as static HTML: every title, event and description sits in the markup, so search engines read the whole listing without running any JavaScript.

--index-title and --index-lede set the heading and the sentence under it. Both are remembered in collection.json, so a later publish does not reset them, and editing that file changes the page on the next publish.

Use --index-only to rebuild the listing without publishing a deck, and --no-index to publish a deck without touching it.

A course is one entry, not nine

A talk that belongs to a course, a school, or any other run of related talks names it:

series: Quantum Simulation Platforms
part: 3
series-description: Nine lectures on the platforms that simulate quantum matter.

The listing then shows one card for the series — its name, the occasion, how many talks it holds, and the range of dates — instead of burying single talks under nine siblings. The card links to a page of its own at series/<name>/, which lists the talks in the order they were given: by part when every member has one, and by date otherwise.

series-description is read from whichever member defines it first, so it need not be repeated in each deck. A series is filed under the year of its most recent talk, so one that runs across New Year appears once. series is the only field needed; part and series-description are optional.

The pages under series/ are regenerated from the talks on every publish, so a series whose talks are gone loses its page. A talk may not be named series, which is reserved for them.

Publishing a course in one go

Several decks can be published together, which is how a course is meant to go up:

quarkfoil publish presentations/0*.md --site homepage:talks/

They are staged as one collection update: the shared figures cross the wire once for the whole course rather than once per lecture, and the listing is rebuilt a single time at the end. Each deck's folder is named after its file; --name renames one, and so applies only when publishing a single deck.

Speaker notes are left out

A published deck's presentation.md is a file anyone can open, and speaker notes are written for the presenter, so publishing omits them. The deck on disk is untouched: only the published copy loses them, and the notes you present from stay where they are.

Add --notes to publish them anyway, which also restores Reveal.js's speaker view on the published page. --no-notes is accepted and is the default.

This is the one place publish deliberately differs from export, which keeps notes unless --no-notes is given: an export is a folder you hand to someone, while publishing puts the deck at a public URL.

Publishing to a web host

A remote --site is an ordinary rsync destination:

You write Meaning
~/talks, ./talks, C:\talks local directory
homepage:talks/ remote over ssh
user@host:/var/www/talks/ remote over ssh
rsync://host/module/talks/, host::module/talks/ rsync daemon

Quarkfoil reports which it read before it transfers anything. A target is remote when it starts with rsync://, contains ::, or has two or more characters before a colon, so a Windows drive letter stays local.

Two transfers run, and they differ deliberately:

rsync -rltL --ignore-existing <staged>/assets/  homepage:talks/assets/
rsync -rltL --delete --delay-updates <staged>/2026-inc-school/  homepage:talks/2026-inc-school/

The shared half is append-only: --ignore-existing never deletes, and a name that already exists holds the same bytes by construction, so nothing is re-sent. The deck's own folder is mirrored, because a re-published talk owns it; --delay-updates swaps its files in at the end, so a reader loading the talk mid-publish does not catch it half-changed. --delete is never run at the root of the collection: publishing a talk cannot remove another one.

Nothing is mirrored locally. Quarkfoil stages the deck in a temporary folder of symlinks — a few hundred kilobytes — and rsync sends only the bytes the host is missing. The staging folder is removed afterwards.

--dry-run passes through to every transfer and reports what would move. Publishing to a remote target needs rsync on the PATH; --rsync selects a different program. Quarkfoil handles no credentials: ssh does, exactly as it does for your other rsync targets.

What the collection does not do

Files are never removed from the pool, so a figure replaced by a new version leaves its predecessor behind. That is what makes publishing safe to interrupt and safe to run from any machine. Collecting the unreferenced ones is a deliberate, separate operation, not something a publish does on its own.

An image written inside prose, rather than as a slide's own image block, is not resolved through the asset map. Quarkfoil keeps a private copy of it beside the deck so the page is still correct, and says so while publishing.