| name | quarto-revealjs-format |
| description | Create custom Quarto RevealJS presentation formats and themes. Use when the user wants to "create a custom revealjs theme", "build a branded quarto presentation", "make a quarto slide template", "convert a PowerPoint template to Quarto", "apply brand guidelines to revealjs", "create a quarto extension for presentations", "customize revealjs slides", "set up a presentation format", or wants to use pptx/pdf templates, logos, or brand guidelines to style Quarto RevealJS slides.
|
| version | 0.1.0 |
Quarto RevealJS Custom Format
Based on Quarto CLI v1.8+ RevealJS architecture.
Overview
A custom Quarto RevealJS format is a Quarto extension repository with this
structure (using lexconf as the extension name — replace with the actual name):
README.md
LICENSE
template.qmd
_extensions/
lexconf/
_extension.yml
theme.scss
logo.png
title.png
README.md / LICENSE — repo documentation and license
template.qmd — starter presentation showing the format in use
_extensions/<name>/ — the extension itself:
_extension.yml — declares the format and default YAML options
theme.scss — SCSS that overrides RevealJS variables
logo.png — logo shown on every slide (bottom corner)
title.png — background image for the title slide
See references/extension-structure.md for
full _extension.yml options and variations.
Workflow
Step 1 — Gather brand inputs
Ask the user for any combination of:
| Input | How to use |
|---|
| PDF or image of slides / brand guide | Read visually with the Read tool to extract colors, fonts, layout |
| PPTX template | Ask user to share key slides as images, OR run python-pptx extraction (see references/brand-analysis.md) |
| Explicit brand values | Colors (hex), font names, logo file paths provided directly |
| Logo files | Copy into assets/, reference in SCSS or YAML |
Always confirm extracted values with the user before writing files.
Step 2 — Map brand to RevealJS variables
Map extracted brand values to the SCSS variables in
references/revealjs-sass-variables.md.
Minimum required mapping:
$r-background-color: #FFFFFF;
$r-main-color: #333333;
$r-heading-color: #1A1A2E;
$r-link-color: #0066CC;
$r-main-font: "Inter", sans-serif;
$r-heading-font: "Inter", sans-serif;
$r-main-font-size: 40px;
$r-heading1-size: 2.5em;
$r-heading2-size: 1.6em;
$r-heading3-size: 1.3em;
Step 3 — Create the extension files
Ask the user for the extension name (e.g. lexconf). All extension files live
under _extensions/<name>/.
_extensions/<name>/_extension.yml — minimal:
title: My Theme
author: Your Name
version: 0.1.0
quarto-required: ">=1.4.0"
contributes:
format:
revealjs:
theme: [default, theme.scss]
slide-number: true
width: 1600
height: 900
The format is referenced in .qmd files as format: <name>-revealjs, e.g.:
format: lexconf-revealjs
theme.scss — basic structure:
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap');
$r-background-color: #FFFFFF !default;
$r-main-color: #333333 !default;
$r-heading-color: #1A1A2E !default;
$r-link-color: #0066CC !default;
$r-main-font: "Inter", sans-serif !default;
$r-heading-font: "Inter", sans-serif !default;
$r-main-font-size: 40px !default;
$r-heading1-size: 2.5em !default;
$r-heading2-size: 1.6em !default;
$r-heading3-size: 1.3em !default;
$r-heading4-size: 1.0em !default;
.reveal .title-slide h1 {
font-size: $r-heading1-size;
}
Step 4 — Handle logos and title background
Place image files directly inside _extensions/<name>/ (not in a subfolder).
Logo on every slide — reference as logo.png in _extension.yml:
contributes:
format:
revealjs:
theme: [default, theme.scss]
logo: logo.png
slide-number: true
Control size/position in theme.scss:
.reveal .slide-logo {
max-height: 50px;
bottom: 12px;
right: 12px;
}
Title slide background — use title.png via a title-slide-specific CSS
rule or a title-slide-attributes YAML option:
.reveal .title-slide {
background-image: url('title.png');
background-size: cover;
background-position: center;
}
Or in _extension.yml using title-slide-attributes:
contributes:
format:
revealjs:
theme: [default, theme.scss]
logo: logo.png
title-slide-attributes:
data-background-image: title.png
data-background-size: cover
Step 5 — Create template.qmd
Always create template.qmd at the repo root demonstrating the format:
---
title: "Presentation Title"
subtitle: "Subtitle"
author: "Author"
date: today
format: lexconf-revealjs
---
## Slide Title
- Bullet point one
- Bullet point two
- Bullet point three
## Code Example
```{r}
1 + 1
```
## {background-image="_extensions/lexconf/title.png" background-size="cover"}
SCSS Architecture for RevealJS
RevealJS uses a two-pass SCSS compilation (unlike HTML/Bootstrap which uses one pass):
- Pass 1 — Theme SCSS compiles during format resolution
- Pass 2 — Sass bundles compile during Pandoc rendering (no access to theme vars)
Consequence: Use CSS custom properties (var(--r-background-color)) in
rules/components, not SCSS variables — the variables won't be in scope for
bundle code. The full variable-to-custom-property mapping is in
references/revealjs-sass-variables.md.
Layer structure (must appear in this order in theme.scss):
/*-- scss:defaults --*/ ← variable overrides (!default)
/*-- scss:functions --*/ ← SCSS functions (optional)
/*-- scss:mixins --*/ ← SCSS mixins (optional)
/*-- scss:rules --*/ ← CSS rules and selectors
Using brand.yml
If the user has or wants a _brand.yml file, use the quarto:brand-yml skill.
RevealJS reads brand.yml automatically when present — brand colors and fonts
map to RevealJS SCSS variables through Quarto's theming pipeline.
Common Issues
Fonts not loading
→ Use @import in /*-- scss:defaults --*/ section, or add font files to
assets/ and reference with @font-face.
Logo appears on title slide but not other slides (or vice versa)
→ Use logo: in YAML for all slides; use .reveal .title-slide CSS for
title-only placement.
Colors look right in SCSS but wrong in output
→ Remember the two-pass architecture: rules using theme colors in components
must reference CSS custom properties (var(--r-heading-color)), not SCSS vars.
Custom slide sizes
→ Set width and height in _extension.yml (default: 1050×700). 16:9 = 1600×900.
Slide transitions
→ Add transition: slide or transition: fade to _extension.yml under
contributes.format.revealjs.