extern crate markdown; use markdown::{ mdast::{Code, Node, Root}, to_html, to_html_with_options, to_mdast, unist::Position, Constructs, Options, ParseOptions, }; use pretty_assertions::assert_eq; #[test] fn code_fenced() -> Result<(), String> { assert_eq!( to_html("```\n<\n >\n```"), "
<\n >\n
", "should support fenced code w/ grave accents" ); assert_eq!( to_html("~~~\n<\n >\n~~~"), "
<\n >\n
", "should support fenced code w/ tildes" ); assert_eq!( to_html("``\nfoo\n``"), "

foo

", "should not support fenced code w/ less than three markers" ); assert_eq!( to_html("```\naaa\n~~~\n```"), "
aaa\n~~~\n
", "should not support a tilde closing sequence for a grave accent opening sequence" ); assert_eq!( to_html("~~~\naaa\n```\n~~~"), "
aaa\n```\n
", "should not support a grave accent closing sequence for a tilde opening sequence" ); assert_eq!( to_html("````\naaa\n```\n``````"), "
aaa\n```\n
", "should support a closing sequence longer, but not shorter than, the opening" ); assert_eq!( to_html("~~~~\naaa\n~~~\n~~~~"), "
aaa\n~~~\n
", "should support a closing sequence equal to, but not shorter than, the opening" ); assert_eq!( to_html("```"), "
\n", "should support an eof right after an opening sequence" ); assert_eq!( to_html("`````\n\n```\naaa\n"), "
\n```\naaa\n
\n", "should support an eof somewhere in content" ); assert_eq!( to_html("> ```\n> aaa\n\nbbb"), "
\n
aaa\n
\n
\n

bbb

", "should support no closing sequence in a block quote" ); assert_eq!( to_html("```\n\n \n```"), "
\n  \n
", "should support blank lines in fenced code" ); assert_eq!( to_html("```\n```"), "
", "should support empty fenced code" ); assert_eq!( to_html(" ```\n aaa\naaa\n```"), "
aaa\naaa\n
", "should remove up to one space from the content if the opening sequence is indented w/ 1 space" ); assert_eq!( to_html(" ```\naaa\n aaa\naaa\n ```"), "
aaa\naaa\naaa\n
", "should remove up to two space from the content if the opening sequence is indented w/ 2 spaces" ); assert_eq!( to_html(" ```\n aaa\n aaa\n aaa\n ```"), "
aaa\n aaa\naaa\n
", "should remove up to three space from the content if the opening sequence is indented w/ 3 spaces" ); assert_eq!( to_html(" ```\n aaa\n ```"), "
```\naaa\n```\n
", "should not support indenteding the opening sequence w/ 4 spaces" ); assert_eq!( to_html("```\naaa\n ```"), "
aaa\n
", "should support an indented closing sequence" ); assert_eq!( to_html(" ```\naaa\n ```"), "
aaa\n
", "should support a differently indented closing sequence than the opening sequence" ); assert_eq!( to_html("```\naaa\n ```\n"), "
aaa\n    ```\n
\n", "should not support an indented closing sequence w/ 4 spaces" ); assert_eq!( to_html("``` ```\naaa"), "

\naaa

", "should not support grave accents in the opening fence after the opening sequence" ); assert_eq!( to_html("~~~~~~\naaa\n~~~ ~~\n"), "
aaa\n~~~ ~~\n
\n", "should not support spaces in the closing sequence" ); assert_eq!( to_html("foo\n```\nbar\n```\nbaz"), "

foo

\n
bar\n
\n

baz

", "should support interrupting paragraphs" ); assert_eq!( to_html("foo\n---\n~~~\nbar\n~~~\n# baz"), "

foo

\n
bar\n
\n

baz

", "should support interrupting other content" ); assert_eq!( to_html("```ruby\ndef foo(x)\n return 3\nend\n```"), "
def foo(x)\n  return 3\nend\n
", "should support the info string as a `language-` class (1)" ); assert_eq!( to_html("````;\n````"), "
", "should support the info string as a `language-` class (2)" ); assert_eq!( to_html("~~~~ ruby startline=3 $%@#$\ndef foo(x)\n return 3\nend\n~~~~~~~"), "
def foo(x)\n  return 3\nend\n
", "should support the info string as a `language-` class, but not the meta string" ); assert_eq!( to_html("``` aa ```\nfoo"), "

