Introduction

Lantern is a terminal presentation tool for markdown decks. It focuses on fast rendering, readable defaults, and plain-text decks that still look good in a terminal.

The current implementation supports interactive presenting, formatted printing, theme selection, syntax-highlighted code, tables, images, speaker notes, and admonitions. The published package contains a library and a binary:

  • The lantern_cli library parses markdown, metadata, themes, highlighting, printing, validation, and terminal UI rendering.
  • The lantern binary exposes the command-line interface.

Lantern is still early.

Some planned features in the roadmap, such as search UI and export commands, are not implemented yet.

Quickstart

Installation

From a local clone:

git clone https://github.com/stormlightlabs/lantern.git
cd lantern
cargo install --path .

You can also run it without installing:

cargo run -- present presentation.md

The installed binary is named lantern.

Create a deck

Create presentation.md:

---
theme: nord
author: Your Name
---

# Welcome to lantern

A terminal presentation tool built with Rust.

---

## Features

- Markdown slides split with `---`
- Base16 themes
- Syntax-highlighted code blocks
- Tables, lists, blockquotes, and horizontal rules
- Image rendering in terminals supported by `ratatui-image`
- GitHub and Obsidian-style admonitions

---

## Code

```rust
fn main() {
    println!("Hello, lantern!");
}
```

---

## Images

![A local image](./image.png)

---

## Done

Press `q` to quit.

Present

lantern present presentation.md

Use a theme from the command line:

lantern present presentation.md --theme catppuccin-mocha

Print

Print a deck to stdout:

lantern print presentation.md

Set the output width:

lantern print presentation.md --width 100

Check a deck

Validate a slide deck:

lantern check presentation.md

Run stricter checks:

lantern check presentation.md --strict

Validate a Base16 theme file:

lantern check --theme theme.yml
KeyAction
, j, Space, nNext slide
, k, pPrevious slide
?Toggle help line
Shift+NToggle notes panel if a slide contains notes
q, Ctrl+C, EscQuit

Slide separators

Put three dashes on a line by themselves between slides:

# Slide 1

Content here.

---

# Slide 2

More content.

Separators inside fenced code blocks are ignored.

Front matter

Lantern accepts YAML front matter:

---
theme: oxocarbon-dark
author: Jane Doe
date: 2026-06-24
paging: "Slide %d / %d"
---

It also accepts TOML front matter:

+++
theme = "nord"
author = "Jane Doe"
+++

Current metadata fields are theme, author, date, and paging.

Theme selection is implemented.

Supported markdown

  • Headings # through ######
  • Paragraphs
  • Bold, italic, strikethrough, and inline code
  • Fenced and indented code blocks
  • Ordered and unordered lists with nesting
  • Horizontal rules
  • Blockquotes
  • Tables
  • Images
  • GitHub and Obsidian-style admonitions
  • Speaker notes with ::: notes blocks

Environment variables

Set the default theme with SLIDES_THEME:

export SLIDES_THEME=nord

Render with a Base16 YAML theme file:

lantern present presentation.md --theme-file ./theme.yml

Named custom themes can also be placed in $XDG_CONFIG_HOME/lantern/themes, $LANTERN_CONFIG_HOME/themes, or ~/.config/lantern/themes.

If no author appears in front matter, lantern uses USER or USERNAME.

Current limitations

  • Search keys are reserved, but the search UI is not implemented yet.
  • author, date, and paging are parsed from front matter but not displayed in the presenter.

More reference

Extensions

Lantern currently has one markdown extension: admonitions. These are highlighted blocks for notes, warnings, tips, and similar callouts.

Supported types

TypeAliases
note
info
tiphint
important
warningcaution, attention
dangererror
successcheck, done
questionhelp, faq
example
quote
abstractsummary, tldr
todo
bug
failurefail, missing

GitHub and Obsidian syntax

> [!NOTE]
> Useful context for the slide.

> [!TIP]
> A practical suggestion.

> [!IMPORTANT]
> Something the audience should not miss.

> [!WARNING]
> A risk or caveat.

> [!CAUTION]
> A stronger warning.

You can add a title after the marker:

> [!WARNING] Production caveat
> This path assumes the database is already migrated.

Obsidian-style lowercase markers work too:

> [!quote]
> The quote text.

> [!example]
> Example content.

> [!bug]
> Known issue.

Fence syntax

Lantern also accepts a simple fence form:

:::note
This is a note.
:::

:::warning
This is a warning.
:::

:::tip
This is a tip.
:::

Fence admonitions currently accept the type only.

Custom titles are supported for the blockquote form, not for fence admonitions.

