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().
chunkstring- 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.
linestring- 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.
textstring- 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.
linesstring[]- Source lines.
startnumber- 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.
nodeobject|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.
textstring- 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.
textstring|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.
textstring- 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.
textstring- 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.
textstringtextstring- 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.
tokensArray<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