pub struct Markdown {
pub source: String,
}Expand description
Renders a subset of Markdown as styled terminal text.
Supports headings (#, ##, ###), bold, italic, inline code,
fenced code blocks, and unordered lists. Designed for rendering
LLM/AI chat output in the terminal.
The markdown source is a prop; style configuration lives in
MarkdownState (internal state with sensible defaults).
§Examples
ⓘ
// Constructor
Markdown::new("# Hello\n\nThis is **bold** and `code`.")
// In the element! macro
element! {
Markdown(key: "response", source: response_text.clone())
}Fields§
§source: StringThe markdown source text to render.
Implementations§
Source§impl Markdown
impl Markdown
Sourcepub fn new(source: impl Into<String>) -> Self
pub fn new(source: impl Into<String>) -> Self
Create a new markdown component with the given source text.
Examples found in repository?
examples/markdown_demo.rs (line 36)
8fn main() -> io::Result<()> {
9 let (width, _) = crossterm::terminal::size()?;
10 let mut r = InlineRenderer::new(width);
11 let mut stdout = io::stdout();
12
13 // User prompt
14 let _prompt = r.push(Text::styled(
15 "› Explain how async/await works in Rust with an example",
16 Style::default()
17 .fg(Color::White)
18 .add_modifier(Modifier::BOLD),
19 ));
20 flush(&mut r, &mut stdout)?;
21
22 // Spacer
23 let _sp = r.push(Text::unstyled(""));
24
25 // Response container
26 let response = r.push(VStack);
27
28 // Thinking spinner
29 let think = r.append_child(response, Spinner::new("Thinking..."));
30 animate_spinner(&mut r, &mut stdout, think, Duration::from_millis(1200))?;
31 r.swap_component(think, Spinner::new("Thinking...").done("Thought for 1.2s"));
32 flush(&mut r, &mut stdout)?;
33 r.freeze(think);
34
35 // Stream the markdown response by rebuilding with progressively more content
36 let md_id = r.append_child(response, Markdown::new(""));
37
38 let response_text = r#"## Async/Await in Rust
39
40Rust's async/await is built on the **Future** trait. When you write an `async fn`, the compiler transforms it into a state machine that implements `Future`.
41
42### Key Concepts
43
44- **Futures are lazy** — they don't run until polled by an *executor*
45- The `await` keyword yields control back to the executor
46- An executor like `tokio` manages scheduling futures onto threads
47
48### Example
49
50```rust
51async fn fetch_data(url: &str) -> Result<String, Error> {
52 let response = reqwest::get(url).await?;
53 let body = response.text().await?;
54 Ok(body)
55}
56
57#[tokio::main]
58async fn main() {
59 let data = fetch_data("https://example.com").await;
60 println!("Got: {:?}", data);
61}
62```
63
64The `.await` points are where the runtime can **suspend** this task and run others. This is *cooperative* multitasking — tasks must explicitly yield via `await`."#;
65
66 // Stream token by token
67 let tokens: Vec<&str> = response_text
68 .split_inclusive(|c: char| c.is_whitespace() || c == '\n')
69 .collect();
70 let mut accumulated = String::new();
71 for token in &tokens {
72 accumulated.push_str(token);
73 r.swap_component(md_id, Markdown::new(accumulated.clone()));
74 flush(&mut r, &mut stdout)?;
75 thread::sleep(Duration::from_millis(20));
76 }
77
78 println!();
79 Ok(())
80}Trait Implementations§
Auto Trait Implementations§
impl Freeze for Markdown
impl RefUnwindSafe for Markdown
impl Send for Markdown
impl Sync for Markdown
impl Unpin for Markdown
impl UnsafeUnpin for Markdown
impl UnwindSafe for Markdown
Blanket Implementations§
Source§impl<T, V> AddTo<DataChildren<T>> for Vwhere
V: Into<T>,
impl<T, V> AddTo<DataChildren<T>> for Vwhere
V: Into<T>,
Source§type Handle<'a> = DataHandle
where
T: 'a
type Handle<'a> = DataHandle where T: 'a
Handle returned after adding. Supports
.key() / .width() chaining.Source§fn add_to(self, collector: &mut DataChildren<T>) -> DataHandle
fn add_to(self, collector: &mut DataChildren<T>) -> DataHandle
Add this value to the collector, returning a handle for chaining
.key() and .width().Source§impl<C> AddTo<Elements> for Cwhere
C: Component,
impl<C> AddTo<Elements> for Cwhere
C: Component,
Source§type Handle<'a> = ElementHandle<'a>
type Handle<'a> = ElementHandle<'a>
Handle returned after adding. Supports
.key() / .width() chaining.Source§fn add_to(self, els: &mut Elements) -> ElementHandle<'_>
fn add_to(self, els: &mut Elements) -> ElementHandle<'_>
Add this value to the collector, returning a handle for chaining
.key() and .width().Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more