slides-chat

A fake AI chat for your Quarto presentations

Lino Galiana

Meet CodeBot

Hi, I’m CodeBot. I can help you write code.

I have a novel in novel.txt. I’d like to know which words come up most often.

Good idea! Split the text into words, then count them.

Can you show me?

Here is a Python script that only uses the standard library:

from collections import Counter
import re

# Read the text, all lowercase
with open("novel.txt", encoding="utf-8") as f:
    text = f.read().lower()

words = re.findall(r"\w+", text)
counts = Counter(w for w in words if len(w) > 3)

for word, n in counts.most_common(5):
    print(f"{word:<12} {n}")

Want me to draw a chart?

Installation

In your Quarto project, run:

quarto add linogaliana/slides-chat

This adds the extension to _extensions/slides-chat/. Commit that folder along with your project.

Then turn the plugin on in the presentation’s YAML header:

format: revealjs
revealjs-plugins:
  - slides-chat
slides-chat:              # optional, deck-wide settings
  user: Lino
  assistant: CodeBot

Writing a chat

:::: {.slides-chat}

::: {.user}
What is 6 × 7?
:::

::: {.assistant .fragment .typing}
**42**, of course.
:::

::::
  • .user / .assistant pick the speaker
  • .fragment shows a message on the next step
  • .typing shows dots first, then the text

What is 6 × 7?

42, of course.

Options

Set them deck-wide under slides-chat: in the YAML header, or on a single chat as attributes: :::: {.slides-chat assistant="Bot" color="#9ece6a"}

Option Default Effect
user (none) Name shown above the person’s messages
assistant Assistant Name of the AI
logo orange asterisk Blinking avatar of the AI (path or URL)
color #d97757 AI colour: name, banner, typing dots
welcome ✱ <assistant> Welcome banner text, false to hide it
background #1a1b26 Background of slides holding a chat, false to keep the theme’s

A single message can also take its own name: ::: {.user name="Alice"}.

Names

Our CI has been failing since this morning.

Same here, the tests time out.

The test job now downloads a 2 GB dataset on every run. Cache it between runs:

- uses: actions/cache@v4
  with:
    path: data/
    key: dataset-v1

Thanks, that did it!

Welcome banner

welcome="..."

A custom banner text.

welcome="false"

No banner at all.

Slide background

Why is this slide purple?

The slide sets its own background-color="#2b1d3a". The extension only adds a dark background when the slide has none.

To change the default for every chat slide, set background: in the YAML header.

No slide background

And here?

With background="false", the slide keeps the theme’s background. The chat stays a dark card on the page.

Theming with CSS variables

Can you do a light theme?

Every colour is a CSS variable. Redefine them on .slides-chat in your own stylesheet:

.slides-chat {
  --slides-chat-bg: #fdf6e3;
  --slides-chat-bright: #073642;
  --slides-chat-prompt: #cb4b16;
}

Pacing

No .fragment: I’m visible right away.

.fragment alone: I appear in one piece.

.fragment .typing on a person: dots, then the whole text.

.fragment alone on the AI: I appear in one piece too.

.fragment .typing on the AI: dots, then my answer streams in word by word. Step back and it rewinds.

Rich content

What can go inside a message?

Any Markdown:

  • bold, italics, inline code and links;
  • lists and tables:
Language Typed First release
Python no 1991
R no 1993
Rust yes 2015

Code blocks and tables fade in whole, while the prose streams in.

Credit and inspiration

The initial inspiration for slides-chat is chat-bubbles by Emil Hvitfeldt, which fakes iMessage, Slack, Discord and Teams conversations in revealjs slides.

slides-chat builds on its foundations (message layout, typing dots, auto-scroll) and specialises them for conversations with an AI.

Warning

This example slidedeck and extension have mostly been AI generated