md

package
v0.4.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 11, 2026 License: MIT Imports: 3 Imported by: 0

Documentation

Overview

Streaming markdown → ANSI renderer for model output.

The model's replies are markdown; printing them raw means literal **bold** and unhighlighted code fences all day. This renderer styles them for the terminal: bold/italic/inline-code spans, dim bullets, bold headers, and colored code-fence blocks.

It's LINE-buffered by design: tokens accumulate until a newline, then the completed line renders with the correct fence state. Styling half a line correctly is impossible (a ` or ** may not have arrived yet), and at local generation speeds line-by-line output reads naturally. Flush() emits any final partial line (rendered best-effort) at end of turn.

When stdout isn't a terminal (NO_COLOR, pipes), tokens pass through untouched — byte-exact markdown for scripts.

Shared markdown table support — one parser, rendered per surface.

Tables can't render line-by-line (they need header + separator + rows together), which is why the streaming line renderer skipped them. This module provides the buffering + parsing once, and renders to ANSI box-drawing (CLI) or plain aligned text (TUI/no-color). The dashboard renders its own HTML from the same markdown, but the DETECTION logic here (isTableHeader/isTableSeparator) is the shared contract so all three surfaces agree on what counts as a table.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func RenderInline

func RenderInline(s string) string

func RenderMarkdownBlock

func RenderMarkdownBlock(src string, color bool, maxWidth int) string

RenderInline styles `code`, **bold**, and *italic* spans. Inline code is handled first by splitting on backticks so its content is protected from bold/italic processing — asterisks inside `code` are code. RenderMarkdownBlock renders a COMPLETE markdown string (not streaming) to ANSI (color) or aligned plain text. Used where the full text is already in hand — the TUI viewport re-renders the whole assistant block each update, and this keeps its tables/headings/emphasis identical to the CLI's streaming renderer. Both go through the same mdtable + renderLine code.

func StripMarkdown

func StripMarkdown(s string) string

StripMarkdown removes inline markdown markers so display width can be measured accurately (a **bold** cell is 4 chars wider than it looks).

func WrapANSI

func WrapANSI(s string, max int) string

WrapANSI word-wraps s to a maximum visible width, treating ANSI escape sequences as zero-width so colored text wraps at the right column. Wrapping happens at spaces where possible; an over-long single word is hard-broken. Box-drawing (table) lines are returned unchanged — they're pre-fit. Leading indentation is preserved on continuation lines so wrapped list items and prose stay visually aligned.

Types

type Writer

type Writer struct {
	// contains filtered or unexported fields
}

func NewMDWriter

func NewMDWriter() *Writer

func (*Writer) Flush

func (m *Writer) Flush()

Flush drains any held state at end of turn: an in-progress table, a pending candidate line, and any partial (newline-less) buffered text.

func (*Writer) Write

func (m *Writer) Write(tok string)

Write consumes a streamed token, printing every completed line. Both color and no-color modes route completed lines through handleLine so tables are detected and rendered (box-drawing with color, aligned plain without).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL