limner
A ratatui markdown renderer with image placeholders, styled headings, code blocks, per-section alignment, and more.
[]
= "0.1"
Usage
use ;
use ;
let content = "# Hello\n\nThis is **markdown** with `code`.";
let style = MarkdownStyle ;
let lines = render_markdown;
let paragraph = new.wrap;
Output lines work directly with ratatui's Paragraph widget — scrolling,
line counting, and word-wrapping are all handled by the existing widget.
Per-section alignment
Every block-level element has a corresponding *_alignment field:
| Element | Alignment field | Supported values |
|---|---|---|
| Paragraph | paragraph_alignment |
Left, Center, Right, Justify |
| Heading 1 | heading_1_alignment |
Left, Center, Right |
| Heading 2 | heading_2_alignment |
Left, Center, Right |
| Heading 3 | heading_3_alignment |
Left, Center, Right |
| Code block | code_block_alignment |
Left, Center, Right |
| Blockquote | quote_alignment |
Left, Center, Right, Justify |
Left is the default for all elements (backward-compatible).
use ;
let style = MarkdownStyle ;
let result = render_markdown;
Justify — limner word-wraps paragraphs itself and distributes extra spaces between words so every line (except the last) fills the full width. Works correctly with inline styles (bold, italic, code) and images.
Render multiple sections with different alignments by calling
render_markdown separately for each section and combining the lines:
use ;
let title = render_markdown;
let body = render_markdown;
let mut all_lines = title.lines;
all_lines.extend;
Features
- Headings (levels 1–3) with configurable styles and alignment
- Bold, italic, strikethrough with proper nesting
- Inline code and code blocks with full-width background and alignment
- Links with styled text and prefix
- Images rendered as placeholder text (
🖼 alt-text) - Blockquotes with per-line indicators and justified continuation lines
- Ordered and unordered lists
- Horizontal rules
- Per-section alignment — center, right, or justify individual elements
- Lightweight — only depends on
ratatui,pulldown-cmark, andunicode-width - Terminal image rendering (optional) — via
image-protocolfeature
Terminal image rendering
Enable the image-protocol feature to render images via the terminal's native
graphics protocol (Kitty, Sixel, or iTerm2):
[]
= { = "0.1", = ["image-protocol"] }
Images in markdown () are tracked as ImageInfo metadata.
After drawing the ratatui frame, call prepare_inline_images() to insert
Image widgets at the correct positions:
use ;
use HashMap;
let result = render_markdown;
let mut protocol_cache = new;
let picker = from_query_stdio?;
let font_size = picker.font_size;
let placements = prepare_inline_images;
// Then render Image widgets inside terminal.draw() using the placements.
The caller is responsible for populating the image_cache
(HashMap<String, DynamicImage>).
Demo
# Text-only (no image rendering required)
# With terminal image rendering (Kitty/Sixel/iTerm2)
Controls: Up/Down to scroll, PageUp/PageDown to scroll faster,
Home to jump to the top, End to jump to the bottom, Q/Esc to quit.
Theming
MarkdownStyle exposes every element's [Style], alignment, and text prefix.
Set only the fields you want to override:
use ;
use *;
let my_style = MarkdownStyle ;
License
MIT