Rendering

Admonitions render with themed colors, Unicode icons, and rounded borders.

Their content is parsed into lantern's normal slide blocks, so paragraphs, lists, and code blocks can appear inside an admonition.

Logging

Lantern uses the tracing framework for internal logging and diagnostics. By default, logging is disabled, but can be enabled via environment variables for debugging and troubleshooting.

Configuration

File Path

To enable logging to a file, set the LANTERN_LOG_FILE environment variable:

export LANTERN_LOG_FILE=/path/to/lantern.log
lantern present slides.md

If LANTERN_LOG_FILE is not set, logs are discarded and won't appear anywhere.

Level

Control the verbosity of logs using the --log-level flag:

LANTERN_LOG_FILE=debug.log lantern --log-level debug present slides.md

Usage Examples

Basic Debugging

Enable info-level logging for general troubleshooting:

LANTERN_LOG_FILE=lantern.log lantern present slides.md

Detailed Diagnostics

Enable trace-level logging for in-depth debugging:

LANTERN_LOG_FILE=lantern-trace.log lantern --log-level trace present slides.md

Temporary Log File

Use a temporary file that gets cleaned up automatically:

LANTERN_LOG_FILE=/tmp/lantern-$$.log lantern present slides.md

Log Format

Logs are written in plain text format without ANSI color codes, making them easy to read and process with standard tools:

2025-11-18T10:30:45.123Z INFO lantern_cli: Presenting slides from: slides.md
2025-11-18T10:30:45.234Z INFO lantern_cli: Theme selection: CLI arg=None, frontmatter=oxocarbon-dark, final=oxocarbon-dark
2025-11-18T10:30:45.345Z DEBUG lantern_cli::parser: Parsed 15 slides from markdown

Themes

Lantern uses embedded Base16 themes.

Each theme defines 16 colors, then lantern maps those colors to slide content, syntax highlighting, admonitions, and UI chrome.

Available themes

Built-in theme names:

  • catppuccin-latte
  • catppuccin-frappe
  • catppuccin-macchiato
  • catppuccin-mocha
  • gruvbox-material-dark
  • gruvbox-material-light
  • nord
  • nord-light
  • oxocarbon-dark
  • oxocarbon-light
  • rose-pine
  • rose-pine-dawn
  • rose-pine-moon
  • solarized-dark
  • solarized-light

default is also accepted. It resolves to oxocarbon-dark or oxocarbon-light based on terminal background detection.

Named themes are loaded from the user config directory first, then from the built-in list. Unknown theme names fail with an error when presenting or printing.

Using a theme

Front matter

---
theme: catppuccin-mocha
---

# First slide

TOML front matter works too:

+++
theme = "nord"
+++

# First slide

Command line

lantern present presentation.md --theme nord
lantern print presentation.md --theme catppuccin-latte
lantern present presentation.md --theme-file ./my-theme.yml

User config directory

Put Base16 YAML themes in one of these directories and reference them by file stem with --theme or front matter:

  • $LANTERN_CONFIG_HOME/themes
  • $XDG_CONFIG_HOME/lantern/themes
  • ~/.config/lantern/themes

For example, ~/.config/lantern/themes/acme.yml can be used as --theme acme or theme: acme.

Environment variable

export SLIDES_THEME=gruvbox-material-dark
lantern present presentation.md

Theme priority

Lantern resolves the theme in this order:

  1. --theme-file on the command line
  2. --theme on the command line
  3. theme in front matter
  4. SLIDES_THEME
  5. Detected default, oxocarbon-dark or oxocarbon-light

Base16 mapping

Content colors:

  • Headings: base0D
  • Body text: base05
  • Bold text: base0E
  • Italic text: base09
  • Code blocks: base0B
  • Inline code background: base02
  • Links: base0C
  • List markers: base0A
  • Rules, borders, and dimmed text: base03

UI colors:

  • UI background: base00
  • Borders and status bar background: base02
  • UI titles: base06
  • UI text: base05

Admonition colors:

  • Note: base0D
  • Tip: base0E
  • Warning: base0A
  • Danger: base08
  • Success: base0B
  • Info: base0C

Validate a theme file

Lantern can validate a Base16 YAML file:

lantern check --theme theme.yml

Custom theme files can be validated, but rendering still uses built-in themes. The same file shape can be rendered with --theme-file or from the user config theme directory.

A valid theme uses this shape:

