cc_audit/parser/
markdown.rs1use super::frontmatter::FrontmatterParser;
4use super::traits::{ContentParser, ContentType, ParsedContent};
5use crate::error::Result;
6
7pub struct MarkdownParser;
9
10impl MarkdownParser {
11 pub fn new() -> Self {
13 Self
14 }
15
16 pub fn extract_body(content: &str) -> &str {
18 if let Some(fm) = FrontmatterParser::extract(content) {
19 let fm_end = content.find("---").unwrap_or(0) + 3 + fm.len() + 3;
21 if fm_end < content.len() {
22 return &content[fm_end..];
23 }
24 }
25 content
26 }
27}
28
29impl Default for MarkdownParser {
30 fn default() -> Self {
31 Self::new()
32 }
33}
34
35impl ContentParser for MarkdownParser {
36 fn parse(&self, content: &str, path: &str) -> Result<ParsedContent> {
37 let mut parsed =
38 ParsedContent::new(ContentType::Markdown, content.to_string(), path.to_string());
39
40 if let Some(fm) = FrontmatterParser::extract(content) {
42 parsed = parsed.with_frontmatter(fm.to_string());
43
44 if let Some(yaml) = FrontmatterParser::parse_json(content) {
46 parsed = parsed.with_structured_data(yaml);
47 }
48 }
49
50 Ok(parsed)
51 }
52
53 fn supported_extensions(&self) -> &[&str] {
54 &[".md", ".markdown"]
55 }
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 #[test]
63 fn test_parse_markdown_with_frontmatter() {
64 let parser = MarkdownParser::new();
65 let content = "---\nname: test\n---\n# Content";
66 let result = parser.parse(content, "test.md").unwrap();
67
68 assert_eq!(result.content_type, ContentType::Markdown);
69 assert!(result.frontmatter.is_some());
70 assert!(result.structured_data.is_some());
71 }
72
73 #[test]
74 fn test_parse_markdown_without_frontmatter() {
75 let parser = MarkdownParser::new();
76 let content = "# Just Content\n\nNo frontmatter here.";
77 let result = parser.parse(content, "test.md").unwrap();
78
79 assert_eq!(result.content_type, ContentType::Markdown);
80 assert!(result.frontmatter.is_none());
81 assert!(result.structured_data.is_none());
82 }
83
84 #[test]
85 fn test_extract_body() {
86 let content = "---\nname: test\n---\n# Body Content";
87 let body = MarkdownParser::extract_body(content);
88 assert!(body.contains("Body Content"));
89 }
90
91 #[test]
92 fn test_supported_extensions() {
93 let parser = MarkdownParser::new();
94 assert!(parser.can_parse("SKILL.md"));
95 assert!(parser.can_parse("README.markdown"));
96 assert!(!parser.can_parse("config.json"));
97 }
98}