diff --git a/Cargo.toml b/Cargo.toml index e9101dbe..4054d45f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,7 +43,7 @@ shell-words = { version = "1.0", optional = true } slug = "0.1.4" emojis = { version = "0.6.2", optional = true } arbitrary = { version = "1", optional = true, features = ["derive"] } -bon = "3" +bon = { version = "3", optional = true } caseless = "0.2.1" [dev-dependencies] @@ -51,9 +51,10 @@ ntest = "0.9" toml = "0.7.3" [features] -default = ["cli", "syntect"] +default = ["cli", "syntect", "bon"] cli = ["clap", "shell-words", "xdg"] shortcodes = ["emojis"] +bon = ["dep:bon"] [target.'cfg(all(not(windows), not(target_arch="wasm32")))'.dependencies] xdg = { version = "^2.5", optional = true } diff --git a/src/lib.rs b/src/lib.rs index f3eab8cd..7d4ff8b1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -90,15 +90,19 @@ pub use html::Anchorizer; #[allow(deprecated)] pub use parser::parse_document_with_broken_link_callback; pub use parser::{ - parse_document, BrokenLinkCallback, BrokenLinkReference, ExtensionOptions, - ExtensionOptionsBuilder, ListStyleType, Options, ParseOptions, ParseOptionsBuilder, Plugins, - PluginsBuilder, RenderOptions, RenderOptionsBuilder, RenderPlugins, RenderPluginsBuilder, - ResolvedReference, URLRewriter, + parse_document, BrokenLinkCallback, BrokenLinkReference, ExtensionOptions, ListStyleType, + Options, ParseOptions, Plugins, RenderOptions, RenderPlugins, ResolvedReference, URLRewriter, }; pub use typed_arena::Arena; pub use xml::format_document as format_xml; pub use xml::format_document_with_plugins as format_xml_with_plugins; +#[cfg(feature = "bon")] +pub use parser::{ + ExtensionOptionsBuilder, ParseOptionsBuilder, PluginsBuilder, RenderOptionsBuilder, + RenderPluginsBuilder, +}; + /// Legacy naming of [`ExtensionOptions`] pub type ComrakExtensionOptions<'c> = ExtensionOptions<'c>; /// Legacy naming of [`Options`] diff --git a/src/parser/mod.rs b/src/parser/mod.rs index d3d11c1b..92372f84 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -18,7 +18,6 @@ use crate::nodes::{ }; use crate::scanners::{self, SetextChar}; use crate::strings::{self, split_off_front_matter, Case}; -use bon::Builder; use std::cell::RefCell; use std::cmp::min; use std::collections::HashMap; @@ -32,6 +31,9 @@ use typed_arena::Arena; use crate::adapters::HeadingAdapter; use crate::parser::multiline_block_quote::NodeMultilineBlockQuote; +#[cfg(feature = "bon")] +use bon::Builder; + use self::inlines::RefMap; const TAB_STOP: usize = 4; @@ -206,7 +208,8 @@ pub(crate) enum WikiLinksMode { } #[non_exhaustive] -#[derive(Default, Debug, Clone, Builder)] +#[derive(Default, Debug, Clone)] +#[cfg_attr(feature = "bon", derive(Builder))] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] /// Options to select extensions. pub struct ExtensionOptions<'c> { @@ -221,7 +224,7 @@ pub struct ExtensionOptions<'c> { /// assert_eq!(markdown_to_html("Hello ~world~ there.\n", &options), /// "

Hello world there.

