Something went wrong. Try again.
Markdown parser fork with extended syntax for personal use.
Something went wrong. Try again.
25 kB · 880 lines
Rust
at hack
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881use markdown::{ mdast::{Emphasis, Node, Paragraph, Root, Strong, Text}, message, to_html, to_html_with_options, to_mdast, unist::Position, CompileOptions, Constructs, Options, ParseOptions,};use pretty_assertions::assert_eq;
#[test]fn attention() -> Result<(), message::Message> { let danger = Options { compile: CompileOptions { allow_dangerous_html: true, allow_dangerous_protocol: true, ..Default::default() }, ..Default::default() };
// Rule 1. assert_eq!( to_html("*foo bar*"), "<p><em>foo bar</em></p>", "should support emphasis w/ `*`" );
assert_eq!( to_html("a * foo bar*"), "<p>a * foo bar*</p>", "should not support emphasis if the opening is not left flanking (1)" );
assert_eq!( to_html("a*\"foo\"*"), "<p>a*"foo"*</p>", "should not support emphasis if the opening is not left flanking (2b)" );
assert_eq!( to_html("* a *"), "<p>* a *</p>", "should not support emphasis unicode whitespace either" );
assert_eq!( to_html("foo*bar*"), "<p>foo<em>bar</em></p>", "should support intraword emphasis w/ `*` (1)" );
assert_eq!( to_html("5*6*78"), "<p>5<em>6</em>78</p>", "should support intraword emphasis w/ `*` (2)" );
// Rule 2. assert_eq!( to_html("_foo bar_"), "<p><em>foo bar</em></p>", "should support emphasis w/ `_`" );
assert_eq!( to_html("_ foo bar_"), "<p>_ foo bar_</p>", "should not support emphasis if the opening is followed by whitespace" );
assert_eq!( to_html("a_\"foo\"_"), "<p>a_"foo"_</p>", "should not support emphasis if the opening is preceded by something else and followed by punctuation" );
assert_eq!( to_html("foo_bar_"), "<p>foo_bar_</p>", "should not support intraword emphasis (1)" );
assert_eq!( to_html("5_6_78"), "<p>5_6_78</p>", "should not support intraword emphasis (2)" );
assert_eq!( to_html("пристаням_стремятся_"), "<p>пристаням_стремятся_</p>", "should not support intraword emphasis (3)" );
assert_eq!( to_html("aa_\"bb\"_cc"), "<p>aa_"bb"_cc</p>", "should not support emphasis if the opening is right flanking and the closing is left flanking" );
assert_eq!( to_html("foo-_(bar)_"), "<p>foo-<em>(bar)</em></p>", "should support emphasis if the opening is both left and right flanking, if it’s preceded by punctuation" );
// Rule 3. assert_eq!( to_html("_foo*"), "<p>_foo*</p>", "should not support emphasis if opening and closing markers don’t match" );
assert_eq!( to_html("*foo bar *"), "<p>*foo bar *</p>", "should not support emphasis w/ `*` if the closing markers are preceded by whitespace" );
assert_eq!( to_html("*foo bar\n*"), "<p>*foo bar\n*</p>", "should not support emphasis w/ `*` if the closing markers are preceded by a line break (also whitespace)" );
assert_eq!( to_html("*(*foo)"), "<p>*(*foo)</p>", "should not support emphasis w/ `*` if the closing markers are not right flanking" );
assert_eq!( to_html("*(*foo*)*"), "<p><em>(<em>foo</em>)</em></p>", "should support nested emphasis" );
// Rule 4. assert_eq!( to_html("_foo bar _"), "<p>_foo bar _</p>", "should not support emphasis if the closing `_` is preceded by whitespace" );
assert_eq!( to_html("_(_foo)"), "<p>_(_foo)</p>", "should not support emphasis w/ `_` if the closing markers are not right flanking" );
assert_eq!( to_html("_(_foo_)_"), "<p><em>(<em>foo</em>)</em></p>", "should support nested emphasis w/ `_`" );
assert_eq!( to_html("_foo_bar"), "<p>_foo_bar</p>", "should not support intraword emphasis w/ `_` (1)" );
assert_eq!( to_html("_пристаням_стремятся"), "<p>_пристаням_стремятся</p>", "should not support intraword emphasis w/ `_` (2)" );
assert_eq!( to_html("_foo_bar_baz_"), "<p><em>foo_bar_baz</em></p>", "should not support intraword emphasis w/ `_` (3)" );
assert_eq!( to_html("_(bar)_."), "<p><em>(bar)</em>.</p>", "should support emphasis if the opening is both left and right flanking, if it’s followed by punctuation" );
// Rule 5. assert_eq!( to_html("**foo bar**"), "<p><strong>foo bar</strong></p>", "should support strong emphasis" );
assert_eq!( to_html("** foo bar**"), "<p>** foo bar**</p>", "should not support strong emphasis if the opening is followed by whitespace" );
assert_eq!( to_html("a**\"foo\"**"), "<p>a**"foo"**</p>", "should not support strong emphasis if the opening is preceded by something else and followed by punctuation" );
assert_eq!( to_html("foo**bar**"), "<p>foo<strong>bar</strong></p>", "should support strong intraword emphasis" );
// Rule 6. assert_eq!( to_html("__foo bar__"), "<p><strong>foo bar</strong></p>", "should support strong emphasis w/ `_`" );
assert_eq!( to_html("__ foo bar__"), "<p>__ foo bar__</p>", "should not support strong emphasis if the opening is followed by whitespace" );
assert_eq!( to_html("__\nfoo bar__"), "<p>__\nfoo bar__</p>", "should not support strong emphasis if the opening is followed by a line ending (also whitespace)" );
assert_eq!( to_html("a__\"foo\"__"), "<p>a__"foo"__</p>", "should not support strong emphasis if the opening is preceded by something else and followed by punctuation" );
assert_eq!( to_html("foo__bar__"), "<p>foo__bar__</p>", "should not support strong intraword emphasis w/ `_` (1)" );
assert_eq!( to_html("5__6__78"), "<p>5__6__78</p>", "should not support strong intraword emphasis w/ `_` (2)" );
assert_eq!( to_html("пристаням__стремятся__"), "<p>пристаням__стремятся__</p>", "should not support strong intraword emphasis w/ `_` (3)" );
assert_eq!( to_html("__foo, __bar__, baz__"), "<p><strong>foo, <strong>bar</strong>, baz</strong></p>", "should support nested strong emphasis" );
assert_eq!( to_html("foo-__(bar)__"), "<p>foo-<strong>(bar)</strong></p>", "should support strong emphasis if the opening is both left and right flanking, if it’s preceded by punctuation" );
// Rule 7. assert_eq!( to_html("**foo bar **"), "<p>**foo bar **</p>", "should not support strong emphasis w/ `*` if the closing is preceded by whitespace" );
assert_eq!( to_html("**(**foo)"), "<p>**(**foo)</p>", "should not support strong emphasis w/ `*` if the closing is preceded by punctuation and followed by something else" );
assert_eq!( to_html("*(**foo**)*"), "<p><em>(<strong>foo</strong>)</em></p>", "should support strong emphasis in emphasis" );
assert_eq!( to_html( "**Gomphocarpus (*Gomphocarpus physocarpus*, syn.\n*Asclepias physocarpa*)**" ), "<p><strong>Gomphocarpus (<em>Gomphocarpus physocarpus</em>, syn.\n<em>Asclepias physocarpa</em>)</strong></p>", "should support emphasis in strong emphasis (1)" );
assert_eq!( to_html("**foo \"*bar*\" foo**"), "<p><strong>foo "<em>bar</em>" foo</strong></p>", "should support emphasis in strong emphasis (2)" );
assert_eq!( to_html("**foo**bar"), "<p><strong>foo</strong>bar</p>", "should support strong intraword emphasis" );
// Rule 8. assert_eq!( to_html("__foo bar __"), "<p>__foo bar __</p>", "should not support strong emphasis w/ `_` if the closing is preceded by whitespace" );
assert_eq!( to_html("__(__foo)"), "<p>__(__foo)</p>", "should not support strong emphasis w/ `_` if the closing is preceded by punctuation and followed by something else" );
assert_eq!( to_html("_(__foo__)_"), "<p><em>(<strong>foo</strong>)</em></p>", "should support strong emphasis w/ `_` in emphasis" );
assert_eq!( to_html("__foo__bar"), "<p>__foo__bar</p>", "should not support strong intraword emphasis w/ `_` (1)" );
assert_eq!( to_html("__пристаням__стремятся"), "<p>__пристаням__стремятся</p>", "should not support strong intraword emphasis w/ `_` (2)" );
assert_eq!( to_html("__foo__bar__baz__"), "<p><strong>foo__bar__baz</strong></p>", "should not support strong intraword emphasis w/ `_` (3)" );
assert_eq!( to_html("__(bar)__."), "<p><strong>(bar)</strong>.</p>", "should support strong emphasis if the opening is both left and right flanking, if it’s followed by punctuation" );
// Rule 9. assert_eq!( to_html("*foo [bar](/url)*"), "<p><em>foo <a href=\"/url\">bar</a></em></p>", "should support content in emphasis" );
assert_eq!( to_html("*foo\nbar*"), "<p><em>foo\nbar</em></p>", "should support line endings in emphasis" );
assert_eq!( to_html("_foo __bar__ baz_"), "<p><em>foo <strong>bar</strong> baz</em></p>", "should support nesting emphasis and strong (1)" );
assert_eq!( to_html("_foo _bar_ baz_"), "<p><em>foo <em>bar</em> baz</em></p>", "should support nesting emphasis and strong (2)" );
assert_eq!( to_html("__foo_ bar_"), "<p><em><em>foo</em> bar</em></p>", "should support nesting emphasis and strong (3)" );
assert_eq!( to_html("*foo *bar**"), "<p><em>foo <em>bar</em></em></p>", "should support nesting emphasis and strong (4)" );
assert_eq!( to_html("*foo **bar** baz*"), "<p><em>foo <strong>bar</strong> baz</em></p>", "should support nesting emphasis and strong (5)" );
assert_eq!( to_html("*foo**bar**baz*"), "<p><em>foo<strong>bar</strong>baz</em></p>", "should support nesting emphasis and strong (6)" );
assert_eq!( to_html("*foo**bar*"), "<p><em>foo**bar</em></p>", "should not support adjacent emphasis in certain cases" );
assert_eq!( to_html("***foo** bar*"), "<p><em><strong>foo</strong> bar</em></p>", "complex (1)" ); assert_eq!( to_html("*foo **bar***"), "<p><em>foo <strong>bar</strong></em></p>", "complex (2)" ); assert_eq!( to_html("*foo**bar***"), "<p><em>foo<strong>bar</strong></em></p>", "complex (3)" );
assert_eq!( to_html("foo***bar***baz"), "<p>foo<em><strong>bar</strong></em>baz</p>", "complex (a)" ); assert_eq!( to_html("foo******bar*********baz"), "<p>foo<strong><strong><strong>bar</strong></strong></strong>***baz</p>", "complex (b)" );
assert_eq!( to_html("*foo **bar *baz* bim** bop*"), "<p><em>foo <strong>bar <em>baz</em> bim</strong> bop</em></p>", "should support indefinite nesting of emphasis (1)" );
assert_eq!( to_html("*foo [*bar*](/url)*"), "<p><em>foo <a href=\"/url\"><em>bar</em></a></em></p>", "should support indefinite nesting of emphasis (2)" );
assert_eq!( to_html("** is not an empty emphasis"), "<p>** is not an empty emphasis</p>", "should not support empty emphasis" );
assert_eq!( to_html("**** is not an empty emphasis"), "<p>**** is not an empty emphasis</p>", "should not support empty strong emphasis" );
// Rule 10. assert_eq!( to_html("**foo [bar](/url)**"), "<p><strong>foo <a href=\"/url\">bar</a></strong></p>", "should support content in strong emphasis" );
assert_eq!( to_html("**foo\nbar**"), "<p><strong>foo\nbar</strong></p>", "should support line endings in emphasis" );
assert_eq!( to_html("__foo _bar_ baz__"), "<p><strong>foo <em>bar</em> baz</strong></p>", "should support nesting emphasis and strong (1)" );
assert_eq!( to_html("__foo __bar__ baz__"), "<p><strong>foo <strong>bar</strong> baz</strong></p>", "should support nesting emphasis and strong (2)" );
assert_eq!( to_html("____foo__ bar__"), "<p><strong><strong>foo</strong> bar</strong></p>", "should support nesting emphasis and strong (3)" );
assert_eq!( to_html("**foo **bar****"), "<p><strong>foo <strong>bar</strong></strong></p>", "should support nesting emphasis and strong (4)" );
assert_eq!( to_html("**foo *bar* baz**"), "<p><strong>foo <em>bar</em> baz</strong></p>", "should support nesting emphasis and strong (5)" );
assert_eq!( to_html("**foo*bar*baz**"), "<p><strong>foo<em>bar</em>baz</strong></p>", "should support nesting emphasis and strong (6)" );
assert_eq!( to_html("***foo* bar**"), "<p><strong><em>foo</em> bar</strong></p>", "should support nesting emphasis and strong (7)" );
assert_eq!( to_html("**foo *bar***"), "<p><strong>foo <em>bar</em></strong></p>", "should support nesting emphasis and strong (8)" );
assert_eq!( to_html("**foo *bar **baz**\nbim* bop**"), "<p><strong>foo <em>bar <strong>baz</strong>\nbim</em> bop</strong></p>", "should support indefinite nesting of emphasis (1)" );
assert_eq!( to_html("**foo [*bar*](/url)**"), "<p><strong>foo <a href=\"/url\"><em>bar</em></a></strong></p>", "should support indefinite nesting of emphasis (2)" );
assert_eq!( to_html("__ is not an empty emphasis"), "<p>__ is not an empty emphasis</p>", "should not support empty emphasis" );
assert_eq!( to_html("____ is not an empty emphasis"), "<p>____ is not an empty emphasis</p>", "should not support empty strong emphasis" );
// Rule 11. assert_eq!( to_html("foo ***"), "<p>foo ***</p>", "should not support emphasis around the same marker" );
assert_eq!( to_html("foo *\\**"), "<p>foo <em>*</em></p>", "should support emphasis around an escaped marker" );
assert_eq!( to_html("foo *_*"), "<p>foo <em>_</em></p>", "should support emphasis around the other marker" );
assert_eq!( to_html("foo *****"), "<p>foo *****</p>", "should not support strong emphasis around the same marker" );
assert_eq!( to_html("foo **\\***"), "<p>foo <strong>*</strong></p>", "should support strong emphasis around an escaped marker" );
assert_eq!( to_html("foo **_**"), "<p>foo <strong>_</strong></p>", "should support strong emphasis around the other marker" );
assert_eq!( to_html("**foo*"), "<p>*<em>foo</em></p>", "should support a superfluous marker at the start of emphasis" );
assert_eq!( to_html("*foo**"), "<p><em>foo</em>*</p>", "should support a superfluous marker at the end of emphasis" );
assert_eq!( to_html("***foo**"), "<p>*<strong>foo</strong></p>", "should support a superfluous marker at the start of strong" );
assert_eq!( to_html("****foo*"), "<p>***<em>foo</em></p>", "should support multiple superfluous markers at the start of strong" );
assert_eq!( to_html("**foo***"), "<p><strong>foo</strong>*</p>", "should support a superfluous marker at the end of strong" );
assert_eq!( to_html("*foo****"), "<p><em>foo</em>***</p>", "should support multiple superfluous markers at the end of strong" );
// Rule 12. assert_eq!( to_html("foo ___"), "<p>foo ___</p>", "should not support emphasis around the same marker" );
assert_eq!( to_html("foo _\\__"), "<p>foo <em>_</em></p>", "should support emphasis around an escaped marker" );
assert_eq!( to_html("foo _X_"), "<p>foo <em>X</em></p>", "should support emphasis around the other marker" );
assert_eq!( to_html("foo _____"), "<p>foo _____</p>", "should not support strong emphasis around the same marker" );
assert_eq!( to_html("foo __\\___"), "<p>foo <strong>_</strong></p>", "should support strong emphasis around an escaped marker" );
assert_eq!( to_html("foo __X__"), "<p>foo <strong>X</strong></p>", "should support strong emphasis around the other marker" );
assert_eq!( to_html("__foo_"), "<p>_<em>foo</em></p>", "should support a superfluous marker at the start of emphasis" );
assert_eq!( to_html("_foo__"), "<p><em>foo</em>_</p>", "should support a superfluous marker at the end of emphasis" );
assert_eq!( to_html("___foo__"), "<p>_<strong>foo</strong></p>", "should support a superfluous marker at the start of strong" );
assert_eq!( to_html("____foo_"), "<p>___<em>foo</em></p>", "should support multiple superfluous markers at the start of strong" );
assert_eq!( to_html("__foo___"), "<p><strong>foo</strong>_</p>", "should support a superfluous marker at the end of strong" );
assert_eq!( to_html("_foo____"), "<p><em>foo</em>___</p>", "should support multiple superfluous markers at the end of strong" );
// Rule 13. assert_eq!( to_html("**foo**"), "<p><strong>foo</strong></p>", "should support strong w/ `*`" );
assert_eq!( to_html("*_foo_*"), "<p><em><em>foo</em></em></p>", "should support emphasis directly in emphasis w/ `_` in `*`" );
assert_eq!( to_html("__foo__"), "<p><strong>foo</strong></p>", "should support strong w/ `_`" );
assert_eq!( to_html("_*foo*_"), "<p><em><em>foo</em></em></p>", "should support emphasis directly in emphasis w/ `*` in `_`" );
assert_eq!( to_html("****foo****"), "<p><strong><strong>foo</strong></strong></p>", "should support strong emphasis directly in strong emphasis w/ `*`" );
assert_eq!( to_html("____foo____"), "<p><strong><strong>foo</strong></strong></p>", "should support strong emphasis directly in strong emphasis w/ `_`" );
assert_eq!( to_html("******foo******"), "<p><strong><strong><strong>foo</strong></strong></strong></p>", "should support indefinite strong emphasis" );
// Rule 14. assert_eq!( to_html("***foo***"), "<p><em><strong>foo</strong></em></p>", "should support strong directly in emphasis w/ `*`" );
assert_eq!( to_html("___foo___"), "<p><em><strong>foo</strong></em></p>", "should support strong directly in emphasis w/ `_`" );
// Rule 15. assert_eq!( to_html("*foo _bar* baz_"), "<p><em>foo _bar</em> baz_</p>", "should not support mismatched emphasis" );
assert_eq!( to_html("*foo __bar *baz bim__ bam*"), "<p><em>foo <strong>bar *baz bim</strong> bam</em></p>", "should not support mismatched strong emphasis" );
// Rule 16. assert_eq!( to_html("**foo **bar baz**"), "<p>**foo <strong>bar baz</strong></p>", "should not shortest strong possible" );
assert_eq!( to_html("*foo *bar baz*"), "<p>*foo <em>bar baz</em></p>", "should not shortest emphasis possible" );
// Rule 17. assert_eq!( to_html("*[bar*](/url)"), "<p>*<a href=\"/url\">bar*</a></p>", "should not mismatch inside links (1)" );
assert_eq!( to_html("_[bar_](/url)"), "<p>_<a href=\"/url\">bar_</a></p>", "should not mismatch inside links (1)" );
assert_eq!( to_html_with_options("*<img src=\"foo\" title=\"*\"/>", &danger)?, "<p>*<img src=\"foo\" title=\"*\"/></p>", "should not end inside HTML" );
assert_eq!( to_html_with_options("*<img src=\"foo\" title=\"*\"/>", &danger)?, "<p>*<img src=\"foo\" title=\"*\"/></p>", "should not end emphasis inside HTML" );
assert_eq!( to_html_with_options("**<a href=\"**\">", &danger)?, "<p>**<a href=\"**\"></p>", "should not end strong inside HTML (1)" );
assert_eq!( to_html_with_options("__<a href=\"__\">", &danger)?, "<p>__<a href=\"__\"></p>", "should not end strong inside HTML (2)" );
assert_eq!( to_html("*a `*`*"), "<p><em>a <code>*</code></em></p>", "should not end emphasis inside code (1)" );
assert_eq!( to_html("_a `_`_"), "<p><em>a <code>_</code></em></p>", "should not end emphasis inside code (2)" );
assert_eq!( to_html("**a<http://foo.bar/?q=**>"), "<p>**a<a href=\"http://foo.bar/?q=**\">http://foo.bar/?q=**</a></p>", "should not end strong emphasis inside autolinks (1)" );
assert_eq!( to_html("__a<http://foo.bar/?q=__>"), "<p>__a<a href=\"http://foo.bar/?q=__\">http://foo.bar/?q=__</a></p>", "should not end strong emphasis inside autolinks (2)" );
assert_eq!( to_html_with_options( "*a*", &Options { parse: ParseOptions { constructs: Constructs { attention: false, ..Default::default() }, ..Default::default() }, ..Default::default() } )?, "<p>*a*</p>", "should support turning off attention" );
assert_eq!( to_mdast("a *alpha* b **bravo** c.", &Default::default())?, Node::Root(Root { children: vec![Node::Paragraph(Paragraph { children: vec![ Node::Text(Text { value: "a ".into(), position: Some(Position::new(1, 1, 0, 1, 3, 2)) }), Node::Emphasis(Emphasis { children: vec![Node::Text(Text { value: "alpha".into(), position: Some(Position::new(1, 4, 3, 1, 9, 8)) }),], position: Some(Position::new(1, 3, 2, 1, 10, 9)) }), Node::Text(Text { value: " b ".into(), position: Some(Position::new(1, 10, 9, 1, 13, 12)) }), Node::Strong(Strong { children: vec![Node::Text(Text { value: "bravo".into(), position: Some(Position::new(1, 15, 14, 1, 20, 19)) }),], position: Some(Position::new(1, 13, 12, 1, 22, 21)) }), Node::Text(Text { value: " c.".into(), position: Some(Position::new(1, 22, 21, 1, 25, 24)) }) ], position: Some(Position::new(1, 1, 0, 1, 25, 24)) })], position: Some(Position::new(1, 1, 0, 1, 25, 24)) }), "should support attention as `Emphasis`, `Strong`s in mdast" );
Ok(())}