# Markdown `deft/stdext/markdown` (`md`) is the Deft-side markdown engine behind the TUI markdown viewer: line classification, inline span rendering (`code`, bold, links), word wrapping, fenced-code extraction, viewport drawing, and a parse-once layout model used for hit-testing, selection and scrolling.
import "deft/stdext/markdown" as md
This page documents the module API. The widget that uses it is described in Widgets and Protocols, and the draw primitives it renders with in Graphics. ## Classifying Lines | Def | Signature | Description | |---|---|---| | `is-heading` / `is-subheading` / `is-h3` | `{| line |}` | `# ` / `## ` / `### ` prefixes | | `is-code-fence` | `{| line |}` | Trimmed ` ``` ` or `~~~` |` | `is-list-item` | `{| line |}` | Bullet or numbered opener | | `list-prefix` | `{| line |}` | Rendered marker (`"• "` or `"N. "`), or nil | | `is-table-row` / `is-table-separator` | `{| line |}` | Leading `|`; separator is pipes/dashes/spaces | | `is-blockquote` | `{| line |}` | `"> "` | ## Drawing | Def | Signature | Description | |---|---|---| | `default-colors` | `{||}` | Color map from the active theme's `:markdown` block, else built-in defaults | | `draw-lines` | `{| ctx x y vp-height scroll lines max-w colors highlight-fn |}` | Scrollable viewport draw; clamps scroll, pre-scans fences | | `draw-markdown-line` | `{| ctx x y line max-w colors in-code highlight-fn |}` | Draw one line; returns the next `in-code` state | | `draw-markdown-line-wrapped` | `{| ctx x y line max-w colors in-code highlight-fn |}` | Same but wraps prose/headings/lists/quotes; tables/code truncate | | `draw-inline` | `{| ctx x y line max-w text-fg text-bg code-fg code-bg bold-fg link-fg |}` | Inline spans within a line | | `rule-for` / `draw-rule-line` | `{…}` | Optional whole-line rules (e.g. diff `+`/`-` lines) from `:line-rules` | `highlight-fn` is `{| line | -> per-character color vector}` or nil for uniform code colors; consumers pass the syntax registry dispatch. ## Layout Engine `build-layout` parses lines once into entries; the renderer, hit-testing and selection all read the same structure. | Def | Signature | Description | |---|---|---| | `build-layout` | `{| lines max-w rules |}` | `%{ entries total-rows blocks }` | | `line-at-row` | `{| layout row |}` | Display row → source line index | | `entry-at-line` | `{| layout line-idx |}` | Layout entry for a source line | | `compute-line-rows` | `{| line max-w in-code |}` | `%{ in-code rows }` without drawing | | `extract-code-at-line` | `{| lines line-idx |}` | `%{ code lang }` for the enclosing fence, or nil | | `wrap-plain` / `wrap-markdown` | `{| text max-w |}` | Wrap a plain string / markdown text into display lines | Layout entry: `%{ line row rows type lang? rule? }`, with `:type` one of `:fence-open :fence-close :code :heading :subheading :h3 :table-sep` :table-row :blockquote :list :text :empty :rule`. `:blocks` holds` inclusive fence spans `@{ %{ start end lang } }` (an unclosed fence ends at EOF). ## Example
set colors [merge [md/default-colors] %{ heading-fg "#ffd54f" }]
[md/draw-lines $ctx 1 1 $vp-height $scroll $lines $max-w $colors nil]

set layout [md/build-layout $lines 40 $rules]
set src-line [md/line-at-row $layout $display-row]
set code [md/extract-code-at-line $lines $cursor-line]
## Colors `default-colors` keys: `heading-fg subheading-fg h3-fg code-fg code-bg` bold-fg link-fg list-fg table-border-fg table-header-fg blockquote-fg blockquote-bar-fg text-fg text-bg`, plus optional `:line-rules`. Set the` `[theme]` `:markdown` section to retheme every viewer at once. ## See Also - Syntax — source of `highlight-fn` - Widgets and Protocols — `markdown-viewer` - Graphics — `draw/*` primitives