Simple markdown parser for agent chat rendering.
Parses a subset of markdown into styled line segments suitable for terminal rendering. This is intentionally not a full CommonMark parser; it handles the patterns that LLM output commonly uses.
Supported syntax
**bold**and__bold__*italic*and_italic_`inline code`[link text](https://example.com)- Fenced code blocks (
`` with optional language tag) -# Headers(levels 1-3) -- list itemsandlist items-> blockquotes- Horizontal rules (---,**,_) ## Output format Returns a list of{line_segments, line_type}tuples where eachline_segmentsis a list of{text, style}pairs andline_type` indicates the block context.
Summary
Types
Extracted code block with language and content.
Line type indicating block context.
A parsed line with its segments and type.
A styled text segment.
Style attributes for a text segment.
Functions
Extracts fenced code blocks from markdown text.
Infers the target file path for a code block from surrounding markdown text.
Parses markdown text into styled line segments.
Parses inline markdown formatting within a single line.
Types
Extracted code block with language and content.
@type line_type() :: :text | :code | {:code_header, String.t()} | :header | :blockquote | :list_item | :rule | :empty
Line type indicating block context.
A parsed line with its segments and type.
A styled text segment.
@type style() :: :plain | :bold | :italic | :bold_italic | :code | {:link, String.t()} | :code_block | {:code_content, String.t()} | {:syntax, Minga.Core.Face.t()} | :header1 | :header2 | :header3 | :blockquote | :list_bullet | :rule
Style attributes for a text segment.
Functions
@spec extract_code_blocks(String.t()) :: [code_block()]
Extracts fenced code blocks from markdown text.
Returns a list of %{language: String.t(), content: String.t()} maps,
one per fenced code block. The content excludes the fence markers.
@spec infer_target_path(String.t(), non_neg_integer()) :: String.t() | nil
Infers the target file path for a code block from surrounding markdown text.
Scans the text preceding the nth code block (0-indexed) for backtick-wrapped file paths. Returns the last match (closest to the code block), or nil.
Examples
iex> MingaAgent.Markdown.infer_target_path("Update `lib/foo.ex`:\n```elixir\ncode\n```", 0)
"lib/foo.ex"
iex> MingaAgent.Markdown.infer_target_path("No file mentioned\n```elixir\ncode\n```", 0)
nil
@spec parse(String.t()) :: [parsed_line()]
Parses markdown text into styled line segments.
Returns a list of {segments, line_type} tuples, one per output line.
Parses inline markdown formatting within a single line.
Returns a list of {text, style} segments.