[go: up one dir, main page]

comrak/
lib.rs

1//! A 100% [CommonMark](http://commonmark.org/) and [GFM](https://github.github.com/gfm/)
2//! compatible Markdown parser.
3//!
4//! Source repository and detailed `README` is at <https://github.com/kivikakk/comrak>.
5//!
6//! You can use `comrak::markdown_to_html` directly:
7//!
8//! ```
9//! use comrak::{markdown_to_html, Options};
10//! assert_eq!(markdown_to_html("Hello, **世界**!", &Options::default()),
11//!            "<p>Hello, <strong>世界</strong>!</p>\n");
12//! ```
13//!
14//! Or you can parse the input into an AST yourself, manipulate it, and then use your desired
15//! formatter:
16//!
17//! ```
18//! use comrak::{Arena, parse_document, format_html, Options};
19//! use comrak::nodes::{AstNode, NodeValue};
20//!
21//! # fn main() {
22//! let arena = Arena::new();
23//!
24//! let root = parse_document(
25//!     &arena,
26//!     "This is my input.\n\n1. Also [my](#) input.\n2. Certainly *my* input.\n",
27//!     &Options::default());
28//!
29//! for node in root.descendants() {
30//!     if let NodeValue::Text(ref mut text) = node.data.borrow_mut().value {
31//!         *text = text.replace("my", "your");
32//!     }
33//! }
34//!
35//! let mut html = vec![];
36//! format_html(root, &Options::default(), &mut html).unwrap();
37//!
38//! assert_eq!(
39//!     String::from_utf8(html).unwrap(),
40//!     "<p>This is your input.</p>\n\
41//!      <ol>\n\
42//!      <li>Also <a href=\"#\">your</a> input.</li>\n\
43//!      <li>Certainly <em>your</em> input.</li>\n\
44//!      </ol>\n");
45//! # }
46//! ```
47
48#![cfg_attr(docsrs, feature(doc_cfg))]
49#![deny(
50    missing_docs,
51    missing_debug_implementations,
52    missing_copy_implementations,
53    trivial_casts,
54    trivial_numeric_casts,
55    unstable_features,
56    unused_import_braces
57)]
58#![allow(
59    unknown_lints,
60    clippy::doc_markdown,
61    cyclomatic_complexity,
62    clippy::bool_to_int_with_if,
63    clippy::too_many_arguments
64)]
65
66use std::io::BufWriter;
67
68pub mod adapters;
69pub mod arena_tree;
70mod character_set;
71mod cm;
72mod ctype;
73mod entity;
74pub mod html;
75pub mod nodes;
76mod parser;
77pub mod plugins;
78mod scanners;
79mod strings;
80#[cfg(test)]
81mod tests;
82mod xml;
83
84pub use cm::escape_inline as escape_commonmark_inline;
85pub use cm::escape_link_destination as escape_commonmark_link_destination;
86pub use cm::format_document as format_commonmark;
87pub use cm::format_document_with_plugins as format_commonmark_with_plugins;
88pub use html::format_document as format_html;
89pub use html::format_document_with_plugins as format_html_with_plugins;
90#[doc(inline)]
91pub use html::Anchorizer;
92#[allow(deprecated)]
93pub use parser::parse_document_with_broken_link_callback;
94pub use parser::{
95    parse_document, BrokenLinkCallback, BrokenLinkReference, ExtensionOptions, ListStyleType,
96    Options, ParseOptions, Plugins, RenderOptions, RenderPlugins, ResolvedReference, URLRewriter,
97    WikiLinksMode,
98};
99pub use typed_arena::Arena;
100pub use xml::format_document as format_xml;
101pub use xml::format_document_with_plugins as format_xml_with_plugins;
102
103#[cfg(feature = "bon")]
104pub use parser::{
105    ExtensionOptionsBuilder, ParseOptionsBuilder, PluginsBuilder, RenderOptionsBuilder,
106    RenderPluginsBuilder,
107};
108
109/// Legacy naming of [`ExtensionOptions`]
110pub type ComrakExtensionOptions<'c> = ExtensionOptions<'c>;
111/// Legacy naming of [`Options`]
112pub type ComrakOptions<'c> = Options<'c>;
113/// Legacy naming of [`ParseOptions`]
114pub type ComrakParseOptions<'c> = ParseOptions<'c>;
115/// Legacy naming of [`Plugins`]
116pub type ComrakPlugins<'a> = Plugins<'a>;
117/// Legacy naming of [`RenderOptions`]
118pub type ComrakRenderOptions = RenderOptions;
119/// Legacy naming of [`RenderPlugins`]
120pub type ComrakRenderPlugins<'a> = RenderPlugins<'a>;
121
122/// Render Markdown to HTML.
123///
124/// See the documentation of the crate root for an example.
125pub fn markdown_to_html(md: &str, options: &Options) -> String {
126    markdown_to_html_with_plugins(md, options, &Plugins::default())
127}
128
129/// Render Markdown to HTML using plugins.
130///
131/// See the documentation of the crate root for an example.
132pub fn markdown_to_html_with_plugins(md: &str, options: &Options, plugins: &Plugins) -> String {
133    let arena = Arena::new();
134    let root = parse_document(&arena, md, options);
135    let mut bw = BufWriter::new(Vec::new());
136    format_html_with_plugins(root, options, &mut bw, plugins).unwrap();
137    String::from_utf8(bw.into_inner().unwrap()).unwrap()
138}
139
140/// Return the version of the crate.
141pub fn version() -> &'static str {
142    env!("CARGO_PKG_VERSION")
143}
144
145/// Render Markdown back to CommonMark.
146pub fn markdown_to_commonmark(md: &str, options: &Options) -> String {
147    let arena = Arena::new();
148    let root = parse_document(&arena, md, options);
149    let mut bw = BufWriter::new(Vec::new());
150    format_commonmark(root, options, &mut bw).unwrap();
151    String::from_utf8(bw.into_inner().unwrap()).unwrap()
152}
153
154/// Render Markdown to CommonMark XML.
155/// See <https://github.com/commonmark/commonmark-spec/blob/master/CommonMark.dtd>.
156pub fn markdown_to_commonmark_xml(md: &str, options: &Options) -> String {
157    markdown_to_commonmark_xml_with_plugins(md, options, &Plugins::default())
158}
159
160/// Render Markdown to CommonMark XML using plugins.
161/// See <https://github.com/commonmark/commonmark-spec/blob/master/CommonMark.dtd>.
162pub fn markdown_to_commonmark_xml_with_plugins(
163    md: &str,
164    options: &Options,
165    plugins: &Plugins,
166) -> String {
167    let arena = Arena::new();
168    let root = parse_document(&arena, md, options);
169    let mut bw = BufWriter::new(Vec::new());
170    format_xml_with_plugins(root, options, &mut bw, plugins).unwrap();
171    String::from_utf8(bw.into_inner().unwrap()).unwrap()
172}