Agent-native slide creation tool for research talks
Project description
Colloquium
Markdown-based slide creation tool for research talks. Git-friendly, AI-drivable, single-file HTML output.
Install
Colloquium uses uv for fast, reliable Python package management.
uv tool install colloquium
# or inside a project
uv pip install colloquium
For development:
git clone https://github.com/natolambert/colloquium.git
cd colloquium
uv pip install -e ".[dev]"
Quick Start
Create a markdown file:
---
title: "My Talk"
author: "Jane Doe"
date: "2026-02-22"
---
# My Talk
Jane Doe
---
## Key Results
- Finding one
- Finding two
---
## Conclusion
Thanks for listening!
Build it:
colloquium build slides.md # → slides.html
colloquium serve slides.md # dev server with live reload
colloquium export slides.md # PDF via a headless Chromium-based browser
CLI Commands
| Command | Description |
|---|---|
colloquium build <file.md> |
Build to self-contained HTML |
colloquium serve <file.md> |
Dev server with live reload |
colloquium export <file.md> |
PDF export (requires a Chromium-based browser) |
Frontmatter Reference
All configuration goes in the YAML frontmatter block at the top of the file.
---
title: "Talk Title"
author: "Author Name"
date: "2026-02-22"
theme: default
aspect_ratio: "16:9"
fonts:
heading: "Playfair Display" # Google Font for h1/h2/h3
body: "Source Sans 3" # Google Font for body text
footer:
left: "https://example.com/logo.png" # image URL → logo, plain text → text
center: "My Talk Title"
right: "auto" # "auto" → slide numbers "3 / 12"
custom_css: ".slide h2 { color: red; }" # inline CSS overrides
---
| Key | Default | Description |
|---|---|---|
title |
"Untitled" |
Presentation title (used in <title> and title slides) |
author |
"" |
Author name |
date |
"" |
Date string |
theme |
"default" |
Theme name |
aspect_ratio |
"16:9" |
Slide aspect ratio |
fonts.heading |
Inter | Google Font for headings |
fonts.body |
Inter | Google Font for body text |
footer.left |
"" |
Left footer zone (text, image URL, or "auto") |
footer.center |
"" |
Center footer zone |
footer.right |
"auto" |
Right footer zone ("auto" = slide numbers) |
custom_css |
"" |
Additional CSS injected into the page |
Footer text supports {n} (slide number) and {N} (total slides) for custom counters, e.g. "Lambert {n}/{N}" → "Lambert 6/23".
When footer: is omitted entirely, a minimal footer with just the slide counter in the right zone is used.
Use {n} and {N} placeholders to embed the current slide number and total count inline with text:
footer:
left: "rlhfbook.com"
right: "Lambert {n}/{N}" # renders as "Lambert 3/25"
If no zone uses "auto", {n}, or {N}, the slide counter is automatically placed in the first empty zone.
Slide Structure
Slides are separated by --- on its own line. The first heading in each slide becomes the slide title:
| Heading | Behavior |
|---|---|
# Title |
Title slide — centered, large text, slide--title layout |
## Title |
Content slide — standard layout with heading at top |
### through ###### |
Rendered as subheadings within slide content |
# Welcome ← title slide (centered, large)
---
## Key Results ← content slide (heading + body)
### Sub-section ← rendered as h3 inside the slide body
Normal paragraph text.
Slide Directives
Per-slide configuration via HTML comments. Place them anywhere in the slide.
## My Slide
<!-- layout: section-break -->
<!-- class: highlight special -->
<!-- style: background: #1a1a2e -->
<!-- notes: Remember to mention X -->
<!-- align: center -->
<!-- valign: bottom -->
<!-- columns: 2 -->
<!-- rows: 35/65 -->
<!-- padding: compact -->
<!-- size: large -->
<!-- title: hidden -->
Layouts
| Directive | Effect |
|---|---|
<!-- layout: title --> |
Centered title slide (used with # Heading) |
<!-- layout: title-left --> |
Left-aligned title slide with stacked metadata |
<!-- layout: title-sidebar --> |
Wide title with a right-side metadata rail |
<!-- layout: title-banner --> |
Editorial title slide with headline up top and metadata near the bottom |
<!-- layout: content --> |
Default content layout (used with ## Heading) |
<!-- layout: section-break --> |
Dark accent background, centered text |
<!-- layout: two-column --> |
Two-column grid |
<!-- layout: image-left --> |
Image on left, text on right |
<!-- layout: image-right --> |
Text on left, image on right |
<!-- layout: code --> |
Optimized for large code blocks |
Columns
Split content with ||| between columns:
<!-- columns: 2 -->
## Results
Left column content
|||
Right column content
| Value | Effect |
|---|---|
2 |
Two equal columns |
3 |
Three equal columns |
60/40 |
60%/40% split |
40/60 |
40%/60% split |
70/30 |
70%/30% split |
30/70 |
30%/70% split |
Arbitrary numeric ratios are allowed, e.g. 25/75, 33/67, or 1/2/1.
Rows
Split a slide vertically with === between row blocks:
<!-- rows: 35/65 -->
## Overview
Top row content
===
Bottom row content
| Value | Effect |
|---|---|
2 |
Two equal rows |
3 |
Three equal rows |
60/40 |
60%/40% split |
40/60 |
40%/60% split |
35/65 |
35%/65% split |
65/35 |
65%/35% split |
70/30 |
70%/30% split |
30/70 |
30%/70% split |
Arbitrary numeric ratios are allowed here too, e.g. 25/75 or 20/30/50.
To use columns inside a specific row block, add a row-local directive at the top of that row:
<!-- rows: 35/65 -->
## Overview
<!-- row-columns: 40/60 -->
Left text
|||
Right text
===

At the slide root, use either columns: or rows:. For nested layouts, use row-columns: inside a row block.
Text & Spacing
| Directive | Values |
|---|---|
<!-- align: ... --> |
left, center, right |
<!-- valign: ... --> |
top, center, bottom |
<!-- size: ... --> |
small (20px), normal (24px), large (28px) |
<!-- padding: ... --> |
compact (30px), normal (60px), wide (90px) |
<!-- title: ... --> |
top, center, hidden |
Other
| Directive | Description |
|---|---|
<!-- class: name1 name2 --> |
Add CSS classes to the slide |
<!-- style: css-here --> |
Inline CSS on the slide element |
<!-- notes: text --> |
Speaker notes (hidden in presentation) |
<!-- class: figure-captions --> |
Turn standalone markdown images on that slide into numbered figures with captions taken from  |
<!-- class: no-figure-captions --> |
Disable deck-wide figure captions for a specific slide |
<!-- img-align: center --> |
Align images only (left, center, right) — title unaffected |
<!-- img-valign: top --> |
Vertically align standalone images in grid/row cells (top, center, bottom) |
<!-- img-fill: true --> |
Expand image to fill available slide space |
<!-- img-overflow: true --> |
Let images in grid cells bleed outside their box instead of fitting inside |
See the examples on the website for rendered decks and copy-paste patterns, or browse the source in examples/.
Bibliography
Frontmatter options:
bibliography: refs.bib
citation_style: author-year
citation_order: auto
citation_style: numerickeeps citations and references in first-appearance order.- Non-numeric styles default to alphabetical ordering.
- Set
citation_order: appearanceto keep author-year or title-year citations in source order.
Content Features
Math (KaTeX) — inline $E=mc^2$ and display $$\sum_{i=1}^n x_i$$
Code (highlight.js) — fenced code blocks with language syntax highlighting
Tables — standard markdown tables
Images —  with automatic sizing (SVG supported for vector graphics)
To enable numbered figure captions across a whole deck, add this to frontmatter:
figure_captions: true
Standalone markdown images will render as numbered figures, using the alt text as the caption:

This renders as Figure 1: Training recipe overview. Leave the alt text empty to suppress the caption:

If you only want captions on selected slides, use figure-captions as a slide class instead:
<!-- class: figure-captions -->

If the deck enables figure_captions: true, add no-figure-captions to a slide to opt that slide out.
Text Sizes
Control font size on any element or block using HTML class attributes:
<span class="text-2xl">Big emphasis text</span>
Normal paragraph text.
<div class="text-sm">
- Dense bullet point one
- Dense bullet point two
</div>
<span class="text-xs">Footnote or citation</span>
<div class="colloquium-spacer-md"></div>
<div class="colloquium-footnote">
This is useful for speaker-side caveats or details that should stay visually secondary.
</div>
| Class | Scale | Use case |
|---|---|---|
text-xs |
0.65em | Footnotes, citations |
text-sm |
0.8em | Dense lists, fine details |
text-base |
1em | Default |
text-lg |
1.2em | Callouts |
text-xl |
1.4em | Key takeaways |
text-2xl |
1.7em | Emphasis |
text-3xl |
2.2em | Large statements |
text-4xl |
2.8em | Hero text |
Spacing and Footnotes
Use small spacer blocks when you want more breathing room between prose and an example:
After pretraining we are left with a glorified autocomplete model.
<div class="colloquium-spacer-md"></div>
```conversation
messages:
...
Available spacer helpers:
- `colloquium-spacer-sm`
- `colloquium-spacer-md`
- `colloquium-spacer-lg`
Use `colloquium-footnote` for secondary caveats or context inside the slide body:
```markdown
<div class="colloquium-footnote">
Base models are also becoming more flexible through midtraining and related data mixtures.
</div>
For slide-level footnotes that sit above the footer, use directives:
<!-- footnote: Base models are also becoming more flexible through midtraining. -->
<!-- footnote-right: Right-aligned note for this slide. -->
These share the same bottom-left / bottom-right area as floating citations, with citations stacked above the footnote when both are present.
For inline numbered footnotes, use ^[...] where you want the marker to appear:
This sentence ends with a numbered footnote.^[Base models are also becoming more flexible through midtraining.]
Inline footnotes collect into the same floating footer area and are numbered per slide. They default to the right side; set the side explicitly when needed:
<!-- footnotes: left -->
Use the dedicated example deck in examples/footnotes/ for copy-paste patterns.
Charts
Inline charts via Chart.js using YAML in fenced code blocks:
```chart
type: line
height: 500
width: 800
data:
labels: [Q1, Q2, Q3, Q4]
datasets:
- label: Revenue
data: [10, 25, 40, 60]
color: "#4AA691"
options:
scales:
y:
ticks:
prefix: "$"
suffix: "K"
```
| Key | Default | Description |
|---|---|---|
type |
bar |
Chart type: line, bar, scatter, pie, doughnut |
height |
400 |
Container height in pixels |
width |
100% |
Container width in pixels (omit for full width) |
data.labels |
[] |
X-axis labels |
data.datasets[].label |
"Series N" |
Legend label |
data.datasets[].data |
[] |
Data values |
data.datasets[].color |
auto | Series color |
options.scales.{x,y}.ticks.prefix |
"" |
Prepend to tick labels (e.g. "$") |
options.scales.{x,y}.ticks.suffix |
"" |
Append to tick labels (e.g. "%") |
options.scales.{x,y}.grid.display |
true |
Show/hide grid lines |
Conversations
Render LLM-style chat bubbles using YAML in fenced code blocks:
```conversation
size: 0.9
messages:
- role: user
content: "What is RLHF?"
- role: assistant
model: "Tülu 3 405B"
content: "**RLHF** is a technique for aligning language models..."
- role: system
content: "You are a helpful AI assistant."
```
| Role | Styling |
|---|---|
user |
Right-aligned bubble, accent background, white text |
assistant |
Left-aligned bubble, code-bg background |
system |
Centered, bordered, muted italic text |
Message content supports markdown formatting (bold, italic, inline code).
Optional conversation settings:
| Key | Default | Description |
|---|---|---|
size |
unset | Bubble font scale as a positive numeric value like 0.9 or 1.05 |
messages[].model |
unset | Optional model label shown next to the role, e.g. ASSISTANT (Llama 3.1 405B Base) |
Boxes
Render a rounded callout card using YAML in fenced code blocks:
```box
title: DPO became popular because:
tone: accent
content: |
- Far simpler to implement
- Far cheaper to run
- Often reaches most of the final performance
```
Optional box settings:
| Key | Default | Description |
|---|---|---|
title |
unset | Bold heading shown at the top of the box |
tone |
accent |
Visual style: accent, muted, or surface |
content |
unset | Optional markdown body below the title |
size |
unset | Font scale as a positive numeric value like 0.9 or 1.05 |
align |
unset | Text alignment inside the box: left, center, or right |
compact |
false |
Tighten paragraph and list spacing inside the box |
box supports a title-only callout too:
```box
title: Core idea
tone: accent
```
The supported tones are:
| Tone | Use |
|---|---|
accent |
High-contrast highlight box using the deck accent color |
muted |
Softer supporting card using the code/background surface |
surface |
Neutral bordered panel for references, caveats, or side notes |
Built With Badge
Render a compact GitHub badge anywhere in a slide using the normal layout tools:
<!-- align: right -->
<!-- valign: bottom -->
```builtwith
repo: natolambert/colloquium
```
Optional settings:
| Key | Default | Description |
|---|---|---|
label |
"Built with" |
Small label above the repo name |
repo |
"natolambert/colloquium" |
GitHub repository slug |
url |
https://github.com/<repo> |
Link target override |
stars |
auto |
Fetch GitHub stars automatically, hide with false, or pin a numeric value |
icon |
true |
Show/hide the GitHub icon |
Because it is a normal block element, you can place it with columns, rows, alignment utilities, or raw HTML wrappers instead of relying on footer-specific behavior.
Citations
Add a .bib file to your project and reference it in frontmatter:
---
bibliography: refs.bib
citation_style: author-year # or "numeric" or "title-year"
---
Use [@key] to cite in slides:
The foundational work on RLHF [@christiano2017] introduced reward models.
Multiple citations: [@christiano2017; @ouyang2022]
A References slide is automatically appended with only the cited works.
| Key | Default | Description |
|---|---|---|
bibliography |
"" |
Path to .bib file (relative to markdown file) |
citation_style |
"author-year" |
Citation format: author-year, numeric, title-year |
Keyboard Shortcuts
| Key | Action |
|---|---|
| Right / Down / Space / PgDn | Next slide |
| Left / Up / PgUp | Previous slide |
| Home | First slide |
| End | Last slide |
| F | Toggle fullscreen |
| Escape | Close picker / exit fullscreen |
Click the slide counter to open the slide picker. Click left 1/3 of screen to go back, right 2/3 to go forward.
PPTX Export (Experimental)
Export to PowerPoint/Google Slides format:
uv pip install colloquium[pptx] # install optional dependency
colloquium export --pptx slides.md # → slides.pptx
This produces a reasonable starting point, but some colloquium features lose fidelity: citations are flattened, math renders as raw LaTeX, and custom themes/CSS aren't applied. Charts and tables become native editable PPTX objects.
PDF Export
Two options:
- Browser: Open the HTML file and
Cmd+P/Ctrl+P— print CSS makes all slides visible with page breaks, footers with slide numbers included - CLI:
colloquium export slides.mduses a headless Chromium-based browser
Output
Everything builds to a single self-contained HTML file. CSS and JS are inlined; math (KaTeX) and code highlighting (highlight.js) load from CDN.
Contributing Elements
Custom block-level elements live in colloquium/elements/. Each module exposes:
PATTERN— compiled regex matching<pre><code class="language-X">...</code></pre>process(yaml_str) -> str— converts the YAML content to HTMLreset()(optional) — resets any counters between builds
The registry in colloquium/elements/__init__.py auto-wires them into the build pipeline. To add a new element:
- Create
colloquium/elements/my_element.pywithPATTERN,process, and optionallyreset - Import and register it in
colloquium/elements/__init__.py - Add any element-specific CSS to
colloquium/themes/default/theme.css
Project details
Release history Release notifications | RSS feed
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 colloquium-0.2.0.tar.gz.
File metadata
- Download URL: colloquium-0.2.0.tar.gz
- Upload date:
- Size: 255.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a9c3613aee446aceacf816206ee76868026bbf627c385f074300fd13d3576ca0
|
|
| MD5 |
28b99713ea2cb3eda15257e0b7b88173
|
|
| BLAKE2b-256 |
816661f966988878dc59d0626f13364fa6b767743cfbc9d7e1a573c0b295e8b8
|
File details
Details for the file colloquium-0.2.0-py3-none-any.whl.
File metadata
- Download URL: colloquium-0.2.0-py3-none-any.whl
- Upload date:
- Size: 51.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2d1be7f82350570ee7836a7805b47a2ed3dfea34bf887cb1660bd079f29531d9
|
|
| MD5 |
99a162c85cb484a4d14da89621f7bd11
|
|
| BLAKE2b-256 |
fe23178f6fb8453145d89cfc6b52d3adc54001bd3f9c96ba06d8ceea1e835911
|