Skip to content

About

Lisp library for parsing and rendering markdown to the CLI

Resources

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

22 Commits

Folders and files

Repository files navigation

cl-termdown

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.

Usage

(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))

Public API

  • markdown-renderer: stateful renderer class
  • markdown-renderer-create: create a renderer with :width
  • markdown-renderer-width: read its effective row width
  • markdown-renderer-closed-code-source: the raw text of the fence that just closed, or nil once another fence opens; its closing row ends in a :code-copy span that applications may turn into a copy control
  • markdown-render-line: render and commit one logical line
  • markdown-render-inline: render inline Markdown within an exact width
  • markdown-render-partial: preview an uncommitted logical line as three values
  • markdown-render-finish: flush an unfinished buffered diagram as source at EOF
  • make-span, span-p, span-role, span-text: neutral (role . text) spans
  • spans-width: total Unicode terminal-cell width of a span row
  • column-widths: allocate cell-aware table column widths
  • fit-text: clip and align a single table cell
  • spans-text: concatenate sanitized visible text, optionally as one line
  • fit-spans: clip sanitized spans by cells without splitting graphemes
  • render-spans: render sanitized text with an optional trusted :style-function accepting (role text) and returning presentation
  • make-widget, widget-p, widget-role, widget-label, widget-action: a label shown like a span of its role that carries an application action; every span function above presents it as its label
  • presentation-spans: replace widgets by the spans of their labels
  • widget-regions: the (start end action) character extents of the widgets in a row, indexing spans-text, from an optional :start offset
  • shift-regions, region-action: move regions after their text is joined to other text, and find the action covering a character offset
  • selector-table-rows: span rows for a vertical Clinedi selector’s visible window as a table, with a selection marker, a label column, further columns from :column-functions returning strings or spans and aligned across the visible rows, and a heading row wherever :group-function changes group; columns empty in every visible row are left out, and the roles are keyword arguments; a selector that is not vertical signals selector-arrangement-error, a type-error whose selector-arrangement-error-selector returns the selector

Semantic roles include :plain, :brand, :dim, :strong, :emphasis, :code, :code-copy, :notice, and the :syntax-* roles produced by Colordiff.

Development

./script/bootstrap
./script/check
./script/check --fix

./script/check runs CL-TERMDOWN/TESTS in an isolated source registry, then checks the source with cheque as cheque.sexp configures it. --fix skips the tests and repairs what cheque can repair. cheque and its tools are development dependencies: checks/qlfile lists them, and the check installs them on first use into ~/.cache/cheque/tools/.

Dependencies

cl-termdown uses Clinedi for Unicode geometry and wrapping, Clermaid for terminal diagrams, ColorLisp and Colordiff for fenced-code highlighting, and Serapeum for declarations. Qlot pins the tested dependency revisions.

License

cl-termdown uses COLL-Attribution. The authoritative terms are in LICENSE.lisp.

Mermaid fences

Fenced blocks tagged mermaid render through Clermaid when they close. Read the original body from markdown-renderer-closed-code-source and use the closing row’s :code-copy span to add a copy control. Unsupported, malformed, excessively large, or too-wide diagrams display numbered source with a :notice diagnostic before it. The diagnostic includes Clermaid’s failure category and condition report, sanitized and wrapped to the renderer’s terminal-cell width. A source-limit diagnostic appears as soon as a fence exceeds the buffering limit.

Open diagrams appear only in speculative previews. Call markdown-render-finish at the end of a document or interrupted stream to display incomplete source. See Clermaid’s README for the supported syntax.

Flowchart subgraphs render as labeled frames, including nested groups and edges between grouped nodes. For example:

flowchart TD
  subgraph Local["Local machine"]
    C[Client] --> S[Server]
  end
  S --> R[Remote]
Loading

Clermaid parses the groups and draws their frames and connections. Use the same Markdown rendering API for grouped and ungrouped diagrams.

About

Lisp library for parsing and rendering markdown to the CLI

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages