#![allow(clippy::pedantic)]
pub use self::configure::{IndentOptions, LineWrapping, Options};
use self::state::{Info, State};
use crate::{message::Message, Document, NodeId, ParseOptions};
use alloc::string::String;
extern crate alloc;
mod configure;
mod construct_name;
mod escape;
mod handle;
mod state;
mod util;
pub fn normalize_markdown(source: &str) -> Result<String, Message> {
normalize_markdown_with_options(source, &ParseOptions::normalize())
}
pub fn normalize_markdown_with_options(
source: &str,
parse_options: &ParseOptions,
) -> Result<String, Message> {
let document = Document::parse(source, parse_options)
.expect("the built-in Markdown parser produces a valid document");
to_markdown_with_options(
&document,
&Options {
line_wrapping: LineWrapping::Unwrap,
..Options::default()
},
)
}
pub fn to_markdown<S: AsRef<str>>(document: &Document<S>) -> Result<String, Message> {
to_markdown_with_options(document, &Options::default())
}
pub fn to_markdown_with_options<S: AsRef<str>>(
document: &Document<S>,
options: &Options,
) -> Result<String, Message> {
to_markdown_node(document, document.root(), options)
}
pub fn to_markdown_node<S: AsRef<str>>(
document: &Document<S>,
node: NodeId,
options: &Options,
) -> Result<String, Message> {
if document.node(node).is_none() {
return Err(state::invalid_node());
}
let kind = &document.node(node).unwrap().kind;
let inline = state::is_phrasing(kind)
|| matches!(kind, crate::stream::EventKind::Opaque { block: false, .. });
let mut state = State::new(options);
state.serialization_root = Some(node);
let mut result = state.handle(document, node, &Info::new("\n", "\n"))?;
if result.contains('\r') {
result = result.replace("\r\n", "\n").replace('\r', "\n");
}
if !inline && !result.is_empty() && !result.ends_with('\n') {
result.push('\n');
}
Ok(result)
}