Raxol.UI.Components.MarkdownRenderer (Raxol v2.6.1)

View Source

Renders Markdown text into styled Raxol elements for terminal display.

Supports headings, bold, italic, code spans, fenced code blocks (/ ~~~), lists (ul/ol), blockquotes, horizontal rules, links, and GFM tables. Parsing is the built-in regex parser, unconditionally. There used to be a second, preferred path here: `EarmarkParser` whenever `Code.ensure_loaded?/1` found it. That made the parser depend on which environment the code ran in -- `ex_doc` pulls EarmarkParser into `:dev` transitively, so `mix raxol.playground` parsed with Earmark while the test suite parsed with the builtin and proved nothing about it. The divergences that hid there: no GFM table support at all (tables rendered as a vertical list of one cell per line), and any fence whose info string had more than one word (````elixir title=demo ```) parsed as an inline code span instead of a code block, losing both the language label and syntax highlighting. It was also ~30x slower on the streaming suite, which matters becauseHarness.MarkdownBodyre-parses the whole buffer on every delta -- and that module states all of its stable-prefix, byte-cap and mid-grapheme-cut guarantees against the BUILTIN parser as its oracle, so the swap silently voided them in the one environment the harness actually runs in. One parser, one behavior, everywhere. Overflowing lines wrap through the sharedTextLayout.wrap/4:prettyengine (Knuth-Plass), and inline styling survives the break: the wrapped line boundaries are applied back to the original styled segments, so a span split across two lines keeps its style on both halves. Fenced code blocks reuseRaxol.UI.Components.CodeBlock.render_lines/3(the sameSyntaxHighlighterpath as DiffViewer). The fence info string selects the lexer but is not displayed. Pass:syntax_theme(default:one_dark) to pick a Makeup style. Trust note: a new output surface added to a shared component inherits the component's OWN trust contract, not the calling path's. This module's contract is "callers may pass untrusted text", so control-byte sanitization happens at THIS module's own boundary (render_with_builtin/3, before the text is split into lines) rather than being left to callers -- some callers pre-strip already (the harness path'sHarness.MarkdownBody, making this redundant-but-cheap there), others don't (the playground'sDemoHelpers.markdown/2`), and a shared component can't assume which kind of caller it has.

Summary

Functions

broadcast(msg)

command(cmd)

handle_event(event, state, context)

Callback implementation for Raxol.UI.Components.Base.Component.handle_event/3.

schedule(msg, delay)