feat: add display UI with splash screen, dashboard, and RSSI sparkline

Implement full SSD1306 OLED display support:
- Splash screen on boot (1.5s) with project name, version, board
- Dashboard showing radio state, config, counters, RSSI/SNR
- RSSI history sparkline (64-sample ring buffer, 2px-wide bars)
- DisplayOn/DisplayOff host commands routed via dedicated channel
- Pure render functions against generic DrawTarget (no hardware coupling)
- Display on/off control bypasses radio task entirely

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
swaitsandClaude Opus 4.6 committed 2026-03-29 20:42:54 -06:00
1 parent 7064110293
commit 3102fc747a
17624 files changed
+4564928 -38

No files matched your search

+140
View File
@@ -0,0 +1,140 @@
use pulldown_cmark::{Options, Parser};
fn parse(md: &str) {
let parser = Parser::new(md);
for _ in parser {}
}
fn parse_all_options(md: &str) {
let parser = Parser::new_ext(md, Options::all());
for _ in parser {}
}
#[test]
fn test_lists_inside_code_spans() {
parse(
r"- `
x
**
*
`",
);
}
#[test]
fn test_fuzzer_input_1() {
parse(">\n >>><N\n");
}
#[test]
fn test_fuzzer_input_2() {
parse(" \u{b}\\\r- ");
}
#[test]
fn test_fuzzer_input_3() {
parse_all_options("\n # #\r\u{1c} ");
}
#[test]
fn test_fuzzer_input_4() {
parse_all_options("\u{0}{\tϐ}\n-");
}
#[test]
fn test_fuzzer_input_5() {
parse_all_options(" \u{c}{}\n-\n");
}
#[test]
fn test_fuzzer_input_6() {
parse("*\t[][\n\t<p]>\n\t[]");
}
#[test]
fn test_fuzzer_input_7() {
parse_all_options("[][{]}\n-");
}
#[test]
fn test_fuzzer_input_8() {
parse_all_options("a\n \u{c}{}\n-");
}
#[test]
fn test_fuzzer_input_9() {
parse_all_options("a\n \u{c}{}\\\n-");
}
#[test]
fn test_fuzzer_input_10() {
parse_all_options("[[ \t\n \u{c}\u{c}\u{c}\u{c}\u{c} {}\n-\r\u{e}\u{0}\u{0}{# }\n\u{b}\u{b}\u{b}\u{b}\u{b}\u{b}\u{b}\u{b}\u{b}\u{b}\u{0}\u{0}");
}
#[test]
fn test_fuzzer_input_11() {
parse_all_options(
"[[\u{c}\u{c} \t\n \u{c}\u{c}\u{c}\u{c}\u{c}\u{c}\u{c}\u{c}\u{c} {}\n-\r\u{e}",
);
}
#[test]
fn test_fuzzer_input_12() {
parse_all_options("\u{c}-\n\u{c}\n-");
}
#[test]
fn test_fuzzer_input_13() {
// Does not fail with Options::all():
Parser::new_ext(
".\r> ^](\r\u{c}\r\0\0\r.\r[^\0\0\\\0\0\0^^^^^]",
Options::ENABLE_FOOTNOTES,
);
}
#[test]
fn test_wrong_code_block() {
parse(
r##"```
* ```
"##,
);
}
#[test]
fn test_unterminated_link() {
parse("[](\\");
}
#[test]
fn test_unterminated_autolink() {
parse("<a");
}
#[test]
fn test_infinite_loop() {
parse("[<!W\n\\\n");
}
#[test]
fn test_html_tag() {
parse("<script\u{feff}");
}
// all of test_bad_slice_* were found in https://github.com/raphlinus/pulldown-cmark/issues/521
#[test]
fn test_bad_slice_a() {
parse("><a\n");
}
#[test]
fn test_bad_slice_b() {
parse("><a a\n");
}
#[test]
fn test_bad_slice_unicode() {
parse("><a a=\n毿>")
}
+351
View File
@@ -0,0 +1,351 @@
// Tests for HTML spec.
#![cfg(feature = "html")]
use pulldown_cmark::{html, BrokenLink, Options, Parser};
#[test]
fn html_test_1() {
let original = r##"Little header
<script type="text/js">
function some_func() {
console.log("teeeest");
}
function another_func() {
console.log("fooooo");
}
</script>"##;
let expected = r##"<p>Little header</p>
<script type="text/js">
function some_func() {
console.log("teeeest");
}
function another_func() {
console.log("fooooo");
}
</script>"##;
let mut s = String::new();
html::push_html(&mut s, Parser::new(original));
assert_eq!(expected, s);
}
#[test]
fn html_test_2() {
let original = r##"Little header
<script
type="text/js">
function some_func() {
console.log("teeeest");
}
function another_func() {
console.log("fooooo");
}
</script>"##;
let expected = r##"<p>Little header</p>
<script
type="text/js">
function some_func() {
console.log("teeeest");
}
function another_func() {
console.log("fooooo");
}
</script>"##;
let mut s = String::new();
html::push_html(&mut s, Parser::new(original));
assert_eq!(expected, s);
}
#[test]
fn html_test_3() {
let original = r##"Little header
<?
<div></div>
<p>Useless</p>
?>"##;
let expected = r##"<p>Little header</p>
<?
<div></div>
<p>Useless</p>
?>"##;
let mut s = String::new();
html::push_html(&mut s, Parser::new(original));
assert_eq!(expected, s);
}
#[test]
fn html_test_4() {
let original = r##"Little header
<!--
<div></div>
<p>Useless</p>
-->"##;
let expected = r##"<p>Little header</p>
<!--
<div></div>
<p>Useless</p>
-->"##;
let mut s = String::new();
html::push_html(&mut s, Parser::new(original));
assert_eq!(expected, s);
}
#[test]
fn html_test_5() {
let original = r##"Little header
<![CDATA[
<div></div>
<p>Useless</p>
]]>"##;
let expected = r##"<p>Little header</p>
<![CDATA[
<div></div>
<p>Useless</p>
]]>"##;
let mut s = String::new();
html::push_html(&mut s, Parser::new(original));
assert_eq!(expected, s);
}
#[test]
fn html_test_6() {
let original = r##"Little header
<!X
Some things are here...
>"##;
let expected = r##"<p>Little header</p>
<!X
Some things are here...
>"##;
let mut s = String::new();
html::push_html(&mut s, Parser::new(original));
assert_eq!(expected, s);
}
#[test]
fn html_test_7() {
let original = r##"Little header
-----------
<script>
function some_func() {
console.log("teeeest");
}
function another_func() {
console.log("fooooo");
}
</script>"##;
let expected = r##"<h2>Little header</h2>
<script>
function some_func() {
console.log("teeeest");
}
function another_func() {
console.log("fooooo");
}
</script>"##;
let mut s = String::new();
html::push_html(&mut s, Parser::new(original));
assert_eq!(expected, s);
}
#[test]
fn html_test_8() {
let original = "A | B\n---|---\nfoo | bar";
let expected = r##"<table><thead><tr><th>A</th><th>B</th></tr></thead><tbody>
<tr><td>foo</td><td>bar</td></tr>
</tbody></table>
"##;
let mut s = String::new();
let mut opts = Options::empty();
opts.insert(Options::ENABLE_TABLES);
html::push_html(&mut s, Parser::new_ext(original, opts));
assert_eq!(expected, s);
}
#[test]
fn html_test_9() {
let original = "---";
let expected = "<hr />\n";
let mut s = String::new();
html::push_html(&mut s, Parser::new(original));
assert_eq!(expected, s);
}
#[test]
fn html_test_10() {
let original = "* * *";
let expected = "<hr />\n";
let mut s = String::new();
html::push_html(&mut s, Parser::new(original));
assert_eq!(expected, s);
}
#[test]
fn html_test_11() {
let original = "hi ~~no~~";
let expected = "<p>hi ~~no~~</p>\n";
let mut s = String::new();
html::push_html(&mut s, Parser::new(original));
assert_eq!(expected, s);
}
#[test]
fn html_test_broken_callback() {
let original = r##"[foo],
[bar],
[baz],
[baz]: https://example.org
"##;
let expected = r##"<p><a href="https://replaced.example.org" title="some title">foo</a>,
[bar],
<a href="https://example.org">baz</a>,</p>
"##;
use pulldown_cmark::{html, Options, Parser};
let mut s = String::new();
let mut callback = |broken_link: BrokenLink| {
if &*broken_link.reference == "foo" || &*broken_link.reference == "baz" {
Some(("https://replaced.example.org".into(), "some title".into()))
} else {
None
}
};
let p = Parser::new_with_broken_link_callback(original, Options::empty(), Some(&mut callback));
html::push_html(&mut s, p);
assert_eq!(expected, s);
}
#[test]
fn newline_in_code() {
let originals = ["`\n `x", "` \n`x"];
let expected = "<p><code> </code>x</p>\n";
for original in originals {
let mut s = String::new();
html::push_html(&mut s, Parser::new(original));
assert_eq!(expected, s);
}
}
#[test]
fn newline_start_end_of_code() {
let original = "`\nx\n`x";
let expected = "<p><code>x</code>x</p>\n";
let mut s = String::new();
html::push_html(&mut s, Parser::new(original));
assert_eq!(expected, s);
}
// https://github.com/raphlinus/pulldown-cmark/issues/715
#[test]
fn trim_space_and_tab_at_end_of_paragraph() {
let original = "one\ntwo \t";
let expected = "<p>one\ntwo</p>\n";
let mut s = String::new();
html::push_html(&mut s, Parser::new(original));
assert_eq!(expected, s);
}
#[test]
fn newline_within_code() {
let originals = ["`\nx \ny\n`x", "`x \ny`x", "`x\n y`x"];
let expected = "<p><code>x y</code>x</p>\n";
for original in originals {
let mut s = String::new();
html::push_html(&mut s, Parser::new(original));
assert_eq!(expected, s);
}
}
#[test]
fn trim_space_tab_nl_at_end_of_paragraph() {
let original = "one\ntwo \t\n";
let expected = "<p>one\ntwo</p>\n";
let mut s = String::new();
html::push_html(&mut s, Parser::new(original));
assert_eq!(expected, s);
}
#[test]
fn trim_space_nl_at_end_of_paragraph() {
let original = "one\ntwo \n";
let expected = "<p>one\ntwo</p>\n";
let mut s = String::new();
html::push_html(&mut s, Parser::new(original));
assert_eq!(expected, s);
}
#[test]
fn trim_space_before_soft_break() {
let original = "one \ntwo";
let expected = "<p>one\ntwo</p>\n";
let mut s = String::new();
html::push_html(&mut s, Parser::new(original));
assert_eq!(expected, s);
}
// Can't easily use regression.txt due to newline normalization.
#[test]
fn issue_819() {
let original = [
"# \\", "# \\\n", "# \\\n\n", "# \\\r\n", "# \\\r\n\r\n", "# \\\n\r\n", "# \\\r\n\n"
];
let expected = "<h1>\\</h1>";
for orig in original {
let mut s = String::new();
html::push_html(&mut s, Parser::new(orig));
// Trailing newline doesn't matter. Just the actual HTML.
assert_eq!(expected, s.trim_end_matches('\n'));
}
for orig in original {
let mut s = String::new();
let mut opts = Options::empty();
opts.insert(Options::ENABLE_HEADING_ATTRIBUTES);
html::push_html(&mut s, Parser::new_ext(orig, opts));
// Trailing newline doesn't matter. Just the actual HTML.
assert_eq!(expected, s.trim_end_matches('\n'));
}
}
+52
View File
@@ -0,0 +1,52 @@
#![cfg(feature = "html")]
use pulldown_cmark::{Options, Parser};
mod suite;
#[inline(never)]
pub fn test_markdown_html(
input: &str,
output: &str,
smart_punct: bool,
metadata_blocks: bool,
old_footnotes: bool,
) {
let mut s = String::new();
let mut opts = Options::empty();
opts.insert(Options::ENABLE_MATH);
opts.insert(Options::ENABLE_TABLES);
opts.insert(Options::ENABLE_STRIKETHROUGH);
opts.insert(Options::ENABLE_TASKLISTS);
opts.insert(Options::ENABLE_GFM);
if old_footnotes {
opts.insert(Options::ENABLE_OLD_FOOTNOTES);
} else {
opts.insert(Options::ENABLE_FOOTNOTES);
}
if metadata_blocks {
opts.insert(Options::ENABLE_YAML_STYLE_METADATA_BLOCKS);
opts.insert(Options::ENABLE_PLUSES_DELIMITED_METADATA_BLOCKS);
}
if smart_punct {
opts.insert(Options::ENABLE_SMART_PUNCTUATION);
}
opts.insert(Options::ENABLE_HEADING_ATTRIBUTES);
let p = Parser::new_ext(input, opts);
pulldown_cmark::html::push_html(&mut s, p);
// normalizing the HTML using html5ever may hide actual errors
// assert_eq!(html_standardize(output), html_standardize(&s));
assert_eq!(html_standardize(output), html_standardize(&s));
}
fn html_standardize(s: &str) -> String {
s.replace("<br>", "<br />")
.replace("<br/>", "<br />")
.replace("<hr>", "<hr />")
.replace("<hr/>", "<hr />")
// permit extra or missing line breaks only between tags
.replace(">\n<", "><")
}
+86
View File
@@ -0,0 +1,86 @@
#[cfg(feature = "serde")]
mod tests {
use std::convert::TryInto;
use pulldown_cmark::CowStr;
#[test]
fn escaped() {
let must_be_escaped = "\"";
let wire = serde_json::to_string(must_be_escaped).unwrap();
let de = serde_json::from_str::<CowStr>(&wire).unwrap();
assert_eq!(&*de, must_be_escaped);
}
#[test]
fn cow_str_to_str_round_trip_bincode() {
for i in &[
CowStr::Borrowed("dssa"),
CowStr::Borrowed(""),
CowStr::Boxed("hello".to_owned().into_boxed_str()),
CowStr::Boxed("".to_owned().into_boxed_str()),
CowStr::Inlined("inline".try_into().unwrap()),
CowStr::Inlined("".try_into().unwrap()),
] {
let encoded = bincode::serialize(i).unwrap();
let decoded1: CowStr = bincode::deserialize(&encoded).unwrap();
let decoded2: String = bincode::deserialize(&encoded).unwrap();
let decoded3: &str = bincode::deserialize(&encoded).unwrap();
assert_eq!(&decoded1, i);
assert_eq!(decoded2, i.as_ref());
assert_eq!(decoded3, i.as_ref());
}
}
#[test]
fn cow_str_to_str_round_trip_json() {
for i in &[
CowStr::Borrowed("dssa"),
CowStr::Borrowed(""),
CowStr::Boxed("hello".to_owned().into_boxed_str()),
CowStr::Boxed("".to_owned().into_boxed_str()),
CowStr::Inlined("inline".try_into().unwrap()),
CowStr::Inlined("".try_into().unwrap()),
] {
let encoded = serde_json::to_string(i).unwrap();
let decoded1: CowStr = serde_json::from_str(&encoded).unwrap();
let decoded2: String = serde_json::from_str(&encoded).unwrap();
let decoded3: &str = serde_json::from_str(&encoded).unwrap();
assert_eq!(&decoded1, i);
assert_eq!(decoded2, i.as_ref());
assert_eq!(decoded3, i.as_ref());
}
}
#[test]
fn str_to_cow_str_json() {
let str = "a borrowed str";
let string = "a owned str".to_owned();
let encoded_str = serde_json::to_string(&str).unwrap();
let encoded_string = serde_json::to_string(&string).unwrap();
let decoded_str: CowStr = serde_json::from_str(&encoded_str).unwrap();
let decoded_string: CowStr = serde_json::from_str(&encoded_string).unwrap();
assert_eq!(decoded_str.as_ref(), str);
assert_eq!(decoded_string.as_ref(), string);
}
#[test]
fn str_to_cow_str_bincode() {
let str = "a borrowed str";
let string = "a owned str".to_owned();
let encoded_str = bincode::serialize(&str).unwrap();
let encoded_string = bincode::serialize(&string).unwrap();
let decoded_str: CowStr = bincode::deserialize(&encoded_str).unwrap();
let decoded_string: CowStr = bincode::deserialize(&encoded_string).unwrap();
assert_eq!(decoded_str.as_ref(), str);
assert_eq!(decoded_string.as_ref(), string);
}
}
+255
View File
@@ -0,0 +1,255 @@
// This file is auto-generated by the build script
// Please, do not modify it manually
use super::test_markdown_html;
#[test]
fn blockquotes_tags_test_1() {
let original = r##"> This is a normal blockquote without tag.
"##;
let expected = r##"<blockquote><p>This is a normal blockquote without tag.</p></blockquote>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn blockquotes_tags_test_2() {
let original = r##"> [!NOTE]
> Note blockquote
"##;
let expected = r##"<blockquote class="markdown-alert-note"><p>Note blockquote</p></blockquote>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn blockquotes_tags_test_3() {
let original = r##"> [!TIP]
> Tip blockquote
"##;
let expected = r##"<blockquote class="markdown-alert-tip"><p>Tip blockquote</p></blockquote>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn blockquotes_tags_test_4() {
let original = r##"> [!IMPORTANT]
> Important blockquote
"##;
let expected = r##"<blockquote class="markdown-alert-important"><p>Important blockquote</p></blockquote>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn blockquotes_tags_test_5() {
let original = r##"> [!WARNING]
> Warning blockquote
"##;
let expected = r##"<blockquote class="markdown-alert-warning"><p>Warning blockquote</p></blockquote>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn blockquotes_tags_test_6() {
let original = r##"> [!CAUTION]
> Caution blockquote
"##;
let expected = r##"<blockquote class="markdown-alert-caution"><p>Caution blockquote</p></blockquote>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn blockquotes_tags_test_7() {
let original = r##"> [!CAUTION]
"##;
let expected = r##"<blockquote class="markdown-alert-caution"></blockquote>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn blockquotes_tags_test_8() {
let original = r##"> [!CAUTION]
> Line 1.
> Line 2.
"##;
let expected = r##"<blockquote class="markdown-alert-caution"><p>Line 1.
Line 2.</p></blockquote>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn blockquotes_tags_test_9() {
let original = r##"> [!CAUTION]
> Line 1.
> [!CAUTION]
> Line 2.
"##;
let expected = r##"<blockquote class="markdown-alert-caution"><p>Line 1.
[!CAUTION]
Line 2.</p></blockquote>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn blockquotes_tags_test_10() {
let original = r##"> [!CAUTION]
> Line 1.
> > [!TIP]
> Line 2.
"##;
let expected = r##"<blockquote class="markdown-alert-caution"><p>Line 1.</p><blockquote class="markdown-alert-tip"><p>Line 2.</p></blockquote></blockquote>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn blockquotes_tags_test_11() {
let original = r##"> [!CAUTION]
> Line 1.
> [!TIP]
> Line 2.
"##;
let expected = r##"<blockquote class="markdown-alert-caution"><p>Line 1.</p></blockquote><blockquote class="markdown-alert-tip"><p>Line 2.</p></blockquote>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn blockquotes_tags_test_12() {
let original = r##"> > [!CAUTION]
> > Line 1.
> Line 2.
"##;
let expected = r##"<blockquote><blockquote class="markdown-alert-caution"><p>Line 1.
Line 2.</p></blockquote></blockquote>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn blockquotes_tags_test_13() {
let original = r##"> [!CAUTION]
> Line 1.
> > [!NOTE]
> > Line 2.
"##;
let expected = r##"<blockquote class="markdown-alert-caution"><p>Line 1.</p>
<blockquote class="markdown-alert-note"><p>Line 2.</p></blockquote>
</blockquote>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn blockquotes_tags_test_14() {
let original = r##"> [!caution]
> Line 1.
> > [!note]
> > Line 2.
"##;
let expected = r##"<blockquote class="markdown-alert-caution"><p>Line 1.</p>
<blockquote class="markdown-alert-note"><p>Line 2.</p></blockquote>
</blockquote>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn blockquotes_tags_test_15() {
let original = r##" * loose lists
> [!NOTE]
> sink ships
"##;
let expected = r##"<ul><li><p>loose lists</p>
<blockquote class="markdown-alert-note"><p>sink ships</p></blockquote>
</li></ul>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn blockquotes_tags_test_16() {
let original = r##"> [!NOTE]
sink ships
> [!NOTE]
> sink ships
* loose lists
> [!NOTE]
sink ships
> [!NOTE]
> sink ships
"##;
let expected = r##"<blockquote class="markdown-alert-note"><p>sink ships</p></blockquote>
<blockquote class="markdown-alert-note"><p>sink ships</p></blockquote>
<ul><li><p>loose lists</p>
<blockquote class="markdown-alert-note"><p>sink ships</p></blockquote>
<blockquote class="markdown-alert-note"><p>sink ships</p></blockquote>
</li></ul>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn blockquotes_tags_test_17() {
let original = r##" * loose lists
> [!NOTE]
- sink ships
> [!NOTE]
> - sink ships
"##;
let expected = r##"<ul><li><p>loose lists</p>
<blockquote class="markdown-alert-note"></blockquote>
<ul><li>sink ships</li></ul>
<blockquote class="markdown-alert-note">
<ul><li>sink ships</li></ul></blockquote>
</li></ul>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn blockquotes_tags_test_18() {
let original = r##"> [!Hello]
> This should be a normal block quote.
"##;
let expected = r##"<blockquote>
<p>[!Hello]
This should be a normal block quote.</p>
</blockquote>
"##;
test_markdown_html(original, expected, false, false, false);
}
+686
View File
@@ -0,0 +1,686 @@
// This file is auto-generated by the build script
// Please, do not modify it manually
use super::test_markdown_html;
#[test]
fn footnotes_test_1() {
let original = r##"Lorem ipsum.[^a] [^missing]
[^a]: Cool.
"##;
let expected = r##"<p>Lorem ipsum.<sup class="footnote-reference"><a href="#a">1</a></sup> [^missing]</p>
<div class="footnote-definition" id="a"><sup class="footnote-definition-label">1</sup>
<p>Cool.</p>
</div>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn footnotes_test_2() {
let original = r##"> This is the song that never ends.\
> Yes it goes on and on my friends.[^lambchops]
>
> [^lambchops]: <https://www.youtube.com/watch?v=0U2zJOryHKQ>
"##;
let expected = r##"<blockquote>
<p>This is the song that never ends.<br />
Yes it goes on and on my friends.<sup class="footnote-reference"><a href="#lambchops">1</a></sup></p>
<div class="footnote-definition" id="lambchops"><sup class="footnote-definition-label">1</sup>
<p><a href="https://www.youtube.com/watch?v=0U2zJOryHKQ">https://www.youtube.com/watch?v=0U2zJOryHKQ</a></p>
</div>
</blockquote>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn footnotes_test_3() {
let original = r##"Songs that simply loop are a popular way to annoy people. [^examples]
[^examples]:
* [The song that never ends](https://www.youtube.com/watch?v=0U2zJOryHKQ)
* [I know a song that gets on everybody's nerves](https://www.youtube.com/watch?v=TehWI09qxls)
* [Ninety-nine bottles of beer on the wall](https://www.youtube.com/watch?v=qVjCag8XoHQ)
"##;
let expected = r##"<p>Songs that simply loop are a popular way to annoy people. <sup class="footnote-reference"><a href="#examples">1</a></sup></p>
<div class="footnote-definition" id="examples"><sup class="footnote-definition-label">1</sup></div>
<ul>
<li><a href="https://www.youtube.com/watch?v=0U2zJOryHKQ">The song that never ends</a></li>
<li><a href="https://www.youtube.com/watch?v=TehWI09qxls">I know a song that gets on everybody's nerves</a></li>
<li><a href="https://www.youtube.com/watch?v=qVjCag8XoHQ">Ninety-nine bottles of beer on the wall</a></li>
</ul>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn footnotes_test_4() {
let original = r##"Songs that simply loop are a popular way to annoy people. [^examples]
[^examples]:
* [The song that never ends](https://www.youtube.com/watch?v=0U2zJOryHKQ)
* [I know a song that gets on everybody's nerves](https://www.youtube.com/watch?v=TehWI09qxls)
* [Ninety-nine bottles of beer on the wall](https://www.youtube.com/watch?v=qVjCag8XoHQ)
"##;
let expected = r##"<p>Songs that simply loop are a popular way to annoy people. <sup class="footnote-reference"><a href="#examples">1</a></sup></p>
<div class="footnote-definition" id="examples"><sup class="footnote-definition-label">1</sup>
<ul>
<li><a href="https://www.youtube.com/watch?v=0U2zJOryHKQ">The song that never ends</a></li>
<li><a href="https://www.youtube.com/watch?v=TehWI09qxls">I know a song that gets on everybody's nerves</a></li>
<li><a href="https://www.youtube.com/watch?v=qVjCag8XoHQ">Ninety-nine bottles of beer on the wall</a></li>
</ul>
</div>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn footnotes_test_5() {
let original = r##"[^not-code] [^code] [^quote] [^not-quote] [^indented-quote]
[^not-code]: not code
[^code]:
code
[^quote]: > quote
[^not-quote]:
> external quote
[^indented-quote]:
> indented quote
"##;
let expected = r##"<p><sup class="footnote-reference"><a href="#not-code">1</a></sup> <sup class="footnote-reference"><a href="#code">2</a></sup> <sup class="footnote-reference"><a href="#quote">3</a></sup> <sup class="footnote-reference"><a href="#not-quote">4</a></sup> <sup class="footnote-reference"><a href="#indented-quote">5</a></sup></p>
<div class="footnote-definition" id="not-code"><sup class="footnote-definition-label">1</sup>
<p>not code</p>
</div>
<div class="footnote-definition" id="code"><sup class="footnote-definition-label">2</sup>
<pre><code>code
</code></pre>
</div>
<div class="footnote-definition" id="quote"><sup class="footnote-definition-label">3</sup>
<blockquote><p>quote</p></blockquote>
</div>
<div class="footnote-definition" id="not-quote"><sup class="footnote-definition-label">4</sup></div>
<blockquote><p>external quote</p></blockquote><div class="footnote-definition" id="indented-quote"><sup class="footnote-definition-label">5</sup>
<blockquote><p>indented quote</p></blockquote>
</div>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn footnotes_test_6() {
let original = r##"[^ab] [^cd]
[^ab]: a
b
[^cd]: c\
d
"##;
let expected = r##"<p><sup class="footnote-reference"><a href="#ab">1</a></sup> <sup class="footnote-reference"><a href="#cd">2</a></sup></p>
<div class="footnote-definition" id="ab"><sup class="footnote-definition-label">1</sup>
<p>a
b</p>
</div>
<div class="footnote-definition" id="cd"><sup class="footnote-definition-label">2</sup>
<p>c<br>
d</p>
</div>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn footnotes_test_7() {
let original = r##"[^lorem]: If heaven ever wishes to grant me a boon, it will be a total effacing of the results of a mere chance which fixed my eye on a certain stray piece of shelf-paper. It was nothing on which I would naturally have stumbled in the course of my daily round, for it was an old number of an Australian journal, the Sydney Bulletin for April 18, 1925. It had escaped even the cutting bureau which had at the time of its issuance been avidly collecting material for my uncle's research.
I had largely given over my inquiries into what Professor Angell called the "Cthulhu Cult", and was visiting a learned friend in Paterson, New Jersey; the curator of a local museum and a mineralogist of note. Examining one day the reserve specimens roughly set on the storage shelves in a rear room of the museum, my eye was caught by an odd picture in one of the old papers spread beneath the stones. It was the Sydney Bulletin I have mentioned, for my friend had wide affiliations in all conceivable foreign parts; and the picture was a half-tone cut of a hideous stone image almost identical with that which Legrasse had found in the swamp.
[^ipsum]: If heaven ever wishes to grant me a boon, it will be a total effacing of the results of a mere chance which fixed my eye on a certain stray piece of shelf-paper. It was nothing on which I would naturally have stumbled in the course of my daily round, for it was an old number of an Australian journal, the Sydney Bulletin for April 18, 1925. It had escaped even the cutting bureau which had at the time of its issuance been avidly collecting material for my uncle's research.
I had largely given over my inquiries into what Professor Angell called the "Cthulhu Cult", and was visiting a learned friend in Paterson, New Jersey; the curator of a local museum and a mineralogist of note. Examining one day the reserve specimens roughly set on the storage shelves in a rear room of the museum, my eye was caught by an odd picture in one of the old papers spread beneath the stones. It was the Sydney Bulletin I have mentioned, for my friend had wide affiliations in all conceivable foreign parts; and the picture was a half-tone cut of a hideous stone image almost identical with that which Legrasse had found in the swamp.
"##;
let expected = r##"<div class="footnote-definition" id="lorem"><sup class="footnote-definition-label">1</sup>
<p>If heaven ever wishes to grant me a boon, it will be a total effacing of the results of a mere chance which fixed my eye on a certain stray piece of shelf-paper. It was nothing on which I would naturally have stumbled in the course of my daily round, for it was an old number of an Australian journal, the Sydney Bulletin for April 18, 1925. It had escaped even the cutting bureau which had at the time of its issuance been avidly collecting material for my uncle's research.</p>
</div>
<p>I had largely given over my inquiries into what Professor Angell called the "Cthulhu Cult", and was visiting a learned friend in Paterson, New Jersey; the curator of a local museum and a mineralogist of note. Examining one day the reserve specimens roughly set on the storage shelves in a rear room of the museum, my eye was caught by an odd picture in one of the old papers spread beneath the stones. It was the Sydney Bulletin I have mentioned, for my friend had wide affiliations in all conceivable foreign parts; and the picture was a half-tone cut of a hideous stone image almost identical with that which Legrasse had found in the swamp.</p>
<div class="footnote-definition" id="ipsum"><sup class="footnote-definition-label">2</sup>
<p>If heaven ever wishes to grant me a boon, it will be a total effacing of the results of a mere chance which fixed my eye on a certain stray piece of shelf-paper. It was nothing on which I would naturally have stumbled in the course of my daily round, for it was an old number of an Australian journal, the Sydney Bulletin for April 18, 1925. It had escaped even the cutting bureau which had at the time of its issuance been avidly collecting material for my uncle's research.</p>
<p>I had largely given over my inquiries into what Professor Angell called the "Cthulhu Cult", and was visiting a learned friend in Paterson, New Jersey; the curator of a local museum and a mineralogist of note. Examining one day the reserve specimens roughly set on the storage shelves in a rear room of the museum, my eye was caught by an odd picture in one of the old papers spread beneath the stones. It was the Sydney Bulletin I have mentioned, for my friend had wide affiliations in all conceivable foreign parts; and the picture was a half-tone cut of a hideous stone image almost identical with that which Legrasse had found in the swamp.</p>
</div>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn footnotes_test_8() {
let original = r##"[^ipsum]: How much wood would a woodchuck chuck.
If a woodchuck could chuck wood.
# Forms of entertainment that aren't childish
"##;
let expected = r##"<div class="footnote-definition" id="ipsum"><sup class="footnote-definition-label">1</sup>
<p>How much wood would a woodchuck chuck.</p>
</div>
<p>If a woodchuck could chuck wood.</p>
<h1>Forms of entertainment that aren't childish</h1>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn footnotes_test_9() {
let original = r##"Footnotes [^one] [^many].
[^one]:
first paragraph inside footnote
[^many]: first paragraph inside footnote
second paragraph still inside footnote
"##;
let expected = r##"<p>Footnotes <sup class="footnote-reference"><a href="#one">1</a></sup> <sup class="footnote-reference"><a href="#many">2</a></sup>.</p>
<div class="footnote-definition" id="one"><sup class="footnote-definition-label">1</sup>
<p>first paragraph inside footnote</p>
</div>
<div class="footnote-definition" id="many"><sup class="footnote-definition-label">2</sup>
<p>first paragraph inside footnote</p>
<p>second paragraph still inside footnote</p>
</div>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn footnotes_test_10() {
let original = r##"> He's also really stupid. [^why]
>
> [^why]: Because your mamma!
As such, we can guarantee that the non-childish forms of entertainment are probably more entertaining to adults, since, having had a whole childhood doing the childish ones, the non-childish ones are merely the ones that haven't gotten boring yet.
"##;
let expected = r##"<blockquote>
<p>He's also really stupid. <sup class="footnote-reference"><a href="#why">1</a></sup></p>
<div class="footnote-definition" id="why"><sup class="footnote-definition-label">1</sup>
<p>Because your mamma!</p>
</div>
</blockquote>
<p>As such, we can guarantee that the non-childish forms of entertainment are probably more entertaining to adults, since, having had a whole childhood doing the childish ones, the non-childish ones are merely the ones that haven't gotten boring yet.</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn footnotes_test_11() {
let original = r##"Nested footnotes are considered poor style. [^a] [^xkcd] [^indent1] [^indent2]
[^a]: This does not mean that footnotes cannot reference each other. [^b]
[^b]: This means that a footnote definition cannot be directly inside another footnote definition.
> This means that a footnote cannot be directly inside another footnote's body. [^e]
>
> [^e]: They can, however, be inside anything else.
[^xkcd]: [The other kind of nested footnote is, however, considered poor style.](https://xkcd.com/1208/)
[^indent1]: indent1
[^indent2]: indent2
"##;
let expected = r##"<p>Nested footnotes are considered poor style. <sup class="footnote-reference"><a href="#a">1</a></sup> <sup class="footnote-reference"><a href="#xkcd">2</a></sup> <sup class="footnote-reference"><a href="#indent1">3</a></sup> <sup class="footnote-reference"><a href="#indent2">4</a></sup></p>
<div class="footnote-definition" id="a"><sup class="footnote-definition-label">1</sup>
<p>This does not mean that footnotes cannot reference each other. <sup class="footnote-reference"><a href="#b">5</a></sup></p>
</div>
<div class="footnote-definition" id="b"><sup class="footnote-definition-label">5</sup>
<p>This means that a footnote definition cannot be directly inside another footnote definition.</p>
</div>
<blockquote>
<p>This means that a footnote cannot be directly inside another footnote's body. <sup class="footnote-reference"><a href="#e">6</a></sup></p>
<div class="footnote-definition" id="e"><sup class="footnote-definition-label">6</sup>
<p>They can, however, be inside anything else.</p>
</div>
</blockquote>
<div class="footnote-definition" id="xkcd"><sup class="footnote-definition-label">2</sup>
<p><a href="https://xkcd.com/1208/">The other kind of nested footnote is, however, considered poor style.</a></p>
</div>
<div class="footnote-definition" id="indent1"><sup class="footnote-definition-label">3</sup>
<p>indent1</p>
</div>
<div class="footnote-definition" id="indent2"><sup class="footnote-definition-label">4</sup>
<p>indent2</p>
</div>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn footnotes_test_12() {
let original = r##"[^foo] [^bar]
[^foo]: [^bar]: 1
"##;
let expected = r##"<p><sup class="footnote-reference"><a href="#foo">1</a></sup> <sup class="footnote-reference"><a href="#bar">2</a></sup></p>
<div class="footnote-definition" id="foo"><sup class="footnote-definition-label">1</sup></div>
<div class="footnote-definition" id="bar"><sup class="footnote-definition-label">2</sup>
<p>1</p>
</div>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn footnotes_test_13() {
let original = r##"[^Doh] Ray Me Fa So La Te Do! [^1]
[^Doh]: I know. Wrong Doe. And it won't render right.
[^1]: Common for people practicing music.
"##;
let expected = r##"<p><sup class="footnote-reference"><a href="#Doh">1</a></sup> Ray Me Fa So La Te Do! <sup class="footnote-reference"><a href="#1">2</a></sup></p>
<div class="footnote-definition" id="Doh"><sup class="footnote-definition-label">1</sup>
<p>I know. Wrong Doe. And it won't render right.</p>
</div>
<div class="footnote-definition" id="1"><sup class="footnote-definition-label">2</sup>
<p>Common for people practicing music.</p>
</div>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn footnotes_test_14() {
let original = r##"Lorem ipsum.[^a]
An unordered list before the footnotes:
* Ipsum
* Lorem
[^a]: Cool.
"##;
let expected = r##"<p>Lorem ipsum.<sup class="footnote-reference"><a href="#a">1</a></sup></p>
<p>An unordered list before the footnotes:</p>
<ul>
<li>Ipsum</li>
<li>Lorem</li>
</ul>
<div class="footnote-definition" id="a"><sup class="footnote-definition-label">1</sup>
<p>Cool.</p>
</div>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn footnotes_test_15() {
let original = r##"Songs that simply loop are a popular way to annoy people. [^examples]
[^examples]: * [The song that never ends](https://www.youtube.com/watch?v=0U2zJOryHKQ)
* [I know a song that gets on everybody's nerves](https://www.youtube.com/watch?v=TehWI09qxls)
* [Ninety-nine bottles of beer on the wall](https://www.youtube.com/watch?v=qVjCag8XoHQ)
Songs that simply loop are a popular way to annoy people. [^examples2]
[^examples2]: * [The song that never ends](https://www.youtube.com/watch?v=0U2zJOryHKQ) 2
* [I know a song that gets on everybody's nerves](https://www.youtube.com/watch?v=TehWI09qxls) 2
- [Ninety-nine bottles of beer on the wall](https://www.youtube.com/watch?v=qVjCag8XoHQ) 2
Songs that simply loop are a popular way to annoy people. [^examples3]
[^examples3]: * [The song that never ends](https://www.youtube.com/watch?v=0U2zJOryHKQ) 3
* [I know a song that gets on everybody's nerves](https://www.youtube.com/watch?v=TehWI09qxls) 3
* [Ninety-nine bottles of beer on the wall](https://www.youtube.com/watch?v=qVjCag8XoHQ) 3
"##;
let expected = r##"<p>Songs that simply loop are a popular way to annoy people. <sup class="footnote-reference"><a href="#examples">1</a></sup></p>
<div class="footnote-definition" id="examples"><sup class="footnote-definition-label">1</sup>
<ul>
<li><a href="https://www.youtube.com/watch?v=0U2zJOryHKQ">The song that never ends</a></li>
</ul>
</div>
<ul>
<li><a href="https://www.youtube.com/watch?v=TehWI09qxls">I know a song that gets on everybody's nerves</a></li>
<li><a href="https://www.youtube.com/watch?v=qVjCag8XoHQ">Ninety-nine bottles of beer on the wall</a></li>
</ul>
<p>Songs that simply loop are a popular way to annoy people. <sup class="footnote-reference"><a href="#examples2">2</a></sup></p>
<div class="footnote-definition" id="examples2"><sup class="footnote-definition-label">2</sup>
<ul>
<li><a href="https://www.youtube.com/watch?v=0U2zJOryHKQ">The song that never ends</a> 2</li>
<li><a href="https://www.youtube.com/watch?v=TehWI09qxls">I know a song that gets on everybody's nerves</a> 2</li>
</ul>
<ul>
<li><a href="https://www.youtube.com/watch?v=qVjCag8XoHQ">Ninety-nine bottles of beer on the wall</a> 2</li>
</ul>
</div>
<p>Songs that simply loop are a popular way to annoy people. <sup class="footnote-reference"><a href="#examples3">3</a></sup></p>
<div class="footnote-definition" id="examples3"><sup class="footnote-definition-label">3</sup>
<ul>
<li><p><a href="https://www.youtube.com/watch?v=0U2zJOryHKQ">The song that never ends</a> 3</p>
</li><li><p><a href="https://www.youtube.com/watch?v=TehWI09qxls">I know a song that gets on everybody's nerves</a> 3</p>
</li><li><p><a href="https://www.youtube.com/watch?v=qVjCag8XoHQ">Ninety-nine bottles of beer on the wall</a> 3</p></li>
</ul>
</div>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn footnotes_test_16() {
let original = r##"My [cmark-gfm][^c].
My [cmark-gfm][cmark-gfm][^c].
My [cmark-gfm][][^c].
My [cmark-gfm] [^c].
My [cmark-gfm[^c]].
[cmark-gfm]: https://github.com/github/cmark-gfm/blob/1e230827a584ebc9938c3eadc5059c55ef3c9abf/test/extensions.txt#L702
[^c]: cmark-gfm is under the MIT license, so incorporating parts of its
test suite into pulldown-cmark should be fine.
My [otherlink[^c]].
[otherlink[^c]]: https://github.com/github/cmark-gfm/blob/1e230827a584ebc9938c3eadc5059c55ef3c9abf/test/extensions.txt#L702
"##;
let expected = r##"<p>My <a href="https://github.com/github/cmark-gfm/blob/1e230827a584ebc9938c3eadc5059c55ef3c9abf/test/extensions.txt#L702">cmark-gfm</a><sup class="footnote-reference"><a href="#c">1</a></sup>.</p>
<p>My <a href="https://github.com/github/cmark-gfm/blob/1e230827a584ebc9938c3eadc5059c55ef3c9abf/test/extensions.txt#L702">cmark-gfm</a><sup class="footnote-reference"><a href="#c">1</a></sup>.</p>
<p>My <a href="https://github.com/github/cmark-gfm/blob/1e230827a584ebc9938c3eadc5059c55ef3c9abf/test/extensions.txt#L702">cmark-gfm</a><sup class="footnote-reference"><a href="#c">1</a></sup>.</p>
<p>My <a href="https://github.com/github/cmark-gfm/blob/1e230827a584ebc9938c3eadc5059c55ef3c9abf/test/extensions.txt#L702">cmark-gfm</a> <sup class="footnote-reference"><a href="#c">1</a></sup>.</p>
<p>My [cmark-gfm<sup class="footnote-reference"><a href="#c">1</a></sup>].</p>
<div class="footnote-definition" id="c"><sup class="footnote-definition-label">1</sup>
<p>cmark-gfm is under the MIT license, so incorporating parts of its
test suite into pulldown-cmark should be fine.</p>
</div>
<p>My [otherlink<sup class="footnote-reference"><a href="#c">1</a></sup>].</p>
<p>[otherlink<sup class="footnote-reference"><a href="#c">1</a></sup>]: https://github.com/github/cmark-gfm/blob/1e230827a584ebc9938c3eadc5059c55ef3c9abf/test/extensions.txt#L702</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn footnotes_test_17() {
let original = r##"[^1]: footnote definition text
<!-- -->
// indented code block
fn main() {
println!("hello world!");
}
"##;
let expected = r##"<div class="footnote-definition" id="1"><sup class="footnote-definition-label">1</sup>
<p>footnote definition text</p>
</div>
<!-- -->
<pre><code>// indented code block
fn main() {
println!("hello world!");
}
</code></pre>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn footnotes_test_18() {
let original = r##"[^1]: footnote definition text
[^1]\: this is a reference, rather than a definition
"##;
let expected = r##"<div class="footnote-definition" id="1"><sup class="footnote-definition-label">1</sup>
<p>footnote definition text
<sup class="footnote-reference"><a href="#1">1</a></sup>: this is a reference, rather than a definition</p>
</div>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn footnotes_test_19() {
let original = r##"[^1]:
| column1 | column2 |
|---------|---------|
| row1a | row1b |
| row2a | row2b |
"##;
let expected = r##"<div class="footnote-definition" id="1"><sup class="footnote-definition-label">1</sup><table>
<thead>
<tr><th>column1</th><th>column2</th></tr>
</thead>
<tbody>
<tr><td>row1a</td><td>row1b</td></tr>
<tr><td>row2a</td><td>row2b</td></tr>
</tbody>
</table>
</div>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn footnotes_test_20() {
let original = r##"* First
[^1]: test
* Second [^1] test
> first
> [^2]: test
> Second [^2] test
First | Second
-----------|----------
first | second
[^3]: test | test [^3]
| First | Second |
|------------|-----------|
| first | second |
| [^4]: test | test [^4] |
> [^5]: * test [^5]
"##;
let expected = r##"<ul>
<li>First
<div class="footnote-definition" id="1"><sup class="footnote-definition-label">1</sup>
<p>test</p>
</div>
</li>
<li>Second <sup class="footnote-reference"><a href="#1">1</a></sup> test</li>
</ul>
<blockquote>
<p>first</p>
<div class="footnote-definition" id="2"><sup class="footnote-definition-label">2</sup>
<p>test
Second <sup class="footnote-reference"><a href="#2">2</a></sup> test</p>
</div>
</blockquote>
<table><thead><tr><th>First</th><th>Second</th></tr></thead><tbody>
<tr><td>first</td><td>second</td></tr>
</tbody></table>
<div class="footnote-definition" id="3"><sup class="footnote-definition-label">3</sup>
<p>test | test <sup class="footnote-reference"><a href="#3">3</a></sup></p>
</div>
<table><thead><tr><th>First</th><th>Second</th></tr></thead><tbody>
<tr><td>first</td><td>second</td></tr>
<tr><td>[^4]: test</td><td>test [^4]</td></tr>
</tbody></table>
<blockquote>
<div class="footnote-definition" id="5"><sup class="footnote-definition-label">4</sup>
<ul>
<li>test <sup class="footnote-reference"><a href="#5">4</a></sup></li>
</ul>
</div>
</blockquote>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn footnotes_test_21() {
let original = r##"Test [^] link
[^]: https://rust-lang.org
"##;
let expected = r##"<p>Test <a href="https://rust-lang.org">^</a> link</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn footnotes_test_22() {
let original = r##"[^foo\
bar]: not a footnote definition
[baz\
quux]: https://rust-lang.org
[first
second]: https://rust-lang.org
[^third
fourth]: not a footnote definition
[baz\
quux]
[^foo\
bar]
[first
second]
[^third
fourth]
"##;
let expected = r##"<p>[^foo<br>
bar]: not a footnote definition</p>
<p>[^third
fourth]: not a footnote definition</p>
<p><a href="https://rust-lang.org">baz<br>
quux</a>
[^foo<br>
bar]
<a href="https://rust-lang.org">first
second</a>
[^third
fourth]</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn footnotes_test_23() {
let original = r##"[^foo
]: https://rust-lang.org
[^foo
]
"##;
let expected = r##"<p><a href="https://rust-lang.org">^foo
</a></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn footnotes_test_24() {
let original = r##"footnote [^baz]
footnote [^quux]
[^quux]: x
[^baz]: x
"##;
let expected = r##"<p>footnote <sup class="footnote-reference"><a href="#baz">1</a></sup>
footnote [^quux]</p>
<pre><code>[^quux]: x
</code></pre>
<div class="footnote-definition" id="baz"><sup class="footnote-definition-label">1</sup>
<p>x</p>
</div>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn footnotes_test_25() {
let original = r##"Lorem ipsum.[^a][^b]
[^a]: Foo
[^b]: Bar
"##;
let expected = r##"<p>Lorem ipsum.<sup class="footnote-reference"><a href="#a">1</a></sup><sup class="footnote-reference"><a href="#b">2</a></sup></p>
<div class="footnote-definition" id="a"><sup class="footnote-definition-label">1</sup>
<p>Foo</p>
</div>
<div class="footnote-definition" id="b"><sup class="footnote-definition-label">2</sup>
<p>Bar</p>
</div>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn footnotes_test_26() {
let original = r##"Lorem ipsum.[^a] [^b]
[^a]: Foo
[^b]: Bar
"##;
let expected = r##"<p>Lorem ipsum.<sup class="footnote-reference"><a href="#a">1</a></sup> <sup class="footnote-reference"><a href="#b">2</a></sup></p>
<div class="footnote-definition" id="a"><sup class="footnote-definition-label">1</sup>
<p>Foo</p>
</div>
<div class="footnote-definition" id="b"><sup class="footnote-definition-label">2</sup>
<p>Bar</p>
</div>
"##;
test_markdown_html(original, expected, false, false, false);
}
+37
View File
@@ -0,0 +1,37 @@
// This file is auto-generated by the build script
// Please, do not modify it manually
use super::test_markdown_html;
#[test]
fn gfm_strikethrough_test_1() {
let original = r##"~~Hi~~ Hello, ~there~ world!
"##;
let expected = r##"<p><del>Hi</del> Hello, <del>there</del> world!</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn gfm_strikethrough_test_2() {
let original = r##"This ~~has a
new paragraph~~.
"##;
let expected = r##"<p>This ~~has a</p>
<p>new paragraph~~.</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn gfm_strikethrough_test_3() {
let original = r##"This will ~~~not~~~ strike.
"##;
let expected = r##"<p>This will ~~~not~~~ strike.</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
+233
View File
@@ -0,0 +1,233 @@
// This file is auto-generated by the build script
// Please, do not modify it manually
use super::test_markdown_html;
#[test]
fn gfm_table_test_1() {
let original = r##"| foo | bar |
| --- | --- |
| baz | bim |
"##;
let expected = r##"<table>
<thead>
<tr>
<th>foo</th>
<th>bar</th>
</tr>
</thead>
<tbody>
<tr>
<td>baz</td>
<td>bim</td>
</tr>
</tbody>
</table>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn gfm_table_test_2() {
let original = r##"| abc | defghi |
:-: | -----------:
bar | baz
"##;
let expected = r##"<table>
<thead>
<tr>
<th style="text-align: center">abc</th>
<th style="text-align: right">defghi</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">bar</td>
<td style="text-align: right">baz</td>
</tr>
</tbody>
</table>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn gfm_table_test_3() {
let original = r##"| f\|oo |
| ------ |
| b `\|` az |
| b **\|** im |
"##;
let expected = r##"<table>
<thead>
<tr>
<th>f|oo</th>
</tr>
</thead>
<tbody>
<tr>
<td>b <code>|</code> az</td>
</tr>
<tr>
<td>b <strong>|</strong> im</td>
</tr>
</tbody>
</table>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn gfm_table_test_4() {
let original = r##"| abc | def |
| --- | --- |
| bar | baz |
> bar
"##;
let expected = r##"<table>
<thead>
<tr>
<th>abc</th>
<th>def</th>
</tr>
</thead>
<tbody>
<tr>
<td>bar</td>
<td>baz</td>
</tr>
</tbody>
</table>
<blockquote>
<p>bar</p>
</blockquote>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn gfm_table_test_5() {
let original = r##"| abc | def |
| --- | --- |
| bar | baz |
bar
bar
"##;
let expected = r##"<table>
<thead>
<tr>
<th>abc</th>
<th>def</th>
</tr>
</thead>
<tbody>
<tr>
<td>bar</td>
<td>baz</td>
</tr>
<tr>
<td>bar</td>
<td></td>
</tr>
</tbody>
</table>
<p>bar</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn gfm_table_test_6() {
let original = r##"| abc | def |
| --- |
| bar |
"##;
let expected = r##"<p>| abc | def |
| --- |
| bar |</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn gfm_table_test_7() {
let original = r##"| abc | def |
| --- | --- |
| bar |
| bar | baz | boo |
"##;
let expected = r##"<table>
<thead>
<tr>
<th>abc</th>
<th>def</th>
</tr>
</thead>
<tbody>
<tr>
<td>bar</td>
<td></td>
</tr>
<tr>
<td>bar</td>
<td>baz</td>
</tr>
</tbody>
</table>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn gfm_table_test_8() {
let original = r##"| abc | def |
| --- | --- |
"##;
let expected = r##"<table>
<thead>
<tr>
<th>abc</th>
<th>def</th>
</tr>
</thead>
<tbody></tbody>
</table>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn gfm_table_test_9() {
let original = r##"Hello World
| abc | def |
| --- | --- |
| bar | baz |
"##;
let expected = r##"<p>Hello World</p>
<table>
<thead>
<tr>
<th>abc</th>
<th>def</th>
</tr>
</thead>
<tbody>
<tr>
<td>bar</td>
<td>baz</td>
</tr>
</tbody>
</table>
"##;
test_markdown_html(original, expected, false, false, false);
}
+45
View File
@@ -0,0 +1,45 @@
// This file is auto-generated by the build script
// Please, do not modify it manually
use super::test_markdown_html;
#[test]
fn gfm_tasklist_test_1() {
let original = r##"- [ ] foo
- [x] bar
"##;
let expected = r##"<ul>
<li><input disabled="" type="checkbox"/>
foo</li>
<li><input disabled="" type="checkbox" checked=""/>
bar</li>
</ul>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn gfm_tasklist_test_2() {
let original = r##"- [x] foo
- [ ] bar
- [x] baz
- [ ] bim
"##;
let expected = r##"<ul>
<li><input disabled="" type="checkbox" checked=""/>
foo
<ul>
<li><input disabled="" type="checkbox"/>
bar</li>
<li><input disabled="" type="checkbox" checked=""/>
baz</li>
</ul>
</li>
<li><input disabled="" type="checkbox"/>
bim</li>
</ul>
"##;
test_markdown_html(original, expected, false, false, false);
}
+596
View File
@@ -0,0 +1,596 @@
// This file is auto-generated by the build script
// Please, do not modify it manually
use super::test_markdown_html;
#[test]
fn heading_attrs_test_1() {
let original = r##"with the ID {#myh1}
===================
with a class {.myclass}
------------
with a custom attribute {myattr=myvalue}
========================================
multiple! {.myclass1 myattr #myh3 otherattr=value .myclass2}
--
"##;
let expected = r##"<h1 id="myh1">with the ID</h1>
<h2 class="myclass">with a class</h2>
<h1 myattr="myvalue">with a custom attribute</h1>
<h2 id="myh3" class="myclass1 myclass2" myattr="" otherattr="value">multiple!</h2>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_2() {
let original = r##"# with the ID {#myh1}
## with a class {.myclass}
#### with a custom attribute {myattr=myvalue}
### multiple! {.myclass1 myattr #myh3 otherattr=value .myclass2}
"##;
let expected = r##"<h1 id="myh1">with the ID</h1>
<h2 class="myclass">with a class</h2>
<h4 myattr="myvalue">with a custom attribute</h4>
<h3 id="myh3" class="myclass1 myclass2" myattr="" otherattr="value">multiple!</h3>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_3() {
let original = r##"# H1 # {#id1}
## H2 ## with ## multiple ## hashes ## {#id2}
### with trailing hash # ### {#id3}
#### non-attribute-block {#id4} ####
"##;
let expected = r##"<h1 id="id1">H1</h1>
<h2 id="id2">H2 ## with ## multiple ## hashes</h2>
<h3 id="id3">with trailing hash #</h3>
<h4>non-attribute-block {#id4}</h4>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_4() {
let original = r##"# spaces {#myid1}
## tabs {#myid2}
"##;
let expected = r##"<h1 id="myid1">spaces</h1>
<h2 id="myid2">tabs</h2>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_5() {
let original = r##"# H1 \
nextline
"##;
let expected = r##"<h1>H1 \</h1>
<p>nextline</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_6() {
let original = r##"# H1 \
{#myid}
## H2 \
nextline {.class}
### H3 [link
](https://example.com/) {#myid3}
"##;
let expected = r##"<h1>H1 \</h1>
<p>{#myid}</p>
<h2>H2 \</h2>
<p>nextline {.class}</p>
<h3>H3 [link</h3>
<p>](https://example.com/) {#myid3}</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_7() {
let original = r##"H1
cont
{#myid}
==
"##;
let expected = r##"<h1 id="myid">H1
cont
</h1>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_8() {
let original = r##"H1
{
.class1
.class2
}
==
"##;
let expected = r##"<h1>H1
{
.class1
.class2
}</h1>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_9() {
let original = r##"# without space, not recommended{#id1}
## recommended style with spaces {#id2}
"##;
let expected = r##"<h1 id="id1">without space, not recommended</h1>
<h2 id="id2">recommended style with spaces</h2>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_10() {
let original = r##"# H1 { #id1 }
## H2 {.myclass #id2 }
### H3 { .myclass}
"##;
let expected = r##"<h1 id="id1">H1</h1>
<h2 id="id2" class="myclass">H2</h2>
<h3 class="myclass">H3</h3>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_11() {
let original = r##"# H1 {#id1.class1.class2 .class3}
## H2 {.class1#id2.class2}
"##;
let expected = r##"<h1 id="id1.class1.class2" class="class3">H1</h1>
<h2 class="class1#id2.class2">H2</h2>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_12() {
let original = r##"# H1 { #id1
## H2 {#id2
"##;
let expected = r##"<h1>H1 { #id1</h1>
<h2>H2 {#id2</h2>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_13() {
let original = r##"# H1 #id1 }
## H2 #id2}
"##;
let expected = r##"<h1>H1 #id1 }</h1>
<h2>H2 #id2}</h2>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_14() {
let original = r##"# H1 { #id1 } foo
## H2 {#id2} <!-- hello -->
"##;
let expected = r##"<h1>H1 { #id1 } foo</h1>
<h2>H2 {#id2} <!-- hello --></h2>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_15() {
let original = r##"# *H1* { #id1 }
## **H2** {#id2}
### _H3_ {#id3}
#### ~~H4~~ {#id4}
##### [text](uri) {#id5}
"##;
let expected = r##"<h1 id="id1"><em>H1</em></h1>
<h2 id="id2"><strong>H2</strong></h2>
<h3 id="id3"><em>H3</em></h3>
<h4 id="id4"><del>H4</del></h4>
<h5 id="id5"><a href="uri">text</a></h5>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_16() {
let original = r##"# H1 {#first #second #last}
"##;
let expected = r##"<h1 id="last">H1</h1>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_17() {
let original = r##"# H1 {.z .a .zz}
"##;
let expected = r##"<h1 class="z a zz">H1</h1>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_18() {
let original = r##"# H1 {.a .a .a}
"##;
let expected = r##"<h1 class="a a a">H1</h1>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_19() {
let original = r##"# H1 {.myclass #myid}
## H2 {.z #m .a}
"##;
let expected = r##"<h1 id="myid" class="myclass">H1</h1>
<h2 id="m" class="z a">H2</h2>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_20() {
let original = r##"# H1 {foo}
## H2 {#myid unknown this#is.ignored attr=value .myclass}
"##;
let expected = r##"<h1 foo="">H1</h1>
<h2 id="myid" class="myclass" unknown="" this#is.ignored="" attr="value">H2</h2>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_21() {
let original = r##"# Header # {myattr=value other_attr}
"##;
let expected = r##"<h1 myattr="value" other_attr="">Header</h1>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_22() {
let original = r##"#### Header {#id myattr= .class1 other_attr=false}
"##;
let expected = r##"<h4 id="id" class="class1" myattr="" other_attr="false">Header</h4>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_23() {
let original = r##"# H1 {.foo{unknown}
## H2 {.foo{.bar}
"##;
let expected = r##"<h1 unknown="">H1 {.foo</h1>
<h2 class="bar">H2 {.foo</h2>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_24() {
let original = r##"# H1 {.foo}bar}
"##;
let expected = r##"<h1>H1 {.foo}bar}</h1>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_25() {
let original = r##"# H1 {<i>foo</i>}
"##;
let expected = r##"<h1>H1 {<i>foo</i>}</h1>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_26() {
let original = r##"# H1 {.foo\}
"##;
let expected = r##"<h1>H1 {.foo}</h1>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_27() {
let original = r##"H1 {.foo
.bar}
==
"##;
let expected = r##"<h1>H1 {.foo
.bar}</h1>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_28() {
let original = r##"H1 {} {}
=====
## H2 {} {}
"##;
let expected = r##"<h1>H1 {}</h1>
<h2>H2 {}</h2>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_29() {
let original = r##"## H2 {} ##
"##;
let expected = r##"<h2>H2 {}</h2>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_30() {
let original = r##"# H1 {\}
## this is also ok \{\}
newline can be used for setext heading {
}
--
"##;
let expected = r##"<h1>H1 {}</h1>
<h2>this is also ok {}</h2>
<h2>newline can be used for setext heading {
}</h2>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_31() {
let original = r##"# H1 \{.foo}
## H2 \\{.bar}
### stray backslash at the end is preserved \
"##;
let expected = r##"<h1 class="foo">H1 \</h1>
<h2 class="bar">H2 \</h2>
<h3>stray backslash at the end is preserved \</h3>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_32() {
let original = r##"H1 \{.foo}
==
H2 \\{.bar}
--
stray backslash at the end is preserved \
--
"##;
let expected = r##"<h1 class="foo">H1 \</h1>
<h2 class="bar">H2 \</h2>
<h2>stray backslash at the end is preserved \</h2>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_33() {
let original = r##"# H1 {#`code`}
## H2 {#foo__bar__baz}
### H3 {#foo**bar**baz}
"##;
let expected = r##"<h1 id="`code`">H1</h1>
<h2 id="foo__bar__baz">H2</h2>
<h3 id="foo**bar**baz">H3</h3>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_34() {
let original = r##"H1 {#`code`}
==
H2-1 {#foo__bar__baz}
----
H2-2 {#foo**bar**baz}
--
"##;
let expected = r##"<h1 id="`code`">H1</h1>
<h2 id="foo__bar__baz">H2-1</h2>
<h2 id="foo**bar**baz">H2-2</h2>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_35() {
let original = r##"# H1 {.foo#bar}
## H2 {#foo.bar}
### H3 {.a"b'c&d}
"##;
let expected = r##"<h1 class="foo#bar">H1</h1>
<h2 id="foo.bar">H2</h2>
<h3 class="a&quot;b&#39;c&amp;d">H3</h3>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_36() {
let original = r##"# H1 {#}
## H2 {.}
"##;
let expected = r##"<h1>H1</h1>
<h2>H2</h2>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_37() {
let original = r##"# H1 {#foo #}
# H1 {.foo . . .bar}
"##;
let expected = r##"<h1 id="foo">H1</h1>
<h1 class="foo bar">H1</h1>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_38() {
let original = r##"# {}
## {}
### {\}
#### {} {}
#{}
"##;
let expected = r##"<h1></h1>
<h2></h2>
<h3>{}</h3>
<h4>{}</h4>
<p>#{}</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_39() {
let original = r##"{}
==
\{}
--
\
--
{\}
==
{}{}
--
"##;
let expected = r##"<h1></h1>
<h2>\</h2>
<h2>\</h2>
<h1>{}</h1>
<h2>{}</h2>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_40() {
let original = r##"# horizontal tab
# horizontal tab {#ht}
## form feed
## form feed {#ff}
### vertical tab
### vertical tab {#vt}
"##;
let expected = r##"<h1>horizontal tab </h1>
<h1 id="ht">horizontal tab </h1>
<h2>form feed </h2>
<h2 id="ff">form feed </h2>
<h3>vertical tab </h3>
<h3 id="vt">vertical tab </h3>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_41() {
let original = r##"# horizontal tab (U+000A) {#ht .myclass}
## form feed (U+000C) {#ff .myclass}
# vertical tab (U+000B) {#vt .myclass}
"##;
let expected = r##"<h1 id="ht" class="myclass">horizontal tab (U+000A)</h1>
<h2 id="ff" class="myclass">form feed (U+000C)</h2>
<h1 id="vt .myclass">vertical tab (U+000B)</h1>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn heading_attrs_test_42() {
let original = r##"# EN SPACE (U+2002) {#en-space .myclass}
## IDEOGRAPHIC SPACE (U+3000) {#ideographic-space .myclass}
"##;
let expected = r##"<h1 id="en-space .myclass">EN SPACE (U+2002)</h1>
<h2 id="ideographic-space .myclass">IDEOGRAPHIC SPACE (U+3000)</h2>
"##;
test_markdown_html(original, expected, false, false, false);
}
+919
View File
@@ -0,0 +1,919 @@
// This file is auto-generated by the build script
// Please, do not modify it manually
use super::test_markdown_html;
#[test]
fn math_test_1() {
let original = r##"This sentence uses `$` delimiters to show math inline: $\sqrt{3x-1}+(1+x)^2$
$\sum_{k=1}^n a_k b_k$: Mathematical expression at head of line
`\` may follow just after the first `$`: $\{1, 2, 3\}$
"##;
let expected = r##"<p>This sentence uses <code>$</code> delimiters to show math inline: <span class="math math-inline">\sqrt{3x-1}+(1+x)^2</span>
<span class="math math-inline">\sum_{k=1}^n a_k b_k</span>: Mathematical expression at head of line</p>
<p><code>\</code> may follow just after the first <code>$</code>: <span class="math math-inline">\{1, 2, 3\}</span></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_2() {
let original = r##"**The Cauchy-Schwarz Inequality**
$$\left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)$$
"##;
let expected = r##"<p><strong>The Cauchy-Schwarz Inequality</strong></p>
<p><span class="math math-display">\left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)</span></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_3() {
let original = r##"Oops empty $$ expression.
$$$$
"##;
let expected = r##"<p>Oops empty $$ expression.</p>
<p><span class="math math-display"></span></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_4() {
let original = r##"$x$$$$$$$y$$
$x$$$$$$y$$
$$x$$$$$$y$$
"##;
let expected = r##"<p><span class="math math-inline">x</span><span class="math math-display"></span><span class="math math-display">y</span></p>
<p><span class="math math-inline">x</span><span class="math math-display"></span><span class="math math-inline">y</span>$</p>
<p><span class="math math-display">x</span><span class="math math-display"></span>y$$</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_5() {
let original = r##"$a<b>c</b>$
$${a*b*c} _c_ d$$
$not `code`$
$![not an](/image)$
$<https://not.a.link/>$
$&alpha;$
"##;
let expected = r##"<p><span class="math math-inline">a&lt;b&gt;c&lt;/b&gt;</span></p>
<p><span class="math math-display">{a*b*c} _c_ d</span></p>
<p><span class="math math-inline">not `code`</span></p>
<p><span class="math math-inline">![not an](/image)</span></p>
<p><span class="math math-inline">&lt;https://not.a.link/&gt;</span></p>
<p><span class="math math-inline">&amp;alpha;</span></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_6() {
let original = r##"Hello $world.
Dollar at end of line$
"##;
let expected = r##"<p>Hello $world.</p>
<p>Dollar at end of line$</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_7() {
let original = r##"$5x + 2 =
17$
$$\left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right)
\left( \sum_{k=1}^n b_k^2 \right)$$
"##;
let expected = r##"<p><span class="math math-inline">5x + 2 =
17</span></p>
<p><span class="math math-display">\left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right)
\left( \sum_{k=1}^n b_k^2 \right)</span></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_8() {
let original = r##"$not a\
hard break
either$
"##;
let expected = r##"<p><span class="math math-inline">not a\
hard break
either</span></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_9() {
let original = r##"$\$$
$$y = \$ x$$
"##;
let expected = r##"<p><span class="math math-inline">\$</span></p>
<p><span class="math math-display">y = \$ x</span></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_10() {
let original = r##"$x $ x$
$$ $ $$
"##;
let expected = r##"<p>$x $ x$</p>
<p>$$ $ $$</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_11() {
let original = r##"alpha$$beta$gamma$$delta
"##;
let expected = r##"<p>alpha$<span class="math math-inline">beta</span>gamma$$delta</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_12() {
let original = r##"these are not math texts: $ y=x$, $y=x $, $
y=x$ and $y=x
$
>The start of a line counts as whitespace $2 +
>$
While displays can start with whitespace, {${
they should not allow inlines to do that $$2 +
$*$
"##;
let expected = r##"<p>these are not math texts: $ y=x$, $y=x $, $
y=x$ and $y=x
$</p>
<blockquote>
<p>The start of a line counts as whitespace $2 +
$</p>
</blockquote>
<p>While displays can start with whitespace, {${
they should not allow inlines to do that $$2 +
<span class="math math-inline">*</span></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_13() {
let original = r##"these are math texts: foo$y=x$bar and $y=x$bar and foo$y=x$ bar
"##;
let expected = r##"<p>these are math texts: foo<span class="math math-inline">y=x</span>bar and <span class="math math-inline">y=x</span>bar and foo<span class="math math-inline">y=x</span> bar</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_14() {
let original = r##"math texts: $x=y$! and $x=y$? and $x=y$: and $x=y$. and $x=y$"
also math texts: !$x=y$! and ?$x=y$? and :$x=y$: and .$x=y$. and "$x=y$"
braces: ($x=y$) [$x=y$] {$x=y$}
"##;
let expected = r##"<p>math texts: <span class="math math-inline">x=y</span>! and <span class="math math-inline">x=y</span>? and <span class="math math-inline">x=y</span>: and <span class="math math-inline">x=y</span>. and <span class="math math-inline">x=y</span>"</p>
<p>also math texts: !<span class="math math-inline">x=y</span>! and ?<span class="math math-inline">x=y</span>? and :<span class="math math-inline">x=y</span>: and .<span class="math math-inline">x=y</span>. and "<span class="math math-inline">x=y</span>"</p>
<p>braces: (<span class="math math-inline">x=y</span>) [<span class="math math-inline">x=y</span>] {<span class="math math-inline">x=y</span>}</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_15() {
let original = r##"$x=y$
"##;
let expected = r##"<p><span class="math math-inline">x=y</span></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_16() {
let original = r##"$a$$b$
$a$$$b$$
$$a$$$b$
$$a$$$$b$$
"##;
let expected = r##"<p><span class="math math-inline">a</span><span class="math math-inline">b</span></p>
<p><span class="math math-inline">a</span><span class="math math-display">b</span></p>
<p><span class="math math-display">a</span><span class="math math-inline">b</span></p>
<p><span class="math math-display">a</span><span class="math math-display">b</span></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_17() {
let original = r##"$Inline `first$ then` code
`Code $first` then$ inline
$$ Display `first $$ then` code
`Code $$ first` then $$ display
"##;
let expected = r##"<p><span class="math math-inline">Inline `first</span> then` code</p>
<p><code>Code $first</code> then$ inline</p>
<p><span class="math math-display"> Display `first </span> then` code</p>
<p><code>Code $$ first</code> then $$ display</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_18() {
let original = r##"$x + y - z$
$x + y
- z$
$$ x + y
> z $$
"##;
let expected = r##"<p><span class="math math-inline">x + y - z</span></p>
<p>$x + y</p>
<ul>
<li>z$</li>
</ul>
<p>$$ x + y</p>
<blockquote>
<p>z $$</p>
</blockquote>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_19() {
let original = r##"$not
math$
$$
not
math
$$
"##;
let expected = r##"<p>$not</p>
<p>math$</p>
<p>$$
not</p>
<p>math
$$</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_20() {
let original = r##"- $not
- *
math$
"##;
let expected = r##"<ul>
<li>$not
<ul>
<li>
<ul>
<li>
</li>
</ul>
</li>
</ul>
math$</li>
</ul>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_21() {
let original = r##"This is display math:
$$
\text{Hello $x^2$}
$$
And this is inline math:
$\text{Hello $x$ there!}$
"##;
let expected = r##"<p>This is display math:
<span class="math math-display">
\text{Hello $x^2$}
</span>
And this is inline math:
<span class="math math-inline">\text{Hello $x$ there!}</span></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_22() {
let original = r##"This is not valid math: $}{$
Neither is this: { $}{$ }
This is: $\}\{$
This is: $\}$
Math environment contains 2+2: $}$2+2$
Math environment contains y: $x {$ $ } $y$
"##;
let expected = r##"<p>This is not valid math: $}{$</p>
<p>Neither is this: { $}{$ }</p>
<p>This is: <span class="math math-inline">\}\{</span></p>
<p>This is: <span class="math math-inline">\}</span></p>
<p>Math environment contains 2+2: $}<span class="math math-inline">2+2</span></p>
<p>Math environment contains y: $x {$ $ } <span class="math math-inline">y</span></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_23() {
let original = r##"This is not display math. It is inline math:
$$\text{first $$ second}$
$$$\text{first $$ second}$
This is display math:
$$\text{first $$ second}$$
$$$\text{first $$ second}$$
This is also display math, but (counterintuitively) it's allowed to be empty
and expected to be as short as possible:
$$$$\text{first $$ second}$$
"##;
let expected = r##"<p>This is not display math. It is inline math:</p>
<p>$<span class="math math-inline">\text{first $$ second}</span></p>
<p>$$<span class="math math-inline">\text{first $$ second}</span></p>
<p>This is display math:</p>
<p><span class="math math-display">\text{first $$ second}</span></p>
<p>$<span class="math math-display">\text{first $$ second}</span></p>
<p>This is also display math, but (counterintuitively) it's allowed to be empty
and expected to be as short as possible:</p>
<p><span class="math math-display"></span>\text{first $$ second}$$</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_24() {
let original = r##"$\text{\$}$
$$x$x$$
${$^$$
$}$$$$
$}$] $$
"##;
let expected = r##"<p><span class="math math-inline">\text{\$}</span></p>
<p>$<span class="math math-inline">x</span>x$$</p>
<p>${<span class="math math-inline">^</span>$</p>
<p>$}<span class="math math-display"></span></p>
<p>$}$] $$</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_25() {
let original = r##"$x$ $`y`$
"##;
let expected = r##"<p><span class="math math-inline">x</span> <span class="math math-inline">`y`</span></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_26() {
let original = r##"- $a$
```math
a
```
$$
a
$$
- ```math
b
```
$$
b
$$
"##;
let expected = r##"<ul>
<li>
<p><span class="math math-inline">a</span></p>
<pre><code class="language-math">a
</code></pre>
<p><span class="math math-display">
a
</span></p>
</li>
<li>
<pre><code class="language-math">b
</code></pre>
<p><span class="math math-display">
b
</span></p>
</li>
</ul>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_27() {
let original = r##"- ![node logo](https://nodejs.org/static/images/logo.svg)
- $x$
"##;
let expected = r##"<ul>
<li><img src="https://nodejs.org/static/images/logo.svg" alt="node logo" /></li>
<li><span class="math math-inline">x</span></li>
</ul>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_28() {
let original = r##"<details>
$A = 5$
$$
A = 5
$$
</details>
"##;
let expected = r##"<details>
<p><span class="math math-inline">A = 5</span></p>
<p><span class="math math-display">
A = 5
</span></p>
</details>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_29() {
let original = r##"$a<b$
$$a<b$$
"##;
let expected = r##"<p><span class="math math-inline">a&lt;b</span></p>
<p><span class="math math-display">a&lt;b</span></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_30() {
let original = r##"[^a]
[^a]: Lorem $a$
"##;
let expected = r##"<p><sup class="footnote-reference"><a href="#a">1</a></sup></p>
<div class="footnote-definition" id="a"><sup class="footnote-definition-label">1</sup>
<p>Lorem <span class="math math-inline">a</span></p>
</div>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_31() {
let original = r##"[$a$](x)
"##;
let expected = r##"<p>
<a href="x"><span class="math math-inline">a</span></a>
</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_32() {
let original = r##"a$x$
-$x$
1$x$
"##;
let expected = r##"<p>a<span class="math math-inline">x</span></p>
<p>-<span class="math math-inline">x</span></p>
<p>1<span class="math math-inline">x</span></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_33() {
let original = r##"_$a$ equals $b$_
_$a$ equals $b$_
**$a$ equals $b$**
"##;
let expected = r##"<p><em><span class="math math-inline">a</span> equals <span class="math math-inline">b</span></em></p>
<p><em><span class="math math-inline">a</span> equals <span class="math math-inline">b</span></em></p>
<p><strong><span class="math math-inline">a</span> equals <span class="math math-inline">b</span></strong></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_34() {
let original = r##"$$
a
$$
- $$
\text{$b$}
$$
"##;
let expected = r##"<p><span class="math math-display">
a
</span>
</p><ul>
<li><span class="math math-display">
\text{$b$}
</span></li>
</ul>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_35() {
let original = r##"$\{a\,b\}$
"##;
let expected = r##"<p><span class="math math-inline">\{a\,b\}</span></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_36() {
let original = r##"$a <b > c$
$[(a+b)c](d+e)$
${a}_b c_{d}$
"##;
let expected = r##"<p><span class="math math-inline">a &lt;b &gt; c</span></p>
<p><span class="math math-inline">[(a+b)c](d+e)</span></p>
<p><span class="math math-inline">{a}_b c_{d}</span></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_37() {
let original = r##"When $a \ne 0$, there are two solutions to $(ax^2 + bx + c = 0)$ and they are
$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$
"##;
let expected = r##"<p>When <span class="math math-inline">a \ne 0</span>, there are two solutions to <span class="math math-inline">(ax^2 + bx + c = 0)</span> and they are
<span class="math math-display"> x = {-b \pm \sqrt{b^2-4ac} \over 2a} </span></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_38() {
let original = r##"$x = \$$
"##;
let expected = r##"<p><span class="math math-inline">x = \$</span></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_39() {
let original = r##"_Equation $\Omega(69)$ in italic text_
"##;
let expected = r##"<p><em>Equation <span class="math math-inline">\Omega(69)</span> in italic text</em></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_40() {
let original = r##"$\pi$
'$\pi$
"$\pi$
($\pi$
[$\pi$
{$\pi$
/$\pi$
"##;
let expected = r##"<p>
<span class="math math-inline">\pi</span>
'<span class="math math-inline">\pi</span>
"<span class="math math-inline">\pi</span>
(<span class="math math-inline">\pi</span>
[<span class="math math-inline">\pi</span>
{<span class="math math-inline">\pi</span>
/<span class="math math-inline">\pi</span>
</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_41() {
let original = r##"| first $|$ second |
|--------|---------|
| a ${ | }$ b |
"##;
let expected = r##"<table><thead>
<tr><th>first $</th><th>$ second</th></tr>
</thead><tbody>
<tr><td>a ${</td><td>}$ b</td></tr>
</tbody></table>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_42() {
let original = r##"| first $\|$ second |
|-------------------|
| a ${ \| }$ b |
"##;
let expected = r##"<table><thead>
<tr><th>first <span class="math math-inline">|</span> second</th></tr>
</thead><tbody>
<tr><td>a <span class="math math-inline">{ | }</span> b</td></tr>
</tbody></table>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_43() {
let original = r##"| Description | Test case |
|-------------|-----------|
| Single | $\$ |
| Double | $\\$ |
| Basic test | $\|$ |
| Basic test 2| $\|\|\$ |
| Basic test 3| $x\|y\|z\$|
| Not pipe | $\.$ |
| Combo | $\.\|$ |
| Combo 2 | $\.\|\$ |
| Extra | $\\\.$ |
| Wait, what? | $\\|$ |
| Wait, what? | $\\\|$ |
| Wait, what? | $\\\\|$ |
| Wait, what? | $\\\\\|$ |
"##;
let expected = r##"<table><thead><tr><th>Description</th><th>Test case</th></tr></thead><tbody>
<tr><td>Single</td><td>$$</td></tr>
<tr><td>Double</td><td><span class="math math-inline">\\</span></td></tr>
<tr><td>Basic test</td><td><span class="math math-inline">|</span></td></tr>
<tr><td>Basic test 2</td><td>$||$</td></tr>
<tr><td>Basic test 3</td><td>$x|y|z$</td></tr>
<tr><td>Not pipe</td><td><span class="math math-inline">\.</span></td></tr>
<tr><td>Combo</td><td><span class="math math-inline">\.|</span></td></tr>
<tr><td>Combo 2</td><td>$.|$</td></tr>
<tr><td>Extra</td><td><span class="math math-inline">\\\.</span></td></tr>
<tr><td>Wait, what?</td><td><span class="math math-inline">\|</span></td></tr>
<tr><td>Wait, what?</td><td><span class="math math-inline">\\|</span></td></tr>
<tr><td>Wait, what?</td><td><span class="math math-inline">\\\|</span></td></tr>
<tr><td>Wait, what?</td><td><span class="math math-inline">\\\\|</span></td></tr>
</tbody></table>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_44() {
let original = r##"This is not an inline math environment: $}{$
But, because it's nested too deeply, this is parsed as an inline math environment:
{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{
improperly $}{$ nested
}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
But this still isn't, because the braces are still counted: $}{$
"##;
let expected = r##"<p>This is not an inline math environment: $}{$
But, because it's nested too deeply, this is parsed as an inline math environment:
{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{
improperly <span class="math math-inline">}{</span> nested
}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
But this still isn't, because the braces are still counted: $}{$</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_45() {
let original = r##"This is also deeply nested, but, unlike the first example,
they don't have an equal number of close braces and open braces,
so aren't detected as math.
{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{
improperly $}$ nested ${$ example
}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
This, however, is detected ${}$
${{{{{{{{{{{{{{{{{{{{{{{{{{{{{{
another improperly nested example
}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}$
"##;
let expected = r##"<p>This is also deeply nested, but, unlike the first example,
they don't have an equal number of close braces and open braces,
so aren't detected as math.
{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{
improperly $}$ nested ${$ example
}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
This, however, is detected <span class="math math-inline">{}</span></p>
<p><span class="math math-inline">{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{
another improperly nested example
}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}</span></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_46() {
let original = r##"${}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 20 brace pairs
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 40 brace pairs
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 60 brace pairs
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 80 brace pairs
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 100 brace pairs
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 120 brace pairs
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 140 brace pairs
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 160 brace pairs
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 180 brace pairs
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 200 brace pairs
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 220 brace pairs
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 240 brace pairs
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{$ 255 brace pairs and one unclosed brace
"##;
let expected = r##"<p><span class="math math-inline">{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 20 brace pairs
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 40 brace pairs
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 60 brace pairs
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 80 brace pairs
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 100 brace pairs
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 120 brace pairs
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 140 brace pairs
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 160 brace pairs
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 180 brace pairs
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 200 brace pairs
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 220 brace pairs
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 240 brace pairs
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{</span> 255 brace pairs and one unclosed brace</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn math_test_47() {
let original = r##"${{{{{{{{{{{{{{{{{{{{ 20 open braces
{{{{{{{{{{{{{{{{{{{{ 40 open braces
{{{{{{{{{{{{{{{{{{{{ 60 open braces
{{{{{{{{{{{{{{{{{{{{ 80 open braces
{{{{{{{{{{{{{{{{{{{{ 100 open braces
{{{{{{{{{{{{{{{{{{{{ 110 open braces
{{{{{{{{{{{{{{{{{{{{ 120 open braces
{{{{{{{{{{{{{{{{{{{{ 140 open braces
{{{{{{{{{{{{{{{{{{{{ 160 open braces
{{{{{{{{{{{{{{{{{{{{ 180 open braces
{{{{{{{{{{{{{{{{{{{{ 200 open braces
{{{{{{{{{{{{{{{{{{{{ 220 open braces
{{{{{{{{{{{{{{{{{{{{ 240 open braces
{{{{{{{{{{{{{{{ 255 open braces
}}}}}}}}}}}}}}}}}}}} 20 close braces
}}}}}}}}}}}}}}}}}}}} 40 close braces
}}}}}}}}}}}}}}}}}}}} 60 close braces
}}}}}}}}}}}}}}}}}}}} 80 close braces
}}}}}}}}}}}}}}}}}}}} 100 close braces
}}}}}}}}}}}}}}}}}}}} 120 close braces
}}}}}}}}}}}}}}}}}}}} 140 close braces
}}}}}}}}}}}}}}}}}}}} 160 close braces
}}}}}}}}}}}}}}}}}}}} 180 close braces
}}}}}}}}}}}}}}}}}}}} 200 close braces
}}}}}}}}}}}}}}}}}}}} 220 close braces
}}}}}}}}}}}}}}}}}}}} 240 close braces
}}}}}}}}}}}}}}}{$ 255 close braces and one open brace
"##;
let expected = r##"<p>${{{{{{{{{{{{{{{{{{{{ 20 open braces
{{{{{{{{{{{{{{{{{{{{ 40 open braces
{{{{{{{{{{{{{{{{{{{{ 60 open braces
{{{{{{{{{{{{{{{{{{{{ 80 open braces
{{{{{{{{{{{{{{{{{{{{ 100 open braces
{{{{{{{{{{{{{{{{{{{{ 110 open braces
{{{{{{{{{{{{{{{{{{{{ 120 open braces
{{{{{{{{{{{{{{{{{{{{ 140 open braces
{{{{{{{{{{{{{{{{{{{{ 160 open braces
{{{{{{{{{{{{{{{{{{{{ 180 open braces
{{{{{{{{{{{{{{{{{{{{ 200 open braces
{{{{{{{{{{{{{{{{{{{{ 220 open braces
{{{{{{{{{{{{{{{{{{{{ 240 open braces
{{{{{{{{{{{{{{{ 255 open braces
}}}}}}}}}}}}}}}}}}}} 20 close braces
}}}}}}}}}}}}}}}}}}}} 40 close braces
}}}}}}}}}}}}}}}}}}}} 60 close braces
}}}}}}}}}}}}}}}}}}}} 80 close braces
}}}}}}}}}}}}}}}}}}}} 100 close braces
}}}}}}}}}}}}}}}}}}}} 120 close braces
}}}}}}}}}}}}}}}}}}}} 140 close braces
}}}}}}}}}}}}}}}}}}}} 160 close braces
}}}}}}}}}}}}}}}}}}}} 180 close braces
}}}}}}}}}}}}}}}}}}}} 200 close braces
}}}}}}}}}}}}}}}}}}}} 220 close braces
}}}}}}}}}}}}}}}}}}}} 240 close braces
}}}}}}}}}}}}}}}{$ 255 close braces and one open brace</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
+181
View File
@@ -0,0 +1,181 @@
// This file is auto-generated by the build script
// Please, do not modify it manually
use super::test_markdown_html;
#[test]
fn metadata_blocks_test_1() {
let original = r##"---
title: example
another_field: 0
---
"##;
let expected = r##""##;
test_markdown_html(original, expected, false, true, false);
}
#[test]
fn metadata_blocks_test_2() {
let original = r##"---
title: example
another_field: 0
"##;
let expected = r##"<hr>
<p>title: example
another_field: 0</p>
"##;
test_markdown_html(original, expected, false, true, false);
}
#[test]
fn metadata_blocks_test_3() {
let original = r##"---
---
"##;
let expected = r##"<hr>
<hr>
"##;
test_markdown_html(original, expected, false, true, false);
}
#[test]
fn metadata_blocks_test_4() {
let original = r##"---
title: example
another_field: 0
---
"##;
let expected = r##"<hr>
<h2>title: example
another_field: 0</h2>
"##;
test_markdown_html(original, expected, false, true, false);
}
#[test]
fn metadata_blocks_test_5() {
let original = r##"My paragraph here.
---
title: example
another_field: 0
---
"##;
let expected = r##"<h2>My paragraph here.</h2>
<h2>title: example
another_field: 0</h2>
"##;
test_markdown_html(original, expected, false, true, false);
}
#[test]
fn metadata_blocks_test_6() {
let original = r##"My paragraph here.
---
title: example
another_field: 0
---
"##;
let expected = r##"<p>My paragraph here.</p>
"##;
test_markdown_html(original, expected, false, true, false);
}
#[test]
fn metadata_blocks_test_7() {
let original = r##"---
title: example
another_field: 0
---
--- -
title: example
another_field: 0
---
"##;
let expected = r##"<hr>
<h2>title: example
another_field: 0</h2>
"##;
test_markdown_html(original, expected, false, true, false);
}
#[test]
fn metadata_blocks_test_8() {
let original = r##"---
title: example
another_field: 0
---
---
title: example
another_field: 0
---a
"##;
let expected = r##"<hr>
<p>title: example
another_field: 0
---a</p>
"##;
test_markdown_html(original, expected, false, true, false);
}
#[test]
fn metadata_blocks_test_9() {
let original = r##"---
title: example
another_field: 0
...
"##;
let expected = r##""##;
test_markdown_html(original, expected, false, true, false);
}
#[test]
fn metadata_blocks_test_10() {
let original = r##"+++
title: example
another_field: 0
+++
"##;
let expected = r##""##;
test_markdown_html(original, expected, false, true, false);
}
#[test]
fn metadata_blocks_test_11() {
let original = r##" ---
Things
---
"##;
let expected = r##"<pre><code>---
Things
---
</code></pre>
"##;
test_markdown_html(original, expected, false, true, false);
}
#[test]
fn metadata_blocks_test_12() {
let original = r##"---
- Item 1
- Item 2
---
"##;
let expected = r##""##;
test_markdown_html(original, expected, false, true, false);
}
+19
View File
@@ -0,0 +1,19 @@
// This file is auto-generated by the build script
// Please, do not modify it manually
pub use super::test_markdown_html;
mod blockquotes_tags;
mod footnotes;
mod gfm_strikethrough;
mod gfm_table;
mod gfm_tasklist;
mod heading_attrs;
mod math;
mod metadata_blocks;
mod old_footnotes;
mod regression;
mod smart_punct;
mod spec;
mod strikethrough;
mod table;
+215
View File
@@ -0,0 +1,215 @@
// This file is auto-generated by the build script
// Please, do not modify it manually
use super::test_markdown_html;
#[test]
fn old_footnotes_test_1() {
let original = r##"Lorem ipsum.[^a]
[^a]: Cool.
"##;
let expected = r##"<p>Lorem ipsum.<sup class="footnote-reference"><a href="#a">1</a></sup></p>
<div class="footnote-definition" id="a"><sup class="footnote-definition-label">1</sup>
<p>Cool.</p>
</div>
"##;
test_markdown_html(original, expected, false, false, true);
}
#[test]
fn old_footnotes_test_2() {
let original = r##"> This is the song that never ends.\
> Yes it goes on and on my friends.[^lambchops]
>
> [^lambchops]: <https://www.youtube.com/watch?v=0U2zJOryHKQ>
"##;
let expected = r##"<blockquote>
<p>This is the song that never ends.<br />
Yes it goes on and on my friends.<sup class="footnote-reference"><a href="#lambchops">1</a></sup></p>
<div class="footnote-definition" id="lambchops"><sup class="footnote-definition-label">1</sup>
<p><a href="https://www.youtube.com/watch?v=0U2zJOryHKQ">https://www.youtube.com/watch?v=0U2zJOryHKQ</a></p>
</div>
</blockquote>
"##;
test_markdown_html(original, expected, false, false, true);
}
#[test]
fn old_footnotes_test_3() {
let original = r##"Songs that simply loop are a popular way to annoy people. [^examples]
[^examples]:
* [The song that never ends](https://www.youtube.com/watch?v=0U2zJOryHKQ)
* [I know a song that gets on everybody's nerves](https://www.youtube.com/watch?v=TehWI09qxls)
* [Ninety-nine bottles of beer on the wall](https://www.youtube.com/watch?v=qVjCag8XoHQ)
"##;
let expected = r##"<p>Songs that simply loop are a popular way to annoy people. <sup class="footnote-reference"><a href="#examples">1</a></sup></p>
<div class="footnote-definition" id="examples"><sup class="footnote-definition-label">1</sup>
<ul>
<li><a href="https://www.youtube.com/watch?v=0U2zJOryHKQ">The song that never ends</a></li>
<li><a href="https://www.youtube.com/watch?v=TehWI09qxls">I know a song that gets on everybody's nerves</a></li>
<li><a href="https://www.youtube.com/watch?v=qVjCag8XoHQ">Ninety-nine bottles of beer on the wall</a></li>
</ul>
</div>
"##;
test_markdown_html(original, expected, false, false, true);
}
#[test]
fn old_footnotes_test_4() {
let original = r##"[^lorem]: If heaven ever wishes to grant me a boon, it will be a total effacing of the results of a mere chance which fixed my eye on a certain stray piece of shelf-paper. It was nothing on which I would naturally have stumbled in the course of my daily round, for it was an old number of an Australian journal, the Sydney Bulletin for April 18, 1925. It had escaped even the cutting bureau which had at the time of its issuance been avidly collecting material for my uncle's research.
I had largely given over my inquiries into what Professor Angell called the "Cthulhu Cult", and was visiting a learned friend in Paterson, New Jersey; the curator of a local museum and a mineralogist of note. Examining one day the reserve specimens roughly set on the storage shelves in a rear room of the museum, my eye was caught by an odd picture in one of the old papers spread beneath the stones. It was the Sydney Bulletin I have mentioned, for my friend had wide affiliations in all conceivable foreign parts; and the picture was a half-tone cut of a hideous stone image almost identical with that which Legrasse had found in the swamp.
"##;
let expected = r##"<div class="footnote-definition" id="lorem"><sup class="footnote-definition-label">1</sup>
<p>If heaven ever wishes to grant me a boon, it will be a total effacing of the results of a mere chance which fixed my eye on a certain stray piece of shelf-paper. It was nothing on which I would naturally have stumbled in the course of my daily round, for it was an old number of an Australian journal, the Sydney Bulletin for April 18, 1925. It had escaped even the cutting bureau which had at the time of its issuance been avidly collecting material for my uncle's research.</p>
</div>
<p>I had largely given over my inquiries into what Professor Angell called the "Cthulhu Cult", and was visiting a learned friend in Paterson, New Jersey; the curator of a local museum and a mineralogist of note. Examining one day the reserve specimens roughly set on the storage shelves in a rear room of the museum, my eye was caught by an odd picture in one of the old papers spread beneath the stones. It was the Sydney Bulletin I have mentioned, for my friend had wide affiliations in all conceivable foreign parts; and the picture was a half-tone cut of a hideous stone image almost identical with that which Legrasse had found in the swamp.</p>
"##;
test_markdown_html(original, expected, false, false, true);
}
#[test]
fn old_footnotes_test_5() {
let original = r##"[^ipsum]: How much wood would a woodchuck chuck.
If a woodchuck could chuck wood.
# Forms of entertainment that aren't childish
"##;
let expected = r##"<div class="footnote-definition" id="ipsum"><sup class="footnote-definition-label">1</sup>
<p>How much wood would a woodchuck chuck.</p>
</div>
<p>If a woodchuck could chuck wood.</p>
<h1>Forms of entertainment that aren't childish</h1>
"##;
test_markdown_html(original, expected, false, false, true);
}
#[test]
fn old_footnotes_test_6() {
let original = r##"> He's also really stupid. [^why]
>
> [^why]: Because your mamma!
As such, we can guarantee that the non-childish forms of entertainment are probably more entertaining to adults, since, having had a whole childhood doing the childish ones, the non-childish ones are merely the ones that haven't gotten boring yet.
"##;
let expected = r##"<blockquote>
<p>He's also really stupid. <sup class="footnote-reference"><a href="#why">1</a></sup></p>
<div class="footnote-definition" id="why"><sup class="footnote-definition-label">1</sup>
<p>Because your mamma!</p>
</div>
</blockquote>
<p>As such, we can guarantee that the non-childish forms of entertainment are probably more entertaining to adults, since, having had a whole childhood doing the childish ones, the non-childish ones are merely the ones that haven't gotten boring yet.</p>
"##;
test_markdown_html(original, expected, false, false, true);
}
#[test]
fn old_footnotes_test_7() {
let original = r##"Nested footnotes are considered poor style. [^a] [^xkcd]
[^a]: This does not mean that footnotes cannot reference each other. [^b]
[^b]: This means that a footnote definition cannot be directly inside another footnote definition.
> This means that a footnote cannot be directly inside another footnote's body. [^e]
>
> [^e]: They can, however, be inside anything else.
[^xkcd]: [The other kind of nested footnote is, however, considered poor style.](https://xkcd.com/1208/)
"##;
let expected = r##"<p>Nested footnotes are considered poor style. <sup class="footnote-reference"><a href="#a">1</a></sup> <sup class="footnote-reference"><a href="#xkcd">2</a></sup></p>
<div class="footnote-definition" id="a"><sup class="footnote-definition-label">1</sup>
<p>This does not mean that footnotes cannot reference each other. <sup class="footnote-reference"><a href="#b">3</a></sup></p>
</div>
<div class="footnote-definition" id="b"><sup class="footnote-definition-label">3</sup>
<p>This means that a footnote definition cannot be directly inside another footnote definition.</p>
<blockquote>
<p>This means that a footnote cannot be directly inside another footnote's body. <sup class="footnote-reference"><a href="#e">4</a></sup></p>
<div class="footnote-definition" id="e"><sup class="footnote-definition-label">4</sup>
<p>They can, however, be inside anything else.</p>
</div>
</blockquote>
</div>
<div class="footnote-definition" id="xkcd"><sup class="footnote-definition-label">2</sup>
<p><a href="https://xkcd.com/1208/">The other kind of nested footnote is, however, considered poor style.</a></p>
</div>
"##;
test_markdown_html(original, expected, false, false, true);
}
#[test]
fn old_footnotes_test_8() {
let original = r##"[^Doh] Ray Me Fa So La Te Do! [^1]
[^Doh]: I know. Wrong Doe. And it will render right.
[^1]: Common for people practicing music.
"##;
let expected = r##"<p><sup class="footnote-reference"><a href="#Doh">1</a></sup> Ray Me Fa So La Te Do! <sup class="footnote-reference"><a href="#1">2</a></sup></p>
<div class="footnote-definition" id="Doh"><sup class="footnote-definition-label">1</sup><p>I know. Wrong Doe. And it will render right.</p></div>
<div class="footnote-definition" id="1"><sup class="footnote-definition-label">2</sup><p>Common for people practicing music.</p></div>
"##;
test_markdown_html(original, expected, false, false, true);
}
#[test]
fn old_footnotes_test_9() {
let original = r##"[Reference to footnotes A[^1], B[^2] and C[^3].
[^1]: Footnote A.
[^2]: Footnote B.
[^3]: Footnote C.
"##;
let expected = r##"<p>[Reference to footnotes A<sup class="footnote-reference"><a href="#1">1</a></sup>, B<sup class="footnote-reference"><a href="#2">2</a></sup> and C<sup class="footnote-reference"><a href="#3">3</a></sup>.</p><div class="footnote-definition" id="1"><sup class="footnote-definition-label">1</sup><p>Footnote A.</p></div><div class="footnote-definition" id="2"><sup class="footnote-definition-label">2</sup><p>Footnote B.</p></div><div class="footnote-definition" id="3"><sup class="footnote-definition-label">3</sup><p>Footnote C.</p></div>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn old_footnotes_test_10() {
let original = r##"Lorem ipsum.[^a][^b]
[^a]: Foo
[^b]: Bar
"##;
let expected = r##"<p>Lorem ipsum.<sup class="footnote-reference"><a href="#a">1</a></sup><sup class="footnote-reference"><a href="#b">2</a></sup></p>
<div class="footnote-definition" id="a"><sup class="footnote-definition-label">1</sup>
<p>Foo</p>
</div>
<div class="footnote-definition" id="b"><sup class="footnote-definition-label">2</sup>
<p>Bar</p>
</div>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn old_footnotes_test_11() {
let original = r##"Lorem ipsum.[^a] [^b]
[^a]: Foo
[^b]: Bar
"##;
let expected = r##"<p>Lorem ipsum.<sup class="footnote-reference"><a href="#a">1</a></sup> <sup class="footnote-reference"><a href="#b">2</a></sup></p>
<div class="footnote-definition" id="a"><sup class="footnote-definition-label">1</sup>
<p>Foo</p>
</div>
<div class="footnote-definition" id="b"><sup class="footnote-definition-label">2</sup>
<p>Bar</p>
</div>
"##;
test_markdown_html(original, expected, false, false, false);
}
File diff suppressed because it is too large. Load diff
+201
View File
@@ -0,0 +1,201 @@
// This file is auto-generated by the build script
// Please, do not modify it manually
use super::test_markdown_html;
#[test]
fn smart_punct_test_1() {
let original = r##""Hello," said the spider.
"'Shelob' is my name."
"##;
let expected = r##"<p>“Hello,” said the spider.
“‘Shelob’ is my name.”</p>
"##;
test_markdown_html(original, expected, true, false, false);
}
#[test]
fn smart_punct_test_2() {
let original = r##"'A', 'B', and 'C' are letters.
"##;
let expected = r##"<p>‘A’, ‘B’, and ‘C’ are letters.</p>
"##;
test_markdown_html(original, expected, true, false, false);
}
#[test]
fn smart_punct_test_3() {
let original = r##"'Oak,' 'elm,' and 'beech' are names of trees.
So is 'pine.'
"##;
let expected = r##"<p>‘Oak,’ ‘elm,’ and ‘beech’ are names of trees.
So is ‘pine.’</p>
"##;
test_markdown_html(original, expected, true, false, false);
}
#[test]
fn smart_punct_test_4() {
let original = r##"'He said, "I want to go."'
"##;
let expected = r##"<p>‘He said, “I want to go.”’</p>
"##;
test_markdown_html(original, expected, true, false, false);
}
#[test]
fn smart_punct_test_5() {
let original = r##"Were you alive in the 70's?
"##;
let expected = r##"<p>Were you alive in the 70’s?</p>
"##;
test_markdown_html(original, expected, true, false, false);
}
#[test]
fn smart_punct_test_6() {
let original = r##"Here is some quoted '`code`' and a "[quoted link](url)".
"##;
let expected = r##"<p>Here is some quoted ‘<code>code</code>’ and a “<a href="url">quoted link</a>”.</p>
"##;
test_markdown_html(original, expected, true, false, false);
}
#[test]
fn smart_punct_test_7() {
let original = r##"'tis the season to be 'jolly'
"##;
let expected = r##"<p>’tis the season to be ‘jolly’</p>
"##;
test_markdown_html(original, expected, true, false, false);
}
#[test]
fn smart_punct_test_8() {
let original = r##"'We'll use Jane's boat and John's truck,' Jenna said.
"##;
let expected = r##"<p>‘We’ll use Jane’s boat and John’s truck,’ Jenna said.</p>
"##;
test_markdown_html(original, expected, true, false, false);
}
#[test]
fn smart_punct_test_9() {
let original = r##""A paragraph with no closing quote.
"Second paragraph by same speaker, in fiction."
"##;
let expected = r##"<p>“A paragraph with no closing quote.</p>
<p>“Second paragraph by same speaker, in fiction.”</p>
"##;
test_markdown_html(original, expected, true, false, false);
}
#[test]
fn smart_punct_test_10() {
let original = r##"[a]'s b'
"##;
let expected = r##"<p>[a]’s b’</p>
"##;
test_markdown_html(original, expected, true, false, false);
}
#[test]
fn smart_punct_test_11() {
let original = r##"\"This is not smart.\"
This isn\'t either.
5\'8\"
"##;
let expected = r##"<p>"This is not smart."
This isn't either.
5'8"</p>
"##;
test_markdown_html(original, expected, true, false, false);
}
#[test]
fn smart_punct_test_12() {
let original = r##"Some dashes: em---em
en--en
em --- em
en -- en
2--3
"##;
let expected = r##"<p>Some dashes: em—em
en–en
em — em
en – en
2–3</p>
"##;
test_markdown_html(original, expected, true, false, false);
}
#[test]
fn smart_punct_test_13() {
let original = r##"one-
two--
three---
four----
five-----
six------
seven-------
eight--------
nine---------
thirteen-------------.
"##;
let expected = r##"<p>one-
two–
three—
four––
five—–
six——
seven—––
eight––––
nine———
thirteen———––.</p>
"##;
test_markdown_html(original, expected, true, false, false);
}
#[test]
fn smart_punct_test_14() {
let original = r##"Escaped hyphens: \-- \-\-\-.
"##;
let expected = r##"<p>Escaped hyphens: -- ---.</p>
"##;
test_markdown_html(original, expected, true, false, false);
}
#[test]
fn smart_punct_test_15() {
let original = r##"Ellipses...and...and....
"##;
let expected = r##"<p>Ellipses…and…and….</p>
"##;
test_markdown_html(original, expected, true, false, false);
}
#[test]
fn smart_punct_test_16() {
let original = r##"No ellipses\.\.\.
"##;
let expected = r##"<p>No ellipses...</p>
"##;
test_markdown_html(original, expected, true, false, false);
}
File diff suppressed because it is too large. Load diff
+164
View File
@@ -0,0 +1,164 @@
// This file is auto-generated by the build script
// Please, do not modify it manually
use super::test_markdown_html;
#[test]
fn strikethrough_test_1() {
let original = r##"~~This is *stricken out*~~
"##;
let expected = r##"<p><del>This is <em>stricken out</em></del></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn strikethrough_test_2() {
let original = r##"~~This is \~\~stricken~~
"##;
let expected = r##"<p><del>This is ~~stricken</del></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn strikethrough_test_3() {
let original = r##"This~~is~~stricken
"##;
let expected = r##"<p>This<del>is</del>stricken</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn strikethrough_test_4() {
let original = r##"~~This~~is~~stricken~~
"##;
let expected = r##"<p><del>This</del>is<del>stricken</del></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn strikethrough_test_5() {
let original = r##"Here I strike out an exclamation point~~!~~.
"##;
let expected = r##"<p>Here I strike out an exclamation point<del>!</del>.</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn strikethrough_test_6() {
let original = r##"~This is stricken out~
"##;
let expected = r##"<p><del>This is stricken out</del></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn strikethrough_test_7() {
let original = r##"~This is \~stricken~
"##;
let expected = r##"<p><del>This is ~stricken</del></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn strikethrough_test_8() {
let original = r##"This~is~nothing
"##;
let expected = r##"<p>This~is~nothing</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn strikethrough_test_9() {
let original = r##"~This~is~nothing~
"##;
let expected = r##"<p><del>This~is~nothing</del></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn strikethrough_test_10() {
let original = r##"Here I fail to strike out an exclamation point~!~.
"##;
let expected = r##"<p>Here I fail to strike out an exclamation point~!~.</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn strikethrough_test_11() {
let original = r##"Here I fail to strike out a tilde ~~~.
"##;
let expected = r##"<p>Here I fail to strike out a tilde ~~~.</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn strikethrough_test_12() {
let original = r##"Here I fail to match up ~~tildes~.
"##;
let expected = r##"<p>Here I fail to match up ~~tildes~.</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn strikethrough_test_13() {
let original = r##"Here I fail to match up ~tildes~~.
"##;
let expected = r##"<p>Here I fail to match up ~tildes~~.</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn strikethrough_test_14() {
let original = r##"~~This ~is stricken.~~
"##;
let expected = r##"<p><del>This ~is stricken.</del></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn strikethrough_test_15() {
let original = r##"~This ~~is stricken.~
"##;
let expected = r##"<p><del>This ~~is stricken.</del></p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn strikethrough_test_16() {
let original = r##"~This ~~is stricken~ but this is not~~
"##;
let expected = r##"<p><del>This ~~is stricken</del> but this is not~~</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
+632
View File
@@ -0,0 +1,632 @@
// This file is auto-generated by the build script
// Please, do not modify it manually
use super::test_markdown_html;
#[test]
fn table_test_1() {
let original = r##"Test header
-----------
"##;
let expected = r##"<h2>Test header</h2>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_2() {
let original = r##"Test|Table
----|-----
"##;
let expected = r##"<table><thead><tr><th>Test</th><th>Table</th></tr></thead><tbody></tbody>
</table>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_3() {
let original = r##"> Test | Table
> ------|------
> Row 1 | Every
> Row 2 | Day
>
> Paragraph
"##;
let expected = r##"<blockquote>
<table><thead><tr><th>Test</th><th>Table</th></tr></thead><tbody>
<tr><td>Row 1</td><td>Every</td></tr>
<tr><td>Row 2</td><td>Day</td></tr>
</tbody></table>
<p>Paragraph</p>
</blockquote>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_4() {
let original = r##" 1. First entry
2. Second entry
Col 1|Col 2
-|-
Row 1|Part 2
Row 2|Part 2
"##;
let expected = r##"<ol>
<li>
<p>First entry</p>
</li>
<li>
<p>Second entry</p>
<table><thead><tr><th>Col 1</th><th>Col 2</th></tr></thead><tbody>
<tr><td>Row 1</td><td>Part 2</td></tr>
<tr><td>Row 2</td><td>Part 2</td></tr>
</tbody></table>
</li>
</ol>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_5() {
let original = r##"|Col 1|Col 2|
|-----|-----|
|R1C1 |R1C2 |
|R2C1 |R2C2 |
"##;
let expected = r##"<table><thead><tr><th>Col 1</th><th>Col 2</th></tr></thead><tbody>
<tr><td>R1C1</td><td>R1C2</td></tr>
<tr><td>R2C1</td><td>R2C2</td></tr>
</tbody></table>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_6() {
let original = r##"| Col 1 | Col 2 |
|-------|-------|
| | |
| | |
"##;
let expected = r##"<table><thead><tr><th>Col 1</th><th>Col 2</th></tr></thead><tbody>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
</tbody></table>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_7() {
let original = r##"| Col 1 | Col 2 |
|-------|-------|
| x | |
| | x |
"##;
let expected = r##"<table><thead><tr><th>Col 1</th><th>Col 2</th></tr></thead><tbody>
<tr><td>x</td><td></td></tr>
<tr><td></td><td>x</td></tr>
</tbody></table>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_8() {
let original = r##"|Col 1|Col 2|
|-----|-----|
|✓ |✓ |
|✓ |✓ |
"##;
let expected = r##"<table><thead><tr><th>Col 1</th><th>Col 2</th></tr></thead><tbody>
<tr><td>✓</td><td>✓</td></tr>
<tr><td>✓</td><td>✓</td></tr>
</tbody></table>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_9() {
let original = r##"| Target | std |rustc|cargo| notes |
|-------------------------------|-----|-----|-----|----------------------------|
| `x86_64-unknown-linux-musl` | ✓ | | | 64-bit Linux with MUSL |
| `arm-linux-androideabi` | ✓ | | | ARM Android |
| `arm-unknown-linux-gnueabi` | ✓ | ✓ | | ARM Linux (2.6.18+) |
| `arm-unknown-linux-gnueabihf` | ✓ | ✓ | | ARM Linux (2.6.18+) |
| `aarch64-unknown-linux-gnu` | ✓ | | | ARM64 Linux (2.6.18+) |
| `mips-unknown-linux-gnu` | ✓ | | | MIPS Linux (2.6.18+) |
| `mipsel-unknown-linux-gnu` | ✓ | | | MIPS (LE) Linux (2.6.18+) |
"##;
let expected = r##"<table><thead><tr><th>Target</th><th>std</th><th>rustc</th><th>cargo</th><th>notes</th></tr></thead><tbody>
<tr><td><code>x86_64-unknown-linux-musl</code></td><td>✓</td><td></td><td></td><td>64-bit Linux with MUSL</td></tr>
<tr><td><code>arm-linux-androideabi</code></td><td>✓</td><td></td><td></td><td>ARM Android</td></tr>
<tr><td><code>arm-unknown-linux-gnueabi</code></td><td>✓</td><td>✓</td><td></td><td>ARM Linux (2.6.18+)</td></tr>
<tr><td><code>arm-unknown-linux-gnueabihf</code></td><td>✓</td><td>✓</td><td></td><td>ARM Linux (2.6.18+)</td></tr>
<tr><td><code>aarch64-unknown-linux-gnu</code></td><td>✓</td><td></td><td></td><td>ARM64 Linux (2.6.18+)</td></tr>
<tr><td><code>mips-unknown-linux-gnu</code></td><td>✓</td><td></td><td></td><td>MIPS Linux (2.6.18+)</td></tr>
<tr><td><code>mipsel-unknown-linux-gnu</code></td><td>✓</td><td></td><td></td><td>MIPS (LE) Linux (2.6.18+)</td></tr>
</tbody></table>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_10() {
let original = r##"|-|-|
|ぃ|い|
"##;
let expected = r##"<p>|-|-|
|ぃ|い|</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_11() {
let original = r##"|ぁ|ぃ|
|-|-|
|ぃ|ぃ|
"##;
let expected = r##"<table><thead><tr><th>ぁ</th><th>ぃ</th></tr></thead><tbody>
<tr><td>ぃ</td><td>ぃ</td></tr>
</tbody></table>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_12() {
let original = r##"|Колонка 1|Колонка 2|
|---------|---------|
|Ячейка 1 |Ячейка 2 |
"##;
let expected = r##"<table><thead><tr><th>Колонка 1</th><th>Колонка 2</th></tr></thead><tbody>
<tr><td>Ячейка 1</td><td>Ячейка 2</td></tr>
</tbody></table>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_13() {
let original = r##"table a
| a | b |
| --- | --- |
| c | d |
table b
| a | b |
| --- | --- |
| c | d |
table c
a | b
--- | ---
c | d
table d
a | b
--|--
c | d
table e
a | b
--|--
c | d
table f
| a | b |
| --- | --- |
| c | d |
table g
a | b
--- | ---
c | d
table h
a
|-|
b
table i
| a
|-
b
table j
| a
-
b
"##;
let expected = r##"<p>table a</p>
<table><thead><tr><th>a</th><th>b</th></tr></thead><tbody>
<tr><td>c</td><td>d</td></tr>
</tbody></table>
<p>table b
| a | b |
| --- | --- |
| c | d |</p>
<p>table c
a | b
--- | ---
c | d</p>
<p>table d
a | b
--|--
c | d</p>
<p>table e
a | b
--|--
c | d</p>
<p>table f</p>
<table><thead><tr><th>a</th><th>b</th></tr></thead><tbody>
<tr><td>c</td><td>d</td></tr>
</tbody></table>
<p>table g
a | b
--- | ---
c | d</p>
<p>table h
a
|-|
b</p>
<p>table i</p>
<table><thead><tr><th>a</th></tr></thead><tbody>
<tr><td>b</td></tr>
</tbody></table>
<h2>table j
| a</h2>
<p>b</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_14() {
let original = r##"a | b
- | -
1 | 2
"##;
let expected = r##"<table><thead><tr><th>a</th><th>b</th></tr></thead><tbody>
<tr><td>1</td><td>2</td></tr>
</tbody></table>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_15() {
let original = r##"a | b\
- | -
1 | 2
"##;
let expected = r##"<p>a | b\</p>
<ul>
<li>| -
1 | 2</li>
</ul>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_16() {
let original = r##"a\
| b | c |
|---|---|
| d | e |
"##;
let expected = r##"<p>a\</p>
<table><thead><tr><th>b</th><th>c</th></tr></thead><tbody>
<tr><td>d</td><td>e</td></tr>
</tbody></table>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_17() {
let original = r##"| Description | Test case |
|-------------|-----------|
| Single | `\` |
| Double | `\\` |
| Basic test | `\|` |
| Basic test 2| `\|\|\` |
| Basic test 3| `x\|y\|z\`|
| Not pipe | `\.` |
| Combo | `\.\|\` |
| Extra | `\\\.` |
| Wait, what? | `\\|` |
| Wait, what? | `\\\|` |
| Wait, what? | `\\\\|` |
| Wait, what? | `\\\\\|` |
| Wait, what? | \|
| Wait, what? | \\|
| Wait, what? | \\\|
| Wait, what?x| \|x
| Wait, what?x| \\|x
| Wait, what?x| \\\|x
| Direct trail| \.|x
"##;
let expected = r##"<table><thead><tr><th>Description</th><th>Test case</th></tr></thead><tbody>
<tr><td>Single</td><td><code>\</code></td></tr>
<tr><td>Double</td><td><code>\\</code></td></tr>
<tr><td>Basic test</td><td><code>|</code></td></tr>
<tr><td>Basic test 2</td><td><code>||\</code></td></tr>
<tr><td>Basic test 3</td><td><code>x|y|z\</code></td></tr>
<tr><td>Not pipe</td><td><code>\.</code></td></tr>
<tr><td>Combo</td><td><code>\.|\</code></td></tr>
<tr><td>Extra</td><td><code>\\\.</code></td></tr>
<tr><td>Wait, what?</td><td><code>\|</code></td></tr>
<tr><td>Wait, what?</td><td><code>\\|</code></td></tr>
<tr><td>Wait, what?</td><td><code>\\\|</code></td></tr>
<tr><td>Wait, what?</td><td><code>\\\\|</code></td></tr>
<tr><td>Wait, what?</td><td>|</td></tr>
<tr><td>Wait, what?</td><td>|</td></tr>
<tr><td>Wait, what?</td><td>\|</td></tr>
<tr><td>Wait, what?x</td><td>|x</td></tr>
<tr><td>Wait, what?x</td><td>|x</td></tr>
<tr><td>Wait, what?x</td><td>\|x</td></tr>
<tr><td>Direct trail</td><td>.</td></tr>
</tbody></table>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_18() {
let original = r##"| Single | `\|` |
|--|--|
| Single | `\|` |
| Double | `\\|` |
|--|--|
| Double | `\\|` |
| Double Twice | `\\|\\|` |
|--|--|
| Double Twice | `\\|\\|` |
| Triple | `\\\|` |
|--|--|
| Triple | `\\\|` |
"##;
let expected = r##"<table><thead><tr><th>Single</th><th><code>|</code></th></tr></thead><tbody>
<tr><td>Single</td><td><code>|</code></td></tr>
</tbody></table>
<table><thead><tr><th>Double</th><th><code>\|</code></th></tr></thead><tbody>
<tr><td>Double</td><td><code>\|</code></td></tr>
</tbody></table>
<table><thead><tr><th>Double Twice</th><th><code>\|\|</code></th></tr></thead><tbody>
<tr><td>Double Twice</td><td><code>\|\|</code></td></tr>
</tbody></table>
<table><thead><tr><th>Triple</th><th><code>\\|</code></th></tr></thead><tbody>
<tr><td>Triple</td><td><code>\\|</code></td></tr>
</tbody></table>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_19() {
let original = r##"| Table | Header |
|-------|--------|
| Table | Body |
|
| Not | Enough |
| Table | Header |
|-------|--------|
| Table | Body |
|
| Not | Enough |
"##;
let expected = r##"<table><thead><tr><th>Table</th><th>Header</th></tr></thead><tbody>
<tr><td>Table</td><td>Body</td></tr>
</tbody></table>
<p>|
| Not | Enough |</p>
<table><thead><tr><th>Table</th><th>Header</th></tr></thead><tbody>
<tr><td>Table</td><td>Body</td></tr>
</tbody></table>
<p>|
| Not | Enough |</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_20() {
let original = r##"| Table | Header |
|-------|--------|
|
"##;
let expected = r##"<table><thead><tr><th>Table</th><th>Header</th></tr></thead><tbody>
</tbody></table>
<p>|</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_21() {
let original = r##"|
|-------|--------|
| Table | Body |
"##;
let expected = r##"<p>|
|-------|--------|
| Table | Body |</p>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_22() {
let original = r##"| Single | [test](first\|second) |
|--|--|
| Double | [test](first\\|second) |
|--|--|
| Triple | [test](first\\\|second) |
|--|--|
"##;
let expected = r##"<table><thead><tr><th>Single</th><th><a href="first%7Csecond">test</a></th></tr></thead><tbody>
</tbody></table>
<table><thead><tr><th>Double</th><th><a href="first%7Csecond">test</a></th></tr></thead><tbody>
</tbody></table>
<table><thead><tr><th>Triple</th><th><a href="first%5C%7Csecond">test</a></th></tr></thead><tbody>
</tbody></table>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_23() {
let original = r##"| Single | [first\|second] |
|--|--|
| Double | [first\\|second] |
|--|--|
| Triple | [first\\\|second] |
|--|--|
[first\|second]: https://rust-lang.org
[first\\|second]: https://docs.rs
"##;
let expected = r##"<table><thead><tr><th>Single</th><th>[first|second]</th></tr></thead><tbody>
</tbody></table>
<table><thead><tr><th>Double</th><th><a href="https://rust-lang.org">first|second</a></th></tr></thead><tbody>
</tbody></table>
<table><thead><tr><th>Triple</th><th><a href="https://docs.rs">first\|second</a></th></tr></thead><tbody>
</tbody></table>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_24() {
let original = r##"Q: Knock knock.
A: Who's there.
Q: Interrupting cow.
A: Interrupting —?
| `Moo\\|ooo` |
|-------------|
| `ooo\\|ooo` |
"##;
let expected = r##"<p>Q: Knock knock.
A: Who's there.
Q: Interrupting cow.
A: Interrupting —?</p>
<table><thead><tr><th><code>Moo\|ooo</code></th></tr></thead><tbody>
<tr><td><code>ooo\|ooo</code></td></tr>
</tbody></table>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_25() {
let original = r##"| ![Moo\\|Moo](image.png) |
|-------------|
| ![Moo\\\|Moo](image.png) |
"##;
let expected = r##"<table><thead><tr><th><img src="image.png" alt="Moo|Moo" /></th></tr></thead><tbody>
<tr><td><img src="image.png" alt="Moo\|Moo" /></td></tr>
</tbody></table>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_26() {
let original = r##"| [Moo](https://example.org "Example\\|Link") |
|---------------------------------------------|
| [Moo](https://example.org "Example\\\|Link") |
"##;
let expected = r##"<table><thead><tr><th><a href="https://example.org" title="Example|Link">Moo</a></th></tr></thead><tbody>
<tr><td><a href="https://example.org" title="Example\|Link">Moo</a></td></tr>
</tbody></table>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_27() {
let original = r##"moo | moo
----|----
moo | moo
*
"##;
let expected = r##"<table><thead><tr><th>moo</th><th>moo</th></tr></thead><tbody>
<tr><td>moo</td><td>moo</td></tr>
</tbody></table>
<ul>
<li></li>
</ul>
"##;
test_markdown_html(original, expected, false, false, false);
}
#[test]
fn table_test_28() {
let original = r##"moo | moo
----|----
moo | moo
2.
"##;
let expected = r##"<table><thead><tr><th>moo</th><th>moo</th></tr></thead><tbody>
<tr><td>moo</td><td>moo</td></tr>
</tbody></table>
<ol start="2">
<li></li>
</ol>
"##;
test_markdown_html(original, expected, false, false, false);
}