Markdown parser fork with extended syntax for personal use.
at hack 437 lines 11 kB view raw
1#![allow(clippy::needless_raw_string_hashes)] 2 3// To do: clippy introduced this in 1.72 but breaks when it fixes it. 4// Remove when solved. 5 6use markdown::{ 7 mdast::{Delete, Node, Paragraph, Root, Text}, 8 message, to_html, to_html_with_options, to_mdast, 9 unist::Position, 10 Options, ParseOptions, 11}; 12use pretty_assertions::assert_eq; 13 14#[test] 15fn gfm_strikethrough() -> Result<(), message::Message> { 16 assert_eq!( 17 to_html("a ~b~ c"), 18 "<p>a ~b~ c</p>", 19 "should ignore strikethrough by default" 20 ); 21 22 assert_eq!( 23 to_html_with_options("a ~b~", &Options::gfm())?, 24 "<p>a <del>b</del></p>", 25 "should support strikethrough w/ one tilde" 26 ); 27 28 assert_eq!( 29 to_html_with_options("a ~~b~~", &Options::gfm())?, 30 "<p>a <del>b</del></p>", 31 "should support strikethrough w/ two tildes" 32 ); 33 34 assert_eq!( 35 to_html_with_options("a ~~~b~~~", &Options::gfm())?, 36 "<p>a ~~~b~~~</p>", 37 "should not support strikethrough w/ three tildes" 38 ); 39 40 assert_eq!( 41 to_html_with_options("a \\~~~b~~ c", &Options::gfm())?, 42 "<p>a ~<del>b</del> c</p>", 43 "should support strikethrough after an escaped tilde" 44 ); 45 46 assert_eq!( 47 to_html_with_options("a ~~b ~~c~~ d~~ e", &Options::gfm())?, 48 "<p>a <del>b <del>c</del> d</del> e</p>", 49 "should support nested strikethrough" 50 ); 51 52 assert_eq!( 53 to_html_with_options("a ~-1~ b", &Options::gfm())?, 54 "<p>a <del>-1</del> b</p>", 55 "should open if preceded by whitespace and followed by punctuation" 56 ); 57 58 assert_eq!( 59 to_html_with_options("a ~b.~ c", &Options::gfm())?, 60 "<p>a <del>b.</del> c</p>", 61 "should close if preceded by punctuation and followed by whitespace" 62 ); 63 64 assert_eq!( 65 to_html_with_options("~b.~.", &Options::gfm())?, 66 "<p><del>b.</del>.</p>", 67 "should close if preceded and followed by punctuation" 68 ); 69 70 assert_eq!( 71 to_html_with_options( 72 r###" 73# Balanced 74 75a ~one~ b 76 77a ~~two~~ b 78 79a ~~~three~~~ b 80 81a ~~~~four~~~~ b 82 83# Unbalanced 84 85a ~one/two~~ b 86 87a ~one/three~~~ b 88 89a ~one/four~~~~ b 90 91*** 92 93a ~~two/one~ b 94 95a ~~two/three~~~ b 96 97a ~~two/four~~~~ b 98 99*** 100 101a ~~~three/one~ b 102 103a ~~~three/two~~ b 104 105a ~~~three/four~~~~ b 106 107*** 108 109a ~~~~four/one~ b 110 111a ~~~~four/two~~ b 112 113a ~~~~four/three~~~ b 114 115## Multiple 116 117a ~one b one~ c one~ d 118 119a ~one b two~~ c one~ d 120 121a ~one b one~ c two~~ d 122 123a ~~two b two~~ c two~~ d 124 125a ~~two b one~ c two~~ d 126 127a ~~two b two~~ c one~ d 128"###, 129 &Options::gfm() 130 )?, 131 r###"<h1>Balanced</h1> 132<p>a <del>one</del> b</p> 133<p>a <del>two</del> b</p> 134<p>a ~~~three~~~ b</p> 135<p>a ~~~~four~~~~ b</p> 136<h1>Unbalanced</h1> 137<p>a ~one/two~~ b</p> 138<p>a ~one/three~~~ b</p> 139<p>a ~one/four~~~~ b</p> 140<hr /> 141<p>a ~~two/one~ b</p> 142<p>a ~~two/three~~~ b</p> 143<p>a ~~two/four~~~~ b</p> 144<hr /> 145<p>a ~~~three/one~ b</p> 146<p>a ~~~three/two~~ b</p> 147<p>a ~~~three/four~~~~ b</p> 148<hr /> 149<p>a ~~~~four/one~ b</p> 150<p>a ~~~~four/two~~ b</p> 151<p>a ~~~~four/three~~~ b</p> 152<h2>Multiple</h2> 153<p>a <del>one b one</del> c one~ d</p> 154<p>a <del>one b two~~ c one</del> d</p> 155<p>a <del>one b one</del> c two~~ d</p> 156<p>a <del>two b two</del> c two~~ d</p> 157<p>a <del>two b one~ c two</del> d</p> 158<p>a <del>two b two</del> c one~ d</p> 159"###, 160 "should handle balance like GitHub" 161 ); 162 163 assert_eq!( 164 to_html_with_options( 165 r###" 166# Flank 167 168a oneRight~ b oneRight~ c oneRight~ d 169 170a oneRight~ b oneRight~ c ~oneLeft d 171 172a oneRight~ b ~oneLeft c oneRight~ d 173 174a ~oneLeft b oneRight~ c oneRight~ d 175 176a ~oneLeft b oneRight~ c ~oneLeft d 177 178a ~oneLeft b ~oneLeft c oneRight~ d 179 180a ~oneLeft b ~oneLeft c ~oneLeft d 181 182*** 183 184a twoRight~~ b twoRight~~ c twoRight~~ d 185 186a twoRight~~ b twoRight~~ c ~~twoLeft d 187 188a twoRight~~ b ~~twoLeft c twoRight~~ d 189 190a ~~twoLeft b twoRight~~ c twoRight~~ d 191 192a ~~twoLeft b twoRight~~ c ~~twoLeft d 193 194a ~~twoLeft b ~~twoLeft c twoRight~~ d 195 196a ~~twoLeft b ~~twoLeft c ~~twoLeft d 197"###, 198 &Options::gfm() 199 )?, 200 r###"<h1>Flank</h1> 201<p>a oneRight~ b oneRight~ c oneRight~ d</p> 202<p>a oneRight~ b oneRight~ c ~oneLeft d</p> 203<p>a oneRight~ b <del>oneLeft c oneRight</del> d</p> 204<p>a <del>oneLeft b oneRight</del> c oneRight~ d</p> 205<p>a <del>oneLeft b oneRight</del> c ~oneLeft d</p> 206<p>a ~oneLeft b <del>oneLeft c oneRight</del> d</p> 207<p>a ~oneLeft b ~oneLeft c ~oneLeft d</p> 208<hr /> 209<p>a twoRight~~ b twoRight~~ c twoRight~~ d</p> 210<p>a twoRight~~ b twoRight~~ c ~~twoLeft d</p> 211<p>a twoRight~~ b <del>twoLeft c twoRight</del> d</p> 212<p>a <del>twoLeft b twoRight</del> c twoRight~~ d</p> 213<p>a <del>twoLeft b twoRight</del> c ~~twoLeft d</p> 214<p>a ~~twoLeft b <del>twoLeft c twoRight</del> d</p> 215<p>a ~~twoLeft b ~~twoLeft c ~~twoLeft d</p> 216"###, 217 "should handle flanking like GitHub" 218 ); 219 220 assert_eq!( 221 to_html_with_options( 222 r###" 223# Interlpay 224 225## Interleave with attention 226 227a ~~two *emphasis* two~~ b 228 229a ~~two **strong** two~~ b 230 231a *marker ~~two marker* two~~ b 232 233a ~~two *marker two~~ marker* b 234 235## Interleave with links 236 237a ~~two [resource](#) two~~ b 238 239a ~~two [reference][#] two~~ b 240 241a [label start ~~two label end](#) two~~ b 242 243a ~~two [label start two~~ label end](#) b 244 245a ~~two [label start ~one one~ label end](#) two~~ b 246 247a ~one [label start ~~two two~~ label end](#) one~ b 248 249a ~one [label start ~one one~ label end](#) one~ b 250 251a ~~two [label start ~~two two~~ label end](#) two~~ b 252 253[#]: # 254 255## Interleave with code (text) 256 257a ~~two `code` two~~ b 258 259a ~~two `code two~~` b 260 261a `code start ~~two code end` two~~ b 262 263a ~~two `code start two~~ code end` b 264 265a ~~two `code start ~one one~ code end` two~~ b 266 267a ~one `code start ~~two two~~ code end` one~ b 268 269a ~one `code start ~one one~ code end` one~ b 270 271a ~~two `code start ~~two two~~ code end` two~~ b 272 273## Emphasis/strong/strikethrough interplay 274 275a ***~~xxx~~*** zzz 276 277b ***xxx***zzz 278 279c **xxx**zzz 280 281d *xxx*zzz 282 283e ***~~xxx~~***yyy 284 285f **~~xxx~~**yyy 286 287g *~~xxx~~*yyy 288 289h ***~~xxx~~*** zzz 290 291i **~~xxx~~** zzz 292 293j *~~xxx~~* zzz 294 295k ~~~**xxx**~~~ zzz 296 297l ~~~xxx~~~zzz 298 299m ~~xxx~~zzz 300 301n ~xxx~zzz 302 303o ~~~**xxx**~~~yyy 304 305p ~~**xxx**~~yyy 306 307r ~**xxx**~yyy 308 309s ~~~**xxx**~~~ zzz 310 311t ~~**xxx**~~ zzz 312 313u ~**xxx**~ zzz 314"###, 315 &Options::gfm() 316 )?, 317 r###"<h1>Interlpay</h1> 318<h2>Interleave with attention</h2> 319<p>a <del>two <em>emphasis</em> two</del> b</p> 320<p>a <del>two <strong>strong</strong> two</del> b</p> 321<p>a <em>marker ~~two marker</em> two~~ b</p> 322<p>a <del>two *marker two</del> marker* b</p> 323<h2>Interleave with links</h2> 324<p>a <del>two <a href="#">resource</a> two</del> b</p> 325<p>a <del>two <a href="#">reference</a> two</del> b</p> 326<p>a <a href="#">label start ~~two label end</a> two~~ b</p> 327<p>a ~~two <a href="#">label start two~~ label end</a> b</p> 328<p>a <del>two <a href="#">label start <del>one one</del> label end</a> two</del> b</p> 329<p>a <del>one <a href="#">label start <del>two two</del> label end</a> one</del> b</p> 330<p>a <del>one <a href="#">label start <del>one one</del> label end</a> one</del> b</p> 331<p>a <del>two <a href="#">label start <del>two two</del> label end</a> two</del> b</p> 332<h2>Interleave with code (text)</h2> 333<p>a <del>two <code>code</code> two</del> b</p> 334<p>a ~~two <code>code two~~</code> b</p> 335<p>a <code>code start ~~two code end</code> two~~ b</p> 336<p>a ~~two <code>code start two~~ code end</code> b</p> 337<p>a <del>two <code>code start ~one one~ code end</code> two</del> b</p> 338<p>a <del>one <code>code start ~~two two~~ code end</code> one</del> b</p> 339<p>a <del>one <code>code start ~one one~ code end</code> one</del> b</p> 340<p>a <del>two <code>code start ~~two two~~ code end</code> two</del> b</p> 341<h2>Emphasis/strong/strikethrough interplay</h2> 342<p>a <em><strong><del>xxx</del></strong></em> zzz</p> 343<p>b <em><strong>xxx</strong></em>zzz</p> 344<p>c <strong>xxx</strong>zzz</p> 345<p>d <em>xxx</em>zzz</p> 346<p>e <em><strong><del>xxx</del></strong></em>yyy</p> 347<p>f <strong><del>xxx</del></strong>yyy</p> 348<p>g <em><del>xxx</del></em>yyy</p> 349<p>h <em><strong><del>xxx</del></strong></em> zzz</p> 350<p>i <strong><del>xxx</del></strong> zzz</p> 351<p>j <em><del>xxx</del></em> zzz</p> 352<p>k ~~~<strong>xxx</strong>~~~ zzz</p> 353<p>l ~~~xxx~~~zzz</p> 354<p>m <del>xxx</del>zzz</p> 355<p>n <del>xxx</del>zzz</p> 356<p>o ~~~<strong>xxx</strong>~~~yyy</p> 357<p>p ~~<strong>xxx</strong>~~yyy</p> 358<p>r ~<strong>xxx</strong>~yyy</p> 359<p>s ~~~<strong>xxx</strong>~~~ zzz</p> 360<p>t <del><strong>xxx</strong></del> zzz</p> 361<p>u <del><strong>xxx</strong></del> zzz</p> 362"###, 363 "should handle interplay like GitHub" 364 ); 365 366 assert_eq!( 367 to_html_with_options("a*~b~*c\n\na*.b.*c", &Options::gfm())?, 368 "<p>a<em><del>b</del></em>c</p>\n<p>a*.b.*c</p>", 369 "should handle interplay w/ other attention markers (GFM)" 370 ); 371 372 assert_eq!( 373 to_html("a*~b~*c\n\na*.b.*c"), 374 "<p>a*~b~*c</p>\n<p>a*.b.*c</p>", 375 "should handle interplay w/ other attention markers (CM reference)" 376 ); 377 378 assert_eq!( 379 to_html_with_options( 380 "a ~b~ ~~c~~ d", 381 &Options { 382 parse: ParseOptions { 383 gfm_strikethrough_single_tilde: false, 384 ..ParseOptions::gfm() 385 }, 386 ..Options::gfm() 387 } 388 )?, 389 "<p>a ~b~ <del>c</del> d</p>", 390 "should not support strikethrough w/ one tilde if `singleTilde: false`" 391 ); 392 393 assert_eq!( 394 to_html_with_options( 395 "a ~b~ ~~c~~ d", 396 &Options { 397 parse: ParseOptions { 398 gfm_strikethrough_single_tilde: true, 399 ..ParseOptions::gfm() 400 }, 401 ..Options::gfm() 402 } 403 )?, 404 "<p>a <del>b</del> <del>c</del> d</p>", 405 "should support strikethrough w/ one tilde if `singleTilde: true`" 406 ); 407 408 assert_eq!( 409 to_mdast("a ~~alpha~~ b.", &ParseOptions::gfm())?, 410 Node::Root(Root { 411 children: vec![Node::Paragraph(Paragraph { 412 children: vec![ 413 Node::Text(Text { 414 value: "a ".into(), 415 position: Some(Position::new(1, 1, 0, 1, 3, 2)) 416 }), 417 Node::Delete(Delete { 418 children: vec![Node::Text(Text { 419 value: "alpha".into(), 420 position: Some(Position::new(1, 5, 4, 1, 10, 9)) 421 }),], 422 position: Some(Position::new(1, 3, 2, 1, 12, 11)) 423 }), 424 Node::Text(Text { 425 value: " b.".into(), 426 position: Some(Position::new(1, 12, 11, 1, 15, 14)) 427 }), 428 ], 429 position: Some(Position::new(1, 1, 0, 1, 15, 14)) 430 })], 431 position: Some(Position::new(1, 1, 0, 1, 15, 14)) 432 }), 433 "should support GFM strikethrough as `Delete`s in mdast" 434 ); 435 436 Ok(()) 437}