Skip to main content

core_markdown/renderer/
markdown_renderer.rs

1// Released under the MIT License.
2// Copyright, 2026, by Samuel Williams.
3
4//! Markdown rendering for mdast trees.
5use super::Renderer;
6use crate::{markdown::Options, mdast::Node, message::Message};
7use alloc::string::String;
8
9/// Render an mdast tree or fragment as Markdown.
10///
11/// The default options produce standard Markdown. Use [`with_options`][Self::with_options]
12/// to configure markers and other formatting choices, or [`try_render`][Self::try_render]
13/// to handle invalid options without panicking.
14///
15/// # Example
16///
17/// ```
18/// use core_markdown::{mdast::Node, to_mdast, MarkdownRenderer, ParseOptions};
19///
20/// let mut tree = to_mdast("# Hello *world*!", &ParseOptions::default()).unwrap();
21/// if let Node::Heading(heading) = &mut tree.children_mut().unwrap()[0] {
22///     heading.depth = 2;
23/// }
24///
25/// let mut renderer = MarkdownRenderer::new();
26/// let markdown = tree.render_with(&mut renderer);
27/// assert_eq!(markdown, "## Hello *world*!\n");
28/// ```
29#[derive(Clone, Debug, Default)]
30pub struct MarkdownRenderer {
31    options: Options,
32}
33
34impl MarkdownRenderer {
35    /// Create a Markdown renderer with default options.
36    #[must_use]
37    pub fn new() -> Self {
38        Self::default()
39    }
40
41    /// Create a Markdown renderer with custom serialization options.
42    #[must_use]
43    pub fn with_options(options: Options) -> Self {
44        Self { options }
45    }
46
47    /// Return the options used by this renderer.
48    #[must_use]
49    pub fn options(&self) -> &Options {
50        &self.options
51    }
52
53    /// Render a node, returning an error if the options are invalid.
54    ///
55    /// # Errors
56    ///
57    /// Returns an error if an option contains an invalid marker or the AST
58    /// contains a node that cannot be serialized.
59    pub fn try_render(&mut self, node: &Node) -> Result<String, Message> {
60        crate::markdown::to_markdown_with_options(node, &self.options)
61    }
62}
63
64impl Renderer for MarkdownRenderer {
65    fn render_node(&mut self, node: &Node) -> String {
66        self.try_render(node)
67            .expect("Markdown rendering failed; use try_render to handle errors")
68    }
69}