GitHub-Style Callouts
February 9, 2026 ยท View on GitHub
Overview
Support for GitHub-style admonition blocks (> [!NOTE], > [!TIP], etc.) with color-coded rendering, custom titles, and collapsible state.
Key Files
src/markdown/parser.rs- Callout detection,CalloutTypeenum, blockquote-to-callout conversionsrc/markdown/editor.rs- Styled rendering with colors, icons, collapse togglesrc/markdown/widgets.rs- Serialization back to markdown syntax
Syntax
> [!NOTE]
> Basic note content
> [!TIP] Custom Title
> Tip with a custom title
> [!WARNING]-
> Collapsed by default, click to expand
Supported Types
| Type | Color | Icon |
|---|---|---|
| NOTE | Blue | โน |
| TIP | Green | ๐ก |
| WARNING | Orange | โ |
| CAUTION | Yellow | โ |
| IMPORTANT | Red | โ |
Implementation Details
Parser (parser.rs)
CalloutTypeenum withfrom_str(case-insensitive),display_name(), andicon()methods.MarkdownNodeType::CalloutAST node withcallout_type,title(Option), andcollapsed(bool) fields.- Processing order:
convert_callout_blockquotesruns beforemerge_consecutive_blockquotesto prevent distinct callouts from being merged into one blockquote. split_and_convert_blockquote: Handles a singleBlockQuotecontaining multiple[!TYPE]markers by splitting it into separateCalloutnodes.extract_callout_info: Parses the[!TYPE], optional-suffix (collapsed), and optional custom title from the first paragraph's text content.
Renderer (editor.rs)
callout_colors(): Returns(border_color, bg_color, title_color)per type usingColor32::from_rgba_unmultipliedwith low alpha (20-25) for subtle backgrounds.- Collapse toggle: Uses
ui.allocate_rect()over the title row withSense::click()for reliable click detection. State is persisted viaegui::Idkeyed on(start_line, end_line). - Pointer cursor: Shows
CursorIcon::PointingHandon hover over the title. - ID uniqueness: Each callout is wrapped in
ui.push_id(("callout_...", start_line, end_line))to prevent egui widget ID collisions. - Both
render_callout_with_structural_keysandrender_calloutimplement the same rendering logic for their respective render paths.
Serializer (widgets.rs)
Reconstructs the original markdown syntax from the AST:
> [!TYPE]for basic callouts> [!TYPE]-for collapsed> [!TYPE] Custom Titlefor custom titles
Tests
8 parser tests in parser.rs:
test_callout_note_basic- Basic NOTE callouttest_callout_custom_title- Custom title parsingtest_callout_collapsed- Collapsed state (-suffix)test_callout_all_types- All 5 types recognizedtest_callout_case_insensitive- Case-insensitive matchingtest_regular_blockquote_not_callout- Regular blockquotes unchangedtest_unknown_callout_type- Unknown types stay as blockquotestest_callout_multiline_content- Multi-paragraph content
Known Considerations
- Consecutive callouts (separated by blank lines) are correctly parsed as separate blocks.
- Unknown
[!TYPE]values are left as regular blockquotes. - Collapse state persists across frames via egui's persistent data store.