Markdown parser fork with extended syntax for personal use.
1use markdown::{
2 mdast::{Node, Paragraph, Root, Text},
3 message, to_html, to_html_with_options, to_mdast,
4 unist::Position,
5 CompileOptions, Constructs, Options, ParseOptions,
6};
7use pretty_assertions::assert_eq;
8
9#[test]
10fn character_escape() -> Result<(), message::Message> {
11 let danger = Options {
12 compile: CompileOptions {
13 allow_dangerous_html: true,
14 allow_dangerous_protocol: true,
15 ..Default::default()
16 },
17 ..Default::default()
18 };
19
20 assert_eq!(
21 to_html(
22 "\\!\\\"\\#\\$\\%\\&\\'\\(\\)\\*\\+\\,\\-\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\\\\\]\\^\\_\\`\\{\\|\\}\\~"),
23 "<p>!"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~</p>",
24 "should support escaped ascii punctuation"
25 );
26
27 assert_eq!(
28 to_html("\\→\\A\\a\\ \\3\\φ\\«"),
29 "<p>\\→\\A\\a\\ \\3\\φ\\«</p>",
30 "should not support other characters after a backslash"
31 );
32
33 assert_eq!(
34 to_html(
35 "\\*not emphasized*\n\\<br/> not a tag\n\\[not a link](/foo)\n\\`not code`\n1\\. not a list\n\\* not a list\n\\# not a heading\n\\[foo]: /url \"not a reference\"\n\\ö not a character entity"),
36 "<p>*not emphasized*\n<br/> not a tag\n[not a link](/foo)\n`not code`\n1. not a list\n* not a list\n# not a heading\n[foo]: /url "not a reference"\n&ouml; not a character entity</p>",
37 "should escape other constructs"
38 );
39
40 assert_eq!(
41 to_html("foo\\\nbar"),
42 "<p>foo<br />\nbar</p>",
43 "should escape a line break"
44 );
45
46 assert_eq!(
47 to_html("`` \\[\\` ``"),
48 "<p><code>\\[\\`</code></p>",
49 "should not escape in text code"
50 );
51
52 assert_eq!(
53 to_html(" \\[\\]"),
54 "<pre><code>\\[\\]\n</code></pre>",
55 "should not escape in indented code"
56 );
57
58 assert_eq!(
59 to_html("<http://example.com?find=\\*>"),
60 "<p><a href=\"http://example.com?find=%5C*\">http://example.com?find=\\*</a></p>",
61 "should not escape in autolink"
62 );
63
64 assert_eq!(
65 to_html_with_options("<a href=\"/bar\\/)\">", &danger)?,
66 "<a href=\"/bar\\/)\">",
67 "should not escape in flow html"
68 );
69
70 assert_eq!(
71 to_html("[foo](/bar\\* \"ti\\*tle\")"),
72 "<p><a href=\"/bar*\" title=\"ti*tle\">foo</a></p>",
73 "should escape in resource and title"
74 );
75
76 assert_eq!(
77 to_html("[foo]: /bar\\* \"ti\\*tle\"\n\n[foo]"),
78 "<p><a href=\"/bar*\" title=\"ti*tle\">foo</a></p>",
79 "should escape in definition resource and title"
80 );
81
82 assert_eq!(
83 to_html("``` foo\\+bar\nfoo\n```"),
84 "<pre><code class=\"language-foo+bar\">foo\n</code></pre>",
85 "should escape in fenced code info"
86 );
87
88 assert_eq!(
89 to_html_with_options(
90 "\\> a",
91 &Options {
92 parse: ParseOptions {
93 constructs: Constructs {
94 character_escape: false,
95 ..Default::default()
96 },
97 ..Default::default()
98 },
99 ..Default::default()
100 }
101 )?,
102 "<p>\\> a</p>",
103 "should support turning off character escapes"
104 );
105
106 assert_eq!(
107 to_mdast("a \\* b", &Default::default())?,
108 Node::Root(Root {
109 children: vec![Node::Paragraph(Paragraph {
110 children: vec![Node::Text(Text {
111 value: "a * b".into(),
112 position: Some(Position::new(1, 1, 0, 1, 7, 6))
113 }),],
114 position: Some(Position::new(1, 1, 0, 1, 7, 6))
115 })],
116 position: Some(Position::new(1, 1, 0, 1, 7, 6))
117 }),
118 "should support character escapes as `Text`s in mdast"
119 );
120
121 Ok(())
122}