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_clilibrary parses markdown, metadata, themes, highlighting, printing, validation, and terminal UI rendering. - The
lanternbinary 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

---
## 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 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
Navigation
| Key | Action |
|---|---|
→, j, Space, n | Next slide |
←, k, p | Previous slide |
? | Toggle help line |
Shift+N | Toggle notes panel if a slide contains notes |
q, Ctrl+C, Esc | Quit |
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
::: notesblocks
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, andpagingare 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
| Type | Aliases |
|---|---|
note | |
info | |
tip | hint |
important | |
warning | caution, attention |
danger | error |
success | check, done |
question | help, faq |
example | |
quote | |
abstract | summary, tldr |
todo | |
bug | |
failure | fail, 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-lattecatppuccin-frappecatppuccin-macchiatocatppuccin-mochagruvbox-material-darkgruvbox-material-lightnordnord-lightoxocarbon-darkoxocarbon-lightrose-pinerose-pine-dawnrose-pine-moonsolarized-darksolarized-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:
--theme-fileon the command line--themeon the command linethemein front matterSLIDES_THEME- Detected default,
oxocarbon-darkoroxocarbon-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
| Symbol | Name / Usage | Code | Notes. |
|---|---|---|---|
| ✓ | Check mark | U+2713 | For "done", success, yes |
| ✗ | Cross / X | U+2717 | For "error", no, wrong |
| → | Right arrow | U+2192 | Navigation / "next" |
| ← | Left arrow | U+2190 | Back / "previous" |
| ↑ | Up arrow | U+2191 | Scroll up / move up |
| ↓ | Down arrow | U+2193 | Scroll down / move down |
| • | Bullet | U+2022 | List item, emphasis |
| … | Ellipsis | U+2026 | Continuation, truncation : |
| – | En dash | U+2013 | Ranges, short break |
| — | Em dash | U+2014 | Strong break, parenthetical clause |
| ‒ | Figure dash | U+2012 | Fixed width dash |
| § | Section sign | U+00A7 | For "section", referencing parts |
| ¶ | Pilcrow / paragraph | U+00B6 | Denote paragraph or break |
| ↑↓ | Up-down arrows | U+2195 | Bidirectional movement / toggle |
| ☐ | Empty checkbox | U+2610 | Unchecked box |
| ☑ | Checked checkbox | U+2611 | Checked box |
| ☒ | Crossed checkbox | U+2612 | Marked "X" in box |
| ⚠ | Warning sign | U+26A0 | Warning / caution |
| ⚗ | Alembic symbol | U+2697 | Science / chemistry motif |
| ✳ | Eight-spoked asterisk | U+2733 | Decorative, emphasis |
| ✴ | Eight-pointed star | U+2734 | Decorative bullet / highlight |
| ★ | Black star | U+2605 | Favorite / highlight |
| ☆ | White star | U+2606 | Unselected star |
| ► | Black right-pointing triangle | U+25BA | Play / next marker |
| ▸ | Small black right-pointing triangle | U+25B8 | Sub-indicator |
| ▪ | Small black square | U+25AA | Bullet / small filler |
| ▬ | Black horizontal bar | U+25AC | Divider line |
| ▀ | Upper half block | U+2580 | Block drawing / shading |
| ▄ | Lower half block | U+2584 | Block drawing / shading |
| ▱ | White square with black small square | U+25F1 | Decorative / status |
| ± | Plus-minus | U+00B1 | Variation, tolerance |
| × | Multiplication sign | U+00D7 | Multiplication or "times" |
| ÷ | Division sign | U+00F7 | Division / ratio |
| ¬ | Logical NOT / negation | U+00AC | Logical operator |
Lines & Blocks
| Symbol | Name / Usage | Code | Notes |
|---|---|---|---|
| ─ | Box Drawings Light Horizontal | U+2500 | Single horizontal line |
| │ | Box Drawings Light Vertical | U+2502 | Single vertical line |
| ┌ | Box Drawings Light Down + Right | U+250C | Top-left corner |
| ┐ | Box Drawings Light Down + Left | U+2510 | Top-right corner |
| └ | Box Drawings Light Up + Right | U+2514 | Bottom-left corner |
| ┘ | Box Drawings Light Up + Left | U+2518 | Bottom-right corner |
| ├ | Box Drawings Light Vertical + Right | U+251C | T junction to the right |
| ┤ | Box Drawings Light Vertical + Left | U+2524 | T junction to the left |
| ┬ | Box Drawings Light Down + Horizontal | U+252C | T junction downward |
| ┴ | Box Drawings Light Up + Horizontal | U+2534 | T junction upward |
| ┼ | Box Drawings Light Vertical + Horizontal | U+253C | Cross intersection |
| ═ | Box Drawings Double Horizontal | U+2550 | Thicker horizontal line |
| ║ | Box Drawings Double Vertical | U+2551 | Thicker vertical line |
| ╔ | Box Drawings Double Down + Right | U+2554 | Double border top-left corner |
| ╗ | Box Drawings Double Down + Left | U+2557 | Double border top-right corner |
| ╚ | Box Drawings Double Up + Right | U+255A | Double border bottom-left corner |
| ╝ | Box Drawings Double Up + Left | U+255D | Double border bottom-right corner |
| ▀ | Upper half block | U+2580 | Fill / shading top half of a cell |
| ▄ | Lower half block | U+2584 | Fill / shading bottom half |
| ▌ | Left half block | U+258C | Fill left half of a cell |
| ▐ | Right half block | U+2590 | Fill right half of a cell |
| ░ | Light shade | U+2591 | Light shading / patterns |
| ▒ | Medium shade | U+2592 | Medium shading |
| ▓ | Dark shade | U+2593 | Dark shading |
| ▉ | Large block / heavy fill | U+2589 | More filled block |
| ▊ | Block | U+258A | Slightly less than full fill |
| ▋ | Block | U+258B | Slightly less than above |
| █ | Full block | U+2588 | Fully filled block |
| ▮ | Black vertical rectangle | U+25AE | Narrow block / bar |
| ▬ | Black horizontal bar | U+25AC | Horizontal bar, divider |
| ╭ | Box Drawings Light Arc Down + Right | U+256D | Rounded corner style |
| ╮ | Box Drawings Light Arc Down + Left | U+256E | Rounded corner |
| ╯ | Box Drawings Light Arc Up + Left | U+256F | Rounded corner |
| ╰ | Box Drawings Light Arc Up + Right | U+2570 | Rounded corner |