extern crate micromark; use micromark::{ mdast::{Delete, Node, Paragraph, Root, Text}, micromark, micromark_to_mdast, micromark_with_options, unist::Position, Constructs, Options, ParseOptions, }; use pretty_assertions::assert_eq; #[test] fn gfm_strikethrough() -> Result<(), String> { let gfm = Options { parse: ParseOptions { constructs: Constructs::gfm(), ..ParseOptions::default() }, ..Options::default() }; assert_eq!( micromark("a ~b~ c"), "

a ~b~ c

", "should ignore strikethrough by default" ); assert_eq!( micromark_with_options("a ~b~", &gfm)?, "

a b

", "should support strikethrough w/ one tilde" ); assert_eq!( micromark_with_options("a ~~b~~", &gfm)?, "

a b

", "should support strikethrough w/ two tildes" ); assert_eq!( micromark_with_options("a ~~~b~~~", &gfm)?, "

a ~~~b~~~

", "should not support strikethrough w/ three tildes" ); assert_eq!( micromark_with_options("a \\~~~b~~ c", &gfm)?, "

a ~b c

", "should support strikethrough after an escaped tilde" ); assert_eq!( micromark_with_options("a ~~b ~~c~~ d~~ e", &gfm)?, "

a b c d e

", "should support nested strikethrough" ); assert_eq!( micromark_with_options("a ~-1~ b", &gfm)?, "

a -1 b

", "should open if preceded by whitespace and followed by punctuation" ); assert_eq!( micromark_with_options("a ~b.~ c", &gfm)?, "

a b. c

", "should close if preceded by punctuation and followed by whitespace" ); assert_eq!( micromark_with_options("~b.~.", &gfm)?, "

b..

", "should close if preceded and followed by punctuation" ); assert_eq!( micromark_with_options( r###" # Balanced a ~one~ b a ~~two~~ b a ~~~three~~~ b a ~~~~four~~~~ b # Unbalanced a ~one/two~~ b a ~one/three~~~ b a ~one/four~~~~ b *** a ~~two/one~ b a ~~two/three~~~ b a ~~two/four~~~~ b *** a ~~~three/one~ b a ~~~three/two~~ b a ~~~three/four~~~~ b *** a ~~~~four/one~ b a ~~~~four/two~~ b a ~~~~four/three~~~ b ## Multiple a ~one b one~ c one~ d a ~one b two~~ c one~ d a ~one b one~ c two~~ d a ~~two b two~~ c two~~ d a ~~two b one~ c two~~ d a ~~two b two~~ c one~ d "###, &gfm )?, r###"

Balanced

a one b

a two b

a ~~~three~~~ b

a ~~~~four~~~~ b

Unbalanced

a ~one/two~~ b

a ~one/three~~~ b

a ~one/four~~~~ b


a ~~two/one~ b

a ~~two/three~~~ b

a ~~two/four~~~~ b


a ~~~three/one~ b

a ~~~three/two~~ b

a ~~~three/four~~~~ b


a ~~~~four/one~ b

a ~~~~four/two~~ b

a ~~~~four/three~~~ b

Multiple

a one b one c one~ d

a one b two~~ c one d

a one b one c two~~ d

a two b two c two~~ d

a two b one~ c two d

a two b two c one~ d

"###, "should handle balance like GitHub" ); assert_eq!( micromark_with_options( r###" # Flank a oneRight~ b oneRight~ c oneRight~ d a oneRight~ b oneRight~ c ~oneLeft d a oneRight~ b ~oneLeft c oneRight~ d a ~oneLeft b oneRight~ c oneRight~ d a ~oneLeft b oneRight~ c ~oneLeft d a ~oneLeft b ~oneLeft c oneRight~ d a ~oneLeft b ~oneLeft c ~oneLeft d *** a twoRight~~ b twoRight~~ c twoRight~~ d a twoRight~~ b twoRight~~ c ~~twoLeft d a twoRight~~ b ~~twoLeft c twoRight~~ d a ~~twoLeft b twoRight~~ c twoRight~~ d a ~~twoLeft b twoRight~~ c ~~twoLeft d a ~~twoLeft b ~~twoLeft c twoRight~~ d a ~~twoLeft b ~~twoLeft c ~~twoLeft d "###, &gfm )?, r###"

Flank

a oneRight~ b oneRight~ c oneRight~ d

a oneRight~ b oneRight~ c ~oneLeft d

a oneRight~ b oneLeft c oneRight d

a oneLeft b oneRight c oneRight~ d

a oneLeft b oneRight c ~oneLeft d

a ~oneLeft b oneLeft c oneRight d

a ~oneLeft b ~oneLeft c ~oneLeft d


a twoRight~~ b twoRight~~ c twoRight~~ d

a twoRight~~ b twoRight~~ c ~~twoLeft d

a twoRight~~ b twoLeft c twoRight d

a twoLeft b twoRight c twoRight~~ d

