roxy_markdown_parser/
lib.rs1use pulldown_cmark::Parser;
2use roxy_core::roxy::Parse;
3
4pub use pulldown_cmark::Options;
5
6#[derive(Debug, Default)]
7pub struct MarkdownParser {
8 options: Option<Options>
9}
10
11impl MarkdownParser {
12 pub fn new() -> Self {
13 Self::default()
14 }
15
16 pub fn with_options(options: Options) -> Self {
17 Self {
18 options: Some(options)
19 }
20 }
21
22 fn get_parser<'a>(&self, input: &'a str) -> Parser<'a> {
23 match self.options {
24 Some(options) => Parser::new_ext(input, options),
25 None => Parser::new(input),
26 }
27 }
28}
29
30impl Parse for MarkdownParser {
31 fn parse(&mut self, _path: &str, src: &[u8], dst: &mut Vec<u8>) -> Result<(), roxy_core::error::Error> {
32 let src = String::from_utf8_lossy(src).to_string();
33 let parser = self.get_parser(src.as_str());
34 pulldown_cmark::html::write_html_io(dst, parser)?;
35 Ok(())
36 }
37}
38
39#[cfg(test)]
40mod tests {
41 use pulldown_cmark::Options;
42 use roxy_core::roxy::Parse;
43
44 use crate::MarkdownParser;
45
46 #[test]
47 fn basic_markdown() {
48 let expected = b"<p><em>this</em> <strong>is</strong> <strong>some</strong> <a href=\"google.com\">markdown</a></p>\n";
49 let input = b"*this* **is** __some__ [markdown](google.com)";
50 let mut parser = MarkdownParser::new();
51 let mut buf = Vec::new();
52 let result = parser.parse("", input, &mut buf);
53 assert!(result.is_ok());
54 assert_eq!(buf, expected);
55 }
56
57 #[test]
58 fn tables() {
59 let expected = b"<table><thead><tr><th>Header 1</th><th>Header 2</th></tr></thead><tbody>
60<tr><td>Cell 1</td><td>Cell 2</td></tr>
61<tr><td>Cell 3</td><td>Cell 4</td></tr>
62</tbody></table>\n";
63
64 let input = b"| Header 1 | Header 2 |
65| -------- | -------- |
66| Cell 1 | Cell 2 |
67| Cell 3 | Cell 4 |";
68 let mut parser = MarkdownParser::with_options(Options::ENABLE_TABLES);
69 let mut buf = Vec::new();
70 let result = parser.parse("", input, &mut buf);
71 assert!(result.is_ok());
72 assert_eq!(buf, expected);
73 }
74}