Native MarkdownExperimentalC • Zsh • MD4C

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 --features

Structured 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.