magical markdown slides
1# lantern
2
3## Plumbing
4
5__Outcome:__ initialize workspace with clap CLI and ratatui terminal setup
6
7Scaffolded multi-crate workspace with present, print, init, and check subcommands, integrated structured logging via tracing, and configured alternate screen with crossterm input handling.
8
9## Data Model
10
11__Outcome:__ implement markdown parser with metadata and validation
12Built pulldown-cmark-based parser that splits on --- separators into Vec<Slide>, supports YAML/TOML front matter, and provides friendly error messages with file/line context.
13
14## Rendering & Navigation
15
16__Objective:__ Build the interactive slide renderer with navigation.
17
18| Task | Description | Key Crates |
19| ------------------------- | ------------------------------------------------------------------------------------------------- | ---------------------- |
20| __✓ Ratatui Integration__ | Build basic slide viewer using layout, blocks, paragraphs. | `ratatui`[^7] |
21| __✓ Input & State__ | Support `←/→`, `j/k`, `q`, numeric jumps, and window resize. | `crossterm`, `ratatui` |
22| __✓ Status Bar__ | Display slide count, filename, clock, and theme name. | `ratatui` |
23| __✓ Color Styling__ | Apply consistent color palette via `owo-colors`. Define traits like `ThemeColor`. | `owo-colors` |
24| __✓ Unicode Headings__ | Use Unicode block symbols (▉▓▒░▌) for h1-h6 instead of markdown `#` syntax. | Unicode constants |
25| __Configurable Themes__ | Base16 YAML theme system with 10 prebuilt themes. | `serde_yml`, `serde` |
26| | Add user theme loading from config directory and CLI `--theme-file` flag. | `dirs` |
27
28## Code Highlighting via Syntect
29
30__Objective:__ Add first-class syntax highlighting using Syntect.
31
32| Task | Description | Key Crates |
33| ------------------- | ---------------------------------------------------------------------------- | ----------------------- |
34| __✓ Syntect__ | Load `.tmTheme` / `.sublime-syntax` definitions on startup. | `syntect`[^8] |
35| | Cache `SyntaxSet` + `ThemeSet`. | |
36| __✓ Code Blocks__ | Detect fenced code blocks with language tags. | `syntect`, `owo-colors` |
37| | Render syntax-highlighted text with color spans mapped to `owo-colors`. | |
38| __✓ Theming__ | Map terminal theme choice to Syntect theme (e.g., `"OneDark"`, `"Monokai"`). | `syntect` |
39| __✓ Performance__ | Lazy-load themes and syntaxes; use `OnceLock` for caching. | `std::sync::OnceLock` |
40| __✓ Mode__ | Render to ANSI-colored plain text output (for `lantern print`). | `owo-colors` |
41
42---
43
44## Presenter
45
46__Objective:__ Introduce features for live presentations and authoring convenience.
47
48| Task | Description | Key Crates |
49| -------------------- | ------------------------------------------------------------- | -------------------------------- |
50| __Speaker Notes__ | `N` toggles speaker notes (parsed via `::: notes`). | `ratatui` |
51| | Note: `n` & `p` move forward & backwards | |
52| __Timer & Progress__ | Session timer + per-slide progress bar. | `ratatui`, `chrono` |
53| __Live Reload__ | File watcher auto-refreshes content. | `notify`[^9] |
54| __Search__ | Fuzzy find slide titles via `ctrl+f`. | `fuzzy-matcher`[^10] |
55| __Theme Commands__ | CLI flag `--theme <name>` switches both Syntect + owo themes. | `clap`, internal `ThemeRegistry` |
56
57## Markdown Extension
58
59__Objective:__ Add richness and visual polish to text and layout.
60
61| Task | Description | Key Crates |
62| ---------------------- | ------------------------------------------------------------- | ----------------------------- |
63| __✓ Tables & Lists__ | Render GitHub-style tables, bullets, and task lists | `pulldown-cmark`, `ratatui` |
64| __✓ Horizontal Rules__ | Use box-drawing (`─`, `═`) and/or black horizontal bar (`▬`) | Unicode constants |
65| __Admonitions__ | Highlighted boxes with icons (use `:::` directives) | `owo-colors`, internal glyphs |
66| | Support obsidian & GH admonitions | |
67| __Generators__ | `lantern init` scaffolds an example deck with code and notes | `include_str!`, `fs` |
68
69## RC
70
71| Task | Description | Key Crates |
72| -------------------- | ------------------------------------------------------------------ | ---------------------------- |
73| __CI/CD + Tooling__ | Setup `cargo fmt`, `clippy`, `test`, and `cross` matrix CI | GitHub Actions |
74| __Config Discovery__ | Read from `$XDG_CONFIG_HOME/lantern/config.toml` for defaults | `dirs`, `serde` |
75| __Theme Registry__ | Built-in theme manifest (e.g., `onedark`, `solarized`, `plain`). | Internal |
76| __Release__ | Tag `v1.0.0-rc.1` with changelog and binaries for major platforms. | `cargo-dist`, GitHub Actions |
77
78## Rendering Core Extension
79
80__Objective:__ Make live, image, and video modes all run on the same slide/timeline + frame renderer pipeline.
81
82| Task | Description | Key Crates |
83| ------------------------- | --------------------------------------------------------------------------------------------------- | ------------------------------------------ |
84| __Event Timeline Core__ | Compile slides into an `Event` timeline (show slide, type, run command, wait, transition, capture). | internal `timeline` module |
85| __Virtual Terminal Core__ | Implement PTY + ANSI parser → `TerminalBuffer { cells, colors, attrs }` shared by live/video/image. | `portable-pty` (or similar), internal ANSI |
86| __Frame Layout Engine__ | Map title/body/terminal regions into a logical canvas (cells or pixels) for all renderers. | internal `layout` module |
87| __Renderer Trait__ | Define `Renderer` trait (`begin`, `handle_event`, `end`) with impls for Live, Image, and Video. | internal `renderer` module |
88
89## Export: Images
90
91__Objective:__ Generate high-quality PNG/SVG snapshots of any slide (Freeze-style) directly from the slide + layout + terminal state.
92
93| Task | Description | Key Crates |
94| ----------------------------- | --------------------------------------------------------------------------------------------------------- | --------------------------------- |
95| __Canvas → Pixmap__ | Implement a `FrameRasterizer` that turns a `Frame` + layout into an RGBA pixmap (background, panes, etc). | `tiny-skia` |
96| __Text Rendering__ | Render slide titles/body text via glyph rasterization and simple layout (left/center, line wrapping). | `ab_glyph` |
97| __Terminal Snapshot Mode__ | Convert `TerminalBuffer` into a rendered terminal "window" (frame, tabs, padding, cursor). | `tiny-skia`, `ab_glyph` |
98| __Slide Screenshot CLI__ | `lantern export-image deck.md --slide 5 --output slide-5.png` (PNG by default, optional SVG/WebP). | `clap`, `image` |
99| __Batch Export__ | `--all` / `--range 3..7` to dump multiple slides, naming convention like `deck-003.png`. | `image` |
100| __Deterministic Layout Test__ | Golden tests comparing generated PNGs against fixtures for regression in layout and text. | `image`, integration test harness |
101
102## Export: Video
103
104__Objective:__ Produce MP4/WebM/GIF recordings of a scripted terminal+slides run (VHS-style) directly from the markdown deck.
105
106| Task | Description | Key Crates | |
107| ----------------------------- | -------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | ----------------- |
108| __Timeline Scheduling__ | Extend `Event` to carry timestamps or durations; implement `Scheduler` to emit frames at target FPS. | internal `timeline` module | |
109| __Frame Capture Loop__ | Drive the same layout/rasterizer used for images at N FPS, yielding a sequence of RGBA frames. | `tiny-skia`, `image` | |
110| __FFmpeg Binding Layer__ | Wrap `ffmpeg-next` to open an encoder, configure codec/container, and accept raw frames. | `ffmpeg-next` | |
111| __Video Export CLI__ | `lantern export-video deck.md --output demo.mp4 --fps 30 --duration 120s` (or auto-duration from events). | `clap`, internal encoder | |
112| __GIF / WebM Variants__ | Add `--format gif | webm mapping to appropriate ffmpeg muxer/codec presets. | `ffmpeg-next`[^7] |
113| __Typing & Cursor Effects__ | Represent typing, deletes, cursor blinks as timeline events, so video export matches live presentation feel. | internal `timeline`, terminal core | |
114| __Audio-less Simplification__ | Keep V1 video export silent (no audio tracks) for simpler ffmpeg integration and smaller binaries. | `ffmpeg-next` | |
115| __Performance Tuning__ | Measure memory/CPU for long decks; stream frames to ffmpeg (no full buffering) and expose `--quality` presets. | `ffmpeg-next`, `image` | |
116
117## Export: Social Media
118
119__Objective:__ Generate vertical (portrait) slides optimized for short-form vertical video.
120
121| Task | Description | Key Crates |
122| -------------------------- | ------------------------------------------------------------------------------------------------ | ----------------------------- |
123| __Portrait Layout Engine__ | Implement 9:16 aspect ratio layout with vertical constraints (1080x1920, 720x1280). | internal `layout` module |
124| __Mobile-Optimized Text__ | Larger font sizes, reduced content density, and simplified layouts for mobile readability. | `ab_glyph`, `tiny-skia` |
125| __Vertical Export CLI__ | `lantern export-vertical deck.md --output reel.mp4` with preset dimensions for each platform. | `clap`, internal encoder |
126| __Platform Presets__ | Built-in presets: `instagram-reel`, `tiktok`, `youtube-shorts` with optimal resolution/duration. | internal preset registry |
127| __Content Adaptation__ | Auto-scale or warn when horizontal content doesn't fit portrait orientation. | internal `layout` module |
128| __Safe Zones__ | Respect platform UI overlays (captions, profile pics) with configurable safe zones. | internal `layout` module |
129| __Swipe Animations__ | Optional slide transition effects optimized for vertical scrolling behavior. | internal `timeline`, `ffmpeg` |
130
131## Authoring & UX for Export
132
133__Objective:__ Make "slides → image/video" a natural extension of your current CLI and authoring workflow.
134
135| Task | Description | Key Crates |
136| ------------------------ | ------------------------------------------------------------------------------------------------ | ---------------------------- |
137| __Export Subcommands__ | Add `lantern export-image` and `lantern export-video` commands with shared flags (theme, range). | `clap` |
138| __Frontmatter Controls__ | Support per-deck/per-slide frontmatter: `fps`, `default_duration`, `transition`, `record: true`. | `pulldown-cmark-frontmatter` |
139| __Deterministic Seeds__ | Add `--seed` for any animations (typing jitter, cursor blink timing) to keep exports repeatable. | internal `timeline` |
140| __Preset Profiles__ | Presets like `social-card`, `doc-screenshot`, `talk-demo` mapping to resolution + theme. | internal profile registry |
141
142[^7]: <https://docs.rs/ratatui/latest/ratatui/>
143[^8]: <https://docs.rs/syntect/latest/syntect/>
144[^9]: <https://docs.rs/notify/latest/notify/>
145[^10]: <https://docs.rs/fuzzy-matcher>