a twoLeft b twoRight c ~~twoLeft d

a ~~twoLeft b twoLeft c twoRight d

a ~~twoLeft b ~~twoLeft c ~~twoLeft d

"###, "should handle flanking like GitHub" ); assert_eq!( micromark_with_options( r###" # Interlpay ## Interleave with attention a ~~two *emphasis* two~~ b a ~~two **strong** two~~ b a *marker ~~two marker* two~~ b a ~~two *marker two~~ marker* b ## Interleave with links a ~~two [resource](#) two~~ b a ~~two [reference][#] two~~ b a [label start ~~two label end](#) two~~ b a ~~two [label start two~~ label end](#) b a ~~two [label start ~one one~ label end](#) two~~ b a ~one [label start ~~two two~~ label end](#) one~ b a ~one [label start ~one one~ label end](#) one~ b a ~~two [label start ~~two two~~ label end](#) two~~ b [#]: # ## Interleave with code (text) a ~~two `code` two~~ b a ~~two `code two~~` b a `code start ~~two code end` two~~ b a ~~two `code start two~~ code end` b a ~~two `code start ~one one~ code end` two~~ b a ~one `code start ~~two two~~ code end` one~ b a ~one `code start ~one one~ code end` one~ b a ~~two `code start ~~two two~~ code end` two~~ b ## Emphasis/strong/strikethrough interplay a ***~~xxx~~*** zzz b ***xxx***zzz c **xxx**zzz d *xxx*zzz e ***~~xxx~~***yyy f **~~xxx~~**yyy g *~~xxx~~*yyy h ***~~xxx~~*** zzz i **~~xxx~~** zzz j *~~xxx~~* zzz k ~~~**xxx**~~~ zzz l ~~~xxx~~~zzz m ~~xxx~~zzz n ~xxx~zzz o ~~~**xxx**~~~yyy p ~~**xxx**~~yyy r ~**xxx**~yyy s ~~~**xxx**~~~ zzz t ~~**xxx**~~ zzz u ~**xxx**~ zzz "###, &gfm )?, r###"

Interlpay

Interleave with attention

a two emphasis two b

a two strong two b

a marker ~~two marker two~~ b

a two *marker two marker* b

Interleave with links

a two resource two b

a two reference two b

a label start ~~two label end two~~ b

a ~~two label start two~~ label end b

a two label start one one label end two b

a one label start two two label end one b

a one label start one one label end one b

a two label start two two label end two b

Interleave with code (text)

a two code two b

a ~~two code two~~ b

a code start ~~two code end two~~ b

a ~~two code start two~~ code end b

a two code start ~one one~ code end two b

a one code start ~~two two~~ code end one b

a one code start ~one one~ code end one b

a two code start ~~two two~~ code end two b

Emphasis/strong/strikethrough interplay

a xxx zzz

b xxxzzz

c xxxzzz

d xxxzzz

e xxxyyy

f xxxyyy

g xxxyyy

h xxx zzz

i xxx zzz

j xxx zzz

k ~~~xxx~~~ zzz

l ~~~xxx~~~zzz

m xxxzzz

n xxxzzz

o ~~~xxx~~~yyy

p ~~xxx~~yyy

r ~xxx~yyy

s ~~~xxx~~~ zzz

t xxx zzz

u xxx zzz

"###, "should handle interplay like GitHub" ); assert_eq!( micromark_with_options( "a ~b~ ~~c~~ d", &Options { parse: ParseOptions { constructs: Constructs::gfm(), gfm_strikethrough_single_tilde: false, ..ParseOptions::default() }, ..Options::default() } )?, "

a ~b~ c d

", "should not support strikethrough w/ one tilde if `singleTilde: false`" ); assert_eq!( micromark_with_options( "a ~b~ ~~c~~ d", &Options { parse: ParseOptions { constructs: Constructs::gfm(), gfm_strikethrough_single_tilde: true, ..ParseOptions::default() }, ..Options::default() } )?, "

a b c d

", "should support strikethrough w/ one tilde if `singleTilde: true`" ); assert_eq!( micromark_to_mdast("a ~~alpha~~ b.", &gfm.parse)?, Node::Root(Root { children: vec![Node::Paragraph(Paragraph { children: vec![ Node::Text(Text { value: "a ".to_string(), position: Some(Position::new(1, 1, 0, 1, 3, 2)) }), Node::Delete(Delete { children: vec![Node::Text(Text { value: "alpha".to_string(), position: Some(Position::new(1, 5, 4, 1, 10, 9)) }),], position: Some(Position::new(1, 3, 2, 1, 12, 11)) }), Node::Text(Text { value: " b.".to_string(), position: Some(Position::new(1, 12, 11, 1, 15, 14)) }), ], position: Some(Position::new(1, 1, 0, 1, 15, 14)) })], position: Some(Position::new(1, 1, 0, 1, 15, 14)) }), "should support GFM strikethrough as `Delete`s in mdast" ); Ok(()) }