Markdown parser fork with extended syntax for personal use.
at main 342 lines 11 kB view raw
1use markdown::{ 2 mdast::{Code, Node, Root}, 3 message, to_html, to_html_with_options, to_mdast, 4 unist::Position, 5 Constructs, Options, ParseOptions, 6}; 7use pretty_assertions::assert_eq; 8 9#[test] 10fn code_fenced() -> Result<(), message::Message> { 11 assert_eq!( 12 to_html("```\n<\n >\n```"), 13 "<pre><code>&lt;\n &gt;\n</code></pre>", 14 "should support fenced code w/ grave accents" 15 ); 16 17 assert_eq!( 18 to_html("~~~\n<\n >\n~~~"), 19 "<pre><code>&lt;\n &gt;\n</code></pre>", 20 "should support fenced code w/ tildes" 21 ); 22 23 assert_eq!( 24 to_html("``\nfoo\n``"), 25 "<p><code>foo</code></p>", 26 "should not support fenced code w/ less than three markers" 27 ); 28 29 assert_eq!( 30 to_html("```\naaa\n~~~\n```"), 31 "<pre><code>aaa\n~~~\n</code></pre>", 32 "should not support a tilde closing sequence for a grave accent opening sequence" 33 ); 34 35 assert_eq!( 36 to_html("~~~\naaa\n```\n~~~"), 37 "<pre><code>aaa\n```\n</code></pre>", 38 "should not support a grave accent closing sequence for a tilde opening sequence" 39 ); 40 41 assert_eq!( 42 to_html("````\naaa\n```\n``````"), 43 "<pre><code>aaa\n```\n</code></pre>", 44 "should support a closing sequence longer, but not shorter than, the opening" 45 ); 46 47 assert_eq!( 48 to_html("~~~~\naaa\n~~~\n~~~~"), 49 "<pre><code>aaa\n~~~\n</code></pre>", 50 "should support a closing sequence equal to, but not shorter than, the opening" 51 ); 52 53 assert_eq!( 54 to_html("```"), 55 "<pre><code></code></pre>\n", 56 "should support an eof right after an opening sequence" 57 ); 58 59 assert_eq!( 60 to_html("`````\n\n```\naaa\n"), 61 "<pre><code>\n```\naaa\n</code></pre>\n", 62 "should support an eof somewhere in content" 63 ); 64 65 assert_eq!( 66 to_html("> ```\n> aaa\n\nbbb"), 67 "<blockquote>\n<pre><code>aaa\n</code></pre>\n</blockquote>\n<p>bbb</p>", 68 "should support no closing sequence in a block quote" 69 ); 70 71 assert_eq!( 72 to_html("```\n\n \n```"), 73 "<pre><code>\n \n</code></pre>", 74 "should support blank lines in fenced code" 75 ); 76 77 assert_eq!( 78 to_html("```\n```"), 79 "<pre><code></code></pre>", 80 "should support empty fenced code" 81 ); 82 83 assert_eq!( 84 to_html(" ```\n aaa\naaa\n```"), 85 "<pre><code>aaa\naaa\n</code></pre>", 86 "should remove up to one space from the content if the opening sequence is indented w/ 1 space" 87 ); 88 89 assert_eq!( 90 to_html(" ```\naaa\n aaa\naaa\n ```"), 91 "<pre><code>aaa\naaa\naaa\n</code></pre>", 92 "should remove up to two space from the content if the opening sequence is indented w/ 2 spaces" 93 ); 94 95 assert_eq!( 96 to_html(" ```\n aaa\n aaa\n aaa\n ```"), 97 "<pre><code>aaa\n aaa\naaa\n</code></pre>", 98 "should remove up to three space from the content if the opening sequence is indented w/ 3 spaces" 99 ); 100 101 assert_eq!( 102 to_html(" ```\n aaa\n ```"), 103 "<pre><code>```\naaa\n```\n</code></pre>", 104 "should not support indenteding the opening sequence w/ 4 spaces" 105 ); 106 107 assert_eq!( 108 to_html("```\naaa\n ```"), 109 "<pre><code>aaa\n</code></pre>", 110 "should support an indented closing sequence" 111 ); 112 113 assert_eq!( 114 to_html(" ```\naaa\n ```"), 115 "<pre><code>aaa\n</code></pre>", 116 "should support a differently indented closing sequence than the opening sequence" 117 ); 118 119 assert_eq!( 120 to_html("```\naaa\n ```\n"), 121 "<pre><code>aaa\n ```\n</code></pre>\n", 122 "should not support an indented closing sequence w/ 4 spaces" 123 ); 124 125 assert_eq!( 126 to_html("``` ```\naaa"), 127 "<p><code> </code>\naaa</p>", 128 "should not support grave accents in the opening fence after the opening sequence" 129 ); 130 131 assert_eq!( 132 to_html("~~~~~~\naaa\n~~~ ~~\n"), 133 "<pre><code>aaa\n~~~ ~~\n</code></pre>\n", 134 "should not support spaces in the closing sequence" 135 ); 136 137 assert_eq!( 138 to_html("foo\n```\nbar\n```\nbaz"), 139 "<p>foo</p>\n<pre><code>bar\n</code></pre>\n<p>baz</p>", 140 "should support interrupting paragraphs" 141 ); 142 143 assert_eq!( 144 to_html("foo\n---\n~~~\nbar\n~~~\n# baz"), 145 "<h2>foo</h2>\n<pre><code>bar\n</code></pre>\n<h1>baz</h1>", 146 "should support interrupting other content" 147 ); 148 149 assert_eq!( 150 to_html("```ruby\ndef foo(x)\n return 3\nend\n```"), 151 "<pre><code class=\"language-ruby\">def foo(x)\n return 3\nend\n</code></pre>", 152 "should support the info string as a `language-` class (1)" 153 ); 154 155 assert_eq!( 156 to_html("````;\n````"), 157 "<pre><code class=\"language-;\"></code></pre>", 158 "should support the info string as a `language-` class (2)" 159 ); 160 161 assert_eq!( 162 to_html("~~~~ ruby startline=3 $%@#$\ndef foo(x)\n return 3\nend\n~~~~~~~"), 163 "<pre><code class=\"language-ruby\">def foo(x)\n return 3\nend\n</code></pre>", 164 "should support the info string as a `language-` class, but not the meta string" 165 ); 166 167 assert_eq!( 168 to_html("``` aa ```\nfoo"), 169 "<p><code>aa</code>\nfoo</p>", 170 "should not support grave accents in the meta string" 171 ); 172 173 assert_eq!( 174 to_html("~~~ aa ``` ~~~\nfoo\n~~~"), 175 "<pre><code class=\"language-aa\">foo\n</code></pre>", 176 "should support grave accents and tildes in the meta string of tilde fenced code" 177 ); 178 179 assert_eq!( 180 to_html("```\n``` aaa\n```"), 181 "<pre><code>``` aaa\n</code></pre>", 182 "should not support info string on closing sequences" 183 ); 184 185 // Our own: 186 assert_eq!( 187 to_html("``` "), 188 "<pre><code></code></pre>\n", 189 "should support an eof after whitespace, after the start fence sequence" 190 ); 191 192 assert_eq!( 193 to_html("``` js\nalert(1)\n```"), 194 "<pre><code class=\"language-js\">alert(1)\n</code></pre>", 195 "should support whitespace between the sequence and the info string" 196 ); 197 198 assert_eq!( 199 to_html("```js"), 200 "<pre><code class=\"language-js\"></code></pre>\n", 201 "should support an eof after the info string" 202 ); 203 204 assert_eq!( 205 to_html("``` js \nalert(1)\n```"), 206 "<pre><code class=\"language-js\">alert(1)\n</code></pre>", 207 "should support whitespace after the info string" 208 ); 209 210 assert_eq!( 211 to_html("```\n "), 212 "<pre><code> \n</code></pre>\n", 213 "should support an eof after whitespace in content" 214 ); 215 216 assert_eq!( 217 to_html(" ```\n "), 218 "<pre><code></code></pre>\n", 219 "should support an eof in the prefix, in content" 220 ); 221 222 assert_eq!( 223 to_html("```j\\+s&copy;"), 224 "<pre><code class=\"language-j+s©\"></code></pre>\n", 225 "should support character escapes and character references in info strings" 226 ); 227 228 assert_eq!( 229 to_html("```a\\&b\0c"), 230 "<pre><code class=\"language-a&amp;b�c\"></code></pre>\n", 231 "should encode dangerous characters in languages" 232 ); 233 234 assert_eq!( 235 to_html(" ```\naaa\n ```"), 236 "<pre><code>aaa\n ```\n</code></pre>\n", 237 "should not support a closing sequence w/ too much indent, regardless of opening sequence (1)" 238 ); 239 240 assert_eq!( 241 to_html("> ```\n>\n>\n>\n\na"), 242 "<blockquote>\n<pre><code>\n\n\n</code></pre>\n</blockquote>\n<p>a</p>", 243 "should not support a closing sequence w/ too much indent, regardless of opening sequence (2)" 244 ); 245 246 assert_eq!( 247 to_html("> ```a\nb"), 248 "<blockquote>\n<pre><code class=\"language-a\"></code></pre>\n</blockquote>\n<p>b</p>", 249 "should not support lazyness (1)" 250 ); 251 252 assert_eq!( 253 to_html("> a\n```b"), 254 "<blockquote>\n<p>a</p>\n</blockquote>\n<pre><code class=\"language-b\"></code></pre>\n", 255 "should not support lazyness (2)" 256 ); 257 258 assert_eq!( 259 to_html("> ```a\n```"), 260 "<blockquote>\n<pre><code class=\"language-a\"></code></pre>\n</blockquote>\n<pre><code></code></pre>\n", 261 "should not support lazyness (3)" 262 ); 263 264 assert_eq!( 265 to_html_with_options( 266 "```", 267 &Options { 268 parse: ParseOptions { 269 constructs: Constructs { 270 code_fenced: false, 271 ..Default::default() 272 }, 273 ..Default::default() 274 }, 275 ..Default::default() 276 } 277 )?, 278 "<p>```</p>", 279 "should support turning off code (fenced)" 280 ); 281 282 assert_eq!( 283 to_mdast( 284 "```js extra\nconsole.log(1)\nconsole.log(2)\n```", 285 &Default::default() 286 )?, 287 Node::Root(Root { 288 children: vec![Node::Code(Code { 289 lang: Some("js".into()), 290 meta: Some("extra".into()), 291 value: "console.log(1)\nconsole.log(2)".into(), 292 position: Some(Position::new(1, 1, 0, 4, 4, 45)) 293 })], 294 position: Some(Position::new(1, 1, 0, 4, 4, 45)) 295 }), 296 "should support code (fenced) as `Code`s in mdast" 297 ); 298 299 assert_eq!( 300 to_mdast("```\nasd", &Default::default())?, 301 Node::Root(Root { 302 children: vec![Node::Code(Code { 303 lang: None, 304 meta: None, 305 value: "asd".into(), 306 position: Some(Position::new(1, 1, 0, 2, 4, 7)) 307 })], 308 position: Some(Position::new(1, 1, 0, 2, 4, 7)) 309 }), 310 "should support code (fenced) w/o closing fence in mdast" 311 ); 312 313 assert_eq!( 314 to_mdast("```\rasd\r```", &Default::default())?, 315 Node::Root(Root { 316 children: vec![Node::Code(Code { 317 lang: None, 318 meta: None, 319 value: "asd".into(), 320 position: Some(Position::new(1, 1, 0, 3, 4, 11)) 321 })], 322 position: Some(Position::new(1, 1, 0, 3, 4, 11)) 323 }), 324 "should support code (fenced) w/o CR line endings" 325 ); 326 327 assert_eq!( 328 to_mdast("```\r\nasd\r\n```", &Default::default())?, 329 Node::Root(Root { 330 children: vec![Node::Code(Code { 331 lang: None, 332 meta: None, 333 value: "asd".into(), 334 position: Some(Position::new(1, 1, 0, 3, 4, 13)) 335 })], 336 position: Some(Position::new(1, 1, 0, 3, 4, 13)) 337 }), 338 "should support code (fenced) w/o CR+LF line endings" 339 ); 340 341 Ok(()) 342}