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”.
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”
“test
”
“
test”
“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 }