systemprompt_generator/content/
markdown.rs1use comrak::{Options, markdown_to_html};
2
3fn strip_first_h1(content: &str) -> String {
4 let lines: Vec<&str> = content.lines().collect();
5 let mut result = Vec::new();
6 let mut found_h1 = false;
7
8 for line in lines {
9 let trimmed = line.trim();
10 if !found_h1 && trimmed.starts_with("# ") && !trimmed.starts_with("## ") {
11 found_h1 = true;
12 continue;
13 }
14 result.push(line);
15 }
16
17 result.join("\n")
18}
19
20pub fn render_markdown(content: &str) -> String {
21 let mut options = Options::default();
22
23 options.extension.strikethrough = true;
24 options.extension.table = true;
25 options.extension.autolink = true;
26 options.extension.tasklist = true;
27 options.extension.superscript = true;
28
29 options.render.r#unsafe = false;
30
31 let content_without_h1 = strip_first_h1(content);
32 markdown_to_html(&content_without_h1, &options)
33}
34
35pub fn extract_frontmatter(content: &str) -> Option<(serde_yaml::Value, String)> {
36 if !content.starts_with("---") {
37 return None;
38 }
39
40 let parts: Vec<&str> = content.splitn(3, "---").collect();
41 if parts.len() < 3 {
42 return None;
43 }
44
45 let frontmatter_str = parts[1].trim();
46 let body = parts[2].to_string();
47
48 match serde_yaml::from_str(frontmatter_str) {
49 Ok(yaml) => Some((yaml, body)),
50 Err(e) => {
51 tracing::warn!(error = %e, "Failed to parse markdown frontmatter");
52 None
53 },
54 }
55}