markdown/lib.rs
1//! Public API of `markdown-rs`.
2//!
3//! This module exposes primarily [`to_html()`][].
4//! It also exposes [`to_html_with_options()`][] and [`to_mdast()`][].
5//!
6//! * [`to_html()`][]
7//! — safe way to transform (untrusted?) markdown into HTML
8//! * [`to_html_with_options()`][]
9//! — like `to_html` but lets you configure how markdown is turned into
10//! HTML, such as allowing dangerous HTML or turning on/off different
11//! constructs (GFM, MDX, and the like)
12//! * [`to_mdast()`][]
13//! — turn markdown into a syntax tree
14//!
15//! ## Features
16//!
17//! * **`default`**
18//! — nothing is enabled by default
19//! * **`log`**
20//! — enable logging (includes `dep:log`);
21//! you can show logs with `RUST_LOG=debug`
22//! * **`serde`**
23//! — enable serde to serialize ASTs and configuration (includes `dep:serde`)
24
25#![no_std]
26#![deny(clippy::pedantic)]
27#![allow(clippy::doc_link_with_quotes)]
28#![allow(clippy::missing_panics_doc)]
29#![allow(clippy::must_use_candidate)]
30#![allow(clippy::too_many_lines)]
31#![allow(clippy::result_large_err)]
32#![doc(
33 html_logo_url = "https://raw.githubusercontent.com/wooorm/markdown-rs/8924580/media/logo-monochromatic.svg?sanitize=true"
34)]
35
36extern crate alloc;
37mod configuration;
38mod construct;
39mod event;
40mod parser;
41mod resolve;
42mod state;
43mod subtokenize;
44mod to_html;
45mod to_mdast;
46mod tokenizer;
47mod util;
48
49pub mod mdast; // To do: externalize?
50pub mod message; // To do: externalize.
51pub mod unist; // To do: externalize.
52
53#[doc(hidden)]
54pub use util::character_reference::{decode_named, decode_numeric};
55
56#[doc(hidden)]
57pub use util::identifier::{id_cont, id_start};
58
59#[doc(hidden)]
60pub use util::sanitize_uri::sanitize;
61
62#[doc(hidden)]
63pub use util::location::Location;
64
65pub use util::line_ending::LineEnding;
66
67pub use util::mdx::{
68 EsmParse as MdxEsmParse, ExpressionKind as MdxExpressionKind,
69 ExpressionParse as MdxExpressionParse, Signal as MdxSignal,
70};
71
72pub use configuration::{CompileOptions, Constructs, Options, ParseOptions};
73
74use alloc::string::String;
75
76/// Turn markdown into HTML.
77///
78/// Compiles markdown to HTML according to `CommonMark`.
79/// Use [`to_html_with_options()`][] to configure how markdown is turned into
80/// HTML.
81///
82/// ## Examples
83///
84/// ```
85/// use markdown::to_html;
86///
87/// assert_eq!(to_html("# Hi Mercury!"), "<h1>Hi Mercury!</h1>");
88/// ```
89pub fn to_html(value: &str) -> String {
90 to_html_with_options(value, &Options::default()).unwrap()
91}
92
93/// Turn markdown into HTML, with configuration.
94///
95/// ## Errors
96///
97/// `to_html_with_options()` never errors with normal markdown because markdown
98/// does not have syntax errors, so feel free to `unwrap()`.
99/// However, MDX does have syntax errors.
100/// When MDX is turned on, there are several errors that can occur with how
101/// expressions, ESM, and JSX are written.
102///
103/// ## Examples
104///
105/// ```
106/// use markdown::{to_html_with_options, CompileOptions, Options};
107/// # fn main() -> Result<(), markdown::message::Message> {
108///
109/// // Use GFM:
110/// let result = to_html_with_options("~Venus~Mars!", &Options::gfm())?;
111///
112/// assert_eq!(result, "<p><del>Venus</del>Mars!</p>");
113///
114/// // Live dangerously / trust the author:
115/// let result = to_html_with_options("<div>\n\n# Hi Jupiter!\n\n</div>", &Options {
116/// compile: CompileOptions {
117/// allow_dangerous_html: true,
118/// allow_dangerous_protocol: true,
119/// ..CompileOptions::default()
120/// },
121/// ..Options::default()
122/// })?;
123///
124/// assert_eq!(result, "<div>\n<h1>Hi Jupiter!</h1>\n</div>");
125/// # Ok(())
126/// # }
127/// ```
128pub fn to_html_with_options(value: &str, options: &Options) -> Result<String, message::Message> {
129 let (events, parse_state) = parser::parse(value, &options.parse)?;
130 Ok(to_html::compile(
131 &events,
132 parse_state.bytes,
133 &options.compile,
134 ))
135}
136
137/// Turn markdown into a syntax tree.
138///
139/// ## Errors
140///
141/// `to_mdast()` never errors with normal markdown because markdown does not
142/// have syntax errors, so feel free to `unwrap()`.
143/// However, MDX does have syntax errors.
144/// When MDX is turned on, there are several errors that can occur with how
145/// JSX, expressions, or ESM are written.
146///
147/// ## Examples
148///
149/// ```
150/// use markdown::{to_mdast, ParseOptions};
151/// # fn main() -> Result<(), markdown::message::Message> {
152///
153/// let tree = to_mdast("# Hi *Earth*!", &ParseOptions::default())?;
154///
155/// println!("{:?}", tree);
156/// // => Root { children: [Heading { children: [Text { value: "Hi ", position: Some(1:3-1:6 (2-5)) }, Emphasis { children: [Text { value: "Earth", position: Some(1:7-1:12 (6-11)) }], position: Some(1:6-1:13 (5-12)) }, Text { value: "!", position: Some(1:13-1:14 (12-13)) }], position: Some(1:1-1:14 (0-13)), depth: 1 }], position: Some(1:1-1:14 (0-13)) }
157/// # Ok(())
158/// # }
159/// ```
160pub fn to_mdast(value: &str, options: &ParseOptions) -> Result<mdast::Node, message::Message> {
161 let (events, parse_state) = parser::parse(value, options)?;
162 let node = to_mdast::compile(&events, parse_state.bytes)?;
163 Ok(node)
164}