pub struct Markdown { /* private fields */ }Expand description
A parsed Markdown document with support for live in-place terminal rendering.
Markdown parses markdown text into an internal element tree, then renders it
with ANSI escape codes. It tracks line counts between renders so subsequent
calls to render overwrite the previous output in-place
using terminal cursor control sequences.
§Examples
use smart_markdown::{Markdown, ThemeMode};
let mut md = Markdown::parse("## Status\n\n**Running...**")
.theme_mode(ThemeMode::Dark)
.code_theme("base16-ocean.dark");
md.render(); // outputs to stdout
// Update a table cell and re-render
md.set_cell_content(0, 1, "new data");
md.render(); // overwrites previous output in-placeImplementations§
Source§impl Markdown
impl Markdown
Sourcepub fn parse(text: &str) -> Self
pub fn parse(text: &str) -> Self
Parse a markdown string into a Markdown document.
Supports: headings (ATX and setext), paragraphs, fenced/indented code blocks, blockquotes, ordered/unordered/task lists, tables, definition lists, horizontal rules, HTML blocks, footnotes, and reference links.
Examples found in repository?
More examples
6fn main() -> Result<(), Box<dyn std::error::Error>> {
7 let mut md = Markdown::parse(
8 "## Build Pipeline\n\n\
9 | Task | Status | Details |\n\
10 |---------|---------|---------------------------------|\n\
11 | build | pending | |\n\
12 | test | pending | |\n\
13 | deploy | pending | |\n\
14 \n\
15 _Live streaming table update demo_\n\n\
16 \n\
17 ### Task Status\n\n\
18 - [x] Compile source\n\
19 - [x] Run unit tests\n\
20 - [ ] Integration tests\n\
21 - [ ] Deploy to staging\n\
22 \n\
23 See the pipeline logs or visit <https://ci.example.com>\n\
24 for detailed build output.\n",
25 );
26
27 println!("\nStreaming Markdown Demo\n-----------------------\n");
28 md.render();
29 io::stdout().flush()?;
30 thread::sleep(Duration::from_millis(800));
31
32 md.append_to_cell(0, 2, "compiling source");
33 md.render();
34 io::stdout().flush()?;
35 thread::sleep(Duration::from_millis(800));
36
37 md.append_to_cell(0, 2, " files...");
38 md.render();
39 io::stdout().flush()?;
40 thread::sleep(Duration::from_millis(800));
41
42 md.append_to_cell(1, 2, "running unit tests across all crates");
43 md.render();
44 io::stdout().flush()?;
45 thread::sleep(Duration::from_millis(800));
46
47 md.set_cell_content(0, 1, "done");
48 md.render();
49 io::stdout().flush()?;
50 thread::sleep(Duration::from_millis(800));
51
52 md.set_cell_content(1, 1, "running");
53 md.append_to_cell(1, 2, " with coverage instrumentation enabled for llvm-cov");
54 md.render();
55 io::stdout().flush()?;
56 thread::sleep(Duration::from_millis(1200));
57
58 md.set_cell_content(2, 1, "queued");
59 md.append_to_cell(0, 2, " and linking final binary artifact");
60 md.render();
61 io::stdout().flush()?;
62 thread::sleep(Duration::from_millis(800));
63
64 md.set_cell_content(2, 1, "done");
65 md.set_cell_content(2, 2, "release published to registry");
66 md.render();
67 io::stdout().flush()?;
68 thread::sleep(Duration::from_millis(800));
69
70 println!();
71
72 Ok(())
73}Sourcepub fn theme_mode(self, mode: ThemeMode) -> Self
pub fn theme_mode(self, mode: ThemeMode) -> Self
Set the syntax highlighting theme mode.
When the syntax-highlight feature is enabled (on by default),
this controls which syntect color theme is used for fenced code blocks.
ThemeMode::Dark— “Base16 Eighties Dark”ThemeMode::Light— “Solarized (light)”ThemeMode::Auto— detects terminal background color at render time
Sourcepub fn code_theme(self, theme: &str) -> Self
pub fn code_theme(self, theme: &str) -> Self
Override the syntax highlighting theme by name.
See highlight::list_themes for available theme names.
When the syntax-highlight feature is disabled, this has no effect.
Sourcepub fn has_terminal_resized(&self) -> bool
pub fn has_terminal_resized(&self) -> bool
Returns true if the terminal width has changed since the last render.
Useful for deciding whether to re-render on SIGWINCH.
Sourcepub fn append_to_cell(&mut self, row: usize, col: usize, text: &str)
pub fn append_to_cell(&mut self, row: usize, col: usize, text: &str)
Append text to a table cell identified by row and column index.
Panics if the document doesn’t contain a table or the indices are out of bounds.
Examples found in repository?
6fn main() -> Result<(), Box<dyn std::error::Error>> {
7 let mut md = Markdown::parse(
8 "## Build Pipeline\n\n\
9 | Task | Status | Details |\n\
10 |---------|---------|---------------------------------|\n\
11 | build | pending | |\n\
12 | test | pending | |\n\
13 | deploy | pending | |\n\
14 \n\
15 _Live streaming table update demo_\n\n\
16 \n\
17 ### Task Status\n\n\
18 - [x] Compile source\n\
19 - [x] Run unit tests\n\
20 - [ ] Integration tests\n\
21 - [ ] Deploy to staging\n\
22 \n\
23 See the pipeline logs or visit <https://ci.example.com>\n\
24 for detailed build output.\n",
25 );
26
27 println!("\nStreaming Markdown Demo\n-----------------------\n");
28 md.render();
29 io::stdout().flush()?;
30 thread::sleep(Duration::from_millis(800));
31
32 md.append_to_cell(0, 2, "compiling source");
33 md.render();
34 io::stdout().flush()?;
35 thread::sleep(Duration::from_millis(800));
36
37 md.append_to_cell(0, 2, " files...");
38 md.render();
39 io::stdout().flush()?;
40 thread::sleep(Duration::from_millis(800));
41
42 md.append_to_cell(1, 2, "running unit tests across all crates");
43 md.render();
44 io::stdout().flush()?;
45 thread::sleep(Duration::from_millis(800));
46
47 md.set_cell_content(0, 1, "done");
48 md.render();
49 io::stdout().flush()?;
50 thread::sleep(Duration::from_millis(800));
51
52 md.set_cell_content(1, 1, "running");
53 md.append_to_cell(1, 2, " with coverage instrumentation enabled for llvm-cov");
54 md.render();
55 io::stdout().flush()?;
56 thread::sleep(Duration::from_millis(1200));
57
58 md.set_cell_content(2, 1, "queued");
59 md.append_to_cell(0, 2, " and linking final binary artifact");
60 md.render();
61 io::stdout().flush()?;
62 thread::sleep(Duration::from_millis(800));
63
64 md.set_cell_content(2, 1, "done");
65 md.set_cell_content(2, 2, "release published to registry");
66 md.render();
67 io::stdout().flush()?;
68 thread::sleep(Duration::from_millis(800));
69
70 println!();
71
72 Ok(())
73}Sourcepub fn set_cell_content(&mut self, row: usize, col: usize, text: &str)
pub fn set_cell_content(&mut self, row: usize, col: usize, text: &str)
Replace the content of a table cell identified by row and column index.
Panics if the document doesn’t contain a table or the indices are out of bounds.
Examples found in repository?
6fn main() -> Result<(), Box<dyn std::error::Error>> {
7 let mut md = Markdown::parse(
8 "## Build Pipeline\n\n\
9 | Task | Status | Details |\n\
10 |---------|---------|---------------------------------|\n\
11 | build | pending | |\n\
12 | test | pending | |\n\
13 | deploy | pending | |\n\
14 \n\
15 _Live streaming table update demo_\n\n\
16 \n\
17 ### Task Status\n\n\
18 - [x] Compile source\n\
19 - [x] Run unit tests\n\
20 - [ ] Integration tests\n\
21 - [ ] Deploy to staging\n\
22 \n\
23 See the pipeline logs or visit <https://ci.example.com>\n\
24 for detailed build output.\n",
25 );
26
27 println!("\nStreaming Markdown Demo\n-----------------------\n");
28 md.render();
29 io::stdout().flush()?;
30 thread::sleep(Duration::from_millis(800));
31
32 md.append_to_cell(0, 2, "compiling source");
33 md.render();
34 io::stdout().flush()?;
35 thread::sleep(Duration::from_millis(800));
36
37 md.append_to_cell(0, 2, " files...");
38 md.render();
39 io::stdout().flush()?;
40 thread::sleep(Duration::from_millis(800));
41
42 md.append_to_cell(1, 2, "running unit tests across all crates");
43 md.render();
44 io::stdout().flush()?;
45 thread::sleep(Duration::from_millis(800));
46
47 md.set_cell_content(0, 1, "done");
48 md.render();
49 io::stdout().flush()?;
50 thread::sleep(Duration::from_millis(800));
51
52 md.set_cell_content(1, 1, "running");
53 md.append_to_cell(1, 2, " with coverage instrumentation enabled for llvm-cov");
54 md.render();
55 io::stdout().flush()?;
56 thread::sleep(Duration::from_millis(1200));
57
58 md.set_cell_content(2, 1, "queued");
59 md.append_to_cell(0, 2, " and linking final binary artifact");
60 md.render();
61 io::stdout().flush()?;
62 thread::sleep(Duration::from_millis(800));
63
64 md.set_cell_content(2, 1, "done");
65 md.set_cell_content(2, 2, "release published to registry");
66 md.render();
67 io::stdout().flush()?;
68 thread::sleep(Duration::from_millis(800));
69
70 println!();
71
72 Ok(())
73}Sourcepub fn render(&mut self)
pub fn render(&mut self)
Render the document to stdout with ANSI escape codes.
On first call, output is simply printed. On subsequent calls, the previous output is overwritten in-place using cursor-up and line-clear sequences. Lines that shrink between renders are properly cleared.
Examples found in repository?
More examples
6fn main() -> Result<(), Box<dyn std::error::Error>> {
7 let mut md = Markdown::parse(
8 "## Build Pipeline\n\n\
9 | Task | Status | Details |\n\
10 |---------|---------|---------------------------------|\n\
11 | build | pending | |\n\
12 | test | pending | |\n\
13 | deploy | pending | |\n\
14 \n\
15 _Live streaming table update demo_\n\n\
16 \n\
17 ### Task Status\n\n\
18 - [x] Compile source\n\
19 - [x] Run unit tests\n\
20 - [ ] Integration tests\n\
21 - [ ] Deploy to staging\n\
22 \n\
23 See the pipeline logs or visit <https://ci.example.com>\n\
24 for detailed build output.\n",
25 );
26
27 println!("\nStreaming Markdown Demo\n-----------------------\n");
28 md.render();
29 io::stdout().flush()?;
30 thread::sleep(Duration::from_millis(800));
31
32 md.append_to_cell(0, 2, "compiling source");
33 md.render();
34 io::stdout().flush()?;
35 thread::sleep(Duration::from_millis(800));
36
37 md.append_to_cell(0, 2, " files...");
38 md.render();
39 io::stdout().flush()?;
40 thread::sleep(Duration::from_millis(800));
41
42 md.append_to_cell(1, 2, "running unit tests across all crates");
43 md.render();
44 io::stdout().flush()?;
45 thread::sleep(Duration::from_millis(800));
46
47 md.set_cell_content(0, 1, "done");
48 md.render();
49 io::stdout().flush()?;
50 thread::sleep(Duration::from_millis(800));
51
52 md.set_cell_content(1, 1, "running");
53 md.append_to_cell(1, 2, " with coverage instrumentation enabled for llvm-cov");
54 md.render();
55 io::stdout().flush()?;
56 thread::sleep(Duration::from_millis(1200));
57
58 md.set_cell_content(2, 1, "queued");
59 md.append_to_cell(0, 2, " and linking final binary artifact");
60 md.render();
61 io::stdout().flush()?;
62 thread::sleep(Duration::from_millis(800));
63
64 md.set_cell_content(2, 1, "done");
65 md.set_cell_content(2, 2, "release published to registry");
66 md.render();
67 io::stdout().flush()?;
68 thread::sleep(Duration::from_millis(800));
69
70 println!();
71
72 Ok(())
73}