cl-termdown parses a restrained Markdown subset into terminal-oriented semantic spans. It preserves Unicode cell widths, whole-word wrapping, bullets and numbered lists, inline emphasis and code, bounded pipe tables, fenced syntax highlighting, and speculative streaming previews.
Rows are lists of neutral cons spans whose car is a keyword role and whose
cdr is text. The caller styles them.
(asdf:load-system :cl-termdown)
(let ((renderer (termdown:markdown-renderer-create :width 48)))
(termdown:markdown-render-line
renderer
"- render **strong** and `code` spans"))
;; => (((:PLAIN . " ")
;; (:BRAND . "• ")
;; (:PLAIN . "render ")
;; (:STRONG . "strong")
;; (:PLAIN . " and ")
;; (:CODE . "code")
;; (:PLAIN . " spans")))One renderer retains fenced-code and pipe-table state across logical lines.
Call markdown-render-line when a newline commits that logical line.
(multiple-value-bind (committed live retained)
(termdown:markdown-render-partial renderer "unfinished **strong")
(values committed live retained))markdown-renderer: stateful renderer classmarkdown-renderer-create: create a renderer with:widthmarkdown-renderer-width: read its effective row widthmarkdown-render-line: render and commit one logical linemarkdown-render-inline: render inline Markdown within an exact widthmarkdown-render-partial: preview an uncommitted logical line as three valuesmake-span,span-p,span-role,span-text: neutral(role . text)spansspans-width: total Unicode terminal-cell width of a span rowcolumn-widths: allocate cell-aware table column widths
Semantic roles include :plain, :brand, :dim, :strong, :emphasis,
:code, and the :syntax-* roles produced by Colordiff.
./script/bootstrap
./script/checkscript/check runs CL-TERMDOWN/TESTS in an isolated source registry.
cl-termdown uses Clinedi for Unicode geometry and wrapping, ColorLisp and Colordiff for fenced-code highlighting, and Serapeum for declarations. Qlot pins the exact tested dependency revisions.
cl-termdown uses COLL-Attribution. The authoritative terms are in
LICENSE.lisp.