Skip to main content

systemprompt_generator/content/
markdown.rs

1use 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}