use markdown::{
mdast::{Definition, Image, ImageReference, Node, Paragraph, ReferenceKind, Root, Text},
to_html, to_html_with_options, to_mdast,
unist::Position,
CompileOptions, Constructs, Options, ParseOptions,
};
use pretty_assertions::assert_eq;
#[test]
fn image() -> Result<(), String> {
assert_eq!(
to_html("[link](/uri \"title\")"),
"
link
",
"should support links"
);
assert_eq!(
to_html("![foo](/url \"title\")"),
"![\"title\" \"foo\"](\"/url\")
",
"should support image w/ resource"
);
assert_eq!(
to_html("[foo *bar*]: train.jpg \"train & tracks\"\n\n![foo *bar*]"),
"![\"train \"foo](\"train.jpg\")
",
"should support image as shortcut reference"
);
assert_eq!(
to_html("![foo ![bar](/url)](/url2)"),
"![\"foo](\"/url2\")
",
"should “support” images in images"
);
assert_eq!(
to_html("![foo [bar](/url)](/url2)"),
"![\"foo](\"/url2\")
",
"should “support” links in images"
);
assert_eq!(
to_html("[foo *bar*]: train.jpg \"train & tracks\"\n\n![foo *bar*][]"),
"![\"train \"foo](\"train.jpg\")
",
"should support “content” in images"
);
assert_eq!(
to_html("[FOOBAR]: train.jpg \"train & tracks\"\n\n![foo *bar*][foobar]"),
"![\"train \"foo](\"train.jpg\")
",
"should support “content” in images"
);
assert_eq!(
to_html("![foo](train.jpg)"),
"![\"foo\"](\"train.jpg\")
",
"should support images w/o title"
);
assert_eq!(
to_html("My ![foo bar](/path/to/train.jpg \"title\" )"),
"My ![\"title\" \"foo](\"/path/to/train.jpg\")
",
"should support images w/ lots of whitespace"
);
assert_eq!(
to_html("![foo]()"),
"![\"foo\"](\"url\")
",
"should support images w/ enclosed destinations"
);
assert_eq!(
to_html("![](/url)"),
"![\"\"](\"/url\")
",
"should support images w/ empty labels"
);
assert_eq!(
to_html("[bar]: /url\n\n![foo][bar]"),
"![\"foo\"](\"/url\")
",
"should support full references (1)"
);
assert_eq!(
to_html("[BAR]: /url\n\n![foo][bar]"),
"![\"foo\"](\"/url\")
",
"should support full references (2)"
);
assert_eq!(
to_html("[foo]: /url \"title\"\n\n![foo][]"),
"![\"title\" \"foo\"](\"/url\")
",
"should support collapsed references (1)"
);
assert_eq!(
to_html("[*foo* bar]: /url \"title\"\n\n![*foo* bar][]"),
"![\"title\" \"foo](\"/url\")
",
"should support collapsed references (2)"
);
assert_eq!(
to_html("[foo]: /url \"title\"\n\n![Foo][]"),
"![\"title\" \"Foo\"](\"/url\")
",
"should support case-insensitive labels"
);
assert_eq!(
to_html("[foo]: /url \"title\"\n\n![foo] \n[]"),
"
\n[]
",
"should not support whitespace between sets of brackets"
);
assert_eq!(
to_html("[foo]: /url \"title\"\n\n![foo]"),
"![\"title\" \"foo\"](\"/url\")
",
"should support shortcut references (1)"
);
assert_eq!(
to_html("[*foo* bar]: /url \"title\"\n\n![*foo* bar]"),
"![\"title\" \"foo](\"/url\")
",
"should support shortcut references (2)"
);
assert_eq!(
to_html("[[foo]]: /url \"title\"\n\n![[foo]]"),
"[[foo]]: /url "title"
\n![[foo]]
",
"should not support link labels w/ unescaped brackets"
);
assert_eq!(
to_html("[foo]: /url \"title\"\n\n![Foo]"),
"![\"title\" \"Foo\"](\"/url\")
",
"should support case-insensitive label matching"
);
assert_eq!(
to_html("[foo]: /url \"title\"\n\n!\\[foo]"),
"![foo]
",
"should “support” an escaped bracket instead of an image"
);
assert_eq!(
to_html("[foo]: /url \"title\"\n\n\\![foo]"),
"!foo
",
"should support an escaped bang instead of an image, but still have a link"
);
// Extra
assert_eq!(
to_html("![foo]()"),
"![\"foo\"](\"\")
",
"should support images w/o destination"
);
assert_eq!(
to_html("![foo](<>)"),
"![\"foo\"](\"\")
",
"should support images w/ explicit empty destination"
);
assert_eq!(
to_html("![](example.png)"),
"![\"\"](\"example.png\")
",
"should support images w/o alt"
);
assert_eq!(
to_html("![alpha](bravo.png \"\")"),
"![\"alpha\"](\"bravo.png\")
",
"should support images w/ empty title (1)"
);
assert_eq!(
to_html("![alpha](bravo.png '')"),
"![\"alpha\"](\"bravo.png\")
",
"should support images w/ empty title (2)"
);
assert_eq!(
to_html("![alpha](bravo.png ())"),
"![\"alpha\"](\"bravo.png\")
",
"should support images w/ empty title (3)"
);
assert_eq!(
to_html("![&©&](example.com/&©& \"&©&\")"),
"![\"&©&\" \"&©&\"](\"example.com/&%C2%A9&\")
",
"should support character references in images"
);
// Extra
// See:
assert_eq!(
to_html("![](<> \"\")"),
"![\"\"](\"\")
",
"should ignore an empty title"
);
assert_eq!(
to_html_with_options(
"![x]()",
&Options {
parse: ParseOptions {
constructs: Constructs {
label_start_image: false,
..Default::default()
},
..Default::default()
},
..Default::default()
}
)?,
"!x
",
"should support turning off label start (image)"
);
assert_eq!(
to_html("![](javascript:alert(1))"),
"![\"\"](\"\")
",
"should ignore non-http protocols by default"
);
assert_eq!(
to_html_with_options(
"![](javascript:alert(1))",
&Options {
compile: CompileOptions {
allow_dangerous_protocol: true,
..Default::default()
},
..Default::default()
}
)?,
"![\"\"](\"javascript:alert(1)\")
",
"should allow non-http protocols w/ `allowDangerousProtocol`"
);
assert_eq!(
to_mdast(
"a ![alpha]() b ![bravo](charlie 'delta') c.",
&Default::default()
)?,
Node::Root(Root {
children: vec![Node::Paragraph(Paragraph {
children: vec![
Node::Text(Text {
value: "a ".into(),
position: Some(Position::new(1, 1, 0, 1, 3, 2))
}),
Node::Image(Image {
alt: "alpha".into(),
url: String::new(),
title: None,
position: Some(Position::new(1, 3, 2, 1, 13, 12))
}),
Node::Text(Text {
value: " b ".into(),
position: Some(Position::new(1, 13, 12, 1, 16, 15))
}),
Node::Image(Image {
alt: "bravo".into(),
url: "charlie".into(),
title: Some("delta".into()),
position: Some(Position::new(1, 16, 15, 1, 41, 40))
}),
Node::Text(Text {
value: " c.".into(),
position: Some(Position::new(1, 41, 40, 1, 44, 43))
})
],
position: Some(Position::new(1, 1, 0, 1, 44, 43))
})],
position: Some(Position::new(1, 1, 0, 1, 44, 43))
}),
"should support image (resource) as `Image`s in mdast"
);
assert_eq!(
to_mdast(
"[x]: y\n\na ![x] b ![x][] c ![d][x] e.",
&Default::default()
)?,
Node::Root(Root {
children: vec![
Node::Definition(Definition {
identifier: "x".into(),
label: Some("x".into()),
url: "y".into(),
title: None,
position: Some(Position::new(1, 1, 0, 1, 7, 6))
}),
Node::Paragraph(Paragraph {
children: vec![
Node::Text(Text {
value: "a ".into(),
position: Some(Position::new(3, 1, 8, 3, 3, 10))
}),
Node::ImageReference(ImageReference {
reference_kind: ReferenceKind::Shortcut,
identifier: "x".into(),
label: Some("x".into()),
alt: "x".into(),
position: Some(Position::new(3, 3, 10, 3, 7, 14))
}),
Node::Text(Text {
value: " b ".into(),
position: Some(Position::new(3, 7, 14, 3, 10, 17))
}),
Node::ImageReference(ImageReference {
reference_kind: ReferenceKind::Collapsed,
identifier: "x".into(),
label: Some("x".into()),
alt: "x".into(),
position: Some(Position::new(3, 10, 17, 3, 16, 23))
}),
Node::Text(Text {
value: " c ".into(),
position: Some(Position::new(3, 16, 23, 3, 19, 26))
}),
Node::ImageReference(ImageReference {
reference_kind: ReferenceKind::Full,
identifier: "x".into(),
label: Some("x".into()),
alt: "d".into(),
position: Some(Position::new(3, 19, 26, 3, 26, 33))
}),
Node::Text(Text {
value: " e.".into(),
position: Some(Position::new(3, 26, 33, 3, 29, 36))
}),
],
position: Some(Position::new(3, 1, 8, 3, 29, 36))
}),
],
position: Some(Position::new(1, 1, 0, 3, 29, 36))
}),
"should support image (reference) as `ImageReference`s in mdast"
);
Ok(())
}