fn run(input: &str, output: &str) { let output = if output.is_empty() { "".to_owned() } else { output.to_owned() + "\n" }; let md = &mut markdown_it::MarkdownIt::new(); markdown_it::plugins::cmark::add(md); markdown_it::plugins::html::add(md); markdown_it::plugins::extra::linkify::add(md); markdown_it::plugins::extra::typographer::add(md); markdown_it::plugins::extra::smartquotes::add(md); let node = md.parse(&(input.to_owned() + "\n")); // make sure we have sourcemaps for everything node.walk(|node, _| assert!(node.srcmap.is_some())); let result = node.render(); assert_eq!(result, output); // make sure it doesn't crash without trailing \n let _ = md.parse(input.trim_end()); } /////////////////////////////////////////////////////////////////////////// // TESTGEN: fixtures/markdown-it/smartquotes.txt #[rustfmt::skip] mod fixtures_markdown_it_smartquotes_txt { use super::run; // this part of the file is auto-generated // don't edit it, otherwise your changes might be lost #[test] fn should_parse_nested_quotes() { let input = r#""foo 'bar' baz" 'foo 'bar' baz'"#; let output = r#"

“foo ‘bar’ baz”

‘foo ‘bar’ baz’

"#; run(input, output); } #[test] fn should_not_overlap_quotes() { let input = r#"'foo "bar' baz""#; let output = r#"

‘foo "bar’ baz"

"#; run(input, output); } #[test] fn should_match_quotes_on_the_same_level() { let input = r#""foo *bar* baz""#; let output = r#"

“foo bar baz”

"#; run(input, output); } #[test] fn should_handle_adjacent_nested_quotes() { let input = r#"'"double in single"' "'single in double'""#; let output = r#"

‘“double in single”’

“‘single in double’”

"#; run(input, output); } #[test] fn should_not_match_quotes_on_different_levels() { let input = r#"*"foo* bar" "foo *bar"* *"foo* bar *baz"*"#; let output = r#"

"foo bar"

"foo bar"

"foo bar baz"

"#; run(input, output); } #[test] fn smartquotes_should_not_overlap_with_other_tags() { let input = r#"*foo "bar* *baz" quux*"#; let output = r#"

foo "bar baz" quux

"#; run(input, output); } #[test] fn should_try_and_find_matching_quote_in_this_case() { let input = r#""foo "bar 'baz""#; let output = r#"

"foo “bar 'baz”

"#; run(input, output); } #[test] fn should_not_touch_inches_in_quotes() { let input = r#""Monitor 21"" and "Monitor"""#; let output = r#"

“Monitor 21"” and “Monitor”"

"#; run(input, output); } #[test] fn should_render_an_apostrophe_as_a_rsquo() { let input = r#"This isn't and can't be the best approach to implement this..."#; let output = r#"

This isn’t and can’t be the best approach to implement this…

"#; run(input, output); } #[test] fn apostrophe_could_end_the_word_that_s_why_original_smartypants_replaces_all_of_them_as_rsquo() { let input = r#"users' stuff"#; let output = r#"

users’ stuff

"#; run(input, output); } #[test] fn quotes_between_punctuation_chars() { let input = r#""(hai)"."#; let output = r#"

“(hai)”.

"#; run(input, output); } #[test] fn quotes_at_the_start_end_of_the_tokens() { let input = r#""*foo* bar" "foo *bar*" "*foo bar*""#; let output = r#"

foo bar”

“foo bar

foo bar

"#; run(input, output); } #[test] fn should_treat_softbreak_as_a_space() { let input = r#""this" and "that". "this" and "that"."#; let output = r#"

“this” and “that”.

“this” and “that”.

"#; run(input, output); } #[test] fn should_treat_hardbreak_as_a_space() { let input = r#""this"\ and "that". "this" and\ "that"."#; let output = r#"

“this”
and “that”.

“this” and
“that”.

"#; run(input, output); } #[test] fn should_allow_quotes_adjacent_to_other_punctuation_characters_643() { let input = r#"The dog---"'man's' best friend""#; let output = r#"

The dog—“‘man’s’ best friend”

"#; run(input, output); } #[test] fn should_parse_quotes_adjacent_to_code_block_677() { let input = r#""test `code`" "`code` test""#; let output = r#"

“test code

code test”

"#; run(input, output); } #[test] fn should_parse_quotes_adjacent_to_inline_html_677() { let input = r#""test
" "
test""#; let output = r#"

“test


test”

"#; run(input, output); } #[test] fn should_be_escapable() { let input = r#""foo" \"foo" "foo\""#; let output = r#"

“foo”

"foo"

"foo"

"#; run(input, output); } #[test] fn should_not_replace_entities() { let input = r#""foo" "foo" "foo""#; let output = r#"

"foo"

"foo"

"foo"

"#; run(input, output); } // end of auto-generated module }