zmdown
Render Markdown directly in Zsh scripts with a standalone compiled module. zmdown keeps parsing, layout, terminal styling, and structured output inside one builtin.
Development release: the current 0.1.0-dev module is ready to try in scripts, but its API may evolve before a stable release.
A Markdown Renderer Built for Zsh
Markdown in the shell
Load one compiled module, then render files, stdin, or strings through the zmdown builtin. No external Markdown command is required.
Inputs that fit scripts
Render a path, accept piped input through EOF, or pass an exact string with --text. Empty input produces an empty result.
Assign without subprocesses
Write rendered output directly into a scalar with -v. Function-local variables work, and trailing newlines survive.
Structured documents
Inspect lines, semantic spans, cell widths, and complete code-block contents through native associative-array output.
CommonMark and GFM
Handle headings, nested lists, quotes, code, links, tables, task lists, strikethrough, autolinks, and styled wrapping.
Safe terminal output
Escape terminal controls, replace invalid UTF-8, keep graphemes intact, and emit only renderer-generated ANSI styles.
Load Once, Render Anywhere
The module bundles a pinned MD4C parser and its own terminal renderer. Load zmdown from a matching Zsh module path, then pass files, stdin, or strings without spawning another process.
zmodload zmdown
zmdown README.md
print -r -- '# Hello **world**' | zmdown
zmdown --text "$message"
local rendered
zmdown -v rendered --text "$message"
print -rn -- "$rendered"The module does not install or modify your supplied Zsh sources. Use a build that matches the ABI of the shell that will load it.
Output for More Than a Terminal
Use structured output when a drawing backend, pager, or application needs more than styled text. zmdown publishes line text, semantic spans, width data, and code metadata through schema 1 output.
local -A document
zmdown --spans document --width 60 --text "$message"
print -r -- "$document[line,1,text]"
zmdown --featuresStructured mode emits no ANSI. Applications can choose their own colors, clipping, hyperlinks, syntax highlighting, or pagination while reusing zmdown's parsed document.
Terminal-Aware by Default
Rendering adapts to the stdout width or an explicit --width value. Word wrapping preserves extended grapheme clusters, tables switch to stacked output when a grid will not fit, and code whitespace remains significant.
Color defaults to auto, with --plain, --color always, and --color never available for pipelines and ANSI-capable pagers. Raw HTML is displayed literally rather than treated as terminal markup.
Current Limits
This version reads a complete document before producing output. It does not provide streaming, persistent document handles, a pager, syntax highlighting, image protocols, mathematics, Mermaid, or footnotes.
Rendering needs no shared Markdown library or curses session, but loading the compiled module into an existing shell requires a matching Zsh ABI. Linux with private Zsh 5.8 and 5.9.2 builds is tested.