maud_pulldown_cmark/
markdown.rs1use std::marker::PhantomData;
2
3use maud::RenderOnce;
4use pulldown_cmark::{ Parser, Event };
5
6use render;
7
8pub struct Markdown<'a, I: 'a + Iterator<Item=Event<'a>>> {
66 events: I,
67 config: render::Config,
68 phantom: PhantomData<&'a I>,
69}
70
71impl<'a> Markdown<'a, Parser<'a>> {
72 pub fn from_string(s: &'a str) -> Markdown<'a, Parser<'a>> {
74 Markdown {
75 events: Parser::new(s),
76 config: render::Config {
77 header_ids: false,
78 },
79 phantom: PhantomData,
80 }
81 }
82}
83
84impl<'a, I: 'a + Iterator<Item=Event<'a>>> Markdown<'a, I> {
85 pub fn from_events(events: I) -> Markdown<'a, I> {
87 Markdown {
88 events: events,
89 config: render::Config {
90 header_ids: false,
91 },
92 phantom: PhantomData,
93 }
94 }
95
96 pub fn with_header_ids(self) -> Markdown<'a, I> {
120 Markdown {
121 config: render::Config {
122 header_ids: true,
123 ..self.config
124 },
125 ..self
126 }
127 }
128}
129
130impl<'a, I: 'a + Iterator<Item=Event<'a>>> RenderOnce for Markdown<'a, I> {
131 fn render_once_to(self, w: &mut String) {
132 render::render_events(self.config, self.events, w);
133 }
134}
135
136#[cfg(test)]
137mod tests {
138 use super::Markdown;
139 use maud::RenderOnce;
140 use pulldown_cmark::{ Parser, Event };
141
142 impl<'a, I: 'a + Iterator<Item=Event<'a>>> Markdown<'a, I> {
143 pub fn render(self) -> String {
144 let mut buffer = String::new();
145 self.render_once_to(&mut buffer);
146 buffer
147 }
148 }
149
150 #[test]
151 pub fn test_from_string() {
152 let markdown = "
153 1. A list
154 2. With some
155 3. <span>Inline html</span>
156 ";
157
158 let buffer = Markdown::from_string(markdown).render();
159 assert_eq!(buffer, "<ol>\n<li>A list</li>\n<li>With some</li>\n<li><span>Inline html</span></li>\n</ol>\n");
160 }
161
162 #[test]
163 pub fn test_from_events() {
164 let markdown = "
165 1. A list
166 2. With some
167 3. <span>Inline html</span>
168 ";
169
170 let events = Parser::new(markdown).map(|ev| match ev {
171 Event::Html(html) | Event::InlineHtml(html) => Event::Text(html),
173 _ => ev,
174 });
175
176 let buffer = Markdown::from_events(events).render();
177 assert_eq!(buffer, "<ol>\n<li>A list</li>\n<li>With some</li>\n<li><span>Inline html</span></li>\n</ol>\n");
178 }
179
180 #[test]
181 pub fn test_without_header_ids() {
182 let markdown = "
183# Header
184## A Sub Header
185 ";
186
187 let buffer = Markdown::from_string(markdown).render();
188 assert_eq!(buffer, "<h1>Header</h1>\n<h2>A Sub Header</h2>\n");
189 }
190
191 #[test]
192 pub fn test_with_header_ids() {
193 let markdown = "
194# Header
195## A Sub Header
196 ";
197
198 let buffer = Markdown::from_string(markdown).with_header_ids().render();
199 assert_eq!(buffer, "<h1 id=\"header\">Header</h1>\n<h2 id=\"a-sub-header\">A Sub Header</h2>\n");
200 }
201
202 #[test]
203 pub fn test_with_header_ids_and_linked_inline_image() {
204 let markdown = "
205# Header [](http://example.com)
206 ";
207
208 let buffer = Markdown::from_string(markdown).with_header_ids().render();
209 assert_eq!(buffer, "<h1 id=\"header-an-image\">Header <a href=\"http://example.com\"><img src=\"http://example.com/image\" alt=\"an image\" /></a></h1>\n");
210 }
211}