lantern#
Plumbing#
Outcome: initialize workspace with clap CLI and ratatui terminal setup
Scaffolded multi-crate workspace with present, print, init, and check subcommands, integrated structured logging via tracing, and configured alternate screen with crossterm input handling.
Data Model#
Outcome: implement markdown parser with metadata and validation Built pulldown-cmark-based parser that splits on --- separators into Vec, supports YAML/TOML front matter, and provides friendly error messages with file/line context.
Rendering & Navigation#
Objective: Build the interactive slide renderer with navigation.
| Task | Description | Key Crates |
|---|---|---|
| ✓ Ratatui Integration | Build basic slide viewer using layout, blocks, paragraphs. | ratatui1 |
| ✓ Input & State | Support ←/→, j/k, q, numeric jumps, and window resize. |
crossterm, ratatui |
| ✓ Status Bar | Display slide count, filename, clock, and theme name. | ratatui |
| ✓ Color Styling | Apply consistent color palette via owo-colors. Define traits like ThemeColor. |
owo-colors |
| ✓ Unicode Headings | Use Unicode block symbols (▉▓▒░▌) for h1-h6 instead of markdown # syntax. |
Unicode constants |
| Configurable Themes | Base16 YAML theme system with 10 prebuilt themes. | serde_yml, serde |
Add user theme loading from config directory and CLI --theme-file flag. |
dirs |
Code Highlighting via Syntect#
Objective: Add first-class syntax highlighting using Syntect.
| Task | Description | Key Crates |
|---|---|---|
| ✓ Syntect | Load .tmTheme / .sublime-syntax definitions on startup. |
syntect2 |
Cache SyntaxSet + ThemeSet. |
||
| ✓ Code Blocks | Detect fenced code blocks with language tags. | syntect, owo-colors |
Render syntax-highlighted text with color spans mapped to owo-colors. |
||
| ✓ Theming | Map terminal theme choice to Syntect theme (e.g., "OneDark", "Monokai"). |
syntect |
| ✓ Performance | Lazy-load themes and syntaxes; use OnceLock for caching. |
std::sync::OnceLock |
| ✓ Mode | Render to ANSI-colored plain text output (for lantern print). |
owo-colors |
Presenter#
Objective: Introduce features for live presentations and authoring convenience.
| Task | Description | Key Crates |
|---|---|---|
| Speaker Notes | N toggles speaker notes (parsed via ::: notes). |
ratatui |
Note: n & p move forward & backwards |
||
| Timer & Progress | Session timer + per-slide progress bar. | ratatui, chrono |
| Live Reload | File watcher auto-refreshes content. | notify3 |
| Search | Fuzzy find slide titles via ctrl+f. |
fuzzy-matcher4 |
| Theme Commands | CLI flag --theme <name> switches both Syntect + owo themes. |
clap, internal ThemeRegistry |
Markdown Extension#
Objective: Add richness and visual polish to text and layout.
| Task | Description | Key Crates |
|---|---|---|
| ✓ Tables & Lists | Render GitHub-style tables, bullets, and task lists | pulldown-cmark, ratatui |
| ✓ Horizontal Rules | Use box-drawing (─, ═) and/or black horizontal bar (▬) |
Unicode constants |
| Admonitions | Highlighted boxes with icons (use ::: directives) |
owo-colors, internal glyphs |
| Support obsidian & GH admonitions | ||
| Generators | lantern init scaffolds an example deck with code and notes |
include_str!, fs |
RC#
| Task | Description | Key Crates |
|---|---|---|
| CI/CD + Tooling | Setup cargo fmt, clippy, test, and cross matrix CI |
GitHub Actions |
| Config Discovery | Read from $XDG_CONFIG_HOME/lantern/config.toml for defaults |
dirs, serde |
| Theme Registry | Built-in theme manifest (e.g., onedark, solarized, plain). |
Internal |
| Release | Tag v1.0.0-rc.1 with changelog and binaries for major platforms. |
cargo-dist, GitHub Actions |
Rendering Core Extension#
Objective: Make live, image, and video modes all run on the same slide/timeline + frame renderer pipeline.
| Task | Description | Key Crates |
|---|---|---|
| Event Timeline Core | Compile slides into an Event timeline (show slide, type, run command, wait, transition, capture). |
internal timeline module |
| Virtual Terminal Core | Implement PTY + ANSI parser → TerminalBuffer { cells, colors, attrs } shared by live/video/image. |
portable-pty (or similar), internal ANSI |
| Frame Layout Engine | Map title/body/terminal regions into a logical canvas (cells or pixels) for all renderers. | internal layout module |
| Renderer Trait | Define Renderer trait (begin, handle_event, end) with impls for Live, Image, and Video. |
internal renderer module |
Export: Images#
Objective: Generate high-quality PNG/SVG snapshots of any slide (Freeze-style) directly from the slide + layout + terminal state.
| Task | Description | Key Crates |
|---|---|---|
| Canvas → Pixmap | Implement a FrameRasterizer that turns a Frame + layout into an RGBA pixmap (background, panes, etc). |
tiny-skia |
| Text Rendering | Render slide titles/body text via glyph rasterization and simple layout (left/center, line wrapping). | ab_glyph |
| Terminal Snapshot Mode | Convert TerminalBuffer into a rendered terminal "window" (frame, tabs, padding, cursor). |
tiny-skia, ab_glyph |
| Slide Screenshot CLI | lantern export-image deck.md --slide 5 --output slide-5.png (PNG by default, optional SVG/WebP). |
clap, image |
| Batch Export | --all / --range 3..7 to dump multiple slides, naming convention like deck-003.png. |
image |
| Deterministic Layout Test | Golden tests comparing generated PNGs against fixtures for regression in layout and text. | image, integration test harness |
Export: Video#
Objective: Produce MP4/WebM/GIF recordings of a scripted terminal+slides run (VHS-style) directly from the markdown deck.
| Task | Description | Key Crates | |
|---|---|---|---|
| Timeline Scheduling | Extend Event to carry timestamps or durations; implement Scheduler to emit frames at target FPS. |
internal timeline module |
|
| Frame Capture Loop | Drive the same layout/rasterizer used for images at N FPS, yielding a sequence of RGBA frames. | tiny-skia, image |
|
| FFmpeg Binding Layer | Wrap ffmpeg-next to open an encoder, configure codec/container, and accept raw frames. |
ffmpeg-next |
|
| Video Export CLI | lantern export-video deck.md --output demo.mp4 --fps 30 --duration 120s (or auto-duration from events). |
clap, internal encoder |
|
| GIF / WebM Variants | Add `--format gif | webm mapping to appropriate ffmpeg muxer/codec presets. | ffmpeg-next1 |
| Typing & Cursor Effects | Represent typing, deletes, cursor blinks as timeline events, so video export matches live presentation feel. | internal timeline, terminal core |
|
| Audio-less Simplification | Keep V1 video export silent (no audio tracks) for simpler ffmpeg integration and smaller binaries. | ffmpeg-next |
|
| Performance Tuning | Measure memory/CPU for long decks; stream frames to ffmpeg (no full buffering) and expose --quality presets. |
ffmpeg-next, image |
Export: Social Media#
Objective: Generate vertical (portrait) slides optimized for short-form vertical video.
| Task | Description | Key Crates |
|---|---|---|
| Portrait Layout Engine | Implement 9:16 aspect ratio layout with vertical constraints (1080x1920, 720x1280). | internal layout module |
| Mobile-Optimized Text | Larger font sizes, reduced content density, and simplified layouts for mobile readability. | ab_glyph, tiny-skia |
| Vertical Export CLI | lantern export-vertical deck.md --output reel.mp4 with preset dimensions for each platform. |
clap, internal encoder |
| Platform Presets | Built-in presets: instagram-reel, tiktok, youtube-shorts with optimal resolution/duration. |
internal preset registry |
| Content Adaptation | Auto-scale or warn when horizontal content doesn't fit portrait orientation. | internal layout module |
| Safe Zones | Respect platform UI overlays (captions, profile pics) with configurable safe zones. | internal layout module |
| Swipe Animations | Optional slide transition effects optimized for vertical scrolling behavior. | internal timeline, ffmpeg |
Authoring & UX for Export#
Objective: Make "slides → image/video" a natural extension of your current CLI and authoring workflow.
| Task | Description | Key Crates |
|---|---|---|
| Export Subcommands | Add lantern export-image and lantern export-video commands with shared flags (theme, range). |
clap |
| Frontmatter Controls | Support per-deck/per-slide frontmatter: fps, default_duration, transition, record: true. |
pulldown-cmark-frontmatter |
| Deterministic Seeds | Add --seed for any animations (typing jitter, cursor blink timing) to keep exports repeatable. |
internal timeline |
| Preset Profiles | Presets like social-card, doc-screenshot, talk-demo mapping to resolution + theme. |
internal profile registry |