Skip to main content

socketry_markdown/markdown/
mod.rs

1// Released under the MIT License.
2// Copyright, 2024, by Bnchi.
3// Copyright, 2024, by Titus Wormer.
4// Copyright, 2026, by Samuel Williams.
5
6//! API.
7//!
8//! JS equivalent: https://github.com/syntax-tree/mdast-util-to-markdown/blob/main/lib/index.js.
9
10// This serializer is ported from `mdast-util-to-markdown`; retain its established
11// implementation while keeping the parser's stricter lints on the surrounding API.
12#![allow(clippy::pedantic)]
13
14pub use self::configure::{IndentOptions, Options};
15use self::state::{Info, State};
16use crate::{mdast::Node, message::Message};
17use alloc::string::String;
18
19extern crate alloc;
20mod association;
21mod configure;
22mod construct_name;
23mod handle;
24mod state;
25mod r#unsafe;
26mod util;
27
28/// Turn an mdast syntax tree into markdown.
29///
30/// # Errors
31///
32/// Returns an error if the AST contains a node that cannot be serialized.
33pub fn to_markdown(tree: &Node) -> Result<String, Message> {
34    to_markdown_with_options(tree, &Options::default())
35}
36
37/// Turn an mdast syntax tree, with options, into markdown.
38///
39/// # Errors
40///
41/// Returns an error if an option contains an invalid marker or the AST contains
42/// a node that cannot be serialized.
43pub fn to_markdown_with_options(tree: &Node, options: &Options) -> Result<String, Message> {
44    let mut state = State::new(options);
45    let mut result = state.handle(tree, &Info::new("\n", "\n"), None)?;
46
47    if !result.is_empty() {
48        let last_char = result.chars().last().unwrap();
49        if last_char != '\n' && last_char != '\r' {
50            result.push('\n');
51        }
52    }
53
54    Ok(result)
55}