Markdown Rendering¶
Experimental
The document pager (run_markdown, render_markdown, MarkdownViewport)
is experimental. The API may still change. The Markdown component used
as a field value is separate and is not covered by this warning.
xnano.markdown loads Markdown from a string, bytes, or file path and either paints one frame or opens an interactive pager — scrollable viewport, status line, and keyboard / wheel navigation.
This is separate from the Markdown
component, which is a field value for embedding markdown inside a grid. The
module here is a document runner and viewport.
Interactive pager¶
run_markdown opens a live session when
a TTY is available. The document is taller than the screen when needed; you
scroll the window rather than painting everything at once.
from xnano.markdown import run_markdown
run_markdown("README.md") # (1)!
# or: run_markdown("# Title\n\nBody text.")
- Path, literal markdown string, or
bytes. Paths set a base directory for relative images.
CLI / entrypoint:
With no path, xnano runs the feature demo instead.
Navigation¶
| Input | Action |
|---|---|
arrows, j / k |
Line scroll |
PageUp / PageDown, space |
Page scroll |
Home / g, End / G |
Start / end of document |
| mouse wheel | Scroll |
i / click / hover |
Expand image preview (when images are present) |
q / esc |
Quit (esc first clears a pinned image expand) |
A status line at the bottom shows scroll position and short hints.
One frame¶
render_markdown paints once and returns
a Frame. No event loop.
from xnano.markdown import render_markdown
frame = render_markdown("# Hello\n\nA single frame.")
print(frame.text)
Interactive
This code block runs in the browser via Pyodide.
Try editing the code!
- Change the heading text.
- Add a second paragraph to the string.
from xnano.markdown import render_markdown
frame = render_markdown("# Hello\n\nA single frame from Markdown.")
print(frame.text)
Loading helpers¶
from pathlib import Path
from xnano.markdown import is_markdown_path, load_markdown_source
is_markdown_path("notes.md") # True if the file exists with a .md-like suffix
text, base = load_markdown_source(Path("docs/guide.md"))
# base is the parent directory for relative assets
Supported suffixes include .md, .markdown, .mdown, .mkd, and .mkdn.
Viewport and images¶
MarkdownViewport is the windowed
body used by the pager: block-aware layout (text + images), scroll offset, and
hover/pin expand for local images.
Inline images paint as compact half-block thumbnails (never upscaled past native
cell resolution). Expand with hover, click, or i for a larger preview without
decoding full-size images on every frame.
The Markdown component is still the right choice when markdown is one
slot inside a larger app grid. Use xnano.markdown when the document is the
session.
Next¶
- Terminal — host used by the pager
- Components —
Markdownas a field value - Device & Cursor — mouse capture for wheel / hover when live