pub struct CompileOptions {
pub allow_any_img_src: bool,
pub allow_dangerous_html: bool,
pub allow_dangerous_protocol: bool,
pub default_line_ending: LineEnding,
pub gfm_footnote_back_label: Option<String>,
pub gfm_footnote_clobber_prefix: Option<String>,
pub gfm_footnote_label_attributes: Option<String>,
pub gfm_footnote_label_tag_name: Option<String>,
pub gfm_footnote_label: Option<String>,
pub gfm_task_list_item_checkable: bool,
pub gfm_tagfilter: bool,
pub heading_ids: bool,
}Expand description
Configuration that describes how to compile to HTML.
You likely either want to turn on the dangerous options
(allow_dangerous_html, allow_dangerous_protocol) when dealing with
input you trust, or want to customize how GFM footnotes are compiled
(typically because the input markdown is not in English).
§Examples
use socketry_markdown::CompileOptions;
// Use the default trait to get safe defaults:
let safe = CompileOptions::default();
// Live dangerously / trust the author:
let danger = CompileOptions {
allow_dangerous_html: true,
allow_dangerous_protocol: true,
..CompileOptions::default()
};
// In French:
let enFrançais = CompileOptions {
gfm_footnote_back_label: Some("Arrière".into()),
gfm_footnote_label: Some("Notes de bas de page".into()),
..CompileOptions::default()
};Fields§
§allow_any_img_src: boolWhether to allow all values in images.
The default is false,
which lets allow_dangerous_protocol control protocol safety for
both links and images.
Pass true to allow all values as src on images,
regardless of allow_dangerous_protocol.
This is safe because the
HTML specification
does not allow executable code in images.
§Examples
use socketry_markdown::{to_html_with_options, CompileOptions, Options};
// By default, some protocols in image sources are dropped:
assert_eq!(
to_html_with_options(
"",
&Options::default()
)?,
"<p><img src=\"\" alt=\"\" /></p>"
);
// Turn `allow_any_img_src` on to allow all values as `src` on images.
// This is safe because browsers do not execute code in images.
assert_eq!(
to_html_with_options(
")",
&Options {
compile: CompileOptions {
allow_any_img_src: true,
..CompileOptions::default()
},
..Options::default()
}
)?,
"<p><img src=\"javascript:alert(1)\" alt=\"\" /></p>"
);allow_dangerous_html: boolWhether to allow (dangerous) HTML.
The default is false, which still parses the HTML according to
CommonMark but shows the HTML as text instead of as elements.
Pass true for trusted content to get actual HTML elements.
When using GFM, make sure to also turn off gfm_tagfilter.
Otherwise, some dangerous HTML is still ignored.
§Examples
use socketry_markdown::{to_html, to_html_with_options, CompileOptions, Options};
// `markdown-rs` is safe by default:
assert_eq!(
to_html("Hi, <i>venus</i>!"),
"<p>Hi, <i>venus</i>!</p>"
);
// Turn `allow_dangerous_html` on to allow potentially dangerous HTML:
assert_eq!(
to_html_with_options(
"Hi, <i>venus</i>!",
&Options {
compile: CompileOptions {
allow_dangerous_html: true,
..CompileOptions::default()
},
..Options::default()
}
)?,
"<p>Hi, <i>venus</i>!</p>"
);allow_dangerous_protocol: boolWhether to allow dangerous protocols in links and images.
The default is false, which drops URLs in links and images that use
dangerous protocols.
Pass true for trusted content to support all protocols.
URLs that have no protocol (which means it’s relative to the current
page, such as ./some/page.html) and URLs that have a safe protocol
(for images: http, https; for links: http, https, irc,
ircs, mailto, xmpp), are safe.
All other URLs are dangerous and dropped.
When the option allow_all_protocols_in_img is enabled,
allow_dangerous_protocol only applies to links.
This is safe because the HTML specification does not allow executable code in images. All modern browsers respect this.
§Examples
use socketry_markdown::{to_html, to_html_with_options, CompileOptions, Options};
// `markdown-rs` is safe by default:
assert_eq!(
to_html("<javascript:alert(1)>"),
"<p><a href=\"\">javascript:alert(1)</a></p>"
);
// Turn `allow_dangerous_protocol` on to allow potentially dangerous protocols:
assert_eq!(
to_html_with_options(
"<javascript:alert(1)>",
&Options {
compile: CompileOptions {
allow_dangerous_protocol: true,
..CompileOptions::default()
},
..Options::default()
}
)?,
"<p><a href=\"javascript:alert(1)\">javascript:alert(1)</a></p>"
);default_line_ending: LineEndingDefault line ending to use when compiling to HTML, for line endings not
in value.
Generally, markdown-rs copies line endings (\r, \n, \r\n) in
the markdown document over to the compiled HTML.
In some cases, such as > a, CommonMark requires that extra line
endings are added: <blockquote>\n<p>a</p>\n</blockquote>.
To create that line ending, the document is checked for the first line
ending that is used.
If there is no line ending, default_line_ending is used.
If that isn’t configured, \n is used.
§Examples
use socketry_markdown::{to_html, to_html_with_options, CompileOptions, LineEnding, Options};
// `markdown-rs` uses `\n` by default:
assert_eq!(
to_html("> a"),
"<blockquote>\n<p>a</p>\n</blockquote>"
);
// Define `default_line_ending` to configure the default:
assert_eq!(
to_html_with_options(
"> a",
&Options {
compile: CompileOptions {
default_line_ending: LineEnding::CarriageReturnLineFeed,
..CompileOptions::default()
},
..Options::default()
}
)?,
"<blockquote>\r\n<p>a</p>\r\n</blockquote>"
);gfm_footnote_back_label: Option<String>Textual label to describe the backreference back to footnote calls.
The default value is "Back to content".
Change it when the markdown is not in English.
This label is used in the aria-label attribute on each backreference
(the ↩ links).
It affects users of assistive technology.
§Examples
use socketry_markdown::{to_html_with_options, CompileOptions, Options, ParseOptions};
// `"Back to content"` is used by default:
assert_eq!(
to_html_with_options(
"[^a]\n\n[^a]: b",
&Options::gfm()
)?,
"<p><sup><a href=\"#user-content-fn-a\" id=\"user-content-fnref-a\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup></p>\n<section data-footnotes=\"\" class=\"footnotes\"><h2 id=\"footnote-label\" class=\"sr-only\">Footnotes</h2>\n<ol>\n<li id=\"user-content-fn-a\">\n<p>b <a href=\"#user-content-fnref-a\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩</a></p>\n</li>\n</ol>\n</section>\n"
);
// Pass `gfm_footnote_back_label` to use something else:
assert_eq!(
to_html_with_options(
"[^a]\n\n[^a]: b",
&Options {
parse: ParseOptions::gfm(),
compile: CompileOptions {
gfm_footnote_back_label: Some("Arrière".into()),
..CompileOptions::gfm()
}
}
)?,
"<p><sup><a href=\"#user-content-fn-a\" id=\"user-content-fnref-a\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup></p>\n<section data-footnotes=\"\" class=\"footnotes\"><h2 id=\"footnote-label\" class=\"sr-only\">Footnotes</h2>\n<ol>\n<li id=\"user-content-fn-a\">\n<p>b <a href=\"#user-content-fnref-a\" data-footnote-backref=\"\" aria-label=\"Arrière\" class=\"data-footnote-backref\">↩</a></p>\n</li>\n</ol>\n</section>\n"
);gfm_footnote_clobber_prefix: Option<String>Prefix to use before the id attribute on footnotes to prevent them
from clobbering.
The default is "user-content-".
Pass Some("".into()) for trusted markdown and when you are careful
with polyfilling.
You could pass a different prefix.
DOM clobbering is this:
<p id="x"></p>
<script>alert(x) // `x` now refers to the `p#x` DOM element</script>The above example shows that elements are made available by browsers,
by their ID, on the window object.
This is a security risk because you might be expecting some other
variable at that place.
It can also break polyfills.
Using a prefix solves these problems.
§Examples
use socketry_markdown::{to_html_with_options, CompileOptions, Options, ParseOptions};
// `"user-content-"` is used by default:
assert_eq!(
to_html_with_options(
"[^a]\n\n[^a]: b",
&Options::gfm()
)?,
"<p><sup><a href=\"#user-content-fn-a\" id=\"user-content-fnref-a\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup></p>\n<section data-footnotes=\"\" class=\"footnotes\"><h2 id=\"footnote-label\" class=\"sr-only\">Footnotes</h2>\n<ol>\n<li id=\"user-content-fn-a\">\n<p>b <a href=\"#user-content-fnref-a\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩</a></p>\n</li>\n</ol>\n</section>\n"
);
// Pass `gfm_footnote_clobber_prefix` to use something else:
assert_eq!(
to_html_with_options(
"[^a]\n\n[^a]: b",
&Options {
parse: ParseOptions::gfm(),
compile: CompileOptions {
gfm_footnote_clobber_prefix: Some("".into()),
..CompileOptions::gfm()
}
}
)?,
"<p><sup><a href=\"#fn-a\" id=\"fnref-a\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup></p>\n<section data-footnotes=\"\" class=\"footnotes\"><h2 id=\"footnote-label\" class=\"sr-only\">Footnotes</h2>\n<ol>\n<li id=\"fn-a\">\n<p>b <a href=\"#fnref-a\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩</a></p>\n</li>\n</ol>\n</section>\n"
);gfm_footnote_label_attributes: Option<String>Attributes to use on the footnote label.
The default value is "class=\"sr-only\"".
Change it to show the label and add other attributes.
This label is typically hidden visually (assuming a sr-only CSS class
is defined that does that), and thus affects screen readers only.
If you do have such a class, but want to show this section to everyone,
pass an empty string.
You can also add different attributes.
👉 Note:
id="footnote-label"is always added, because footnote calls use it witharia-describedbyto provide an accessible label.
§Examples
use socketry_markdown::{to_html_with_options, CompileOptions, Options, ParseOptions};
// `"class=\"sr-only\""` is used by default:
assert_eq!(
to_html_with_options(
"[^a]\n\n[^a]: b",
&Options::gfm()
)?,
"<p><sup><a href=\"#user-content-fn-a\" id=\"user-content-fnref-a\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup></p>\n<section data-footnotes=\"\" class=\"footnotes\"><h2 id=\"footnote-label\" class=\"sr-only\">Footnotes</h2>\n<ol>\n<li id=\"user-content-fn-a\">\n<p>b <a href=\"#user-content-fnref-a\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩</a></p>\n</li>\n</ol>\n</section>\n"
);
// Pass `gfm_footnote_label_attributes` to use something else:
assert_eq!(
to_html_with_options(
"[^a]\n\n[^a]: b",
&Options {
parse: ParseOptions::gfm(),
compile: CompileOptions {
gfm_footnote_label_attributes: Some("class=\"footnote-heading\"".into()),
..CompileOptions::gfm()
}
}
)?,
"<p><sup><a href=\"#user-content-fn-a\" id=\"user-content-fnref-a\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup></p>\n<section data-footnotes=\"\" class=\"footnotes\"><h2 id=\"footnote-label\" class=\"footnote-heading\">Footnotes</h2>\n<ol>\n<li id=\"user-content-fn-a\">\n<p>b <a href=\"#user-content-fnref-a\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩</a></p>\n</li>\n</ol>\n</section>\n"
);gfm_footnote_label_tag_name: Option<String>HTML tag name to use for the footnote label element.
The default value is "h2".
Change it to match your document structure.
This label is typically hidden visually (assuming a sr-only CSS class
is defined that does that), and thus affects screen readers only.
If you do have such a class, but want to show this section to everyone,
pass different attributes with the gfm_footnote_label_attributes
option.
§Examples
use socketry_markdown::{to_html_with_options, CompileOptions, Options, ParseOptions};
// `"h2"` is used by default:
assert_eq!(
to_html_with_options(
"[^a]\n\n[^a]: b",
&Options::gfm()
)?,
"<p><sup><a href=\"#user-content-fn-a\" id=\"user-content-fnref-a\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup></p>\n<section data-footnotes=\"\" class=\"footnotes\"><h2 id=\"footnote-label\" class=\"sr-only\">Footnotes</h2>\n<ol>\n<li id=\"user-content-fn-a\">\n<p>b <a href=\"#user-content-fnref-a\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩</a></p>\n</li>\n</ol>\n</section>\n"
);
// Pass `gfm_footnote_label_tag_name` to use something else:
assert_eq!(
to_html_with_options(
"[^a]\n\n[^a]: b",
&Options {
parse: ParseOptions::gfm(),
compile: CompileOptions {
gfm_footnote_label_tag_name: Some("h1".into()),
..CompileOptions::gfm()
}
}
)?,
"<p><sup><a href=\"#user-content-fn-a\" id=\"user-content-fnref-a\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup></p>\n<section data-footnotes=\"\" class=\"footnotes\"><h1 id=\"footnote-label\" class=\"sr-only\">Footnotes</h1>\n<ol>\n<li id=\"user-content-fn-a\">\n<p>b <a href=\"#user-content-fnref-a\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩</a></p>\n</li>\n</ol>\n</section>\n"
);gfm_footnote_label: Option<String>Textual label to use for the footnotes section.
The default value is "Footnotes".
Change it when the markdown is not in English.
This label is typically hidden visually (assuming a sr-only CSS class
is defined that does that), and thus affects screen readers only.
If you do have such a class, but want to show this section to everyone,
pass different attributes with the gfm_footnote_label_attributes
option.
§Examples
use socketry_markdown::{to_html_with_options, CompileOptions, Options, ParseOptions};
// `"Footnotes"` is used by default:
assert_eq!(
to_html_with_options(
"[^a]\n\n[^a]: b",
&Options::gfm()
)?,
"<p><sup><a href=\"#user-content-fn-a\" id=\"user-content-fnref-a\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup></p>\n<section data-footnotes=\"\" class=\"footnotes\"><h2 id=\"footnote-label\" class=\"sr-only\">Footnotes</h2>\n<ol>\n<li id=\"user-content-fn-a\">\n<p>b <a href=\"#user-content-fnref-a\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩</a></p>\n</li>\n</ol>\n</section>\n"
);
// Pass `gfm_footnote_label` to use something else:
assert_eq!(
to_html_with_options(
"[^a]\n\n[^a]: b",
&Options {
parse: ParseOptions::gfm(),
compile: CompileOptions {
gfm_footnote_label: Some("Notes de bas de page".into()),
..CompileOptions::gfm()
}
}
)?,
"<p><sup><a href=\"#user-content-fn-a\" id=\"user-content-fnref-a\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup></p>\n<section data-footnotes=\"\" class=\"footnotes\"><h2 id=\"footnote-label\" class=\"sr-only\">Notes de bas de page</h2>\n<ol>\n<li id=\"user-content-fn-a\">\n<p>b <a href=\"#user-content-fnref-a\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩</a></p>\n</li>\n</ol>\n</section>\n"
);gfm_task_list_item_checkable: boolWhether or not GFM task list html <input> items are enabled.
This determines whether or not the user of the browser is able to click and toggle generated checkbox items. The default is false.
§Examples
use socketry_markdown::{to_html_with_options, CompileOptions, Options, ParseOptions};
// With `gfm_task_list_item_checkable`, generated `<input type="checkbox" />`
// tags do not contain the attribute `disabled=""` and are thus toggleable by
// browser users.
assert_eq!(
to_html_with_options(
"* [x] y.",
&Options {
parse: ParseOptions::gfm(),
compile: CompileOptions {
gfm_task_list_item_checkable: true,
..CompileOptions::gfm()
}
}
)?,
"<ul>\n<li><input type=\"checkbox\" checked=\"\" /> y.</li>\n</ul>"
);gfm_tagfilter: boolWhether to support the GFM tagfilter.
This option does nothing if allow_dangerous_html is not turned on.
The default is false, which does not apply the GFM tagfilter to HTML.
Pass true for output that is a bit closer to GitHub’s actual output.
The tagfilter is kinda weird and kinda useless. The tag filter is a naïve attempt at XSS protection. You should use a proper HTML sanitizing algorithm instead.
§Examples
use socketry_markdown::{to_html_with_options, CompileOptions, Options, ParseOptions};
// With `allow_dangerous_html`, `markdown-rs` passes HTML through untouched:
assert_eq!(
to_html_with_options(
"<iframe>",
&Options {
parse: ParseOptions::gfm(),
compile: CompileOptions {
allow_dangerous_html: true,
..CompileOptions::default()
}
}
)?,
"<iframe>"
);
// Pass `gfm_tagfilter: true` to make some of that safe:
assert_eq!(
to_html_with_options(
"<iframe>",
&Options {
parse: ParseOptions::gfm(),
compile: CompileOptions {
allow_dangerous_html: true,
gfm_tagfilter: true,
..CompileOptions::default()
}
}
)?,
"<iframe>"
);§References
heading_ids: boolWhether to add unique id attributes to headings for in-page links
and tables of contents.
IDs use the same text normalization and duplicate suffixes as
mdast::Headings::extract.
The default is false.
Implementations§
Source§impl CompileOptions
impl CompileOptions
Sourcepub fn gfm() -> Self
pub fn gfm() -> Self
GFM.
GFM stands for GitHub flavored markdown. On the compilation side, GFM turns on the GFM tag filter. The tagfilter is useless, but it’s included here for consistency, and this method exists for parity to parse options.
For more information, see the GFM specification: https://github.github.com/gfm/.