Packages
Multi-surface application runtime for Elixir. One TEA module renders to terminal, browser (LiveView), SSH, and MCP (agents). 30+ widgets, flexbox + CSS grid, AI agent runtime, distributed swarm with CRDTs, time-travel debugging, session recording, sandboxed REPL, and agentic commerce.
Current section
Files
Jump to
Current section
Files
lib/raxol/ui/components/markdown_renderer.ex
defmodule Raxol.UI.Components.MarkdownRenderer do
@moduledoc """
Renders Markdown text into Raxol elements or raw HTML.
Requires the `earmark` dependency.
"""
use Raxol.UI.Components.Base.Component
@doc """
Renders the given Markdown string.
"""
# Option 1: Render as raw HTML (Simpler, relies on browser rendering)
# Requires Raxol to have a way to render raw HTML, e.g., a `raw_html` element
# or specific handling in the rendering engine.
# def render(assigns) do
# ~H"""
# <div class="markdown-content">
# <%= raw_html(render_markdown(@markdown_text)) %>
# </div>
# """
# end
# Option 2: Basic Earmark AST to Raxol Elements (More complex, less feature complete)
# This is a placeholder implementation and likely needs significant expansion
# to handle various Markdown features correctly.
# It avoids raw HTML but might not render complex Markdown accurately.
@spec render(map(), map()) :: any()
@impl true
def render(state, _context) do
markdown_text = state[:markdown_text] || ""
case Code.ensure_loaded?(Earmark) do
true ->
html_content =
Earmark.as_html!(markdown_text,
gfm: true,
breaks: true,
smartypants: true
)
Raxol.View.Components.text(content: html_content)
false ->
Raxol.View.Components.text(
content:
markdown_text <>
"\n[MarkdownRenderer Error: Earmark library not found.]"
)
end
end
@doc "Initializes the MarkdownRenderer component state from props."
@spec init(map()) :: map()
@impl true
def init(props), do: props
@doc "Updates the MarkdownRenderer component state. No updates are handled by default."
@spec update(term(), map()) :: map()
@impl true
def update(_message, state), do: state
@doc "Handles events for the MarkdownRenderer component. No events are handled by default."
@spec handle_event(term(), map(), map()) :: {map(), list()}
@impl true
def handle_event(_event, state, _context), do: {state, []}
# Hypothetical raw_html component/function - needed for the above approach
# If Raxol doesn't have this, the render function needs to change.
# defp raw_html(assigns), do: # ... implementation depends on Raxol internals
@doc """
Mount hook - called when component is mounted.
No special setup needed for MarkdownRenderer.
"""
@impl true
@spec mount(map()) :: {map(), list()}
def mount(state), do: {state, []}
@doc """
Unmount hook - called when component is unmounted.
No cleanup needed for MarkdownRenderer.
"""
@impl true
@spec unmount(map()) :: map()
def unmount(state), do: state
end