\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub strikethrough: bool, /// Enables the @@ -236,7 +239,7 @@ pub struct ExtensionOptions<'c> { /// assert_eq!(markdown_to_html("Hello .\n\n<xmp>", &options), /// "<p>Hello &lt;xmp>.</p>\n&lt;xmp>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub tagfilter: bool, /// Enables the [table extension](https://github.github.com/gfm/#tables-extension-) @@ -250,7 +253,7 @@ pub struct ExtensionOptions<'c> { /// "<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n</tr>\n</thead>\n\ /// <tbody>\n<tr>\n<td>c</td>\n<td>d</td>\n</tr>\n</tbody>\n</table>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub table: bool, /// Enables the [autolink extension](https://github.github.com/gfm/#autolinks-extension-) @@ -263,7 +266,7 @@ pub struct ExtensionOptions<'c> { /// assert_eq!(markdown_to_html("Hello www.github.com.\n", &options), /// "<p>Hello <a href=\"http://www.github.com\">www.github.com</a>.</p>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub autolink: bool, /// Enables the @@ -282,7 +285,7 @@ pub struct ExtensionOptions<'c> { /// "<ul>\n<li><input type=\"checkbox\" checked=\"\" disabled=\"\" /> Done</li>\n\ /// <li><input type=\"checkbox\" disabled=\"\" /> Not done</li>\n</ul>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub tasklist: bool, /// Enables the superscript Comrak extension. @@ -294,7 +297,7 @@ pub struct ExtensionOptions<'c> { /// assert_eq!(markdown_to_html("e = mc^2^.\n", &options), /// "<p>e = mc<sup>2</sup>.</p>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub superscript: bool, /// Enables the header IDs Comrak extension. @@ -320,7 +323,7 @@ pub struct ExtensionOptions<'c> { /// assert_eq!(markdown_to_html("Hi[^x].\n\n[^x]: A greeting.\n", &options), /// "<p>Hi<sup class=\"footnote-ref\"><a href=\"#fn-x\" id=\"fnref-x\" data-footnote-ref>1</a></sup>.</p>\n<section class=\"footnotes\" data-footnotes>\n<ol>\n<li id=\"fn-x\">\n<p>A greeting. <a href=\"#fnref-x\" class=\"footnote-backref\" data-footnote-backref data-footnote-backref-idx=\"1\" aria-label=\"Back to reference 1\">↩</a></p>\n</li>\n</ol>\n</section>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub footnotes: bool, /// Enables the description lists extension. @@ -349,7 +352,7 @@ pub struct ExtensionOptions<'c> { /// assert_eq!(markdown_to_html("Term\n\n: Definition", &options), /// "<dl>\n<dt>Term</dt>\n<dd>\n<p>Definition</p>\n</dd>\n</dl>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub description_lists: bool, /// Enables the front matter extension. @@ -415,7 +418,7 @@ pub struct ExtensionOptions<'c> { /// assert_eq!(markdown_to_html(">>>\nparagraph\n>>>", &options), /// "<blockquote>\n<p>paragraph</p>\n</blockquote>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub multiline_block_quotes: bool, /// Enables math using dollar syntax. @@ -437,7 +440,7 @@ pub struct ExtensionOptions<'c> { /// assert_eq!(markdown_to_html("$$\nx^2\n$$\n", &options), /// "<p><span data-math-style=\"display\">\nx^2\n</span></p>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub math_dollars: bool, /// Enables math using code syntax. @@ -459,7 +462,7 @@ pub struct ExtensionOptions<'c> { /// assert_eq!(markdown_to_html("```math\nx^2\n```\n", &options), /// "<pre><code class=\"language-math\" data-math-style=\"display\">x^2\n</code></pre>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub math_code: bool, #[cfg(feature = "shortcodes")] @@ -476,7 +479,7 @@ pub struct ExtensionOptions<'c> { /// assert_eq!(markdown_to_html("Happy Friday! :smile:", &options), /// "<p>Happy Friday! 😄</p>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub shortcodes: bool, /// Enables wikilinks using title after pipe syntax @@ -497,7 +500,7 @@ pub struct ExtensionOptions<'c> { /// assert_eq!(markdown_to_html("[[url|link label]]", &options), /// "<p><a href=\"url\" data-wikilink=\"true\">link label</a></p>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub wikilinks_title_after_pipe: bool, /// Enables wikilinks using title before pipe syntax @@ -517,7 +520,7 @@ pub struct ExtensionOptions<'c> { /// assert_eq!(markdown_to_html("[[link label|url]]", &options), /// "<p><a href=\"url\" data-wikilink=\"true\">link label</a></p>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub wikilinks_title_before_pipe: bool, /// Enables underlines using double underscores @@ -534,7 +537,7 @@ pub struct ExtensionOptions<'c> { /// assert_eq!(markdown_to_html("__underlined text__", &options), /// "<p><u>underlined text</u></p>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub underline: bool, /// Enables subscript text using single tildes. @@ -554,7 +557,7 @@ pub struct ExtensionOptions<'c> { /// assert_eq!(markdown_to_html("H~2~O", &options), /// "<p>H<sub>2</sub>O</p>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub subscript: bool, /// Enables spoilers using double vertical bars @@ -571,7 +574,7 @@ pub struct ExtensionOptions<'c> { /// assert_eq!(markdown_to_html("Darth Vader is ||Luke's father||", &options), /// "<p>Darth Vader is <span class=\"spoiler\">Luke's father</span></p>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub spoiler: bool, /// Requires at least one space after a `>` character to generate a blockquote, @@ -601,7 +604,7 @@ pub struct ExtensionOptions<'c> { /// "<p>three</p>\n", /// "</blockquote>\n")); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub greentext: bool, /// Wraps embedded image URLs using a function or custom trait object. @@ -653,7 +656,8 @@ impl<'c> ExtensionOptions<'c> { } #[non_exhaustive] -#[derive(Default, Clone, Debug, Builder)] +#[derive(Default, Clone, Debug)] +#[cfg_attr(feature = "bon", derive(Builder))] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] /// Options for parser functions. pub struct ParseOptions<'c> { @@ -669,7 +673,7 @@ pub struct ParseOptions<'c> { /// assert_eq!(markdown_to_html("'Hello,' \"world\" ...", &options), /// "<p>‘Hello,’ “world” …</p>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub smart: bool, /// The default info string for fenced code blocks. @@ -687,7 +691,7 @@ pub struct ParseOptions<'c> { pub default_info_string: Option<String>, /// Whether or not a simple `x` or `X` is used for tasklist or any other symbol is allowed. - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub relaxed_tasklist_matching: bool, /// Relax parsing of autolinks, allow links to be detected inside brackets @@ -705,7 +709,7 @@ pub struct ParseOptions<'c> { /// assert_eq!(markdown_to_html("[https://foo.com]", &options), /// "<p>[<a href=\"https://foo.com\">https://foo.com</a>]</p>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub relaxed_autolinks: bool, /// In case the parser encounters any potential links that have a broken @@ -742,7 +746,8 @@ pub struct ParseOptions<'c> { } #[non_exhaustive] -#[derive(Default, Debug, Clone, Copy, Builder)] +#[derive(Default, Debug, Clone, Copy)] +#[cfg_attr(feature = "bon", derive(Builder))] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] /// Options for formatter functions. pub struct RenderOptions { @@ -759,7 +764,7 @@ pub struct RenderOptions { /// assert_eq!(markdown_to_html("Hello.\nWorld.\n", &options), /// "<p>Hello.<br />\nWorld.</p>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub hardbreaks: bool, /// GitHub-style `<pre lang="xyz">` is used for fenced code blocks with info tags. @@ -774,7 +779,7 @@ pub struct RenderOptions { /// assert_eq!(markdown_to_html("``` rust\nfn hello();\n```\n", &options), /// "<pre lang=\"rust\"><code>fn hello();\n</code></pre>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub github_pre_lang: bool, /// Enable full info strings for code blocks @@ -789,7 +794,7 @@ pub struct RenderOptions { /// let html = markdown_to_html("``` rust extra info\nfn hello();\n```\n", &options); /// assert!(html.contains(r#"data-meta="extra info""#)); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub full_info_string: bool, /// The wrap column when outputting CommonMark. @@ -812,7 +817,7 @@ pub struct RenderOptions { /// "hello hello hello\nhello hello hello\n"); /// # } /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub width: usize, /// Allow rendering of raw HTML and potentially dangerous links. @@ -838,7 +843,7 @@ pub struct RenderOptions { /// <p><a href=\"javascript:alert(document.cookie)\">Dangerous</a>.</p>\n\ /// <p><a href=\"http://commonmark.org\">Safe</a>.</p>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub unsafe_: bool, /// Escape raw HTML instead of clobbering it. @@ -854,7 +859,7 @@ pub struct RenderOptions { /// assert_eq!(markdown_to_html(input, &options), /// "<p>&lt;i&gt;italic text&lt;/i&gt;</p>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub escape: bool, /// Set the type of [bullet list marker](https://spec.commonmark.org/0.30/#bullet-list-marker) to use. Options are: @@ -878,7 +883,7 @@ pub struct RenderOptions { /// assert_eq!(markdown_to_commonmark(input, &options), /// "* one\n* two\n* three\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub list_style: ListStyleType, /// Include source position attributes in HTML and XML output. @@ -901,7 +906,7 @@ pub struct RenderOptions { /// ``` /// /// [`experimental_inline_sourcepos`]: crate::RenderOptionsBuilder::experimental_inline_sourcepos - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub sourcepos: bool, /// Include inline sourcepos in HTML output, which is known to have issues. @@ -917,7 +922,7 @@ pub struct RenderOptions { /// assert_eq!(markdown_to_html(input, &options), /// "<p data-sourcepos=\"1:1-1:14\">Hello <em data-sourcepos=\"1:7-1:13\">world</em>!</p>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub experimental_inline_sourcepos: bool, /// Wrap escaped characters in a `<span>` to allow any @@ -935,7 +940,7 @@ pub struct RenderOptions { /// assert_eq!(markdown_to_html(input, &options), /// "<p>Notify user <span data-escaped-char>@</span>example</p>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub escaped_char_spans: bool, /// Ignore setext headings in input. @@ -952,7 +957,7 @@ pub struct RenderOptions { /// assert_eq!(markdown_to_html(input, &options), /// "<p>setext heading</p>\n<hr />\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub ignore_setext: bool, /// Ignore empty links in input. @@ -968,7 +973,7 @@ pub struct RenderOptions { /// options.render.ignore_empty_links = true; /// assert_eq!(markdown_to_html(input, &options), "<p>[]()</p>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub ignore_empty_links: bool, /// Enables GFM quirks in HTML output which break CommonMark compatibility. @@ -985,7 +990,7 @@ pub struct RenderOptions { /// assert_eq!(markdown_to_html(input, &options), /// "<p><strong>abcd</strong> <em><em>foo</em></em></p>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub gfm_quirks: bool, /// Prefer fenced code blocks when outputting CommonMark. @@ -1007,7 +1012,7 @@ pub struct RenderOptions { /// format_commonmark(&root, &options, &mut buf); /// assert_eq!(str::from_utf8(&buf).unwrap(), "```\nhello\n```\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub prefer_fenced: bool, /// Render the image as a figure element with the title as its caption. @@ -1024,7 +1029,7 @@ pub struct RenderOptions { /// assert_eq!(markdown_to_html(input, &options), /// "<p><figure><img src=\"https://example.com/image.png\" alt=\"image\" title=\"this is an image\" /><figcaption>this is an image</figcaption></figure></p>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub figure_with_caption: bool, /// Add classes to the output of the tasklist extension. This allows tasklists to be styled. @@ -1042,7 +1047,7 @@ pub struct RenderOptions { /// assert_eq!(markdown_to_html(input, &options), /// "<ul class=\"contains-task-list\">\n<li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"\" /> Foo</li>\n</ul>\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub tasklist_classes: bool, /// Render ordered list with a minimum marker width. @@ -1060,21 +1065,23 @@ pub struct RenderOptions { /// assert_eq!(markdown_to_commonmark(input, &options), /// "1. Something\n"); /// ``` - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub ol_width: usize, } #[non_exhaustive] -#[derive(Default, Debug, Clone, Builder)] +#[derive(Default, Debug, Clone)] +#[cfg_attr(feature = "bon", derive(Builder))] /// Umbrella plugins struct. pub struct Plugins<'p> { /// Configure render-time plugins. - #[builder(default)] + #[cfg_attr(feature = "bon", builder(default))] pub render: RenderPlugins<'p>, } #[non_exhaustive] -#[derive(Default, Clone, Builder)] +#[derive(Default, Clone)] +#[cfg_attr(feature = "bon", derive(Builder))] /// Plugins for alternative rendering. pub struct RenderPlugins<'p> { /// Provide a syntax highlighter adapter implementation for syntax