Skip to main content

snakedown/render/formats/
md.rs

1use std::path::{Path, PathBuf};
2
3use color_eyre::Result;
4use url::Url;
5
6use crate::render::formats::Renderer;
7
8#[derive(Default)]
9pub struct MdRenderer {}
10impl MdRenderer {
11    pub fn new() -> Self {
12        Self {}
13    }
14}
15impl Renderer for MdRenderer {
16    fn render_header(&self, content: &str, level: usize) -> String {
17        format!("{} {}", &"#".repeat(level), content.trim())
18    }
19
20    fn render_front_matter(&self, title: Option<&str>) -> String {
21        if let Some(t) = title {
22            self.render_header(t, 1)
23        } else {
24            String::new()
25        }
26    }
27
28    fn render_reference(
29        &self,
30        display_text: Option<String>,
31        _target_prefix: &Path,
32        target: String,
33    ) -> Result<String> {
34        let t = if Url::parse(&target).is_ok() {
35            target
36        } else {
37            format!("{}.md", target)
38        };
39        let rendered = match display_text {
40            Some(text) => format!("[{text}]({t})"),
41            None => format!("[{t}]({t})"),
42        };
43        Ok(rendered)
44    }
45
46    fn content_path(&self) -> Option<PathBuf> {
47        None
48    }
49
50    fn index_file(&self, _title: Option<String>) -> Option<(PathBuf, String)> {
51        None
52    }
53}
54
55#[cfg(test)]
56mod test {
57    use std::path::PathBuf;
58
59    use pretty_assertions::assert_eq;
60
61    use color_eyre::Result;
62
63    use crate::render::formats::{Renderer, md::MdRenderer};
64    #[test]
65    fn test_render_md_header() -> Result<()> {
66        let text = String::from("foo");
67        let out = MdRenderer::new().render_header(&text, 1);
68        assert_eq!(out, String::from("# foo"));
69        Ok(())
70    }
71
72    #[test]
73    fn test_render_external_ref() -> Result<()> {
74        let text = String::from("foo");
75        let url = String::from("https://example.com/docs/foo/bar/baz.html#Bullshit");
76        let out = MdRenderer::new().render_reference(Some(text), &PathBuf::from(""), url)?;
77        assert_eq!(
78            out,
79            String::from("[foo](https://example.com/docs/foo/bar/baz.html#Bullshit)")
80        );
81        Ok(())
82    }
83    #[test]
84    fn test_render_internal_ref() -> Result<()> {
85        let text = String::from("foo");
86        let rel_path = String::from("foo/bar/index");
87
88        let out = MdRenderer::new().render_reference(Some(text), &PathBuf::from(""), rel_path)?;
89        assert_eq!(out, String::from("[foo](foo/bar/index.md)"));
90        Ok(())
91    }
92}