aa\nfoo

", "should not support grave accents in the meta string" ); assert_eq!( to_html("~~~ aa ``` ~~~\nfoo\n~~~"), "
foo\n
", "should support grave accents and tildes in the meta string of tilde fenced code" ); assert_eq!( to_html("```\n``` aaa\n```"), "
``` aaa\n
", "should not support info string on closing sequences" ); // Our own: assert_eq!( to_html("``` "), "
\n", "should support an eof after whitespace, after the start fence sequence" ); assert_eq!( to_html("``` js\nalert(1)\n```"), "
alert(1)\n
", "should support whitespace between the sequence and the info string" ); assert_eq!( to_html("```js"), "
\n", "should support an eof after the info string" ); assert_eq!( to_html("``` js \nalert(1)\n```"), "
alert(1)\n
", "should support whitespace after the info string" ); assert_eq!( to_html("```\n "), "
  \n
\n", "should support an eof after whitespace in content" ); assert_eq!( to_html(" ```\n "), "
\n", "should support an eof in the prefix, in content" ); assert_eq!( to_html("```j\\+s©"), "
\n", "should support character escapes and character references in info strings" ); assert_eq!( to_html("```a\\&b\0c"), "
\n", "should encode dangerous characters in languages" ); assert_eq!( to_html(" ```\naaa\n ```"), "
aaa\n ```\n
\n", "should not support a closing sequence w/ too much indent, regardless of opening sequence (1)" ); assert_eq!( to_html("> ```\n>\n>\n>\n\na"), "
\n
\n\n\n
\n
\n

a

", "should not support a closing sequence w/ too much indent, regardless of opening sequence (2)" ); assert_eq!( to_html("> ```a\nb"), "
\n
\n
\n

b

", "should not support lazyness (1)" ); assert_eq!( to_html("> a\n```b"), "
\n

a

\n
\n
\n", "should not support lazyness (2)" ); assert_eq!( to_html("> ```a\n```"), "
\n
\n
\n
\n", "should not support lazyness (3)" ); assert_eq!( to_html_with_options( "```", &Options { parse: ParseOptions { constructs: Constructs { code_fenced: false, ..Default::default() }, ..Default::default() }, ..Default::default() } )?, "

```

", "should support turning off code (fenced)" ); assert_eq!( to_mdast( "```js extra\nconsole.log(1)\nconsole.log(2)\n```", &Default::default() )?, Node::Root(Root { children: vec![Node::Code(Code { lang: Some("js".into()), meta: Some("extra".into()), value: "console.log(1)\nconsole.log(2)".into(), position: Some(Position::new(1, 1, 0, 4, 4, 45)) })], position: Some(Position::new(1, 1, 0, 4, 4, 45)) }), "should support code (fenced) as `Code`s in mdast" ); assert_eq!( to_mdast("```\nasd", &Default::default())?, Node::Root(Root { children: vec![Node::Code(Code { lang: None, meta: None, value: "asd".into(), position: Some(Position::new(1, 1, 0, 2, 4, 7)) })], position: Some(Position::new(1, 1, 0, 2, 4, 7)) }), "should support code (fenced) w/o closing fence in mdast" ); assert_eq!( to_mdast("```\rasd\r```", &Default::default())?, Node::Root(Root { children: vec![Node::Code(Code { lang: None, meta: None, value: "asd".into(), position: Some(Position::new(1, 1, 0, 3, 4, 11)) })], position: Some(Position::new(1, 1, 0, 3, 4, 11)) }), "should support code (fenced) w/o CR line endings" ); assert_eq!( to_mdast("```\r\nasd\r\n```", &Default::default())?, Node::Root(Root { children: vec![Node::Code(Code { lang: None, meta: None, value: "asd".into(), position: Some(Position::new(1, 1, 0, 3, 4, 13)) })], position: Some(Position::new(1, 1, 0, 3, 4, 13)) }), "should support code (fenced) w/o CR+LF line endings" ); Ok(()) }