PUBLIC MODULE · lib/app/markdown/index.js

App.Markdown

lib/app/markdown/index.js — App.Markdown: markdown STRUCTURE for any render target, presentation-free.

This module depends on no other library code. App.TUI, App.Web, and external hosts can use its public functions.

The interface is marked-style CALLBACKS: a renderer is an object of string-in/string-out functions — inline: text, strong, em, codespan, link, br, mathInline; block: heading, code, mathBlock, blockquote, list, listItem, table, tableRow/tableCell (or marked's tablerow/tablecell), paragraph, hr, space — every one optional (missing ones default to plain text). Whole-text tokenization routes internally: the optional marked package's lexer when it resolves (a guarded dynamic import in lib/app/markdown/marked.js), or the builtin lexer (lib/app/markdown/lexer.js). Both produce the marked-shaped tokens accepted by the same walker (lib/app/markdown/walk.js), so renderers receive the same token contract from either engine. Dollar-bearing text uses the builtin lexer for consistent math boundaries.

Render targets hook in two ways: - whole text: renderMarkdown(text, renderer) — async (the marked import is), engine-routed; - incrementally (a still-growing stream, where marked's whole-text requirement can't apply): classifyLine() per complete line + renderInline() for the inline spans — the builtin engine's own primitives, synchronous.

class BashSanitizer class

Streaming sanitizer — one instance PER LIVE TOOL CALL (typically one bash command). Holds the look-back buffer that catches escape sequences split across chunks, so concurrent calls must never share an instance.

Defined in lib/app/markdown/text-safe.js

constructor({ markdown = false } = {…}) constructor

Create one sanitizer for one live tool call.

Returns BashSanitizer — A new streaming sanitizer instance.

Throws — {TypeError} If `options` is `null` and cannot be destructured.

end() method

Flush held bytes when the call ends, dropping any unfinished escape and balancing streamed emphasis. Resets the pending buffer and emphasis state for this instance.

Returns string — Sanitized text remaining in the buffer, plus any needed closing Markdown markers.

push(chunk) method

Sanitize the next raw chunk. A trailing INCOMPLETE escape is held back (not emitted) until the following chunk completes it — or end().

chunk string
Raw chunk, coerced with `String(chunk ?? "")`.

Returns string — Display-safe portion of the stream; any incomplete trailing escape is withheld. Coercion exceptions from the supplied chunk propagate to the caller.

class Markdown class

Canonical markdown module namespace. Static-only by design.

Defined in lib/app/markdown/index.js

classifyLine(line, state = {…}) function

Classify one complete Markdown source line into its block kind. Fence markers are recognized against and update the supplied fence state; while inside a fence, non-closing lines are classified as code. Outside fences, block markers are checked in horizontal-rule, heading, list, and quote order; unmatched lines are plain text.

line string
One source line, without a trailing `\n`.

Returns {kind: "fence", lang: string, raw: string — | {kind: "code", raw: string} | {kind: "hr", width: number, raw: string} | {kind: "heading", depth: number, text: string, raw: string} | {kind: "list", indent: string, marker: string, ordered: boolean, text: string, raw: string} | {kind: "quote", text: string, raw: string} | {kind: "text", text: string, raw: string}} Classification object. `raw` is always the source line; where present, `text` is content with the block marker stripped. List `marker` preserves the source marker (for example, `-`, `*`, or `2.`); normalization is left to the renderer.

Throws — {TypeError} If `line` is not a string or `state` is null/undefined when explicitly supplied; regular-expression matching and state access require valid inputs.

Defined in lib/app/markdown/line.js

async lexMarkdown(text) function

Tokenize complete markdown text. A unified Git diff is detected first and returned as its own single token (see parseGitDiff); otherwise marked's lexer (gfm, breaks) runs when available without math delimiters; otherwise the builtin lexer handles math. Same token shapes for walkTokens.

text string
Complete markdown source; nullish values are coerced to an empty string at runtime.

Returns Promise<Array<object>> — Resolves to marked-shaped block tokens; recognized unified Git diffs are returned as a single token.

Throws — {Error} Rejects if engine loading or tokenization fails.

Defined in lib/app/markdown/index.js

async markdownEngine() function

Determine which engine whole-text rendering routes through, lazily loading and caching optional-engine availability.

Returns Promise<"marked"|"builtin"> — Resolves to `"marked"` when the optional package is available, or `"builtin"` otherwise; import failure selects `"builtin"`.

Defined in lib/app/markdown/index.js

mathBlockAt(lines, start) function

Find a complete, line-delimited display-math block; an unclosed block is not consumed.

lines string[]
Source lines.
start number
Candidate opening-line index.

Returns {end: number, text: string, source: string, tree: object}|null — Block data and parsed AST, or null.

Defined in lib/app/markdown/math.js

mathText(node) function

Convert a math AST node to a plain-text fallback representation.

node object|null|undefined
Math AST node; nullish input produces an empty string.

Returns string — Plain-text rendering; recursively visits child nodes.

Defined in lib/app/markdown/math.js

parseGitDiff(text) function

Parse one complete unified Git diff synchronously, with exact source-line spans.

text string
Source text; coerced to a string by the parser.

Returns object|null — The Git-diff token, or `null` when the text is not a complete recognized diff.

Throws — {TypeError} If converting `text` to a string fails.

Defined in lib/app/markdown/index.js

parseInline(text) function

Tokenize inline markdown into flat, non-nested spans, choosing the earliest recognized markup. Code spans, links, math, strong, and emphasis are recognized; unrecognized content remains text.

text string|null|undefined
one line/fragment; nullish values are treated as empty, otherwise converted with String

Returns Array<{type: string, text: string, href?: string, source?: string, tree?: object}> — Ordered spans; math spans also contain source and parsed tree

Throws — {Error} May propagate errors raised by inline-math parsing

Defined in lib/app/markdown/inline.js

parseMath(source) function

Parse a bounded TeX subset into presentation-independent nodes; unknown commands remain literal.

source *
Input converted to a string (nullish values become empty).

Returns {type: string, [key: string]: any} — AST node; over-limit input is returned as one literal symbol.

Throws — String conversion may throw for hostile values.

Defined in lib/app/markdown/math.js

renderInline(text, renderer = {…}) function

Render one fragment of inline markdown through a renderer's inline callbacks, synchronously, via the builtin tokenizer (engine routing needs whole text — inline fragments don't have it). This is the primitive incremental renderers style complete lines with.