system: "base16"
name: "My Theme"
author: "Your Name"
variant: "dark"
palette:
  base00: "#1a1b26"
  base01: "#16161e"
  base02: "#2f3549"
  base03: "#444b6a"
  base04: "#787c99"
  base05: "#a9b1d6"
  base06: "#cbccd1"
  base07: "#d5d6db"
  base08: "#c0caf5"
  base09: "#a9b1d6"
  base0A: "#0db9d7"
  base0B: "#9ece6a"
  base0C: "#b4f9f8"
  base0D: "#2ac3de"
  base0E: "#bb9af7"
  base0F: "#f7768e"

Rendering notes

The printer and TUI use Unicode symbols for readable terminal output:

  • ▉ ▓ ▒ ░ ▌ for heading levels
  • and for horizontal rules
  • for blockquotes and table dividers
  • for unordered lists

Code blocks use Syntect for syntax highlighting. Lantern chooses a light or dark Syntect theme based on the active lantern theme variant.

Unicode Symbols

Icons/Signage

SymbolName / UsageCodeNotes.
Check markU+2713For "done", success, yes
Cross / XU+2717For "error", no, wrong
Right arrowU+2192Navigation / "next"
Left arrowU+2190Back / "previous"
Up arrowU+2191Scroll up / move up
Down arrowU+2193Scroll down / move down
BulletU+2022List item, emphasis
EllipsisU+2026Continuation, truncation :
En dashU+2013Ranges, short break
Em dashU+2014Strong break, parenthetical clause
Figure dashU+2012Fixed width dash
§Section signU+00A7For "section", referencing parts
Pilcrow / paragraphU+00B6Denote paragraph or break
↑↓Up-down arrowsU+2195Bidirectional movement / toggle
Empty checkboxU+2610Unchecked box
Checked checkboxU+2611Checked box
Crossed checkboxU+2612Marked "X" in box
Warning signU+26A0Warning / caution
Alembic symbolU+2697Science / chemistry motif
Eight-spoked asteriskU+2733Decorative, emphasis
Eight-pointed starU+2734Decorative bullet / highlight
Black starU+2605Favorite / highlight
White starU+2606Unselected star
Black right-pointing triangleU+25BAPlay / next marker
Small black right-pointing triangleU+25B8Sub-indicator
Small black squareU+25AABullet / small filler
Black horizontal barU+25ACDivider line
Upper half blockU+2580Block drawing / shading
Lower half blockU+2584Block drawing / shading
White square with black small squareU+25F1Decorative / status
±Plus-minusU+00B1Variation, tolerance
×Multiplication signU+00D7Multiplication or "times"
÷Division signU+00F7Division / ratio
¬Logical NOT / negationU+00ACLogical operator

Lines & Blocks

SymbolName / UsageCodeNotes
Box Drawings Light HorizontalU+2500Single horizontal line
Box Drawings Light VerticalU+2502Single vertical line
Box Drawings Light Down + RightU+250CTop-left corner
Box Drawings Light Down + LeftU+2510Top-right corner
Box Drawings Light Up + RightU+2514Bottom-left corner
Box Drawings Light Up + LeftU+2518Bottom-right corner
Box Drawings Light Vertical + RightU+251CT junction to the right
Box Drawings Light Vertical + LeftU+2524T junction to the left
Box Drawings Light Down + HorizontalU+252CT junction downward
Box Drawings Light Up + HorizontalU+2534T junction upward
Box Drawings Light Vertical + HorizontalU+253CCross intersection
Box Drawings Double HorizontalU+2550Thicker horizontal line
Box Drawings Double VerticalU+2551Thicker vertical line
Box Drawings Double Down + RightU+2554Double border top-left corner
Box Drawings Double Down + LeftU+2557Double border top-right corner
Box Drawings Double Up + RightU+255ADouble border bottom-left corner
Box Drawings Double Up + LeftU+255DDouble border bottom-right corner
Upper half blockU+2580Fill / shading top half of a cell
Lower half blockU+2584Fill / shading bottom half
Left half blockU+258CFill left half of a cell
Right half blockU+2590Fill right half of a cell
Light shadeU+2591Light shading / patterns
Medium shadeU+2592Medium shading
Dark shadeU+2593Dark shading
Large block / heavy fillU+2589More filled block
BlockU+258ASlightly less than full fill
BlockU+258BSlightly less than above
Full blockU+2588Fully filled block
Black vertical rectangleU+25AENarrow block / bar
Black horizontal barU+25ACHorizontal bar, divider
Box Drawings Light Arc Down + RightU+256DRounded corner style
Box Drawings Light Arc Down + LeftU+256ERounded corner
Box Drawings Light Arc Up + LeftU+256FRounded corner
Box Drawings Light Arc Up + RightU+2570Rounded corner