text string
Inline markdown (no block structure).
[renderer={}] object
Inline callbacks; missing callbacks default to plain text.

Returns string — The synchronously rendered inline fragment.

Throws — {Error} Propagates errors thrown during parsing or by renderer callbacks.

Defined in lib/app/markdown/index.js

async renderMarkdown(text, renderer = {…}) function

Render complete markdown text through a renderer's callbacks, engine-routed (see lexMarkdown). Rendered tokens join with one "\n"; source blank lines are space tokens, so one blank line remains one blank line in the output.

text string
Complete markdown source passed to {@link lexMarkdown}.
[renderer={}] object
Marked-style callbacks; missing callbacks default to plain text.

Returns Promise<string> — Resolves to rendered output with tokens joined by newlines.

Throws — {Error} Rejects if tokenization or rendering fails.

Defined in lib/app/markdown/index.js

sanitizeText(text, { markdown = false, state = null, open = false } = {…}) function

Sanitize a COMPLETE untrusted string for display. - \r\n and lone \r (progress-bar carriage returns) become \n - ANSI escape sequences are removed: CSI, OSC (BEL- or ST-terminated), DCS/SOS/PM/APC (ST-terminated), charset/designate/short ESC forms - SGR bold/italic/underline become Markdown markers when markdown=true (balanced across style changes; nothing left open at the end) - C0 controls (except \t, \n), DEL, and C1 controls are dropped A trailing INCOMPLETE escape is removed — this string is finished.

text string
text string
Input value, coerced with `String(text ?? "")`.

Returns string — Sanitized display text, with optional balanced Markdown emphasis markers.

Throws — {TypeError} If `options` is `null` and cannot be destructured.

Throws — {Error} If input coercion throws an error.

Defined in lib/app/markdown/text-safe.js

walkTokens(tokens, renderer = {…}) function

Render marked-shaped block tokens, completing missing renderer callbacks with plain-text defaults. Nested block and inline content is rendered recursively; top-level block results are joined with one newline. List and table callbacks receive normalized item/cell metadata, and gitdiff callbacks receive per-line classifications before the enclosing callback.

tokens Array<object>|null|undefined
block tokens; nullish input is treated as empty
[renderer={}] object
renderer callbacks; missing callbacks use plain-text defaults

Returns string — rendered block output

Throws — {TypeError} if tokens is not an array, a token is nullish, or a renderer callback throws

Defined in lib/app/markdown/walk.js